Skip to content

ci: unblock changesets publish from npm's devEngines check - #396

Merged
kraenhansen merged 2 commits into
mainfrom
claude/react-native-node-api-ci-0uc7tc
Aug 11, 2026
Merged

ci: unblock changesets publish from npm's devEngines check#396
kraenhansen merged 2 commits into
mainfrom
claude/react-native-node-api-ci-0uc7tc

Conversation

@kraenhansen

@kraenhansen kraenhansen commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Fixes the failing Release job in run 31467628286 (and the identical failure on the Version Packages (#393) merge, run 31466790389).

The failure

🦋  info npm info @react-native-node-api/cli-utils
…
🦋  error Received an unknown error code: EBADDEVENGINES for npm info "@react-native-node-api/cli-utils"
🦋  error The developer of this package has specified the following through devEngines
🦋  error Invalid devEngines.packageManager
🦋  error Invalid name "pnpm" does not match "npm" for "packageManager"

changeset publish shells out to npm info <pkg> --json to work out which versions are already on the registry — changesets 2.x always uses npm for this, there is no pnpm code path. npm ≥ 11 validates the root package.json's devEngines in BaseCommand#checkDevEngines, i.e. on every command including info, so it exits 1 with EBADDEVENGINES because we declare devEngines.packageManager: pnpm and the process running is npm.

This is why the publish only broke now: the Release job only runs the publish command once the Version Packages PR has been merged, and the last actual publish was on 2026-01-05. All packages on npm are currently behind the repo (react-native-node-api 1.0.1 vs 1.1.0, cmake-rn 0.6.3 vs 0.7.0, ferric-cli 0.3.11 vs 0.4.0, …), so releases are blocked until this lands.

The fix

Set npm_config_force: true on the changesets step. npm's checkDevEngines downgrades devEngines errors to warnings when force is set, which is the only supported escape hatch — --ignore-dev-engines is not a thing in npm 11 (it warns Unknown cli config "--ignore-dev-engines" and still errors).

Verified locally against the repo root with Node 24 / npm 11.17:

$ npm info react-native-node-api --json; echo $?
npm error code EBADDEVENGINES
… 1
$ npm_config_force=true npm info react-native-node-api --json > /dev/null; echo $?
npm warn EBADDEVENGINES …   # stderr only, JSON on stdout is unaffected
0

Deliberately scoped to that one step rather than the workflow (so pnpm install above is untouched) and rather than relaxing devEngines in package.json (which would weaken the guard for everyone locally). Publishing itself is not affected by force: changesets detects the pnpm lockfile and uploads via pnpm publish, and pnpm publish ignores the npm force config.

Why not upgrade changesets instead

Changesets v3 does fix the root cause properly — its publish pipeline is package-manager-aware and runs pnpm info / pnpm pack / pnpm publish when pnpm is detected, so npm is never invoked. But it isn't reachable yet:

  • @changesets/cli v3 exists only as a prerelease (next = 3.0.0-next.12); latest is still 2.31.1, whose shipped dist spawns bare npm info.
  • It can't be upgraded on its own. v3 dropped the New tag: <pkg>@<version> stdout line that changesets/action@v1 parses; the action's v2 line instead has the CLI write NDJSON git-tag events to $CHANGESETS_OUTPUT and reads that file. CLI v3 with action v1 would publish but report published: false and push no git tags or GitHub releases — a silent regression rather than a loud one.
  • changesets/action v2 is prerelease-only too (v2.0.0-next.4, latest stable v1.9.0) and renames every input to kebab-case, so this step would become publish-script: plus a github-token: input.

So that migration is two coordinated prerelease majors on the release pipeline itself, and it's worth its own PR. The workflow comment records it as the removal condition for this workaround.

Heads-up, not addressed here

NPM_TOKEN was dropped from this step in 3690bd1 ("Update release to use the main environment") and nothing has been published since 2026-01-05, so the auth side of the publish is untested. If npm trusted publishing is not set up for these packages, the next failure will be an auth error and the step will need either NPM_TOKEN mapped back in from the main environment or permissions: id-token: write on the job. I left that alone since I can't see the environment's secrets or the npm-side configuration — let me know which it should be and I'll follow up.

claude added 2 commits August 11, 2026 07:27
`changeset publish` shells out to `npm info` to find out what is already
on the registry. npm >= 11 validates the root package.json's devEngines
on every command, so it errors with EBADDEVENGINES ("Invalid name
\"pnpm\" does not match \"npm\"") before the release can start.

Set npm_config_force on the changesets step, which downgrades that check
to a warning. Publishing itself is unaffected: changesets detects the
pnpm lockfile and uploads through `pnpm publish`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P2UZcjV4P98WFjzfRfLQvx
@kraenhansen
kraenhansen merged commit c371c18 into main Aug 11, 2026
9 checks passed
@kraenhansen
kraenhansen deleted the claude/react-native-node-api-ci-0uc7tc branch August 11, 2026 07:50
kraenhansen added a commit that referenced this pull request Aug 12, 2026
Bumps @changesets/cli to 3.0.0 (stable — the two prerelease majors this
was blocked on, @changesets/cli@3.0.0 and changesets/action@v2.0.0, both
shipped stable since #397 was filed) and changesets/action to v2, moving
both together as required: v3 dropped the "New tag: <pkg>@<version>"
stdout line action v1 parses, in favor of NDJSON `git-tag` events written
to $CHANGESETS_OUTPUT that only action v2 reads.

- .changeset/config.json: bump the schema pin to @changesets/config@4.0.0
  (the version @changesets/cli@3.0.0 depends on). None of our config keys
  are affected by v4's breaking changes (no `prettier` key, baseBranch is
  already "main", no experimental snapshot option in use).
- release.yml: rename the action's inputs to v2's kebab-case scheme
  (`publish:` -> `publish-script:`) and drop the `GITHUB_TOKEN` env var,
  since v2 reads it through a `github-token:` input that already defaults
  to `${{ github.token }}`.

Corrects an assumption in #397: it expected this upgrade to let
`npm_config_force: true` (added in #396) be removed, on the theory that
v3's publish pipeline is pnpm-aware and never invokes npm. That part
holds for `pnpm pack`/`pnpm publish`, verified here with strace, but
`pnpm info` (which `changeset publish`/`publish-plan` use to check what's
already on the registry) is itself a passthrough to the real npm CLI —
`pnpm info <pkg>` execs `npm info <pkg>` — so it still trips npm's
devEngines validation of this repo's root package.json. The workaround
stays, with an updated comment; there's no changesets- or pnpm-version
bump that removes the need for it, so the workflow comment no longer
frames it as removable by this upgrade.

Verified locally on Node 24 / pnpm 10.33: `changeset status`,
`changeset publish-plan` (fails with EBADDEVENGINES without the env var,
succeeds with it — same behavior as before), build, prettier:check, and
the workspace test suite (failures are pre-existing/environmental, see
below) all pass.

Not verified: the actual GitHub Actions publish path (action v1 -> v2 PR
description, output/input renames) only exercises the publish step once
a "Version Packages" PR merges, so this needs a real run to confirm.

Co-authored-by: Claude <noreply@anthropic.com>
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.

2 participants