Skip to content

ci: stop commits to main from serializing into one concurrency queue - #638

Merged
mxschmitt merged 2 commits into
mainfrom
fix/ci-concurrency-serializes-main
Aug 17, 2026
Merged

ci: stop commits to main from serializing into one concurrency queue#638
mxschmitt merged 2 commits into
mainfrom
fix/ci-concurrency-serializes-main

Conversation

@mxschmitt

Copy link
Copy Markdown
Owner

Commits to main currently queue behind each other instead of building in parallel, and most of them never build at all.

Cause

All three workflows key concurrency on github.ref, and cancel-in-progress evaluates to false for pushes:

group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

For every push to main, github.ref is the same string (refs/heads/main), so all of them land in one group and serialize. Worse, GitHub keeps only one pending run per group — a newly queued run cancels the previously-pending one. With a ~20 minute test matrix, a burst of merges means only the first and last commits ever build.

Observed on main today:

commit created outcome
6380436 03:28:02 ran to 03:51
4ebaf2b 03:28:39 cancelled at 03:46, never ran
3b1e7c9 03:46:45 stuck queued
74db994 04:08:53 stuck pending

4ebaf2b is main's HEAD. Three cancelled-in-a-row also show up on 2026-06-25.

Fix

Key pushes by commit instead of by ref:

group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
  • pushpull_request.number is null, so the group is the SHA: every commit gets its own group, nothing queues, nothing gets cancelled.
  • pull_request → the group is the PR number, so a new push still supersedes the in-progress check via cancel-in-progress. Using the PR number rather than the merge ref also avoids two fork PRs sharing a branch name colliding.

Applied to build.yml and verify_type_generation.yml.

docs.yml is left serialized on purpose — it pushes to gh-pages, where concurrent deploys can race and publish an older build last. Added a comment so it doesn't read as the same oversight.

🤖 Generated with Claude Code

https://claude.ai/code/session_01M4oTuMi5F5wkzwribhTKdu

mxschmitt and others added 2 commits August 16, 2026 21:18
The concurrency group was keyed on `github.ref`, which is `refs/heads/main`
for every push to main, and `cancel-in-progress` is false for pushes. So
every commit to main queued behind the previous one, and because GitHub
permits only one *pending* run per group, each new commit cancelled the
previously-pending run — intermediate commits on main were never built.

Key pushes by `github.sha` instead so each commit gets its own group.
Pull requests keep collapsing onto one group (now the PR number rather
than the merge ref) so a new push still supersedes the running check.

docs.yml stays serialized on purpose — it deploys to gh-pages, where
concurrent runs can race and publish an older build last.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M4oTuMi5F5wkzwribhTKdu
Adopts the common head_ref||run_id idiom's run_id fallback, so a commit
that lands on two triggering refs (roll/* then main) does not queue
against itself, and cancel-in-progress can be an unconditional true --
inert on pushes because each push group holds a single run.

Keeps the PR number rather than head_ref as the pull_request key:
head_ref is a branch name, so two fork PRs both using patch-1 would
share a group and cancel each other.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M4oTuMi5F5wkzwribhTKdu
@mxschmitt
mxschmitt merged commit 416d1ca into main Aug 17, 2026
21 checks passed
@mxschmitt
mxschmitt deleted the fix/ci-concurrency-serializes-main branch August 17, 2026 04:24
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