ci: exempt only push from concurrency cancellation

The two self-hosted standby drills each run their complete unsharded
aggregate with one gate worker, which takes longer than the interval
between master merges, so unconditional cancel-in-progress supersedes a
drill before it reaches a verdict and the lane yields no readiness
evidence for the failover runbook to point a responder at.

Exempt push and nothing else. This has to be decided at workflow level:
cancellation applies to the whole superseded run, so a job-level
concurrency group cannot exempt its job. The negated form is
load-bearing — naming pull_request alone would also stop cancelling
workflow_dispatch, and each runner benchmark fans out to twelve larger
runners for up to fifteen minutes in this same group on master, so a
re-dispatch would queue ahead of a drill instead of replacing a stale
measurement. It does not promise every push run finishes: a newer
pending run still displaces an older one, only that the lanes
periodically reach a verdict.

A master push carries only wine-apt-cache and the two drills; every other
job is pull-request-gated, workflow_dispatch-gated, or if: false. The
spec pins that set and classifies by exact condition, since a negated
event test mentions the event it excludes.
This commit is contained in:
Chinesezjc
2026-08-12 17:55:56 +08:00
parent 15c84cdc4b
commit ba1b0e15fc
5 changed files with 88 additions and 3 deletions
+13 -1
View File
@@ -15,9 +15,21 @@ on:
- larger-runner-benchmark
- consolidated-runner-benchmark
# Cancel a superseded run on every event EXCEPT push. A push run carries the two
# self-hosted standby drills, which take longer than the interval between master
# merges, so cancelling supersedes a drill before it reaches a verdict and the
# lane yields no readiness evidence. Must be decided here: cancellation applies
# to the whole superseded run, so a job-level group cannot exempt its job.
# Negated rather than `== 'pull_request'` so workflow_dispatch keeps cancelling:
# a re-dispatched runner benchmark holds up to 12 larger runners for 15 minutes
# and shares this group with the drills on master, so queueing it would delay
# them. This does not promise every push run finishes (a newer pending run still
# displaces an older one) — only that the lanes periodically reach a verdict.
# Rationale and the bound on this carve-out:
# .agents/notes/implemented/process/2026-07-26-ci-failover-runbook.md
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
cancel-in-progress: ${{ github.event_name != 'push' }}
permissions:
contents: read