Skip to content

fix(ci): main runs were being cancelled, recording nothing - #42

Merged
vietanhdev merged 1 commit into
mainfrom
fix/ci-main-runs-cancelled
Jul 20, 2026
Merged

fix(ci): main runs were being cancelled, recording nothing#42
vietanhdev merged 1 commit into
mainfrom
fix/ci-main-runs-cancelled

Conversation

@vietanhdev

Copy link
Copy Markdown
Owner

Found while checking that main was healthy after this batch of merges. It wasn't being checked at all.

The bug

ci.yml's concurrency block intended never to cancel on main — the comment said "Never cancel on main: those runs record what shipped" — and did the opposite:

cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

The expression renders to the string "false", and a non-empty string is truthy in that position. So main was cancelled like any other ref.

It failed silently for exactly as long as nobody merged two things in quick succession — which is why it survived until this batch.

What it cost

Four main runs were cancelled during these merges, each with zero jobs recorded:

29714394275  push  cancelled  fix(fan-curve): ... (#36)     0 jobs
29714371727  push  cancelled  fix(mcp): ...       (#37)     0 jobs
29714814590  push  cancelled  docs(apt): ...      (#39)     0 jobs
29715014158  push  cancelled  security(sync): ... (#32)     0 jobs

Each was killed ~40s in by the next merge. Those four commits have no evidence they ever built. The runs meant to be the record of what shipped are precisely the ones that got killed.

The fix

Put the condition in the concurrency group instead, where it's unambiguous:

group: ci-${{ github.workflow }}-${{ github.ref }}-${{ github.ref == 'refs/heads/main' && github.sha || 'shared' }}
cancel-in-progress: true

On main the SHA gives every run its own group, so there is never a run to supersede. Every other ref keeps a per-ref group, so a force-push still cancels the superseded run.

Guard

tests/workflow_concurrency.rs covers both halves, because fixing one and breaking the other is worse than the original:

  • cancel-in-progress must be a literal true/false, never an expression
  • the group must keep its per-SHA component — with cancel-in-progress: true and a plain per-ref group, main would be cancelled on every push

Mutation-verified — restoring the original two lines fails both:

main_runs_cannot_be_superseded ... FAILED
  the concurrency group must include github.sha for main
cancel_in_progress_is_never_an_expression ... FAILED
  cancel-in-progress must be a literal true/false ...

It lives outside .github/ so it can't match its own explanation, and strips # comments so the warning I left in ci.yml documenting the broken form isn't flagged as a violation.

118 tests, clippy clean, fmt clean.

The concurrency block intended never to cancel on main -- the comment said
so -- and did the opposite:

  cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

The expression renders to the STRING "false", and a non-empty string is
truthy in that position, so main was cancelled like any other ref. It
failed silently for exactly as long as nobody merged twice in quick
succession.

Four main runs were cancelled during this batch of merges (#36, #37, #39,
#32), each with ZERO jobs recorded -- so those commits have no evidence
they ever built. The runs that were supposed to be the record of what
shipped are the ones that got killed.

Encoding the rule in the concurrency GROUP is unambiguous: on main the SHA
gives every run its own group, so there is nothing to supersede; every
other ref keeps a per-ref group, so a force-push still cancels the old run.

tests/workflow_concurrency.rs guards both halves -- an expression-valued
cancel-in-progress, and a group that lost its per-SHA component (which
with cancel-in-progress: true would cancel main on every push, strictly
worse than the bug it replaced). Mutation-verified: restoring the original
two lines fails both.

118 tests.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
thinkutils 88c6d0d Jul 20 2026, 03:46 AM

@vietanhdev
vietanhdev merged commit 1a60914 into main Jul 20, 2026
9 of 10 checks passed
@vietanhdev
vietanhdev deleted the fix/ci-main-runs-cancelled branch July 20, 2026 03:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant