From c7cbfa86b08f75fb34758686a5c0c3527d8a96c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=9A=80=20Jack?= Date: Tue, 5 May 2026 11:02:10 +1000 Subject: [PATCH 1/2] fix(core): allow nx build scripts in generated pnpm-workspace.yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pnpm 11 defaults strictDepBuilds to true. When create-nx-workspace runs a third-party preset (anything that hits the createEmptyWorkspace + createPreset code path), the initial `pnpm install --no-frozen-lockfile` fires ERR_PNPM_IGNORED_BUILDS for nx's postinstall script and the workspace-creation step fails before the preset can run. Extend addPnpmSettings to emit an allowBuilds entry for nx in the generated pnpm-workspace.yaml, so the initial install succeeds. Include the pnpm 10-compatible onlyBuiltDependencies form as well — pnpm silently ignores the key it doesn't recognize. --- .../src/generators/new/generate-workspace-files.spec.ts | 4 ++++ .../src/generators/new/generate-workspace-files.ts | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/workspace/src/generators/new/generate-workspace-files.spec.ts b/packages/workspace/src/generators/new/generate-workspace-files.spec.ts index 98911f9f18883..40fdaeaefaa33 100644 --- a/packages/workspace/src/generators/new/generate-workspace-files.spec.ts +++ b/packages/workspace/src/generators/new/generate-workspace-files.spec.ts @@ -391,6 +391,10 @@ describe('@nx/workspace:generateWorkspaceFiles', () => { - "packages/*" autoInstallPeers: true + allowBuilds: + nx: true + onlyBuiltDependencies: + - nx " `); expect(tree.exists('proj/.npmrc')).toBeFalsy(); diff --git a/packages/workspace/src/generators/new/generate-workspace-files.ts b/packages/workspace/src/generators/new/generate-workspace-files.ts index fa43c348c91d8..9f7afe7450fa5 100644 --- a/packages/workspace/src/generators/new/generate-workspace-files.ts +++ b/packages/workspace/src/generators/new/generate-workspace-files.ts @@ -335,12 +335,16 @@ async function createReadme( }); } -// ensure that pnpm install add all the missing peer deps - +// pnpm 11 requires allowBuilds for packages with postinstall scripts; +// onlyBuiltDependencies is the pnpm 10 equivalent (unknown keys are ignored). function addPnpmSettings(tree: Tree, options: NormalizedSchema) { tree.write( join(options.directory, 'pnpm-workspace.yaml'), `autoInstallPeers: true +allowBuilds: + nx: true +onlyBuiltDependencies: + - nx ` ); } From 585b4a04cf87308ff387a4664a5fdc9d5e5fd13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=9A=80=20Jack?= Date: Thu, 7 May 2026 05:48:33 +1000 Subject: [PATCH 2/2] fix(core): version-gate pnpm build allowlist in generated pnpm-workspace.yaml Use getPackageManagerVersion to emit only the correct key: - pnpm 11+: allowBuilds (the new pnpm 11 setting) - pnpm 10.6.0-10.x: onlyBuiltDependencies (the pnpm 10 setting) --- .../new/generate-workspace-files.spec.ts | 34 ++++++++++++++++--- .../new/generate-workspace-files.ts | 21 ++++++------ 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/packages/workspace/src/generators/new/generate-workspace-files.spec.ts b/packages/workspace/src/generators/new/generate-workspace-files.spec.ts index 40fdaeaefaa33..ffd3c0f034439 100644 --- a/packages/workspace/src/generators/new/generate-workspace-files.spec.ts +++ b/packages/workspace/src/generators/new/generate-workspace-files.spec.ts @@ -384,19 +384,45 @@ describe('@nx/workspace:generateWorkspaceFiles', () => { workspaceGlobs: ['apps/*', 'packages/*'], }); - const packageJson = tree.read('/proj/pnpm-workspace.yaml', 'utf-8'); - expect(packageJson).toMatchInlineSnapshot(` + const pnpmWorkspace = tree.read('/proj/pnpm-workspace.yaml', 'utf-8'); + expect(pnpmWorkspace).toMatchInlineSnapshot(` "packages: - "apps/*" - "packages/*" autoInstallPeers: true - allowBuilds: - nx: true onlyBuiltDependencies: - nx " `); expect(tree.exists('proj/.npmrc')).toBeFalsy(); }); + + it('should configure the pnpm settings in pnpm-workspace.yaml with allowBuilds for pnpm 11+', async () => { + tree.write('proj/package.json', JSON.stringify({})); + jest.spyOn(devkit, 'getPackageManagerVersion').mockReturnValue('11.0.0'); + + await generateWorkspaceFiles(tree, { + name: 'proj', + directory: 'proj', + preset: Preset.NPM, + defaultBase: 'main', + packageManager: 'pnpm', + isCustomPreset: false, + workspaceGlobs: ['apps/*', 'packages/*'], + }); + + const pnpmWorkspace = tree.read('/proj/pnpm-workspace.yaml', 'utf-8'); + expect(pnpmWorkspace).toMatchInlineSnapshot(` + "packages: + - "apps/*" + - "packages/*" + + autoInstallPeers: true + allowBuilds: + nx: true + " + `); + expect(tree.exists('proj/.npmrc')).toBeFalsy(); + }); }); diff --git a/packages/workspace/src/generators/new/generate-workspace-files.ts b/packages/workspace/src/generators/new/generate-workspace-files.ts index 9f7afe7450fa5..cc1551ef5bb34 100644 --- a/packages/workspace/src/generators/new/generate-workspace-files.ts +++ b/packages/workspace/src/generators/new/generate-workspace-files.ts @@ -198,7 +198,7 @@ export async function generateWorkspaceFiles( const [packageMajor] = packageManagerVersion.split('.'); if (options.packageManager === 'pnpm' && +packageMajor >= 7) { if (gte(packageManagerVersion, '10.6.0')) { - addPnpmSettings(tree, options); + addPnpmSettings(tree, options, packageManagerVersion); } else { createNpmrc(tree, options); } @@ -335,17 +335,18 @@ async function createReadme( }); } -// pnpm 11 requires allowBuilds for packages with postinstall scripts; -// onlyBuiltDependencies is the pnpm 10 equivalent (unknown keys are ignored). -function addPnpmSettings(tree: Tree, options: NormalizedSchema) { +function addPnpmSettings( + tree: Tree, + options: NormalizedSchema, + packageManagerVersion: string +) { + const buildAllowlist = gte(packageManagerVersion, '11.0.0') + ? `allowBuilds:\n nx: true` + : `onlyBuiltDependencies:\n - nx`; + tree.write( join(options.directory, 'pnpm-workspace.yaml'), - `autoInstallPeers: true -allowBuilds: - nx: true -onlyBuiltDependencies: - - nx -` + `autoInstallPeers: true\n${buildAllowlist}\n` ); }