Skip to content

Commit 352781e

Browse files
committed
Replace rolling canary release each run for immutable-release repos
1 parent 5e38c5a commit 352781e

1 file changed

Lines changed: 17 additions & 21 deletions

File tree

.github/workflows/release-canary.yml

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -120,35 +120,31 @@ jobs:
120120
labels: ${{ steps.docker-meta.outputs.labels }}
121121
annotations: ${{ steps.docker-meta.outputs.annotations }}
122122

123-
# The `canary` tag is intentionally mutable. Per .claude/rules/release.md, tag rulesets
124-
# in this org cover only `main` and `v*` tags, so GITHUB_TOKEN can force-update it.
125-
# If a future ruleset covers `canary*`, switch this step to an App token.
126-
- name: Move canary tag to current commit
123+
# GitHub's immutable-releases feature on this repo prevents editing existing releases
124+
# and their tags. Rolling canary is therefore implemented as delete-then-create on
125+
# every run. Per .claude/rules/release.md, tag rulesets cover only `main` and `v*`,
126+
# so deletion of `canary` via GITHUB_TOKEN is permitted.
127+
- name: Replace rolling canary release
127128
env:
128129
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
129130
REPO: ${{ github.repository }}
130131
SHA: ${{ github.sha }}
131132
TAG: ${{ steps.canary-meta.outputs.tag }}
132-
run: |
133-
set -euo pipefail
134-
if gh api "repos/${REPO}/git/ref/tags/${TAG}" >/dev/null 2>&1; then
135-
gh api --method PATCH "repos/${REPO}/git/refs/tags/${TAG}" -f sha="$SHA" -F force=true >/dev/null
136-
else
137-
gh api --method POST "repos/${REPO}/git/refs" -f ref="refs/tags/${TAG}" -f sha="$SHA" >/dev/null
138-
fi
139-
140-
- name: Update rolling canary pre-release
141-
env:
142-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
143-
SHA: ${{ github.sha }}
144-
TAG: ${{ steps.canary-meta.outputs.tag }}
145133
TITLE: ${{ steps.canary-meta.outputs.title }}
146134
NOTES_FILE: ${{ steps.canary-meta.outputs.notes_file }}
147135
run: |
148136
set -euo pipefail
137+
main_head=$(gh api "repos/${REPO}/git/ref/heads/main" --jq .object.sha)
138+
if [[ "$main_head" != "$SHA" ]]; then
139+
echo "::error::main HEAD ($main_head) advanced past workflow SHA ($SHA); refusing to replace canary"
140+
exit 1
141+
fi
149142
if gh release view "$TAG" >/dev/null 2>&1; then
150-
gh release upload "$TAG" octi-server-canary.zip --clobber
151-
gh release edit "$TAG" --title "$TITLE" --notes-file "$NOTES_FILE" --prerelease
152-
else
153-
gh release create "$TAG" octi-server-canary.zip --title "$TITLE" --notes-file "$NOTES_FILE" --prerelease --target "$SHA" --verify-tag
143+
gh release delete "$TAG" --yes
144+
fi
145+
if gh api "repos/${REPO}/git/ref/tags/${TAG}" >/dev/null 2>&1; then
146+
gh api --method DELETE "repos/${REPO}/git/refs/tags/${TAG}" >/dev/null
154147
fi
148+
gh release create "$TAG" octi-server-canary.zip \
149+
--title "$TITLE" --notes-file "$NOTES_FILE" \
150+
--prerelease --target "$SHA"

0 commit comments

Comments
 (0)