From 2f024f279ac360b6154b56a52aa876c5a99682dd Mon Sep 17 00:00:00 2001 From: Vladislav Tupikin Date: Tue, 21 Jul 2026 20:06:09 +0300 Subject: [PATCH] ci: publish with changeset publish so releases get tagged and reruns skip published versions --- .github/workflows/release.yml | 56 ++++++++++------------------------- package.json | 2 +- 2 files changed, 16 insertions(+), 42 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f4ec806d..cfdb344f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -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 @@ -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' diff --git a/package.json b/package.json index e5717dda..4824799a 100644 --- a/package.json +++ b/package.json @@ -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" },