ci(publish): use npx for npm publish, drop broken in-place npm self-upgrade#163
Conversation
The previous workflow upgraded the system npm in place
(`npm install -g npm@^11.5.1`) so that `npm publish` would use an
OIDC-capable version. That step hit a long-standing npm self-upgrade
bug:
npm error code MODULE_NOT_FOUND
npm error Cannot find module 'promise-retry'
npm error - .../npm/node_modules/@npmcli/arborist/lib/arborist/rebuild.js
`npm install -g npm` replaces /opt/hostedtoolcache/.../node_modules/npm/
in place while npm is still executing out of that same directory, so
arborist's mid-flight `require('promise-retry')` fails as the file is
overwritten. The bug is independent of which version we pin to and
shows up across major-version self-upgrades on GHA Ubuntu runners.
Fix: stop upgrading the system npm. Invoke npm 11.5.1+ via
`npx -y npm@^11.5.1` from each publish step instead. npx fetches
npm 11.x into its cache and runs it as a one-shot — the system npm
10.x stays untouched, so the in-place self-clobber is impossible.
npx caches between invocations, so the three publish steps share the
same downloaded npm.
The OIDC preflight no longer checks the system npm version (the npx
specifier enforces >=11.5.1 at the point of use); it just verifies
`id-token: write` is granted.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
WalkthroughThe publish GitHub Actions workflow refactors npm version management by replacing global npm upgrades with inline Changesnpm/OIDC publish refactoring
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Follow-up to #162
The OIDC migration landed but the first publish run 25986313074 failed at the new `Upgrade npm for OIDC trusted publishing` step:
```
npm error code MODULE_NOT_FOUND
npm error Cannot find module 'promise-retry'
npm error - /opt/hostedtoolcache/node/22.22.2/x64/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/rebuild.js
```
This is the well-known npm in-place self-upgrade bug — `npm install -g npm` replaces `/opt/hostedtoolcache/.../node_modules/npm/` while npm is still executing out of it, so arborist's mid-flight `require('promise-retry')` blows up as the file is overwritten. Hits any major-version self-upgrade on GHA's Ubuntu runners; not specific to the `^11.5.1` pin.
Fix
Don't upgrade the system npm at all. Invoke npm 11.5.1+ via `npx -y npm@^11.5.1` from each publish step. npx fetches npm 11.x into its cache and runs it as a one-shot — the system npm 10.x stays untouched, so the in-place self-clobber is impossible. npx caches between invocations, so the three publish steps share the same downloaded npm.
The OIDC preflight no longer checks the system npm version (the `npx` specifier enforces `>=11.5.1` at the point of use); it just verifies `id-token: write` is granted.
Why npx and not Node 24
Considered bumping the publish workflow to Node 24 (which bundles npm 11.x). Rejected to keep the publish runtime aligned with the test/CI workflows (Node 22). Publishing on a Node version different from CI introduces a "we test on X but ship from Y" gap that npx neatly avoids — and the published artifacts are byte-identical either way (esbuild has no `--target` flag, tsc respects `tsconfig`, no `engines` field).
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit