Repository navigation
ci(publish): cancel superseded runs for pull requests only - #145
Merged
chrisuthe merged 1 commit intoOct 7, 2026
Conversation
A run whose publish-report cancelled an in-progress predecessor has its deploy-pages job rejected by GitHub with an internal server error before it is dispatched, so the report is not published. Only pull request runs now share a per-ref concurrency group. Every other event gets a group of its own, so a run that deploys never cancels another through it. Pull request runs never deploy and are where the superseded macOS minutes were being spent.
There was a problem hiding this comment.
🟢 Approval recommended
The focused workflow change matches the stated deployment-safety goal while preserving PR cancellation.
0 open findings
What changed in this PR
Limits superseded-run cancellation to pull requests, preventing deploy-capable runs from cancelling one another.
Changes:
- Uses the PR ref for pull-request concurrency groups.
- Uses the unique run ID for all other events.
| File | Description |
|---|---|
.github/workflows/publish.yml |
Adjusts publish-job concurrency grouping by event type. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
chrisuthe
marked this pull request as ready for review
October 7, 2026 18:51
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.
Problem
Since #138, two
mainpublish runs have built the report successfully and then failed to deploy it, so the published report is stale (192 cases, revisions[3,4,5], against 16 scenarios and revisions up to 6 onmain).scripts/detect_regressions.pycompares every pull request against that published baseline, so the regression gate is weakened for as long as it stays stale.What actually happens
The failed
deploy-pagesjobs never start. GitHub rejects them before dispatch:deploy-pagesannotationInternal server error. Correlation ID: 6e0591d9-56c8-44d2-b32f-7578e7ef5debInternal server error. Correlation ID: 6af99b7e-2315-4ba1-b23b-2de8ff9748d6Both jobs have no runner, no steps and no log, and both completed exactly 56 seconds after their
publish-reportfinished. The annotation is only visible on the job page; the check-run annotations API returns an empty list for both.It is not leftover environment state. The deployments API shows no deployment was created for either failed run, and none for the cancelled runs before them (
4c9c79a,72dcdc4), whosedeploy-pageswas skipped. Thegithub-pagesenvironment has a single rule, themainbranch policy, and no other run held thepagesgroup at either failure.What the two failed runs share, and no successful deploy does: their
publish-reportjob is the one that cancelled an in-progress predecessor through the per-refcancel-in-progressgroup. Runs since #138 that cancelled nothing deployed normally (98f963c,4a5236c,dd3b9ed), as did every run before it.This is a correlation, two of two against three of three. Why GitHub errors is not observable from outside.
Change
Only pull request runs share a per-ref concurrency group. Every other event gets a group keyed on
github.run_id, so a run that deploys never cancels another through it.deploy-pagesis gated ongithub.event_name != 'pull_request'), so cancelling them cannot interact with a deployment. They are also where the superseded macOS minutes were spent, so that saving is kept in full.mainruns run to completion again, as they did before ci(publish): cancel superseded runs per ref without cancelling Pages deployments #138. Two can overlap; their deploys are still serialised by thepagesgroup.The steps, their conditions and the job outputs are untouched.
Alternatives
cancel-in-progress: ${{ github.event_name == 'pull_request' }}with the group unchanged.mainruns would then queue in the shared group, and a newer arrival cancels the pending one. That is still a deploying run displacing another through this group, so there is no evidence it avoids the error.workflow_runworkflow. A second workflow, a cross-run artifact download and default-branch semantics, for a one-line problem.Known limits
mainrun finishes after a newer one, it deploys the older report. This is the behaviour from before ci(publish): cancel superseded runs per ref without cancelling Pages deployments #138, and the next push or the nightly run corrects it.pagesgroup also came in with ci(publish): cancel superseded runs per ref without cancelling Pages deployments #138. With overlappingmainruns, a third deployment arriving while one is in flight and one is pending cancels the pending one. The run history has not exercised that case, so this change removes the observed trigger rather than proving the deploy path safe.Verification
Verified locally:
actionlint .github/workflows/publish.ymlexits 0 with no findings (actionlint 1.7.12), before and after the change.python -m unittest discover -s tests: 344 tests, OK, 2 skipped.Only a live merge can show:
mainpush arriving while anothermainrun is in progress leaves both running and both deploying.