Skip to content

feat: implement changesets in repo #51

feat: implement changesets in repo

feat: implement changesets in repo #51

# -------------------------------------------------------------
# 🚢 Changesets – Create/Update Release PR and Cut Tags
# Two paths:
# 1) PR path: show a Changesets preview comment on the PR (no publishing)
# 2) Main path: on push to main, create/update the Release PR and cut tags/GitHub Releases
# -------------------------------------------------------------
name: Changesets – Create/Update Release PR and Cut Tags
on:
# Run on PRs to main so contributors see what would be released
pull_request:
branches: ["main"]
# Only run if one of the following events occurs
types: [opened, synchronize, reopened, ready_for_review]
push:
branches: ["main"]
workflow_dispatch:
inputs:
action:
description: "Choose an action"
required: true
default: "version"
type: choice
options:
- version
- release
permissions:
# Needed to push version commit + create releases
contents: write
# Needed to open/update the Release PR
pull-requests: write
jobs:
# PR PATH: Preview only
preview:
if: github.event_name == 'pull_request'
name: 🔎 Changesets Preview (PR)
runs-on: ubuntu-24.04
concurrency:
group: changesets-preview-${{ github.event.pull_request.number }}
cancel-in-progress: true
steps:
# Check out the PR HEAD commit (not the merge ref) to report the correct plan
- name: ⏬ Checkout PR head (not merge ref)
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }} # Force checkout to the PR head ref, not the merge ref
- name: 🔄 Init Node & NPM cache
uses: ./.github/actions/npm-cache
# Make sure we have full history and the base branch locally for proper diffing
- name: 🔁 Ensure full history & fetch base (main)
shell: bash
run: |
set -euo pipefail
if [ -f .git/shallow ]; then
git fetch --unshallow --no-tags --prune
fi
git fetch --no-tags --prune origin +refs/heads/main:refs/remotes/origin/main
git branch -a
git rev-parse HEAD
git rev-parse remotes/origin/main
# Produce human-readable Changesets status and expose it for the PR comment
- name: 📋 Show changeset status (since origin/main)
id: status
shell: bash
run: |
set -euo pipefail
npx changeset status --since=origin/main --verbose > .changeset-status.txt || {
echo "⚠️ changeset status failed; falling back to listing existing changesets"
ls -1 .changeset/*.md 2>/dev/null || true
: > .changeset-status.txt
}
{
printf 'STATUS<<EOF\n'
cat .changeset-status.txt
printf '\nEOF\n'
} >> "$GITHUB_OUTPUT"
# Upsert a single bot comment on the PR with the status preview
- name: 💬 Upsert PR comment with preview
uses: actions/github-script@v7
env:
BODY: ${{ steps.status.outputs.STATUS }}
with:
script: |
const { owner, repo, number } = context.issue;
const marker = '<!-- changesets-preview-marker -->';
const header = '### Changesets Preview (since origin/main)\n\n';
const raw = process.env.BODY || '_No status available._';
const body = `${header}\n\`\`\`\n${raw}\n\`\`\`\n\n${marker}`;
const { data: comments } = await github.rest.issues.listComments({ owner, repo, issue_number: number, per_page: 100 });
const existing = comments.find(c => c.user?.type === 'Bot' && c.body?.includes(marker));
if (existing) {
await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body });
} else {
await github.rest.issues.createComment({ owner, repo, issue_number: number, body });
}
# MAIN PATH: Create/Update Release PR & cut tags/releases
release_pr:
# Only run on main pushes (merge to main done) to drive versioning + tags
if: github.event_name == 'push' && startsWith(github.ref, 'refs/heads/main')
name: 🧩 Create/Update Release PR (and cut tags/releases)
runs-on: ubuntu-24.04
concurrency:
group: changesets-main-${{ github.ref }}
cancel-in-progress: true
steps:
# Work on the main branch that was just pushed
- name: ⏬ Checkout main
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: 🔄 Init Node & NPM cache
uses: ./.github/actions/npm-cache
# Let changesets open/update the "Version Packages" PR, commit bumped versions and create GitHub Releases/tags
- name: 🧩 Changesets Action
id: changesets
uses: changesets/action@v1
with:
commit: "chore(release): version packages"
title: "chore(release): version packages"
# Let the action create GitHub releases for you
createGithubReleases: true
publish: "echo 'Publishing handled by release.yml'"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Ensure Husky hooks (e.g., branch name patterns) don't block CI commits
HUSKY: "0"
CI: "true"
# Write a brief job summary so reviewers see what happened
- name: 🖨️ Summary
if: always()
run: |
if [ "${{ steps.changesets.outputs.hasChangesets }}" = "true" ]; then
echo "### Changesets\n- Release PR was created or updated." >> $GITHUB_STEP_SUMMARY
fi
if [ "${{ steps.changesets.outputs.published }}" = "true" ]; then
echo "### Tags & Releases\n- New tags and GitHub Releases were created by Changesets.\n- Your **release.yml** will now build and publish." >> $GITHUB_STEP_SUMMARY
fi