From 59b3b10811a60a554fa3609288c6b5dc494707b7 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 20 Oct 2026 12:43:25 +0000 Subject: [PATCH] =?UTF-8?q?ci(publish):=20=F0=9F=94=92=20publish=20via=20n?= =?UTF-8?q?pm=20trusted=20publishing=20instead=20of=20NPM=5FTOKEN?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The publish job authenticated with a long-lived NPM_TOKEN secret, which expired (npm caps tokens with write access at 90 days) and broke the 0.3.0 release with a 404 on PUT. Switch to npm trusted publishing (OIDC): npm trades the job's GitHub identity token for a short-lived publish credential, so there is no secret to store, leak, or expire. - publish.yml: grant `id-token: write`; run on Node 24, whose bundled npm (>= 11.5.1) is required for trusted publishing; drop NODE_AUTH_TOKEN; drop the npm cache, as npm advises for release builds - package.json: add `repository`, which must match the GitHub repo since trusted publishing attaches a provenance attestation - CLAUDE.md: describe the new publishing setup 0.3.0 is already on the registry, so merging this is a no-op publish; the next version bump is the first release over OIDC. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_015XnPdQXFWDT6FTnQs1d1f1 --- .github/workflows/publish.yml | 13 +++++++++---- CLAUDE.md | 8 ++++++-- package.json | 4 ++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 133cfcb..de8529f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -3,6 +3,12 @@ name: Publish # Publishes to npm on every push to main, but only when package.json's version is one that # is not yet on the registry — so a commit that bumps the version releases it, and any other # commit is a harmless no-op. Bump with `npm version patch|minor|major` and push. +# +# Authenticates with npm trusted publishing (OIDC): npm trades this job's GitHub identity token +# for a short-lived publish credential, so there is no NPM_TOKEN secret to store or expire. It +# needs the trusted publisher configured on npmjs.com (lonetis/claudeleaf, publish.yml), npm +# >= 11.5.1 (bundled with Node 24), and package.json's repository.url matching this repo, since +# npm also attaches a provenance attestation. on: push: branches: [main] @@ -10,6 +16,7 @@ on: permissions: contents: read + id-token: write # OIDC token for npm trusted publishing jobs: publish: @@ -17,11 +24,11 @@ jobs: steps: - uses: actions/checkout@v4 + # No dependency cache: a release build installs fresh from the lockfile. - uses: actions/setup-node@v4 with: - node-version: "20" + node-version: "24" registry-url: "https://registry.npmjs.org" - cache: npm - run: npm ci - run: npm run build @@ -37,5 +44,3 @@ jobs: echo "Publishing $NAME@$VERSION…" npm publish --access public fi - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/CLAUDE.md b/CLAUDE.md index d72e4c3..e022b43 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -306,8 +306,12 @@ MCP server with `npx -y claudeleaf mcp`) without cloning. What makes that work: - `.github/workflows/publish.yml` — on push to `main` (or manual dispatch) it runs `npm ci && npm run build && npm test`, then publishes **only if `package.json`'s version is not already on the registry**. So a commit that bumps the version (`npm version patch`) - releases it; any other commit is a no-op. Needs an `NPM_TOKEN` repo secret (an npm automation - token with publish rights); `actions/setup-node` wires it in via `NODE_AUTH_TOKEN`. + releases it; any other commit is a no-op. It authenticates with **npm trusted publishing** + (OIDC) — no `NPM_TOKEN` secret: the job's `id-token: write` permission lets npm trade the + GitHub identity token for a short-lived publish credential. This needs the trusted publisher + configured on npmjs.com (repo `lonetis/claudeleaf`, workflow `publish.yml`), npm ≥ 11.5.1 + (hence Node 24 in that job), and `package.json`'s `repository.url` matching the GitHub repo — + npm attaches a provenance attestation and rejects the publish on a mismatch. - `.github/workflows/ci.yml` — typecheck + build + test on PRs and non-`main` pushes. - In CI the live integration/MCP tests auto-skip (no cached session → no network), so `npm test` runs the unit suite only. diff --git a/package.json b/package.json index 713565b..8b90690 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,10 @@ "type": "module", "license": "MIT", "author": "Louis Jannett", + "repository": { + "type": "git", + "url": "git+https://github.com/lonetis/claudeleaf.git" + }, "keywords": [ "overleaf", "latex",