From fb9e6f5aea206dc1f33634eaf104b1bacdc58a78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isaac=20Rold=C3=A1n?= Date: Tue, 28 Apr 2026 11:51:10 +0200 Subject: [PATCH] Automate tag, stable branch, and GitHub release after changeset publish MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- .github/workflows/release.yml | 54 +++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9511bf29273..4695f9652a4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -116,6 +116,60 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SHOPIFY_CLI_BUILD_REPO: ${{ github.repository }} + - name: Get version + id: version + if: steps.changesets.outputs.hasChangesets == 'false' + run: | + VERSION=$(node -p "require('./packages/cli/package.json').version") + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "Version: $VERSION" + + - name: Create tag + if: steps.changesets.outputs.hasChangesets == 'false' + env: + TAG: ${{ steps.version.outputs.version }} + run: | + set -euo pipefail + if git ls-remote --exit-code --tags origin "$TAG" >/dev/null 2>&1; then + echo "Tag $TAG already exists, skipping" + exit 0 + fi + git tag "$TAG" + git push origin "$TAG" + echo "Created tag $TAG" + + - name: Create stable branch + if: steps.changesets.outputs.hasChangesets == 'false' && github.ref_name == 'main' && endsWith(steps.version.outputs.version, '.0') + env: + VERSION: ${{ steps.version.outputs.version }} + run: | + set -euo pipefail + MINOR=${VERSION%.0} + BRANCH="stable/$MINOR" + if git ls-remote --exit-code --heads origin "$BRANCH" >/dev/null 2>&1; then + echo "Branch $BRANCH already exists, skipping" + exit 0 + fi + git push origin "HEAD:refs/heads/$BRANCH" + echo "Created branch $BRANCH" + + - name: Create GitHub release + if: steps.changesets.outputs.hasChangesets == 'false' + env: + TAG: ${{ steps.version.outputs.version }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + if gh release view "$TAG" >/dev/null 2>&1; then + echo "Release $TAG already exists, skipping" + exit 0 + fi + gh release create "$TAG" \ + --title "$TAG" \ + --notes "" \ + --latest=legacy + echo "Created release $TAG" + # Manual/Cron release job - runs on schedule or manual trigger with tag manual-cron-release: name: Manual & Cron Release