fix(ci): the template that let a commit cancel another commit's run - #53
Merged
Conversation
Twenty-eight of twenty-nine repos in the fleet carry
`group: ci-${{ github.ref }}` with `cancel-in-progress: true`, because
that is what templates/ci/ has always said. It lets a newer merge cancel
an older commit's CI run, and every deploy path keys off that run.
It broke two repos today, in the two ways it can break:
fleetcrown, silently. Deploy chains off workflow_run and requires
conclusion == success; a cancelled run reports cancelled, so Deploy
skipped. Four merges sat on main with every check green, nothing red
anywhere, and the box serving the previous build. Each needed a Deploy
dispatched by hand, and the only way to notice was to compare the box's
build stamp against main's tip.
hirnli, loudly. Its Deploy waits for CI to pass on the commit it is
shipping, found the cancelled run, and failed — which is the better of the
two outcomes, because somebody sees it.
Both had the same second cause underneath: auto-merge re-arms CI with a
dispatch, and under one group-per-branch that dispatch cancels the push
run for the SAME commit.
So the templates key main per commit, and the hygiene audit gains
ci-strands-commits so the repos that already copied the old line are found
by a sweep rather than by an outage. The rule only fires where a collision
is actually possible: a group already keyed by github.sha, or one that
never cancels, is left alone.
The rule has its own test, including the case that matters — a file whose
COMMENT mentions github.sha while its group does not must still flag.
Comments are stripped before matching, because a gate that a comment can
satisfy is not a gate.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Z7YRpgsEtNjRqr1usHMQY
This was referenced Sep 11, 2026
catomean
added a commit
to bitbaum/substrata
that referenced
this pull request
Sep 11, 2026
The concurrency group was keyed by branch with cancel-in-progress, so a newer merge cancels an older commit's CI — and every deploy path keys off that run. One that waits for CI to pass on the commit finds a cancelled run and stops. One chained on workflow_run sees conclusion=cancelled and skips. auto-merge also re-arms CI with a dispatch, and under one group-per-branch that dispatch cancels the push run for the SAME commit. Measured across the fleet on 2026-09-11: 28 of 39 ci.yml files had this shape. It broke two repos that day, in the two ways it can break. fleetcrown failed silently — Deploy skipped, four merges sat on main with every check green and nothing red while the box served the previous build, each needing a hand-dispatched deploy. hirnli failed loudly, erroring at its wait-for-CI step, which is the better outcome because somebody sees it. Keying main per commit lets both runs finish, so whatever the deploy path looks for is there. Branch behaviour is unchanged: the newest push is still the only one that matters there. The templates this was copied from are fixed in bitbaum/fleet#53, which also adds a ci-strands-commits rule to the hygiene audit so the remaining repos are found by a sweep rather than by an outage. Claude-Session: https://claude.ai/code/session_018Z7YRpgsEtNjRqr1usHMQY Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
catomean
added a commit
to bitbaum/solon
that referenced
this pull request
Sep 11, 2026
The concurrency group was keyed by branch with cancel-in-progress, so a newer merge cancels an older commit's CI — and every deploy path keys off that run. One that waits for CI to pass on the commit finds a cancelled run and stops. One chained on workflow_run sees conclusion=cancelled and skips. auto-merge also re-arms CI with a dispatch, and under one group-per-branch that dispatch cancels the push run for the SAME commit. Measured across the fleet on 2026-09-11: 28 of 39 ci.yml files had this shape. It broke two repos that day, in the two ways it can break. fleetcrown failed silently — Deploy skipped, four merges sat on main with every check green and nothing red while the box served the previous build, each needing a hand-dispatched deploy. hirnli failed loudly, erroring at its wait-for-CI step, which is the better outcome because somebody sees it. Keying main per commit lets both runs finish, so whatever the deploy path looks for is there. Branch behaviour is unchanged: the newest push is still the only one that matters there. The templates this was copied from are fixed in bitbaum/fleet#53, which also adds a ci-strands-commits rule to the hygiene audit so the remaining repos are found by a sweep rather than by an outage. Claude-Session: https://claude.ai/code/session_018Z7YRpgsEtNjRqr1usHMQY Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
catomean
added a commit
to bitbaum/botsmann
that referenced
this pull request
Sep 11, 2026
The concurrency group was keyed by branch with cancel-in-progress, so a newer merge cancels an older commit's CI — and every deploy path keys off that run. One that waits for CI to pass on the commit finds a cancelled run and stops. One chained on workflow_run sees conclusion=cancelled and skips. auto-merge also re-arms CI with a dispatch, and under one group-per-branch that dispatch cancels the push run for the SAME commit. Measured across the fleet on 2026-09-11: 28 of 39 ci.yml files had this shape. It broke two repos that day, in the two ways it can break. fleetcrown failed silently — Deploy skipped, four merges sat on main with every check green and nothing red while the box served the previous build, each needing a hand-dispatched deploy. hirnli failed loudly, erroring at its wait-for-CI step, which is the better outcome because somebody sees it. Keying main per commit lets both runs finish, so whatever the deploy path looks for is there. Branch behaviour is unchanged: the newest push is still the only one that matters there. The templates this was copied from are fixed in bitbaum/fleet#53, which also adds a ci-strands-commits rule to the hygiene audit so the remaining repos are found by a sweep rather than by an outage. Claude-Session: https://claude.ai/code/session_018Z7YRpgsEtNjRqr1usHMQY Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
catomean
added a commit
to bitbaum/datacat
that referenced
this pull request
Sep 11, 2026
The concurrency group was keyed by branch with cancel-in-progress, so a newer merge cancels an older commit's CI — and every deploy path keys off that run. One that waits for CI to pass on the commit finds a cancelled run and stops. One chained on workflow_run sees conclusion=cancelled and skips. auto-merge also re-arms CI with a dispatch, and under one group-per-branch that dispatch cancels the push run for the SAME commit. Measured across the fleet on 2026-09-11: 28 of 39 ci.yml files had this shape. It broke two repos that day, in the two ways it can break. fleetcrown failed silently — Deploy skipped, four merges sat on main with every check green and nothing red while the box served the previous build, each needing a hand-dispatched deploy. hirnli failed loudly, erroring at its wait-for-CI step, which is the better outcome because somebody sees it. Keying main per commit lets both runs finish, so whatever the deploy path looks for is there. Branch behaviour is unchanged: the newest push is still the only one that matters there. The templates this was copied from are fixed in bitbaum/fleet#53, which also adds a ci-strands-commits rule to the hygiene audit so the remaining repos are found by a sweep rather than by an outage. Claude-Session: https://claude.ai/code/session_018Z7YRpgsEtNjRqr1usHMQY Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
catomean
added a commit
to bitbaum/petvity
that referenced
this pull request
Sep 11, 2026
The concurrency group was keyed by branch with cancel-in-progress, so a newer merge cancels an older commit's CI — and every deploy path keys off that run. One that waits for CI to pass on the commit finds a cancelled run and stops. One chained on workflow_run sees conclusion=cancelled and skips. auto-merge also re-arms CI with a dispatch, and under one group-per-branch that dispatch cancels the push run for the SAME commit. Measured across the fleet on 2026-09-11: 28 of 39 ci.yml files had this shape. It broke two repos that day, in the two ways it can break. fleetcrown failed silently — Deploy skipped, four merges sat on main with every check green and nothing red while the box served the previous build, each needing a hand-dispatched deploy. hirnli failed loudly, erroring at its wait-for-CI step, which is the better outcome because somebody sees it. Keying main per commit lets both runs finish, so whatever the deploy path looks for is there. Branch behaviour is unchanged: the newest push is still the only one that matters there. The templates this was copied from are fixed in bitbaum/fleet#53, which also adds a ci-strands-commits rule to the hygiene audit so the remaining repos are found by a sweep rather than by an outage. Claude-Session: https://claude.ai/code/session_018Z7YRpgsEtNjRqr1usHMQY Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
catomean
added a commit
to bitbaum/orangecat
that referenced
this pull request
Sep 11, 2026
The concurrency group was keyed by branch with cancel-in-progress, so a newer merge cancels an older commit's CI — and every deploy path keys off that run. One that waits for CI to pass on the commit finds a cancelled run and stops. One chained on workflow_run sees conclusion=cancelled and skips. auto-merge also re-arms CI with a dispatch, and under one group-per-branch that dispatch cancels the push run for the SAME commit. Measured across the fleet on 2026-09-11: 28 of 39 ci.yml files had this shape. It broke two repos that day, in the two ways it can break. fleetcrown failed silently — Deploy skipped, four merges sat on main with every check green and nothing red while the box served the previous build, each needing a hand-dispatched deploy. hirnli failed loudly, erroring at its wait-for-CI step, which is the better outcome because somebody sees it. Keying main per commit lets both runs finish, so whatever the deploy path looks for is there. Branch behaviour is unchanged: the newest push is still the only one that matters there. The templates this was copied from are fixed in bitbaum/fleet#53, which also adds a ci-strands-commits rule to the hygiene audit so the remaining repos are found by a sweep rather than by an outage. Claude-Session: https://claude.ai/code/session_018Z7YRpgsEtNjRqr1usHMQY Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
28 of 29 repos carry
group: ci-${{ github.ref }}withcancel-in-progress: true, because that is whattemplates/ci/has always said. It lets a newer merge cancel an older commit's CI run, and every deploy path keys off that run.It broke two repos today, in the two ways it can break.
fleetcrown — silently. Deploy chains off
workflow_runand requiresconclusion == 'success'; a cancelled run reportscancelled, so Deploy skipped. Four merges sat on main with every check green, nothing red anywhere, and the box serving the previous build. Each needed a Deploy dispatched by hand, and the only way to notice was comparing the box's build stamp against main's tip. (bitbaum/fleetcrown#662)hirnli — loudly. Its Deploy waits for CI to pass on the commit it is shipping, found the cancelled run, and failed. That is the better of the two outcomes, because somebody sees it. (bitbaum/hirnli#111)
Both share a second cause: auto-merge re-arms CI with a dispatch, and under one group-per-branch that dispatch cancels the push run for the same commit.
What changes
cicd-hygiene-audit.shgainsci-strands-commits, so the repos that already copied the old line are found by a sweep instead of by an outage. It fires only where a collision is possible: a group already keyed bygithub.sha, or one that never cancels, is left alone.The rule has a test
scripts/ci/test-ci-strands-commits.sh:That last case is the point. Comments are stripped before matching, because a gate a comment can satisfy is not a gate.
Shell syntax checked; both templates parse as YAML.
🤖 Generated with Claude Code
https://claude.ai/code/session_018Z7YRpgsEtNjRqr1usHMQY