Skip to content

[rush] Move the rushstack repo to pnpm 12.13.0 - #6136

Draft
Bharat Middha (bmiddha) wants to merge 1 commit into
mainfrom
bmiddha-bump-rushstack-to-pnpm-12
Draft

Bharat Middha (bmiddha) wants to merge 1 commit into
mainfrom
bmiddha-bump-rushstack-to-pnpm-12

Conversation

@bmiddha

Copy link
Copy Markdown
Member

Summary

This PR moves the rushstack repo itself from pnpm 10.27.0 to pnpm 12.13.0.

This PR is stacked on #6133 (#6131 → #6133 → this PR). Do not merge it until:

  1. A Rush release includes [rush] Close native pnpm compatibility gaps #6131, fix(rush): synchronize native pnpm injections from the installed layout #6133, and the small rush-lib fix in this PR, and this repo's rushVersion is bumped to that release. The pinned Rush 5.181.0 does not work with pnpm 12. See "How it was tested".
  2. The packagefeedproxy.microsoft.io npm feed serves pnpm@12.13.0. The feed currently tops out at 12.10.1, apparently because of a release-age quarantine of about 7 days. 12.13.0 was released on 2026-10-13.

Changes:

  • rush.json: changed pnpmVersion from 10.27.0 to 12.13.0.
  • common/config/rush/pnpm-config.json: replaced globalNeverBuiltDependencies with globalAllowBuilds, because pnpm 11 removed the old setting.
  • Regenerated both subspace lockfiles (default, build-tests-subspace) and their repo-state.json files with pnpm 12.
  • rush-lib: rush install now uses --prefer-frozen-lockfile instead of --frozen-lockfile when pnpm is >= 12 and the subspace has injected workspace dependencies. A change file is included.

Details

Why 12.13.0 and not 12.10.1

pnpm 12.10.1 and older drop files that .npmignore re-includes through negations under *. For example, rigs/heft-node-rig/.npmignore re-includes !/profiles/**, and rush-lib re-includes !/dist/** and !/lib-*/**. This breaks injected dependencies:

  • The injected local-node-rig → heft-node-rig copy in build-tests-subspace had no profiles/, so rush build failed at startup with Cannot find module "@rushstack/heft-node-rig/profiles/default/config/rush-project.json".
  • rush-pnpm pack was broken too. pnpm pack --dry-run emitted 5 files for heft-node-rig, where npm pack emits 27.

