diff --git a/cmd/gbrgames/worker.go b/cmd/gbrgames/worker.go index c8a62fd..13fbdf3 100644 --- a/cmd/gbrgames/worker.go +++ b/cmd/gbrgames/worker.go @@ -360,7 +360,9 @@ func (c *workerConfig) openPR(dir string, job *builderJob, res *buildResult) (st if len(short) > 8 { short = short[:8] } - branch := "draft/" + res.GameID + "-" + short + // One branch per run: a rerun of the same job must not push onto the earlier run's branch, which + // may have gained review commits since + branch := draftBranch(res.GameID, short, time.Now()) auth := "http.extraHeader=Authorization: token " + c.botToken steps := []struct { name string @@ -415,3 +417,7 @@ func readJSON(p string, out any) error { } return json.Unmarshal(raw, out) } + +func draftBranch(gameID, job string, at time.Time) string { + return "draft/" + gameID + "-" + job + "-" + at.UTC().Format("20060102-150405") +} diff --git a/cmd/gbrgames/worker_test.go b/cmd/gbrgames/worker_test.go index 895d5fe..b81d21c 100644 --- a/cmd/gbrgames/worker_test.go +++ b/cmd/gbrgames/worker_test.go @@ -5,6 +5,7 @@ import ( "net/http/httptest" "strings" "testing" + "time" ) func TestCheckBotNeedsPushAccess(t *testing.T) { @@ -68,3 +69,11 @@ func TestCheckBotWithRepositoryOnlyToken(t *testing.T) { t.Errorf("identity = %s <%s>", c.botLogin, c.botEmail) } } + +func TestDraftBranchIsNewForEveryRun(t *testing.T) { + first := draftBranch("example", "4b174b2d", time.Date(2026, 10, 25, 21, 30, 0, 0, time.UTC)) + rerun := draftBranch("example", "4b174b2d", time.Date(2026, 10, 25, 22, 5, 9, 0, time.UTC)) + if first != "draft/example-4b174b2d-20261025-213000" || first == rerun { + t.Errorf("first %q, rerun %q", first, rerun) + } +}