From 11471eebee9f69955b60081d88e9cdc72141f0c9 Mon Sep 17 00:00:00 2001 From: Chris Hall Date: Thu, 21 May 2026 15:51:05 -0400 Subject: [PATCH] fix(ci): strip stale _authToken from .npmrc so OIDC Trusted Publisher fires Symptom: every `npm publish --provenance` step in the Release workflow fails with `npm error 404 Not Found - PUT registry.npmjs.org/...`, even though npm Trusted Publisher is correctly configured for @fetchproxy/*. Cause: `setup-node` with `registry-url:` writes a .npmrc that says `//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}`. We don't pass NPM_TOKEN as a secret (the whole point is OIDC), so GitHub Actions expands NODE_AUTH_TOKEN to the masked placeholder `XXXXX-XXXXX-XXXXX-XXXXX`. npm picks up the placeholder as a static auth token, tries it against the registry first, gets rejected, and returns a privacy-preserving 404 instead of falling through to OIDC. Fix: strip the `_authToken` line (in addition to the existing `always-auth` strip) before `npm publish`. With no static auth in .npmrc, npm publish takes the OIDC path that Trusted Publisher expects, and provenance + publish both succeed. Dump the final .npmrc to the log so future debugging has a record of what npm actually sees. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/release.yml | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 18d5276..51a8378 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,8 +21,30 @@ jobs: cache: npm registry-url: https://registry.npmjs.org - # Strip always-auth from .npmrc (set by setup-node, deprecated in npm 11) - - run: sed -i '/always-auth/d' "$NPM_CONFIG_USERCONFIG" + # Clean up the .npmrc setup-node generated. + # + # setup-node with `registry-url:` writes two lines: + # //registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN} + # always-auth=true + # + # We don't pass `NPM_TOKEN` because we publish via npm Trusted + # Publisher OIDC (provenance below). But when `NPM_TOKEN` is + # absent, GitHub Actions masks `NODE_AUTH_TOKEN` with the + # placeholder `XXXXX-XXXXX-XXXXX-XXXXX`, and npm tries to use + # that placeholder as a static auth token before falling through + # to OIDC. The registry rejects the bogus token with a + # privacy-preserving 404 and never tries OIDC. + # + # Strip both lines so npm has no static auth at all — OIDC is + # then the only path npm publish can take, and Trusted Publisher + # works as designed. + - name: Strip stale npm auth from .npmrc + run: | + sed -i '/always-auth/d' "$NPM_CONFIG_USERCONFIG" + sed -i '/_authToken/d' "$NPM_CONFIG_USERCONFIG" + echo "----- final .npmrc -----" + cat "$NPM_CONFIG_USERCONFIG" + echo "------------------------" - run: npm ci