Skip to content

Commit 8e2f3c7

Browse files
saby1101claude
andcommitted
ci(release): publish on release published, and verify tag matches version
The trigger was release:created. GitHub fires created when a draft release is saved, which would publish from the default branch before the tag exists; it then fires published (not created) when that draft is released, so the real release would ship nothing. Every release so far was created and published in one action, which is why this never bit. The job also published whatever version happened to be in package.json at the release commit, so a tag and a version could disagree silently. A guard now compares them and fails the job. publishConfig.registry pins GitHub Packages. CI worked only because setup-node writes the runner .npmrc; a local npm publish would target npmjs.org and fail against a scope we do not own. Lint and build join the pre-publish test gate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 219beea commit 8e2f3c7

2 files changed

Lines changed: 28 additions & 5 deletions

File tree

‎.github/workflows/npm-publish-github-packages.yml‎

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2-
# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
1+
# Publishes to GitHub Packages when a release is published.
2+
# See .claude/skills/release/SKILL.md for the release procedure.
33

44
name: Node.js Package
55

66
on:
77
release:
8-
types: [created]
8+
# published, not created: GitHub fires `created` when a *draft* is saved, which
9+
# would publish from the default branch before the tag exists — and then fires
10+
# `published` (not `created`) when that draft is released, so the real release
11+
# would ship nothing.
12+
types: [published]
913

1014
env:
1115
NODE_VERSION: 24
@@ -21,6 +25,8 @@ jobs:
2125
node-version: ${{ env.NODE_VERSION }}
2226
cache: pnpm
2327
- run: pnpm install --frozen-lockfile
28+
- run: pnpm run lint
29+
- run: pnpm run build
2430
- run: pnpm test
2531

2632
publish-gpr:
@@ -38,9 +44,23 @@ jobs:
3844
cache: pnpm
3945
registry-url: https://npm.pkg.github.com/
4046
- run: pnpm install --frozen-lockfile
47+
48+
# The release tag and package.json must agree, or the published version silently
49+
# differs from the tag people will go looking for. TAG comes through env rather
50+
# than being interpolated into the script.
51+
- name: Verify tag matches package.json version
52+
env:
53+
TAG: ${{ github.event.release.tag_name }}
54+
run: |
55+
VERSION="v$(node -p 'require("./package.json").version')"
56+
if [ "$VERSION" != "$TAG" ]; then
57+
echo "Release tag $TAG does not match package.json $VERSION" >&2
58+
exit 1
59+
fi
60+
4161
# npm publish, not pnpm publish: pnpm adds git-state checks the release flow
4262
# does not need. prepublishOnly runs the build either way.
4363
# No --provenance: GitHub Packages does not accept provenance attestations.
4464
- run: npm publish
4565
env:
46-
NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
66+
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

‎package.json‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,8 @@
6363
"typescript": "^6.0.3",
6464
"typescript-eslint": "^8.67.0"
6565
},
66-
"packageManager": "pnpm@10.13.1"
66+
"packageManager": "pnpm@10.13.1",
67+
"publishConfig": {
68+
"registry": "https://npm.pkg.github.com/"
69+
}
6770
}

0 commit comments

Comments
 (0)