Skip to content

Commit 631e97b

Browse files
johnscaclaude
andcommitted
record the tag claim rather than inferring it, and read previous_version
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent bc459ca commit 631e97b

1 file changed

Lines changed: 27 additions & 19 deletions

File tree

‎.github/workflows/cut-release.yml‎

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,11 @@ jobs:
113113
114114
# Only fires on the first release, where the baseline is 0.0.0. A patch
115115
# from there lands v0.0.1 permanently, so this is enforced rather than
116-
# left to the input description.
116+
# left to the input description. Reads `previous_version` rather than
117+
# `previous_tag`, which carries the action's tag prefix and would make
118+
# this a second copy of a default owned elsewhere.
117119
- name: Require the first release to be major
118-
if: ${{ steps.version.outputs.previous_tag == 'v0.0.0' && inputs.bump != 'major' }}
120+
if: ${{ steps.version.outputs.previous_version == '0.0.0' && inputs.bump != 'major' }}
119121
env:
120122
BUMP: ${{ inputs.bump }}
121123
run: |
@@ -182,28 +184,33 @@ jobs:
182184
# taken, the release call publishes against whatever commit that tag
183185
# points at, and immutability makes that permanent.
184186
#
185-
# Claiming first leaves the tag briefly unlocked, and a tag left
187+
# Claiming first leaves the tag briefly unlocked, and one left
186188
# behind makes the next dispatch skip this version number. So the
187-
# cleanup is armed before the claim, leaving no window where the tag
188-
# is unowned, and it is conditional on the tag being this run's so
189-
# that it never deletes one the claim lost to. Anything it cannot
190-
# confirm it leaves alone: a stray tag costs a number, a wrong delete
191-
# costs a release.
189+
# cleanup is armed before the claim, and acts only on a claim that
190+
# returned. Ownership is recorded rather than read back off the tag,
191+
# because a tag that beat us to the name is almost always at this
192+
# same commit: every run targets the default-branch tip.
193+
#
194+
# What is left is the one statement between the claim landing and
195+
# `claimed=1`, and it fails the safe way. A stray tag costs a version
196+
# number, a wrong delete costs a release.
192197
#
193198
# An EXIT trap covers a cancelled job as well as a failed command,
194199
# though not a SIGKILL.
200+
claimed=0
195201
cleanup() {
196-
local ref_sha releases
197-
ref_sha=$(gh api "repos/${GITHUB_REPOSITORY}/git/ref/tags/${TAG}" --jq .object.sha 2>/dev/null) || return 0
198-
if [ "${ref_sha}" != "${COMMIT}" ]; then
199-
return 0
200-
fi
201-
# Listing answers "no release" with an empty result and a success,
202-
# which is what tells a confirmed absence apart from a lookup that
203-
# failed. Asking for the release by tag reports both the same way,
204-
# and deleting on an unconfirmed absence would strip the tag off a
205-
# release that did publish.
206-
releases=$(gh api --paginate "repos/${GITHUB_REPOSITORY}/releases" \
202+
[ "${claimed}" = 1 ] || return 0
203+
local releases
204+
# The release call can land while this run dies before clearing
205+
# the trap, so a tag of ours can already be locked. Listing
206+
# answers "no release" with an empty result and a success, which
207+
# tells a confirmed absence apart from a lookup that failed.
208+
# Asking for the release by tag reports both the same way, and
209+
# deleting on an unconfirmed absence would strip the tag off a
210+
# release that did publish. One page is enough, newest first, and
211+
# it keeps this to a bounded number of calls inside whatever
212+
# grace period a cancelled job gets.
213+
releases=$(gh api "repos/${GITHUB_REPOSITORY}/releases?per_page=100" \
207214
--jq '.[] | select(.tag_name == env.TAG) | .id') || return 0
208215
if [ -n "${releases}" ]; then
209216
return 0
@@ -214,6 +221,7 @@ jobs:
214221
gh api "repos/${GITHUB_REPOSITORY}/git/refs" \
215222
-f "ref=refs/tags/${TAG}" \
216223
-f "sha=${COMMIT}" > /dev/null
224+
claimed=1
217225
gh release create "${TAG}" \
218226
--repo "${GITHUB_REPOSITORY}" \
219227
--target "${COMMIT}" \

0 commit comments

Comments
 (0)