Skip to content

Restore the NODE_AUTH_TOKEN placeholder in the publish job - #2837

Merged
jar-stripe merged 3 commits into
masterfrom
jar/fix-publish-npmrc
Sep 1, 2026
Merged

jar-stripe merged 3 commits into
masterfrom
jar/fix-publish-npmrc

Conversation

@jar-stripe

@jar-stripe jar-stripe commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Why?

The publish job currently fails in inside prepack with Failed to replace env in config: ${NODE_AUTH_TOKEN}. #2824 moved this job's setup-node from v4 to v7; both versions write an .npmrc holding _authToken=${NODE_AUTH_TOKEN} when given registry-url but only v4 also supplied a placeholder value for that variable which allows yarn to work.

What?

  • sets NODE_AUTH_TOKEN to setup-node's former placeholder on the publish step

See Also

jar-stripe and others added 3 commits September 1, 2026 12:10
`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
jar-stripe marked this pull request as ready for review September 1, 2026 20:14
@jar-stripe
jar-stripe requested a review from a team as a code owner September 1, 2026 20:14
@jar-stripe
jar-stripe requested review from xavdid and a lite review from Copilot and removed request for a team September 1, 2026 20:14
@jar-stripe
jar-stripe merged commit 998f558 into master Sep 1, 2026
14 checks passed
@jar-stripe
jar-stripe deleted the jar/fix-publish-npmrc branch September 1, 2026 20:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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_TOKEN during the “Publish to NPM” step to prevent yarn’s .npmrc env 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants