Summary
release.yml runs the authorization verifier under Zsh but never installs it:
- name: Verify release authorization
run: zsh -f scripts/verify-release-tag.zsh
ubuntu-latest has no Zsh, so the step exits 127 before any verification happens:
/home/runner/work/_temp/....sh: line 1: zsh: command not found
##[error]Process completed with exit code 127
Every other workflow in the repository that runs Zsh installs it first, for example promotion-readiness.yml:27 and zsh-n.yml:84 (sudo apt-get install -yq zsh). release.yml is the only one that does not.
How it surfaced
The workflow reached main only with #494, since #470 added it on next before v2.0.0 shipped. Pushing v2.0.1 was therefore its first ever execution, and it failed on that first run. The defect has been latent since #470.
Impact
Publication is blocked for every tag. The failure is also awkward to recover from: verify-release-tag.zsh requires the tag target to equal the current origin/main, so landing a fix moves main and invalidates any tag already pushed. That forces either a moved tag or a burned version number.
v2.0.1 was published manually to avoid moving a public tag. The verifier itself was run locally against the exact tag first and passed:
Release authorization verified for v2.0.1 at 86758198344052d60b25f454cd3b64269a8ef2ea.
so only the broken execution environment was bypassed, not the authorization logic.
Fix
Add a Zsh install step to the publish job before the verification step, matching the pattern the rest of the repository uses.
Worth considering separately
The tag-equals-main precondition makes a failed publication expensive to retry, because any fix to the release path invalidates the pending tag. Loosening it to "tag target is an ancestor of origin/main" would keep the intent, that a release comes from reviewed stable history, while allowing a retry after a workflow fix. Not addressed here.
Summary
release.ymlruns the authorization verifier under Zsh but never installs it:ubuntu-latesthas no Zsh, so the step exits 127 before any verification happens:Every other workflow in the repository that runs Zsh installs it first, for example
promotion-readiness.yml:27andzsh-n.yml:84(sudo apt-get install -yq zsh).release.ymlis the only one that does not.How it surfaced
The workflow reached
mainonly with #494, since #470 added it onnextbefore v2.0.0 shipped. Pushingv2.0.1was therefore its first ever execution, and it failed on that first run. The defect has been latent since #470.Impact
Publication is blocked for every tag. The failure is also awkward to recover from:
verify-release-tag.zshrequires the tag target to equal the currentorigin/main, so landing a fix movesmainand invalidates any tag already pushed. That forces either a moved tag or a burned version number.v2.0.1 was published manually to avoid moving a public tag. The verifier itself was run locally against the exact tag first and passed:
so only the broken execution environment was bypassed, not the authorization logic.
Fix
Add a Zsh install step to the
publishjob before the verification step, matching the pattern the rest of the repository uses.Worth considering separately
The tag-equals-
mainprecondition makes a failed publication expensive to retry, because any fix to the release path invalidates the pending tag. Loosening it to "tag target is an ancestor oforigin/main" would keep the intent, that a release comes from reviewed stable history, while allowing a retry after a workflow fix. Not addressed here.