Skip to content

Commit 3068222

Browse files
catomeanclaude
andcommitted
ci: publish on a version tag, with provenance
threadkit has a CI workflow but no way to ship. The package is publish-ready — name unclaimed on npm, `files: ["dist"]`, README and LICENSE both in the tarball, 27 files, builds clean — so the only thing standing between it and a release was a manual `npm publish` from someone's laptop. This is the same workflow ai-forms already carries, so the two libraries release identically rather than each growing its own procedure: - triggered by a `v*` tag, so every published artifact traces to a commit - `id-token: write` for npm provenance — the registry can prove the tarball was built by this workflow from this commit, not uploaded from a laptop - runs `npm run verify` first: never publish something that would not pass CI - refuses to publish when the tag and package.json version disagree, instead of silently shipping the wrong number Verified locally with the workflow's exact steps: `npm ci --ignore-scripts` then `npm run verify` — 31 tests pass. Needs the NPM_TOKEN repo secret once; after that a release is `npm version` plus a tag push. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 82723a5 commit 3068222

1 file changed

Lines changed: 42 additions & 0 deletions

File tree

.github/workflows/publish.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Publish
2+
3+
# Publishing is driven by a version tag, so the released artifact is always
4+
# traceable to a commit. `npm version` creates the tag; pushing it ships.
5+
on:
6+
push:
7+
tags: ['v*']
8+
9+
jobs:
10+
publish:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: read
14+
# Required for npm provenance — proves on the registry that this tarball
15+
# was built by this workflow from this commit.
16+
id-token: write
17+
steps:
18+
- uses: actions/checkout@v4
19+
- uses: actions/setup-node@v4
20+
with:
21+
node-version: '22'
22+
registry-url: 'https://registry.npmjs.org'
23+
24+
- run: npm ci --ignore-scripts
25+
26+
# Never publish something that would not have passed CI.
27+
- run: npm run verify
28+
29+
# Refuse to publish a tag whose version does not match package.json,
30+
# rather than silently shipping the wrong number.
31+
- name: Check tag matches package version
32+
run: |
33+
tag="${GITHUB_REF_NAME#v}"
34+
pkg=$(node -p "require('./package.json').version")
35+
if [ "$tag" != "$pkg" ]; then
36+
echo "Tag v$tag does not match package.json version $pkg" >&2
37+
exit 1
38+
fi
39+
40+
- run: npm publish
41+
env:
42+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

0 commit comments

Comments
 (0)