Repository navigation
[rush] Use the common pnpm-config.json fallback for every pnpm catalog consumer - #6138
Draft
Bharat Middha (bmiddha) wants to merge 1 commit into
Draft
Bharat Middha (bmiddha) wants to merge 1 commit into
Bharat Middha (bmiddha) wants to merge 1 commit into
Conversation
Bharat Middha (bmiddha)
force-pushed
the
bmiddha-catalog-config-fallback
branch
from
October 14, 2026 20:53
06b9dcd to
e5c4551
Compare
Bharat Middha (bmiddha)
added this pull request to stack #6134
October 14, 2026 21:29
Bharat Middha (bmiddha)
force-pushed
the
bmiddha-catalog-config-fallback
branch
from
October 15, 2026 01:41
e5c4551 to
b6b929f
Compare
Subspaces without their own pnpm-config.json install with the catalogs from common/config/rush/pnpm-config.json, but the repo-state.json catalog hash, catalog change detection, and the rush-pnpm update catalog sync only read the subspace's own file. Route all of them through a new internal getEffectivePnpmOptions() helper so they match install. When syncing catalogs into a pnpm-config.json that several subspaces share, only add or update entries and tell the user which other subspaces need "rush update". Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Bharat Middha (bmiddha)
force-pushed
the
bmiddha-catalog-config-fallback
branch
from
October 20, 2026 21:13
b6b929f to
951f191
Compare
This branch has not been deployed
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.
Summary
When a subspace has no
pnpm-config.jsonof its own,rush install/rush updatefall back tocommon/config/rush/pnpm-config.json(subspace.getPnpmOptions() || rushConfiguration.pnpmOptions) and write itsglobalCatalogsinto the generatedpnpm-workspace.yaml. Several other catalog consumers only read the subspace's own file and had no fallback, so they saw no catalogs:Subspace.getPnpmCatalogsHash(), which feedsrepo-state.json. The hash could disagree with what install actually wrote.ProjectChangeAnalyzercatalog change detection, which diffed a file that isn't in effect, so catalog edits didn't markcatalog:consumers as changed.rush-pnpm up/rush-pnpm updatecatalog sync-back, which wrote to a subspace file that doesn't exist instead of the file in effect.This PR adds one internal helper with exactly the same fallback semantics as install and routes all of these consumers through it, so install, the repo-state hash, change detection, and catalog sync can't disagree.
Details
New internal helper:
libraries/rush-lib/src/logic/pnpm/EffectivePnpmOptions.ts. It is not exported from the package index.getEffectivePnpmOptions(subspace, rushConfiguration): IEffectivePnpmOptionsreturns{ pnpmOptions, pnpmConfigFilePath, isFallback }. That is the subspace's ownpnpm-config.jsonif it exists, otherwisecommon/config/rush/pnpm-config.json.getEffectivePnpmCatalogs(subspace, rushConfiguration)returns exactly the catalogs install writes topnpm-workspace.yaml. It returnsundefinedwhen the package manager isn't pnpm or there are no catalogs.getOtherSubspacesSharingPnpmConfig(subspace, rushConfiguration)returns the other subspaces whose effective config is the same file.mergePnpmCatalogs(existing, toAdd)merges catalogs: it only adds or updates entries and never removes them.Consumers routed through the helper:
Subspace.getPnpmCatalogsHashInstallHelpers.resolvePnpmSettingsSubspacePnpmfileConfigurationPnpmShrinkwrapFile, for its lockfile policy checksBaseInstallManager, which now includes the effective config file in its list of potentially changed filesProjectChangeAnalyzer.#detectCatalogChangesAsync, which diffs the effective file. For old catalogs at the merge base, it reads the subspace's own file first and falls back to the common file.RushPnpmCommandLineParser, for theup/updatecatalog syncCatalog sync when the file is shared by several subspaces. A subspace's pnpm workspace only contains that subspace's projects, so pnpm's view of the catalogs is partial.
mergePnpmCatalogs(add/update only) rather than replacing. This avoids dropping entries used by other subspaces.rush update --subspace <name>line for each other subspace sharing the file. Those subspaces must be updated before their lockfile catalogs and repo-state hashes match again; pnpm 12's frozen-install check compares lockfile catalogs.catalog:field that pnpm may write for the default catalog.rush.jsonpnpmOptions.PnpmOptionsConfiguration.globalCatalogsis now a getter.updateGlobalCatalogsAsyncupdates the in-memory value as well as the file, so therush updatethat follows a sync uses the new catalogs. In the API report,readonly globalCatalogsbecomesget globalCatalogs(). The type is unchanged.Compatibility:
Subspace.getPnpmConfigFilePath()already pointed atcommon/config/rush/pnpm-config.json, so nothing changes there.pnpm-config.json, the repo-state catalog hash now reflects the common catalogs. This matches what install writes, so repos in that state may see a one-timerepo-state.jsonupdate.catalogPrune/cleanupUnusedCatalogsare intentionally not enabled, since pruning from one subspace's workspace would drop entries used by other subspaces.How it was tested
New fixture
libraries/rush-lib/src/logic/test/repoWithSubspacesCommonCatalogs/has subspaces enabled. Catalogs exist only incommon/config/rush/pnpm-config.json, except for one subspace that has its own config.New and extended tests:
EffectivePnpmOptions.test.ts(new)Subspace.test.tsInstallHelpers.test.ts: a newresolvePnpmSettingstest checks that the catalogs written to the workspace file matchgetPnpmCatalogsHash.ProjectChangeAnalyzer.test.ts: covers fallback and own-config diffs.RushPnpmCommandLineParser.test.ts: covers sync into a shared file (merge, no removals, warning) and into a subspace's own file.All commands below were run in
libraries/rush-libafter bootstrapping with a locally built dev Rush (start-dev.js installandstart-dev.js build --to @microsoft/rush-lib):node_modules/.bin/heft build --clean: passed with no warnings. The API report was updated.node_modules/.bin/heft test --test-path-pattern "EffectivePnpmOptions|InstallHelpers|RushPnpmCommandLineParser|ProjectChangeAnalyzer|Subspace|RepoState|PnpmOptions|PnpmShrinkwrap|Pnpmfile|BaseInstall": passed, 186/186.node_modules/.bin/heft test(full rush-lib suite): 1938 passed, 1 failed:TarExecutable › kills tar when its signal aborts while it runs. That test also fails on the base branch without these changes (checked withgit stash), so it is unrelated to this PR.Impacted documentation
globalCatalogsincommon/config/rush/pnpm-config.jsonnow applies to every subspace that has nopnpm-config.jsonof its own, including for hashing, change detection, andrush-pnpm updatesync.