ci: a commit with a build still queued or running is not queued again !175

merged merged by cmc on 2026-09-03 00:03 UTC · krz/gitbay:ci-dedupe-pending into main

2 files changed, +24 −4

Layout: unified · split

e2e/ci_dedupe_test.go +20 −1
@@ -57,6 +57,25 @@ func TestFastForwardMergeSkipsBuiltCommit(t *testing.T) {
5757 t.Fatalf("statuses on the merged commit changed:\n%s", status)
5858 }
5959
60 // A branch merged before its build has run: the queued build will
61 // say, so the merge queues nothing either.
62 mustGit(t, dir, env, "checkout", "-q", "-b", "early")
63 os.WriteFile(filepath.Join(dir, "g.txt"), []byte("y\n"), 0o644)
64 mustGit(t, dir, env, "add", ".")
65 mustGit(t, dir, env, "commit", "-q", "-m", "early change")
66 mustGit(t, dir, env, "push", "-q", "origin", "early")
67 if _, errOut, code := inst.ssh(t, aliceKey, "", "mr", "create", "alice/app", "--source", "early", "--target", "main", "--title", "early"); code != 0 {
68 t.Fatalf("mr create: %s", errOut)
69 }
70 before = strings.Count(inst.buildList(t, aliceKey), "\n")
71 if _, errOut, code := inst.ssh(t, aliceKey, "", "mr", "merge", "alice/app", "2", "--strategy", "ff"); code != 0 {
72 t.Fatalf("mr merge early: %s", errOut)
73 }
74 if after := strings.Count(inst.buildList(t, aliceKey), "\n"); after != before {
75 t.Fatalf("a merge before the branch build ran queued a second build:\n%s", inst.buildList(t, aliceKey))
76 }
77 inst.runnerOnce(t, runnerKey) // the branch's queued build, now the only one
78
6079 // A branch whose build fails is built again when it lands.
6180 mustGit(t, dir, env, "checkout", "-q", "-b", "bad")
6281 os.WriteFile(filepath.Join(dir, "fail.txt"), []byte("x\n"), 0o644)
@@ -72,7 +91,7 @@ func TestFastForwardMergeSkipsBuiltCommit(t *testing.T) {
7291 t.Fatalf("mr create: %s", errOut)
7392 }
7493 before = strings.Count(inst.buildList(t, aliceKey), "\n")
75 if _, errOut, code := inst.ssh(t, aliceKey, "", "mr", "merge", "alice/app", "2", "--strategy", "ff"); code != 0 {
94 if _, errOut, code := inst.ssh(t, aliceKey, "", "mr", "merge", "alice/app", "3", "--strategy", "ff"); code != 0 {
7695 t.Fatalf("mr merge bad: %s", errOut)
7796 }
7897 if after := strings.Count(inst.buildList(t, aliceKey), "\n"); after != before+1 {
internal/control/build.go +4 −3
@@ -510,8 +510,9 @@ func QueueBranchBuilds(
510510 }
511511 // A build is a fact about a commit, not a ref: a job has no branch
512512 // filter, so a commit that already passed a job on another branch has
513 // nothing left to prove when a fast-forward lands it here. A failed or
514 // abandoned build does not count; that commit runs again.
513 // nothing left to prove when a fast-forward lands it here, and one
514 // still queued or running there will say soon enough. A failed,
515 // abandoned or cancelled build does not count; that commit runs again.
515516 built, err := st.BuildsForCommit(repo.ID, sha)
516517 if err != nil {
517518 built = nil
@@ -522,7 +523,7 @@ func QueueBranchBuilds(
522523 if j.Tags != "" {
523524 continue
524525 }
525 if b, ok := built[j.Name]; ok && b.Status == "success" {
526 if b, ok := built[j.Name]; ok && (b.Status == "success" || b.Status == "pending" || b.Status == "running") {
526527 continue
527528 }
528529 // Scheduled jobs run on their cron, not on push; a default-branch