pnpm 12.11.0 fixed this (pnpm/pnpm#16743, pnpm/pnpm#16761). With 12.13.0, the pack --dry-run file lists match npm pack exactly for heft-node-rig, heft, rush-lib, node-core-library, api-extractor, rush-sdk, and rush.

globalAllowBuilds migration

pnpm 11+ fails installation when a dependency's build script is neither allowed nor denied. pnpm 10 ran every build script not listed in globalNeverBuiltDependencies, so the new setting:

  • explicitly allows @swc/core, @vscode/vsce-sign, esbuild, fsevents, and keytar, which install or validate native binaries;
  • denies unrs-resolver, which was previously never-built;
  • denies aws-sdk, core-js, and core-js-pure, whose scripts only print banners.

Injected dependencies vs. --frozen-lockfile (rush-lib change)

Native pnpm 12 checks the freshness of injected workspace dependencies during a frozen install (lockfile_freshness/directory_deps). That check fails for every Rush repo for two reasons:

  • It reads the raw package.json, without pnpmfile readPackage hooks, so it sees workspace:*.
  • workspace: targets must be inside the pnpm workspace root, which is common/temp/<subspace>. Every Rush project lives outside that folder.

The result is ERR_PNPM_OUTDATED_LOCKFILE ... local dependency "..." is outdated, which still happens with 12.13.0. Before invoking pnpm, Rush already verifies that the committed shrinkwrap satisfies all package.json files. So when pnpm is >= 12 and subspace.getPackageJsonInjectedDependenciesHash() is defined, Rush now passes --no-frozen-lockfile --prefer-frozen-lockfile and prints an informational line, not a warning.

The tradeoff: for subspaces with injected dependencies, pnpm may re-resolve during rush install, which fetches metadata. In testing, the resolved package set was identical to the committed lockfile. Rush never copies the lockfile back during install. Subspaces without injected dependencies, such as default here, still use --frozen-lockfile. I did not find an existing upstream pnpm issue for the containment check.

Lockfile tarball URLs

When pnpm 12 re-resolves, it records tarball: URLs that point at rotating ms-feed-N.pkgs.visualstudio.com hosts, and later fails with ERR_PNPM_TARBALL_URL_MISMATCH when the host differs. The committed lockfiles therefore have these tarball: fields stripped, and the repo-state.json hashes were recomputed. Apart from those fields, the lockfiles are byte-identical to pnpm 12.13.0's output.

Known gaps (not addressed here)

How it was tested

Testing ran on macOS arm64 with Node 22.23.2. The feed does not serve pnpm 12.13.0 yet, so I placed the official pnpm-darwin-arm64 binary from the pnpm v12.13.0 GitHub release into Rush's ~/.rush/node-v22.23.2/pnpm-12.13.0 folder.

"Local Rush" means node apps/rush/lib-commonjs/start-dev.js, built from this branch, so it includes #6131, #6133, and this PR.

Baseline, before the switch, with pnpm 10.27.0 and pinned Rush 5.181.0:

  • node common/scripts/install-run-rush.js install: passed
  • node common/scripts/install-run-rush.js build --to @microsoft/rush: passed

Pinned Rush 5.181.0 with pnpm 12:

  • CI=true node common/scripts/install-run-rush.js install with pnpm 12.13.0 (and earlier 12.10.1): failed with ERR_PNPM_OUTDATED_LOCKFILE on the injected @microsoft/rush-lib in build-tests-subspace.
  • node common/scripts/install-run-rush.js update with pnpm 12.10.1: failed with ERR_PNPM_TARBALL_URL_MISMATCH.

Local Rush with pnpm 12.13.0, on the final commit's contents:

  • update: passed. Both lockfiles match the committed ones after the tarball fields are stripped. They were first regenerated with update --recheck (pnpm 12.10.1) to work around [rush] With pnpm 12, rush update does not update pnpm-lock.yaml after pnpm changes a peer variant #6117.
  • CI=true install: passed.
    • build-tests-subspace printed PNPM 12.13.0 cannot verify injected workspace dependencies with "--frozen-lockfile"; using "--prefer-frozen-lockfile" instead.
    • default used --frozen-lockfile and printed "Lockfile is up to date, resolution step is skipped".
  • build --production --to @microsoft/rush --to rush-lib-test --to rush-sdk-test --to typescript-newest-test --to typescript-v4-test --to webpack-local-version-test: passed. 51 operations succeeded and 6 were no-op, with no warnings.
  • build --production (whole repo): passed. 132 operations succeeded, 51 came from cache, and 17 were no-op, with no warnings.
  • change --verify --target-branch origin/bmiddha/pnpm12-injected-sync: passed.

Other checks:

  • pnpm install --frozen-lockfile --strict-peer-dependencies --config.auto-install-peers=false --config.resolutionMode=highest --config.dedupe-peer-dependents=false with pnpm 12.13.0, run directly in common/temp/build-tests-subspace: failed with local dependency "@rushstack/terminal" at "../../../libraries/terminal" is outdated. This confirms the rush-lib change is still needed on 12.13.0.
  • heft build in libraries/rush-lib: passed with no warnings.
  • heft test --test-path-pattern "BaseInstallManager|Subspace.test" in libraries/rush-lib: passed (27/27).
  • pnpm pack --dry-run vs. npm pack --dry-run:
    • With pnpm 12.13.0, the file lists are identical for 7 packages.
    • With pnpm 12.10.1, heft-node-rig packed 5 files where npm pack packed 27.

Impacted documentation

None.

…ncies

With pnpm 12 or newer, "rush install" for a subspace that has injected
workspace dependencies now passes "--no-frozen-lockfile
--prefer-frozen-lockfile" instead of "--frozen-lockfile".

Native pnpm's frozen-lockfile freshness check reads the injected
workspace manifests without applying pnpmfile hooks, and it rejects
"workspace:" targets that live outside the pnpm workspace root. Every
Rush project is outside common/temp/<subspace>, so that check always
fails with ERR_PNPM_OUTDATED_LOCKFILE. Rush has already verified that
the committed shrinkwrap satisfies every package.json, so pnpm can
safely reuse the lockfile as-is. Subspaces without injected
dependencies, and pnpm versions below 12, keep using
"--frozen-lockfile".

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@bmiddha
Bharat Middha (bmiddha) force-pushed the bmiddha-bump-rushstack-to-pnpm-12 branch from 2de40d6 to 34059d1 Compare October 20, 2026 21:13

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Needs triage

Development

Successfully merging this pull request may close these issues.

1 participant