CI runs four jobs per push when two would do, and re-runs everything on a rebase #177

closed cmc opened this on 2026-09-06 20:07 UTC · milestone v1.15.0

Discussion

cmc 2026-09-06 20:07 UTC

Landing a four-branch stack today cost somewhere over twenty job runs on a serial runner. Most of them told nobody anything. Two separate causes.

** The wrong jobs run per push

.gitbay/ci.yml runs build, test, vuln and sonar on every push to every branch. Only two of those inform a merge decision:

  • build — go build and go vet, finishes in seconds. Keep it everywhere.
  • test — the e2e suite, ~8 minutes, and the only job that actually gates a merge. Keep it on branches.
  • sonar — ends in || true, so it is report-only and cannot fail a build. Analysing four rebases of a branch that is about to disappear informs nobody. Its per-branch mode exists so a branch does not overwrite main's results (#154), which argues for running it on main rather than on every push.
  • vuln — runs govulncheck@latest, and its own comment says it scans "against the database as it is today, not as it was at commit time". That is a time-dependent signal with a push-shaped trigger. An advisory published against unchanged code is invisible until somebody happens to push, while a rebase that changes nothing re-scans it. It belongs on a schedule.

Proposal: build and test on branches; sonar on main; vuln nightly on main via the schedule: support that already exists. Two jobs per push instead of four, and vulnerability coverage gets better, not worse — a nightly scan notices an advisory that no push would have surfaced.

** A rebase re-runs work already done

Build dedupe exists — TestFastForwardMergeSkipsBuiltCommit, and the comment at internal/control/build.go:692: "if the commit already passed this job on another ref". It keys on the commit sha.

A rebase produces a new sha for an identical tree. Every rebase today therefore re-ran everything, four branches at a time, over a stack that had already passed: the diff between the last fully green tip and the rebased tip was one wiki file and zero code files.

Keying dedupe on the tree hash instead of, or in addition to, the commit sha would have skipped nearly all of it. The question worth settling is whether the job's result is a property of the tree or of the commit. For build and test it is the tree — same files in, same result out. For vuln it is neither, which is the argument for scheduling it above.

Same root as #176: both are the CI treating a rebased branch as new work when its content is not new.

Ref #176, #169.

closed by commit 537b85aba4 by cmc: ci, wiki: run vuln and sonar nightly, not on every push

2026-09-06 22:25 UTC

referenced in commit 387b381242 by cmc: store, control, wiki: reuse a job's success across commits with the same tree

2026-09-07 03:08 UTC

referenced in commit dfb48fe52b by cmc: hookd, wiki: every push shape, what CI makes of it, and a test per row

2026-09-08 07:18 UTC