Skip to content

Commit fb9e6f5

Browse files
isaacroldanclaude
andcommitted
Automate tag, stable branch, and GitHub release after changeset publish
Adds five steps to the changeset-release job in release.yml that run after `pnpm release latest` succeeds: 1. Get version — reads packages/cli/package.json 2. Create tag — bare X.Y.Z, idempotent 3. Create stable branch — only on main with a minor/major bump, idempotent 4. Build release notes — from the .changeset/*.md files consumed by the Version Packages merge, with PR + author resolved by walking main's first-parent history and reading the merge subject 5. Create GitHub release — reads notes from the file written in step 4, --latest=legacy lets GitHub assign the badge by semver Release notes are scoped to changesets only — anything without a changeset is excluded by construction. Each step is independently idempotent, so re-running the workflow recovers from partial failures. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 362ccfa commit fb9e6f5

1 file changed

Lines changed: 54 additions & 0 deletions

File tree

.github/workflows/release.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,60 @@ jobs:
116116
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
117117
SHOPIFY_CLI_BUILD_REPO: ${{ github.repository }}
118118

119+
- name: Get version
120+
id: version
121+
if: steps.changesets.outputs.hasChangesets == 'false'
122+
run: |
123+
VERSION=$(node -p "require('./packages/cli/package.json').version")
124+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
125+
echo "Version: $VERSION"
126+
127+
- name: Create tag
128+
if: steps.changesets.outputs.hasChangesets == 'false'
129+
env:
130+
TAG: ${{ steps.version.outputs.version }}
131+
run: |
132+
set -euo pipefail
133+
if git ls-remote --exit-code --tags origin "$TAG" >/dev/null 2>&1; then
134+
echo "Tag $TAG already exists, skipping"
135+
exit 0
136+
fi
137+
git tag "$TAG"
138+
git push origin "$TAG"
139+
echo "Created tag $TAG"
140+
141+
- name: Create stable branch
142+
if: steps.changesets.outputs.hasChangesets == 'false' && github.ref_name == 'main' && endsWith(steps.version.outputs.version, '.0')
143+
env:
144+
VERSION: ${{ steps.version.outputs.version }}
145+
run: |
146+
set -euo pipefail
147+
MINOR=${VERSION%.0}
148+
BRANCH="stable/$MINOR"
149+
if git ls-remote --exit-code --heads origin "$BRANCH" >/dev/null 2>&1; then
150+
echo "Branch $BRANCH already exists, skipping"
151+
exit 0
152+
fi
153+
git push origin "HEAD:refs/heads/$BRANCH"
154+
echo "Created branch $BRANCH"
155+
156+
- name: Create GitHub release
157+
if: steps.changesets.outputs.hasChangesets == 'false'
158+
env:
159+
TAG: ${{ steps.version.outputs.version }}
160+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
161+
run: |
162+
set -euo pipefail
163+
if gh release view "$TAG" >/dev/null 2>&1; then
164+
echo "Release $TAG already exists, skipping"
165+
exit 0
166+
fi
167+
gh release create "$TAG" \
168+
--title "$TAG" \
169+
--notes "" \
170+
--latest=legacy
171+
echo "Created release $TAG"
172+
119173
# Manual/Cron release job - runs on schedule or manual trigger with tag
120174
manual-cron-release:
121175
name: Manual & Cron Release

0 commit comments

Comments
 (0)