fix(core): unbreak pnpm 11 installs by acknowledging build-script deps from generators - #36302
Merged
Merged
Conversation
✅ Deploy Preview for nx-dev ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for nx-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Contributor
|
View your CI Pipeline Execution ↗ for commit b2b4148
☁️ Nx Cloud last updated this comment at |
AgentEnder
approved these changes
Jul 10, 2026
AgentEnder
force-pushed
the
fix/pnpm11-generated-allow-builds
branch
2 times, most recently
from
July 13, 2026 14:06
a2c39f5 to
025ae23
Compare
FrozenPandaz
force-pushed
the
fix/pnpm11-generated-allow-builds
branch
2 times, most recently
from
July 13, 2026 15:52
4b6fff2 to
4eb02a1
Compare
FrozenPandaz
force-pushed
the
fix/pnpm11-generated-allow-builds
branch
from
July 15, 2026 15:50
1e9180a to
180addf
Compare
A plugin that throws a non-Error value (or an error that loses its message crossing the plugin worker boundary) crashed formatAggregateCreateNodesError with "Cannot read properties of undefined (reading 'split')", masking the real failure. Coerce tuple values to Errors in the AggregateCreateNodesError constructor and fall back to the message when a deserialized error has no stack.
@angular/cli 22.0.5 requires node ^22.22.3 || ^24.15.0 || >=26, so ng new refuses to run on the previously pinned 22.13.0 / 24.0.0 and every e2e-nx-init and e2e-angular combo fails.
… add build-script deps pnpm 11 fails installs with ERR_PNPM_IGNORED_BUILDS when a dependency's build scripts are neither allowed nor denied, so generators that introduce such dependencies now record the decision in pnpm-workspace.yaml before their install task runs: jest acknowledges unrs-resolver, vite and esbuild acknowledge esbuild, swc setups acknowledge @swc/core, nest acknowledges @nestjs/core (all skipped, matching pnpm 10 behavior since they ship prebuilt binaries or only print funding messages), while cypress and detox allow their builds because those scripts are required for the tools to function. The comment-preserving helper never overwrites existing user entries and no-ops for non-pnpm workspaces and pnpm < 11. Note: 'nx add <plugin>' installs the plugin package before its init generator runs, so a plugin whose own dependency tree carries a build-script package (e.g. @nx/jest -> jest-resolve -> unrs-resolver) still surfaces pnpm's approve-builds error in that flow.
e2e tests pnpm-add plugins without running a generator first, so pnpm 11's strict build gate fails those installs before any allowBuilds entry can be recorded. Seed e2e-created pnpm and lerna workspaces with strictDepBuilds: false to restore pnpm 10's warn-and-skip behavior in the test environment.
'nx add <plugin>' and 'nx init' install packages before any plugin generator can record allowBuilds decisions, so pnpm 11's strict build gate failed them: the plugin's own dependency tree can carry build-script packages (e.g. @nx/jest -> jest-resolve -> unrs-resolver), and nx itself has a postinstall that existing repos have not acknowledged. - nx init records 'allowBuilds: nx: true' when it adds nx to an existing pnpm 11 workspace (acknowledgePnpmBuildScripts now accepts a filesystem root as well as a Tree). - nx add and nx init run their bootstrap installs with --config.strictDepBuilds=false, restoring pnpm 10's warn-and-skip behavior for that one install; the plugin init generators that run right after record the durable allowBuilds entries.
Rename acknowledgePnpmBuildScripts to acknowledgeBuildScripts and require callers to pass their PackageManager instead of inferring pnpm from the presence of pnpm-workspace.yaml. The generic entry no-ops for package managers other than pnpm (they run build scripts unconditionally) and delegates to a pnpm-specific function that records allowBuilds entries.
Replace the strictDepBuilds: false seed in e2e-created pnpm workspaces with --config.strictDepBuilds=false on the harness's raw install commands (packageInstall, the post-copy reinstall, and the lerna workspace bootstrap). Generator-driven installs inside tests stay strict, so e2e still fails if a generator forgets to record its allowBuilds entry.
runInstall and addDepsToPackageJson now take the PackageManager instead of re-detecting it internally; each init/import flow detects once and passes it down.
…s in repos without one With the package manager passed in explicitly, the file's absence no longer doubles as pnpm detection. Single-package pnpm repos without a pnpm-workspace.yaml (e.g. nx init targets) now get the file created with the allowBuilds entries, mirroring what pnpm approve-builds does.
…s in repos without one [Self-Healing CI Rerun]
…init flows add-nx-to-monorepo, add-nx-to-nest, and the angular init now detect the package manager once and pass it to addDepsToPackageJson and runInstall, matching the other init flows.
- pnpm 11 ignores .npmrc prefer-frozen-lockfile, so set pnpm_config_frozen_lockfile=false at the env level - npx strips protected _authToken env keys, so npm publish needs the local registry token in the workspace .npmrc
pnpm 11 no longer reads the pnpm field in package.json, so the override forcing lerna to use the locally published nx was silently ignored and the smoke test ran against the npmjs-published nx instead.
- ts-solution tarball snapshots: sorted contents now list dist/README.md before dist/index.* (path sort added in the release publish executor) - lerna smoke: pnpm 11 no longer echoes the script command, so strip the echo line for every package manager instead of normalizing it
The nightly job env duplicated the pnpm_config_* settings that global-setup already puts on process.env for everything jest spawns; the outer pnpm handoff passes its implicit checks against the repo's committed allowBuilds without softening.
…Json Every call site passes it, and most passed undefined just to skip past the optional additionalPackages param.
…ites Slicing the field fed raw ranges like ^11 or latest into semver.gte, which throws; parseVersionFromPackageManagerField returns null for non-exact pins so the version is probed from pnpm itself instead.
…en e2e projects" This reverts commit 95c30b8.
AgentEnder
added a commit
that referenced
this pull request
Jul 15, 2026
#36359) ## Current Behavior Name-ref sentinels (used to keep `dependsOn`/`inputs` project references correct across renames) are written back through a pointer to the array they were created in. Merges copy sentinels **by reference** into fresh arrays — most visibly when a project.json pattern target (e.g. `e2e-ci--**/**`) with a `"..."` spread is applied to every matching atomized target. The copies never get resolved, leaving raw internal objects (`RootRef { value, parent, targetPart }`) in the final project configuration, and task graph creation crashes with: ``` NX pattern is not iterable ``` ## Expected Behavior Every name ref resolves to its project name wherever it ends up. `applySubstitutions` now sweeps the merged rootMap and resolves each sentinel in place, covering arrays a sentinel was copied into. Since write-back no longer depends on back-references, the `parent`/`key` fields, the `allRefs` registry, and the parent-rebinding branches are removed. The new integration test reproduces the exact corruption on the previous implementation (raw `RootRef` objects in the atomized targets' `dependsOn`) and passes with the sweep. ## Related Issue(s) Found while using `"..."` in the `dependsOn` of atomized e2e pattern targets in this repo (see `e2e/gradle/project.json` / `e2e/maven/project.json`); that cleanup was reverted from #36302 and can be re-applied once this fix ships. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Qjm3xvLS2vLRsaxt4vv56d <!-- polygraph-session-start --> --- [View session information ↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/PR-for-pnpm-11-ERR_PNPM_IGNORED_BUILDS-fix-f71af2eb) <!-- polygraph-session-end --> --------- Co-authored-by: Craigory Coppola <craigorycoppola@gmail.com>
FrozenPandaz
force-pushed
the
fix/pnpm11-generated-allow-builds
branch
from
July 15, 2026 21:16
fecb261 to
d3ab8e5
Compare
…en e2e projects" [Self-Healing CI Rerun]
Contributor
There was a problem hiding this comment.
Nx Cloud has identified a flaky task in your failed CI:
🔂 Since the failure was identified as flaky, we triggered a CI rerun by adding an empty commit to this branch.
🎓 Learn more about Self-Healing CI on nx.dev
…en e2e projects" [Self-Healing CI Rerun]
AgentEnder
added a commit
that referenced
this pull request
Jul 17, 2026
#36359) ## Current Behavior Name-ref sentinels (used to keep `dependsOn`/`inputs` project references correct across renames) are written back through a pointer to the array they were created in. Merges copy sentinels **by reference** into fresh arrays — most visibly when a project.json pattern target (e.g. `e2e-ci--**/**`) with a `"..."` spread is applied to every matching atomized target. The copies never get resolved, leaving raw internal objects (`RootRef { value, parent, targetPart }`) in the final project configuration, and task graph creation crashes with: ``` NX pattern is not iterable ``` ## Expected Behavior Every name ref resolves to its project name wherever it ends up. `applySubstitutions` now sweeps the merged rootMap and resolves each sentinel in place, covering arrays a sentinel was copied into. Since write-back no longer depends on back-references, the `parent`/`key` fields, the `allRefs` registry, and the parent-rebinding branches are removed. The new integration test reproduces the exact corruption on the previous implementation (raw `RootRef` objects in the atomized targets' `dependsOn`) and passes with the sweep. ## Related Issue(s) Found while using `"..."` in the `dependsOn` of atomized e2e pattern targets in this repo (see `e2e/gradle/project.json` / `e2e/maven/project.json`); that cleanup was reverted from #36302 and can be re-applied once this fix ships. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Qjm3xvLS2vLRsaxt4vv56d <!-- polygraph-session-start --> --- [View session information ↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/PR-for-pnpm-11-ERR_PNPM_IGNORED_BUILDS-fix-f71af2eb) <!-- polygraph-session-end --> --------- Co-authored-by: Craigory Coppola <craigorycoppola@gmail.com>
This was referenced Jul 20, 2026
FrozenPandaz
added a commit
that referenced
this pull request
Jul 20, 2026
#36359) ## Current Behavior Name-ref sentinels (used to keep `dependsOn`/`inputs` project references correct across renames) are written back through a pointer to the array they were created in. Merges copy sentinels **by reference** into fresh arrays — most visibly when a project.json pattern target (e.g. `e2e-ci--**/**`) with a `"..."` spread is applied to every matching atomized target. The copies never get resolved, leaving raw internal objects (`RootRef { value, parent, targetPart }`) in the final project configuration, and task graph creation crashes with: ``` NX pattern is not iterable ``` ## Expected Behavior Every name ref resolves to its project name wherever it ends up. `applySubstitutions` now sweeps the merged rootMap and resolves each sentinel in place, covering arrays a sentinel was copied into. Since write-back no longer depends on back-references, the `parent`/`key` fields, the `allRefs` registry, and the parent-rebinding branches are removed. The new integration test reproduces the exact corruption on the previous implementation (raw `RootRef` objects in the atomized targets' `dependsOn`) and passes with the sweep. ## Related Issue(s) Found while using `"..."` in the `dependsOn` of atomized e2e pattern targets in this repo (see `e2e/gradle/project.json` / `e2e/maven/project.json`); that cleanup was reverted from #36302 and can be re-applied once this fix ships. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Qjm3xvLS2vLRsaxt4vv56d <!-- polygraph-session-start --> --- [View session information ↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/PR-for-pnpm-11-ERR_PNPM_IGNORED_BUILDS-fix-f71af2eb) <!-- polygraph-session-end --> --------- Co-authored-by: Craigory Coppola <craigorycoppola@gmail.com> (cherry picked from commit 4a05b10)
FrozenPandaz
added a commit
that referenced
this pull request
Jul 20, 2026
…s from generators (#36302) ## Current Behavior pnpm 11 fails installs with `ERR_PNPM_IGNORED_BUILDS` when a dependency's build scripts are neither allowed nor denied. Workspaces generated by `create-nx-workspace` only allow `nx`, so any flow that pulls in a build-script dependency hard-fails: jest 30 pulls in `unrs-resolver` (via `jest-resolve`), vite pulls in `esbuild`, swc setups pull in `@swc/core`, etc. This breaks preset installs for real pnpm 11 users and is the dominant cause of the nightly E2E matrix failures (~70 of 139 jobs die in `newProject()`): https://github.com/nrwl/nx/actions/runs/28642151329 Three more nightly root causes ride along: - When a plugin throws a non-Error value, `formatAggregateCreateNodesError` crashes with `Cannot read properties of undefined (reading 'split')`, masking the real error (js-strip-types failures). - `@angular/cli@22.0.5` raised its Node floor to `^22.22.3 || ^24.15.0`, so `ng new` refuses to run on the matrix's pinned Node 22.13.0 / 24.0.0 (e2e-nx-init, e2e-angular). - e2e tests `pnpm add` plugins directly (no generator runs first), so they hit the strict build gate regardless of generator fixes. ## Expected Behavior - Generators that introduce build-script dependencies record the `allowBuilds` decision in `pnpm-workspace.yaml` before their install task runs, via a new comment-preserving `acknowledgePnpmBuildScripts` helper (exposed through `@nx/devkit/internal`): jest acknowledges `unrs-resolver`, vite/esbuild acknowledge `esbuild`, swc setups acknowledge `@swc/core`, nest acknowledges `@nestjs/core` (all `false` = skipped, matching pnpm 10 behavior since they ship prebuilt binaries or only print funding messages); cypress and detox set `true` because their install scripts are required to function. Entries the user already set are never overwritten; the helper no-ops for non-pnpm workspaces and pnpm < 11. Generated workspaces no longer preseed entries for dependencies they may never have. - Non-Error `createNodes` failures are coerced to Errors in the `AggregateCreateNodesError` constructor so the real failure always surfaces. - The e2e matrix pins Node 22.22.3 / 24.15.0, satisfying the Angular CLI floor. - e2e-created pnpm/lerna workspaces are seeded with `strictDepBuilds: false` (pnpm 10's warn-and-skip behavior) since tests install plugins without running generators first. Known gap (documented in the commit): `nx add <plugin>` installs the plugin package before its init generator runs, so a plugin whose own dependency tree carries a build-script package (e.g. `@nx/jest` → `jest-resolve` → `unrs-resolver`) still surfaces pnpm's `approve-builds` error in that flow. ## Related Issue(s) Nightly E2E matrix failure: https://github.com/nrwl/nx/actions/runs/28642151329 <!-- polygraph-session-start --> --- [View session information ↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/PR-for-pnpm-11-ERR_PNPM_IGNORED_BUILDS-fix-f71af2eb) <!-- polygraph-session-end --> --------- Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com> (cherry picked from commit e380258)
FrozenPandaz
pushed a commit
that referenced
this pull request
Jul 20, 2026
## Current Behavior The `e2e-docker` project depends on the `local-registry` target, while its `populate-local-registry-storage` dependency pulls in `local-registry-e2e`. Both serve verdaccio on port 4873, so the two tasks start milliseconds apart and race for the port. Verdaccio's busy-port fallback does not save this: both probe the port before either has bound, and the loser then fails at bind time with `EADDRINUSE`, which fails the run before any test executes. The nightly docker npm and pnpm jobs have failed this way on every run since #36302 landed. ## Expected Behavior `e2e-docker` depends on `local-registry-e2e`, the same target every other e2e project uses, so only one verdaccio server starts. ## Implementation Details #36302 introduced `local-registry-e2e` and migrated `nx.json`, `e2e/gradle/project.json` and `e2e/maven/project.json`, but left `e2e/docker/project.json` on the old target. Verified against the task graph (`nx run e2e-docker:e2e-local --graph=<file>`): `@nx/nx-source:local-registry` is gone from both the task list and `continuousDependencies`, and `@nx/nx-source:local-registry-e2e` remains. A full e2e-docker run was not executed locally. <!-- polygraph-session-start --> --- [View session information ↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/fix-e2e-docker-local-registry-target-ecd65894) <!-- polygraph-session-end -->
FrozenPandaz
pushed a commit
that referenced
this pull request
Jul 20, 2026
…ollup (#36412) ## Current Behavior Configuring rollup with the swc compiler adds `@swc/core` to `package.json` without recording a build-script decision for it. pnpm 11 refuses to install a dependency whose build scripts are neither allowed nor denied, so the install that follows the generator fails. #36302 added these acknowledgements across the generators that pull in `@swc/core`, including `@nx/js`, but missed this call site. ## Expected Behavior The generator records the decision alongside the dependency, matching what `@nx/js` already does, so the install succeeds. The build script is denied rather than allowed: `@swc/core`'s postinstall only fetches a wasm fallback for platforms its prebuilt optional dependencies do not cover, so there is nothing to run on a supported platform. Existing decisions in `pnpm-workspace.yaml` are never overwritten, and this is a no-op for npm, yarn, bun, and for pnpm below 11. <!-- polygraph-session-start --> --- [View session information ↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/fix-jest-swc-core-peer-1fe697de) <!-- polygraph-session-end -->
FrozenPandaz
added a commit
that referenced
this pull request
Jul 28, 2026
…istry (#36482) ## Current Behavior Four e2e targets declare their own per-test-file `dependsOn` in `project.json`: ```json "e2e-macos-ci--src/detox.test.ts": { "dependsOn": ["nx:build-native", "@nx/nx-source:populate-local-registry-storage"], "inputs": ["e2eInputs", "^production"] } ``` These date back to #23429 (May 2024), when no e2e `targetDefault` declared a `dependsOn` at all and every test file spelled out its own. `@nx/nx-source:local-registry-e2e` did not exist then — it was added in #36302, renamed from `local-registry`. Because `dependsOn` replaces rather than merges, these overrides silently drop the registry once it moved into `targetDefaults`: ``` nx.json e2e-macos-ci--**/* -> [populate-local-registry-storage, local-registry-e2e] resolved e2e-macos-ci--src/detox.test.ts -> [nx:build-native, populate-local-registry-storage] ``` For the two `e2e/detox` targets that is a real hang. `populate-local-registry-storage` is the only thing anchoring the continuous registry task, and `cleanUpUnneededContinuousTasks` keeps a continuous task alive only while some *incomplete* task lists it in `continuousDependencies`. The detox targets don't, so verdaccio is killed the moment `populate` completes — before the detox task even starts. Its Jest `globalSetup` then polls `http://localhost:4873` in a `while (true)` loop with no timeout, so the agent spins until the job's `timeout-minutes` fires with no diagnostic. The `e2e/node` and `e2e/js` entries name test files that no longer exist (`src/webpack.test.ts` → `node-webpack.test.ts`, `src/js-generators.test.ts` → `js-generators.ts`), so they materialize as unreachable ghost targets. The sibling e2e projects that need an extra dependency get this right by appending to the full list rather than replacing it: ``` e2e/gradle -> [populate, local-registry-e2e, :gradle-project-graph:gradle:publishToMavenLocal] e2e/maven -> [populate, local-registry-e2e, nx-maven-plugin:install] e2e/docker -> [populate, local-registry-e2e, start-docker-registry] ``` ## Expected Behavior All four overrides are removed, so every per-file e2e target inherits the `targetDefaults` and gets the registry back. `nx:build-native` is not lost — it is already covered transitively: ``` populate-local-registry-storage -> dependsOn { target: build, projects: [tag:npm:public] } project.json -> nx:build -> build-base packages/nx/project.json -> build-base dependsOn ['^build-base', 'build-native', ...] nx.json targetDefaults ``` `nx` carries the `npm:public` tag from nx's own package-json plugin, so it is in that set — and publishing to the local registry has to build nx regardless. Verified with `nx show project` before and after: | target | before | after | | --- | --- | --- | | `e2e-detox:e2e-macos-ci--src/detox.test.ts` | `[build-native, populate]` — no registry | `[populate, local-registry-e2e]` | | `e2e-detox:e2e-macos-ci--src/detox-legacy.test.ts` | `[build-native, populate]` — no registry | `[populate, local-registry-e2e]` | | `e2e-node:e2e-ci--src/webpack.test.ts` | ghost target | removed | | `e2e-js:e2e-ci--src/js-generators.test.ts` | ghost target | removed | Every per-file e2e target across the three projects now resolves with `local-registry-e2e`, and no ghost targets remain. `inputs` were already identical to the defaults (`["e2eInputs", "^production"]`) for the detox targets, so nothing else changes. ## Related Issue(s) N/A — internal CI configuration fix, no linked issue. <!-- polygraph-session-start --> --- [View session information ↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/Restore-local-registry-dependency-for-e2e-target-overrides-88ebe0ee) <!-- polygraph-session-end --> Co-authored-by: FrozenPandaz <jasonjean1993@gmail.com>
FrozenPandaz
pushed a commit
that referenced
this pull request
Jul 29, 2026
## Current Behavior The `e2e-docker` project depends on the `local-registry` target, while its `populate-local-registry-storage` dependency pulls in `local-registry-e2e`. Both serve verdaccio on port 4873, so the two tasks start milliseconds apart and race for the port. Verdaccio's busy-port fallback does not save this: both probe the port before either has bound, and the loser then fails at bind time with `EADDRINUSE`, which fails the run before any test executes. The nightly docker npm and pnpm jobs have failed this way on every run since #36302 landed. ## Expected Behavior `e2e-docker` depends on `local-registry-e2e`, the same target every other e2e project uses, so only one verdaccio server starts. ## Implementation Details #36302 introduced `local-registry-e2e` and migrated `nx.json`, `e2e/gradle/project.json` and `e2e/maven/project.json`, but left `e2e/docker/project.json` on the old target. Verified against the task graph (`nx run e2e-docker:e2e-local --graph=<file>`): `@nx/nx-source:local-registry` is gone from both the task list and `continuousDependencies`, and `@nx/nx-source:local-registry-e2e` remains. A full e2e-docker run was not executed locally. <!-- polygraph-session-start --> --- [View session information ↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/fix-e2e-docker-local-registry-target-ecd65894) <!-- polygraph-session-end --> (cherry picked from commit d196355)
FrozenPandaz
pushed a commit
that referenced
this pull request
Jul 29, 2026
…ollup (#36412) ## Current Behavior Configuring rollup with the swc compiler adds `@swc/core` to `package.json` without recording a build-script decision for it. pnpm 11 refuses to install a dependency whose build scripts are neither allowed nor denied, so the install that follows the generator fails. #36302 added these acknowledgements across the generators that pull in `@swc/core`, including `@nx/js`, but missed this call site. ## Expected Behavior The generator records the decision alongside the dependency, matching what `@nx/js` already does, so the install succeeds. The build script is denied rather than allowed: `@swc/core`'s postinstall only fetches a wasm fallback for platforms its prebuilt optional dependencies do not cover, so there is nothing to run on a supported platform. Existing decisions in `pnpm-workspace.yaml` are never overwritten, and this is a no-op for npm, yarn, bun, and for pnpm below 11. <!-- polygraph-session-start --> --- [View session information ↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/fix-jest-swc-core-peer-1fe697de) <!-- polygraph-session-end --> (cherry picked from commit 866a107)
FrozenPandaz
added a commit
that referenced
this pull request
Jul 29, 2026
…istry (#36482) ## Current Behavior Four e2e targets declare their own per-test-file `dependsOn` in `project.json`: ```json "e2e-macos-ci--src/detox.test.ts": { "dependsOn": ["nx:build-native", "@nx/nx-source:populate-local-registry-storage"], "inputs": ["e2eInputs", "^production"] } ``` These date back to #23429 (May 2024), when no e2e `targetDefault` declared a `dependsOn` at all and every test file spelled out its own. `@nx/nx-source:local-registry-e2e` did not exist then — it was added in #36302, renamed from `local-registry`. Because `dependsOn` replaces rather than merges, these overrides silently drop the registry once it moved into `targetDefaults`: ``` nx.json e2e-macos-ci--**/* -> [populate-local-registry-storage, local-registry-e2e] resolved e2e-macos-ci--src/detox.test.ts -> [nx:build-native, populate-local-registry-storage] ``` For the two `e2e/detox` targets that is a real hang. `populate-local-registry-storage` is the only thing anchoring the continuous registry task, and `cleanUpUnneededContinuousTasks` keeps a continuous task alive only while some *incomplete* task lists it in `continuousDependencies`. The detox targets don't, so verdaccio is killed the moment `populate` completes — before the detox task even starts. Its Jest `globalSetup` then polls `http://localhost:4873` in a `while (true)` loop with no timeout, so the agent spins until the job's `timeout-minutes` fires with no diagnostic. The `e2e/node` and `e2e/js` entries name test files that no longer exist (`src/webpack.test.ts` → `node-webpack.test.ts`, `src/js-generators.test.ts` → `js-generators.ts`), so they materialize as unreachable ghost targets. The sibling e2e projects that need an extra dependency get this right by appending to the full list rather than replacing it: ``` e2e/gradle -> [populate, local-registry-e2e, :gradle-project-graph:gradle:publishToMavenLocal] e2e/maven -> [populate, local-registry-e2e, nx-maven-plugin:install] e2e/docker -> [populate, local-registry-e2e, start-docker-registry] ``` ## Expected Behavior All four overrides are removed, so every per-file e2e target inherits the `targetDefaults` and gets the registry back. `nx:build-native` is not lost — it is already covered transitively: ``` populate-local-registry-storage -> dependsOn { target: build, projects: [tag:npm:public] } project.json -> nx:build -> build-base packages/nx/project.json -> build-base dependsOn ['^build-base', 'build-native', ...] nx.json targetDefaults ``` `nx` carries the `npm:public` tag from nx's own package-json plugin, so it is in that set — and publishing to the local registry has to build nx regardless. Verified with `nx show project` before and after: | target | before | after | | --- | --- | --- | | `e2e-detox:e2e-macos-ci--src/detox.test.ts` | `[build-native, populate]` — no registry | `[populate, local-registry-e2e]` | | `e2e-detox:e2e-macos-ci--src/detox-legacy.test.ts` | `[build-native, populate]` — no registry | `[populate, local-registry-e2e]` | | `e2e-node:e2e-ci--src/webpack.test.ts` | ghost target | removed | | `e2e-js:e2e-ci--src/js-generators.test.ts` | ghost target | removed | Every per-file e2e target across the three projects now resolves with `local-registry-e2e`, and no ghost targets remain. `inputs` were already identical to the defaults (`["e2eInputs", "^production"]`) for the detox targets, so nothing else changes. ## Related Issue(s) N/A — internal CI configuration fix, no linked issue. <!-- polygraph-session-start --> --- [View session information ↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/Restore-local-registry-dependency-for-e2e-target-overrides-88ebe0ee) <!-- polygraph-session-end --> Co-authored-by: FrozenPandaz <jasonjean1993@gmail.com> (cherry picked from commit 4894978)
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.
Current Behavior
pnpm 11 fails installs with
ERR_PNPM_IGNORED_BUILDSwhen a dependency's build scripts are neither allowed nor denied. Workspaces generated bycreate-nx-workspaceonly allownx, so any flow that pulls in a build-script dependency hard-fails: jest 30 pulls inunrs-resolver(viajest-resolve), vite pulls inesbuild, swc setups pull in@swc/core, etc. This breaks preset installs for real pnpm 11 users and is the dominant cause of the nightly E2E matrix failures (~70 of 139 jobs die innewProject()): https://github.com/nrwl/nx/actions/runs/28642151329Three more nightly root causes ride along:
formatAggregateCreateNodesErrorcrashes withCannot read properties of undefined (reading 'split'), masking the real error (js-strip-types failures).@angular/cli@22.0.5raised its Node floor to^22.22.3 || ^24.15.0, song newrefuses to run on the matrix's pinned Node 22.13.0 / 24.0.0 (e2e-nx-init, e2e-angular).pnpm addplugins directly (no generator runs first), so they hit the strict build gate regardless of generator fixes.Expected Behavior
allowBuildsdecision inpnpm-workspace.yamlbefore their install task runs, via a new comment-preservingacknowledgePnpmBuildScriptshelper (exposed through@nx/devkit/internal): jest acknowledgesunrs-resolver, vite/esbuild acknowledgeesbuild, swc setups acknowledge@swc/core, nest acknowledges@nestjs/core(allfalse= skipped, matching pnpm 10 behavior since they ship prebuilt binaries or only print funding messages); cypress and detox settruebecause their install scripts are required to function. Entries the user already set are never overwritten; the helper no-ops for non-pnpm workspaces and pnpm < 11. Generated workspaces no longer preseed entries for dependencies they may never have.createNodesfailures are coerced to Errors in theAggregateCreateNodesErrorconstructor so the real failure always surfaces.strictDepBuilds: false(pnpm 10's warn-and-skip behavior) since tests install plugins without running generators first.Known gap (documented in the commit):
nx add <plugin>installs the plugin package before its init generator runs, so a plugin whose own dependency tree carries a build-script package (e.g.@nx/jest→jest-resolve→unrs-resolver) still surfaces pnpm'sapprove-buildserror in that flow.Related Issue(s)
Nightly E2E matrix failure: https://github.com/nrwl/nx/actions/runs/28642151329
View session information ↗