Restore the NODE_AUTH_TOKEN placeholder in the publish job (#2837)
* Stop setup-node from writing an .npmrc into the publish job
`registry-url` makes setup-node write `$RUNNER_TEMP/.npmrc` containing
`//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}` and export
NPM_CONFIG_USERCONFIG pointing at it. Through v4 it also exported a dummy
`NODE_AUTH_TOKEN=XXXXX-XXXXX-XXXXX-XXXXX` whenever the caller supplied none. v7
narrowed that to only fire when the variable is already present in the
environment. This repo never sets it -- publishing goes through OIDC -- so from
v7 on the placeholder is gone and the `${NODE_AUTH_TOKEN}` in that file has
nothing to resolve to.
`npm publish` runs `prepack`, which is `just install && just build`, so yarn
reads NPM_CONFIG_USERCONFIG and refuses to continue:
error Error: Failed to replace env in config: ${NODE_AUTH_TOKEN}
at envReplace (/usr/local/lib/node_modules/yarn/lib/cli.js:95448:16)
v22.6.1 died there, before packing anything.
Dropping `registry-url` fixes it: no file, no NPM_CONFIG_USERCONFIG, nothing
for yarn to choke on. The OIDC exchange never reads that file --
`lib/commands/publish.js` resolves the registry through
`npmFetch.pickRegistry()`, and `lib/utils/oidc.js` needs only that plus the
`ACTIONS_ID_TOKEN_REQUEST_*` pair granted by `id-token: write`, after which it
sets `_authToken` itself. Both settings the file did carry are accounted for:
`registry` was already npm's default and now sits on the `npm publish` command,
where it stays explicit about where a release lands, and `always-auth` is a key
npm 11 already warns is unknown.
Deleting the generated file in a separate step, which is what the temporary
release probe in #2824 did, ends up in the same place but keeps the input that
creates the problem and discards the explicit registry along with it.
Verified against yarn 1.22.22, the version CI runs. An .npmrc holding
`_authToken=${NODE_AUTH_TOKEN}` reproduces the failure above when
NPM_CONFIG_USERCONFIG points at it and NODE_AUTH_TOKEN is unset, succeeds when
the dummy value is present, and succeeds when neither is set.
Committed-By-Agent: claude
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Committed-By-Agent: claude
* Restore the NODE_AUTH_TOKEN placeholder in the publish job
Replaces the approach in the preceding commit, which dropped `registry-url`
instead. Both fix the failure; this one leaves registry resolution in the release
path exactly where it was, and OIDC has enough moving parts already.
`registry-url` makes setup-node write `$RUNNER_TEMP/.npmrc` containing
`//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}` and export
NPM_CONFIG_USERCONFIG pointing at it. Through v4 the action also exported a
placeholder `NODE_AUTH_TOKEN=XXXXX-XXXXX-XXXXX-XXXXX` whenever the caller
supplied no token of its own. actions/setup-node#1558 narrowed that to fire only
when the variable is already in the environment, and #2824 brought in the version
carrying the change.
Nothing here sets the variable, because publishing goes through OIDC. `npm`
tolerates the unresolved `${NODE_AUTH_TOKEN}` left behind; yarn, which
`npm publish` runs by way of `prepack`, aborts:
error Error: Failed to replace env in config: ${NODE_AUTH_TOKEN}
at envReplace (/usr/local/lib/node_modules/yarn/lib/cli.js:95448:16)
v22.6.1 died there, before packing anything.
Setting the placeholder on the publish step reproduces the environment the job
ran with through v22.6.0, so the release path is unchanged apart from the one
variable that went missing. The fake value never reaches the registry: npm's OIDC
exchange overwrites it first, via `config.set(authTokenKey, token, 'user')` in
`lib/utils/oidc.js`, which is the same config level the .npmrc loads into.
setup-node#1558 removed the placeholder to avoid surprising callers who were not
expecting a non-functional token in their npmrc, and notes it "didn't break OIDC
flows"; here it is deliberate, so it is set narrowly on the one step that needs it
and commented in place.
Verified against yarn 1.22.22, the version CI runs. An .npmrc holding
`_authToken=${NODE_AUTH_TOKEN}` reproduces the failure above when
NPM_CONFIG_USERCONFIG points at it and the variable is unset, and installs
cleanly once the placeholder is present.
Committed-By-Agent: claude
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Committed-By-Agent: claude
* Update main.yml
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com> J
jar-stripe committed
998f558b1abbe950baba7e6d41faf378fa72b542
Parent: 9f82c46
Committed by GitHub <noreply@github.com>
on 9/1/2026, 8:16:22 PM