[fix] release: stop the snapshot job starving the release job
Publish snapshot / snapshot (push) Successful in 1m5s

Pushing a release pushes the branch and then the tags seconds apart.
publish-snapshot.yml keys its concurrency group on the branch and
release.yml keys its own on the tag, so the two never gate each other —
on a single runner they race for it and the branch push always wins.

On 1.0.1 the snapshot job wedged extracting a layer of the runner image,
the release job never started, release.mjs gave up after its 20-minute
wait, and two of three tags were left unpushed. The report still printed
a bold "Done" above an empty shipped list, so it read as a success.

- publish-snapshot.yml skips commits whose message starts with "release:".
  A snapshot of a release commit is the same tree the tag is about to
  publish properly, so skipping costs nothing and removes the race.
- waitForRelease() offers to keep waiting instead of giving up. No
  timeout value survives a wedged runner, so the real choice is between
  asking and making the operator finish the release by hand. --yes and a
  non-interactive run still give up; the latter matters because confirm()
  answers with its default without a terminal, which would extend the
  deadline forever.
- The final header says "Blocked" when it is, and labels the packages
  that did ship before the blockage.
- --wait-timeout defaults to 2400s rather than 1200s.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DCzYTAm9QUhvLNr2EpdagJ
This commit is contained in:
Benjamin Diedrichsen
2026-09-01 15:28:12 +02:00
co-authored by Claude Opus 5
parent eac44b637e
commit 2810d4491f
3 changed files with 73 additions and 14 deletions
+11
View File
@@ -20,6 +20,17 @@ concurrency:
jobs:
snapshot:
# Not on a release commit. `scripts/release.mjs` pushes the branch and then
# the tags seconds apart, and this workflow's concurrency group is keyed on
# the branch while release.yml's is keyed on the tag — so the two never gate
# each other, they race for the runner, and the branch push always gets
# there first. Measured: a snapshot job that wedged pulling the runner image
# held the runner long enough for release.mjs to give up waiting on npmjs,
# leaving two of three tags unpushed.
#
# Skipping costs nothing. A snapshot of a release commit is the same tree
# the tag is about to publish properly, under a version nobody installs.
if: ${{ !startsWith(github.event.head_commit.message, 'release:') }}
runs-on: ubuntu-latest
env: