Restore the NODE_AUTH_TOKEN placeholder in the publish job - #2837
Merged
Merged
Conversation
`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
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
jar-stripe
marked this pull request as ready for review
September 1, 2026 20:14
jar-stripe
requested review from
xavdid
and
a lite review from Copilot
and removed request for
a team
September 1, 2026 20:14
xavdid
approved these changes
Sep 1, 2026
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The current non-empty dummy NODE_AUTH_TOKEN value may be interpreted as an actual auth token by npm and could interfere with OIDC/trusted publishing; using an empty value is safer while still unblocking yarn.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR updates the tag-gated publish job in the main workflow to avoid yarn failing during npm publish lifecycle execution after the actions/setup-node upgrade changed NODE_AUTH_TOKEN placeholder behavior.
Changes:
- Defines
NODE_AUTH_TOKENduring the “Publish to NPM” step to prevent yarn’s.npmrcenv interpolation error. - Adds explanatory inline comments documenting why the variable must be present for the publish flow.
File summaries
| File | Description |
|---|---|
.github/workflows/main.yml |
Adds a NODE_AUTH_TOKEN env value to keep npm publish’s prepack (which runs yarn) from failing on ${NODE_AUTH_TOKEN} interpolation. |
Review details
- Files reviewed: 1/1 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+131
to
+135
| # needed because setup-node writes a .npmrc file with `registry-url` and | ||
| # `_authToken=${NODE_AUTH_TOKEN}`. OIDC overwrites this with a real token | ||
| # before anything is uploaded, but we need to have a value for yarn install | ||
| # to work. | ||
| NODE_AUTH_TOKEN: XXXXX-XXXXX-XXXXX-XXXXX |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why?
The publish job currently fails in inside
prepackwithFailed to replace env in config: ${NODE_AUTH_TOKEN}. #2824 moved this job'ssetup-nodefrom v4 to v7; both versions write an.npmrcholding_authToken=${NODE_AUTH_TOKEN}when givenregistry-urlbut only v4 also supplied a placeholder value for that variable which allows yarn to work.What?
NODE_AUTH_TOKENto setup-node's former placeholder on the publish stepSee Also