From 07c4e4c570fd244e4b2a78ccb27ea93d45b20043 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 19:15:46 +0000 Subject: [PATCH 1/3] Initial plan From cb413817accb70c875face4a9c7251fc9813ef90 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 19:22:08 +0000 Subject: [PATCH 2/3] Add globalOnlyBuiltDependencies support for PNPM 10.x Co-authored-by: iclanton <5010588+iclanton@users.noreply.github.com> --- common/reviews/api/rush-lib.api.md | 2 ++ .../common/config/rush/pnpm-config.json | 17 ++++++++++++++++ .../logic/installManager/InstallHelpers.ts | 19 ++++++++++++++++++ .../logic/pnpm/PnpmOptionsConfiguration.ts | 20 +++++++++++++++++++ .../test/PnpmOptionsConfiguration.test.ts | 13 ++++++++++++ .../pnpm-config-onlyBuiltDependencies.json | 3 +++ .../src/schemas/pnpm-config.schema.json | 9 +++++++++ 7 files changed, 83 insertions(+) create mode 100644 libraries/rush-lib/src/logic/pnpm/test/jsonFiles/pnpm-config-onlyBuiltDependencies.json diff --git a/common/reviews/api/rush-lib.api.md b/common/reviews/api/rush-lib.api.md index da3c87d6bd4..e0f49f952c7 100644 --- a/common/reviews/api/rush-lib.api.md +++ b/common/reviews/api/rush-lib.api.md @@ -743,6 +743,7 @@ export interface _IPnpmOptionsJson extends IPackageManagerOptionsJsonBase { globalCatalogs?: Record>; globalIgnoredOptionalDependencies?: string[]; globalNeverBuiltDependencies?: string[]; + globalOnlyBuiltDependencies?: string[]; globalOverrides?: Record; globalPackageExtensions?: Record; globalPatchedDependencies?: Record; @@ -1155,6 +1156,7 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration readonly globalCatalogs: Record> | undefined; readonly globalIgnoredOptionalDependencies: string[] | undefined; readonly globalNeverBuiltDependencies: string[] | undefined; + readonly globalOnlyBuiltDependencies: string[] | undefined; readonly globalOverrides: Record | undefined; readonly globalPackageExtensions: Record | undefined; get globalPatchedDependencies(): Record | undefined; diff --git a/libraries/rush-lib/assets/rush-init/common/config/rush/pnpm-config.json b/libraries/rush-lib/assets/rush-init/common/config/rush/pnpm-config.json index d677fa2179f..ef0b93f659c 100644 --- a/libraries/rush-lib/assets/rush-init/common/config/rush/pnpm-config.json +++ b/libraries/rush-lib/assets/rush-init/common/config/rush/pnpm-config.json @@ -306,6 +306,23 @@ /*[LINE "HYPOTHETICAL"]*/ "fsevents" ], + /** + * The `globalOnlyBuiltDependencies` setting specifies an allowlist of dependencies that are permitted + * to run build scripts (`preinstall`, `install`, `postinstall`). In PNPM 10.x, build scripts are + * disabled by default for security. Use this setting to explicitly permit specific packages to run + * their build scripts. This is the inverse of `globalNeverBuiltDependencies`. + * + * The settings are copied into the `pnpm.onlyBuiltDependencies` field of the `common/temp/package.json` + * file that is generated by Rush during installation. + * + * (SUPPORTED ONLY IN PNPM 10.1.0 AND NEWER) + * + * PNPM documentation: https://pnpm.io/package_json#pnpmonlybuiltdependencies + */ + "globalOnlyBuiltDependencies": [ + /*[LINE "HYPOTHETICAL"]*/ "esbuild" + ], + /** * The `globalIgnoredOptionalDependencies` setting suppresses the installation of optional NPM * dependencies specified in the list. This is useful when certain optional dependencies are diff --git a/libraries/rush-lib/src/logic/installManager/InstallHelpers.ts b/libraries/rush-lib/src/logic/installManager/InstallHelpers.ts index 8f850b4e73d..35a1998c6a9 100644 --- a/libraries/rush-lib/src/logic/installManager/InstallHelpers.ts +++ b/libraries/rush-lib/src/logic/installManager/InstallHelpers.ts @@ -31,6 +31,7 @@ interface ICommonPackageJson extends IPackageJson { packageExtensions?: typeof PnpmOptionsConfiguration.prototype.globalPackageExtensions; peerDependencyRules?: typeof PnpmOptionsConfiguration.prototype.globalPeerDependencyRules; neverBuiltDependencies?: typeof PnpmOptionsConfiguration.prototype.globalNeverBuiltDependencies; + onlyBuiltDependencies?: typeof PnpmOptionsConfiguration.prototype.globalOnlyBuiltDependencies; ignoredOptionalDependencies?: typeof PnpmOptionsConfiguration.prototype.globalIgnoredOptionalDependencies; allowedDeprecatedVersions?: typeof PnpmOptionsConfiguration.prototype.globalAllowedDeprecatedVersions; patchedDependencies?: typeof PnpmOptionsConfiguration.prototype.globalPatchedDependencies; @@ -76,6 +77,24 @@ export class InstallHelpers { commonPackageJson.pnpm.neverBuiltDependencies = pnpmOptions.globalNeverBuiltDependencies; } + if (pnpmOptions.globalOnlyBuiltDependencies) { + if ( + rushConfiguration.rushConfigurationJson.pnpmVersion !== undefined && + semver.lt(rushConfiguration.rushConfigurationJson.pnpmVersion, '10.1.0') + ) { + terminal.writeWarningLine( + Colorize.yellow( + `Your version of pnpm (${rushConfiguration.rushConfigurationJson.pnpmVersion}) ` + + `doesn't support the "globalOnlyBuiltDependencies" field in ` + + `${rushConfiguration.commonRushConfigFolder}/${RushConstants.pnpmConfigFilename}. ` + + 'Remove this field or upgrade to pnpm 10.1.0 or newer.' + ) + ); + } + + commonPackageJson.pnpm.onlyBuiltDependencies = pnpmOptions.globalOnlyBuiltDependencies; + } + if (pnpmOptions.globalIgnoredOptionalDependencies) { if ( rushConfiguration.rushConfigurationJson.pnpmVersion !== undefined && diff --git a/libraries/rush-lib/src/logic/pnpm/PnpmOptionsConfiguration.ts b/libraries/rush-lib/src/logic/pnpm/PnpmOptionsConfiguration.ts index 555f02e7dd0..d0289c9ff4d 100644 --- a/libraries/rush-lib/src/logic/pnpm/PnpmOptionsConfiguration.ts +++ b/libraries/rush-lib/src/logic/pnpm/PnpmOptionsConfiguration.ts @@ -114,6 +114,10 @@ export interface IPnpmOptionsJson extends IPackageManagerOptionsJsonBase { * {@inheritDoc PnpmOptionsConfiguration.globalNeverBuiltDependencies} */ globalNeverBuiltDependencies?: string[]; + /** + * {@inheritDoc PnpmOptionsConfiguration.globalOnlyBuiltDependencies} + */ + globalOnlyBuiltDependencies?: string[]; /** * {@inheritDoc PnpmOptionsConfiguration.globalIgnoredOptionalDependencies} */ @@ -365,6 +369,21 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration */ public readonly globalNeverBuiltDependencies: string[] | undefined; + /** + * The `globalOnlyBuiltDependencies` setting specifies an allowlist of dependencies that are permitted + * to run build scripts (`preinstall`, `install`, `postinstall`). In PNPM 10.x, build scripts are + * disabled by default for security. Use this setting to explicitly permit specific packages to run + * their build scripts. This is the inverse of `globalNeverBuiltDependencies`. + * + * The settings are copied into the `pnpm.onlyBuiltDependencies` field of the `common/temp/package.json` + * file that is generated by Rush during installation. + * + * (SUPPORTED ONLY IN PNPM 10.1.0 AND NEWER) + * + * PNPM documentation: https://pnpm.io/package_json#pnpmonlybuiltdependencies + */ + public readonly globalOnlyBuiltDependencies: string[] | undefined; + /** * The ignoredOptionalDependencies setting allows you to exclude certain optional dependencies from being installed * during the Rush installation process. This can be useful when optional dependencies are not required or are @@ -468,6 +487,7 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration this.globalPeerDependencyRules = json.globalPeerDependencyRules; this.globalPackageExtensions = json.globalPackageExtensions; this.globalNeverBuiltDependencies = json.globalNeverBuiltDependencies; + this.globalOnlyBuiltDependencies = json.globalOnlyBuiltDependencies; this.globalIgnoredOptionalDependencies = json.globalIgnoredOptionalDependencies; this.globalAllowedDeprecatedVersions = json.globalAllowedDeprecatedVersions; this.unsupportedPackageJsonSettings = json.unsupportedPackageJsonSettings; diff --git a/libraries/rush-lib/src/logic/pnpm/test/PnpmOptionsConfiguration.test.ts b/libraries/rush-lib/src/logic/pnpm/test/PnpmOptionsConfiguration.test.ts index c590ca689fe..ad9dd94b3e9 100644 --- a/libraries/rush-lib/src/logic/pnpm/test/PnpmOptionsConfiguration.test.ts +++ b/libraries/rush-lib/src/logic/pnpm/test/PnpmOptionsConfiguration.test.ts @@ -74,6 +74,19 @@ describe(PnpmOptionsConfiguration.name, () => { ]); }); + it('loads onlyBuiltDependencies', () => { + const pnpmConfiguration: PnpmOptionsConfiguration = PnpmOptionsConfiguration.loadFromJsonFileOrThrow( + `${__dirname}/jsonFiles/pnpm-config-onlyBuiltDependencies.json`, + fakeCommonTempFolder + ); + + expect(TestUtilities.stripAnnotations(pnpmConfiguration.globalOnlyBuiltDependencies)).toEqual([ + 'esbuild', + 'canvas', + '@prisma/client' + ]); + }); + it('loads minimumReleaseAge', () => { const pnpmConfiguration: PnpmOptionsConfiguration = PnpmOptionsConfiguration.loadFromJsonFileOrThrow( `${__dirname}/jsonFiles/pnpm-config-minimumReleaseAge.json`, diff --git a/libraries/rush-lib/src/logic/pnpm/test/jsonFiles/pnpm-config-onlyBuiltDependencies.json b/libraries/rush-lib/src/logic/pnpm/test/jsonFiles/pnpm-config-onlyBuiltDependencies.json new file mode 100644 index 00000000000..94beb1042b3 --- /dev/null +++ b/libraries/rush-lib/src/logic/pnpm/test/jsonFiles/pnpm-config-onlyBuiltDependencies.json @@ -0,0 +1,3 @@ +{ + "globalOnlyBuiltDependencies": ["esbuild", "canvas", "@prisma/client"] +} diff --git a/libraries/rush-lib/src/schemas/pnpm-config.schema.json b/libraries/rush-lib/src/schemas/pnpm-config.schema.json index c7e628af851..8af96611e63 100644 --- a/libraries/rush-lib/src/schemas/pnpm-config.schema.json +++ b/libraries/rush-lib/src/schemas/pnpm-config.schema.json @@ -150,6 +150,15 @@ } }, + "globalOnlyBuiltDependencies": { + "description": "This field specifies an allowlist of dependencies that are permitted to run build scripts (preinstall, install, postinstall). In PNPM 10.x, build scripts are disabled by default for security. Use this setting to explicitly permit specific packages to run their build scripts. This is the inverse of \"globalNeverBuiltDependencies\".\n\n(SUPPORTED ONLY IN PNPM 10.1.0 AND NEWER)\n\nPNPM documentation: https://pnpm.io/package_json#pnpmonlybuiltdependencies", + "type": "array", + "items": { + "description": "Specify package name of the dependency allowed to run build scripts", + "type": "string" + } + }, + "globalIgnoredOptionalDependencies": { "description": "This field allows you to skip the installation of specific optional dependencies. The listed packages will be treated as if they are not present in the dependency tree during installation, meaning they will not be installed even if required by other packages.\n\n(SUPPORTED ONLY IN PNPM 9.0.0 AND NEWER)\n\nPNPM documentation: https://pnpm.io/package_json#pnpmalloweddeprecatedversions", "type": "array", From 93acd5732a61c0fe6991df8ac6c7789e55fa2fb4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 19:32:00 +0000 Subject: [PATCH 3/3] Fix schema item description to match convention Co-authored-by: iclanton <5010588+iclanton@users.noreply.github.com> --- libraries/rush-lib/src/schemas/pnpm-config.schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/rush-lib/src/schemas/pnpm-config.schema.json b/libraries/rush-lib/src/schemas/pnpm-config.schema.json index 8af96611e63..078e673fd73 100644 --- a/libraries/rush-lib/src/schemas/pnpm-config.schema.json +++ b/libraries/rush-lib/src/schemas/pnpm-config.schema.json @@ -154,7 +154,7 @@ "description": "This field specifies an allowlist of dependencies that are permitted to run build scripts (preinstall, install, postinstall). In PNPM 10.x, build scripts are disabled by default for security. Use this setting to explicitly permit specific packages to run their build scripts. This is the inverse of \"globalNeverBuiltDependencies\".\n\n(SUPPORTED ONLY IN PNPM 10.1.0 AND NEWER)\n\nPNPM documentation: https://pnpm.io/package_json#pnpmonlybuiltdependencies", "type": "array", "items": { - "description": "Specify package name of the dependency allowed to run build scripts", + "description": "Specify package name of the dependency", "type": "string" } },