From 73768420c138ffa269c8b22d4c060cbdf8904709 Mon Sep 17 00:00:00 2001 From: fujibee Date: Fri, 21 Aug 2026 13:54:14 -0700 Subject: [PATCH] ci: cancel a PR's superseded test run when its head moves (#848) A pull_request run whose head has been replaced can be used for nothing -- not a verdict, not a gate -- and it keeps its four macOS shards until it finishes. The account runs at most five macOS jobs at once (measured 2026-08-21: 35 runs, 140 macOS jobs, start waits of 0-50 min; one PR's shard waited 50 min behind runs whose heads had already moved). A concurrency group keyed by PR number with cancel-in-progress frees those slots the moment a new head arrives. A push to main is never cancelled: its group is its own run id, and a release reads that run. --- .github/workflows/tests.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 54649be2..a5a9f778 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -54,6 +54,18 @@ on: permissions: contents: read +# A PR run whose head has moved is dead weight: its verdict can be used for +# nothing, and it keeps holding the runner slots -- four macOS shards per run, +# and the account runs at most five macOS jobs at once (measured 2026-08-21: +# 35 runs that day, 140 macOS jobs, queue waits of 0-50 min, one PR's shard +# waiting 50 min behind runs whose heads had already been replaced). So a new +# run for the same PR cancels the one before it. A push to main is never +# cancelled: its group is its own run id, and that run is what a release reads +# (#848). +concurrency: + group: tests-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || github.run_id }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + env: # Number of parallel bats shards per OS. The matrix and the shard helper must # stay in lockstep; the stable summary job below verifies that they do.