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) {
57 t.Fatalf("statuses on the merged commit changed:\n%s", status) 57 t.Fatalf("statuses on the merged commit changed:\n%s", status)
58 } 58 }
59 59
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
60 // A branch whose build fails is built again when it lands. 79 // A branch whose build fails is built again when it lands.
61 mustGit(t, dir, env, "checkout", "-q", "-b", "bad") 80 mustGit(t, dir, env, "checkout", "-q", "-b", "bad")
62 os.WriteFile(filepath.Join(dir, "fail.txt"), []byte("x\n"), 0o644) 81 os.WriteFile(filepath.Join(dir, "fail.txt"), []byte("x\n"), 0o644)
@@ -72,7 +91,7 @@ func TestFastForwardMergeSkipsBuiltCommit(t *testing.T) {
72 t.Fatalf("mr create: %s", errOut) 91 t.Fatalf("mr create: %s", errOut)
73 } 92 }
74 before = strings.Count(inst.buildList(t, aliceKey), "\n") 93 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 {
76 t.Fatalf("mr merge bad: %s", errOut) 95 t.Fatalf("mr merge bad: %s", errOut)
77 } 96 }
78 if after := strings.Count(inst.buildList(t, aliceKey), "\n"); after != before+1 { 97 if after := strings.Count(inst.buildList(t, aliceKey), "\n"); after != before+1 {
internal/control/build.go +4 −3
@@ -510,8 +510,9 @@ func QueueBranchBuilds(
510 } 510 }
511 // A build is a fact about a commit, not a ref: a job has no branch 511 // A build is a fact about a commit, not a ref: a job has no branch
512 // filter, so a commit that already passed a job on another branch has 512 // 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 513 // nothing left to prove when a fast-forward lands it here, and one
514 // abandoned build does not count; that commit runs again. 514 // still queued or running there will say soon enough. A failed,
515 // abandoned or cancelled build does not count; that commit runs again.
515 built, err := st.BuildsForCommit(repo.ID, sha) 516 built, err := st.BuildsForCommit(repo.ID, sha)
516 if err != nil { 517 if err != nil {
517 built = nil 518 built = nil
@@ -522,7 +523,7 @@ func QueueBranchBuilds(
522 if j.Tags != "" { 523 if j.Tags != "" {
523 continue 524 continue
524 } 525 }
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") {
526 continue 527 continue
527 } 528 }
528 // Scheduled jobs run on their cron, not on push; a default-branch 529 // Scheduled jobs run on their cron, not on push; a default-branch