Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 15 additions & 41 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,20 @@ jobs:

# Changesets action:
# - If changesets are pending → creates/updates "Version Packages" PR
# - If this IS the version commit (no pending changesets) → publishes to npm
# - If this IS the version commit (no pending changesets) → publishes to npm,
# then tags the release commit and creates the GitHub release.
#
# `release:publish` is `changeset publish`, not `pnpm publish`, and that choice
# is load-bearing here:
# - it queries the registry per package and publishes only versions not
# already there, so a master push with nothing to release is a clean no-op
# instead of `pnpm publish` erroring on "cannot publish over 3.0.1";
# - it prints the `New tag:` lines the action greps to learn what shipped, so
# the action tags the actual release commit and cuts the GitHub release —
# `pnpm publish` prints neither, which is why v3.0.0 had to be tagged by hand.
# Provenance is preserved via NPM_CONFIG_PROVENANCE: `changeset publish` shells
# out to `pnpm publish`, which reads it as `--provenance` (needs id-token: write,
# granted above).
- name: 📦 Create Release PR or Publish
id: changesets
uses: changesets/action@v1
Expand All @@ -63,43 +76,4 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

# changesets/action tags and releases only the packages it detects as
# published, and it detects them by grepping the publish command's stdout for
# the "New tag:" lines that only `changeset publish` prints — never `pnpm
# publish`. So the publish path uploads to npm but leaves no tag behind, and
# v3.0.0 had to be tagged by hand. This step closes that gap without touching
# the known-good `pnpm publish --provenance` command.
#
# It fires on every master push, so it tells the two paths apart itself:
# - changesets still pending → the action only opened/updated the version
# PR; nothing was published, so do nothing.
# - none pending → the version commit merged and was published,
# so tag it. Idempotent: skips when the tag is
# already there, so a re-run cannot double-tag.
- name: 🏷️ Tag and release the published version
if: steps.changesets.outputs.published != 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
pending="$(find .changeset -maxdepth 1 -name '*.md' ! -name 'README.md' | wc -l | tr -d ' ')"
if [ "${pending}" != "0" ]; then
echo "Changesets still pending — the action opened the version PR, nothing published. Nothing to tag."
exit 0
fi

version="$(node -p "require('./package.json').version")"
tag="v${version}"

if git rev-parse -q --verify "refs/tags/${tag}" >/dev/null; then
echo "Tag ${tag} already exists — nothing to do."
exit 0
fi

awk -v h="## ${version}" '$0==h{f=1;next} /^## /{if(f)exit} f' CHANGELOG.md > /tmp/release-notes.md
if [ -s /tmp/release-notes.md ]; then
gh release create "${tag}" --target "${GITHUB_SHA}" --title "${tag}" --notes-file /tmp/release-notes.md
else
echo "No CHANGELOG section for ${version}; falling back to generated notes."
gh release create "${tag}" --target "${GITHUB_SHA}" --title "${tag}" --generate-notes
fi
NPM_CONFIG_PROVENANCE: 'true'
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
"changeset:version": "changeset version",
"changeset:status": "changeset status",
"version:dev": "node scripts/devVersion.ts",
"release:publish": "pnpm publish --no-git-checks --provenance",
"release:publish": "changeset publish",
"prepare": "husky",
"audit:schemas": "node scripts/schemaAudit.ts"
},
Expand Down