Skip to content

feat(core): show target uses task graph + filter broken dependsOn during normalization - #35367

Merged
FrozenPandaz merged 1 commit into
masterfrom
wry-splash
Apr 30, 2026
Merged

feat(core): show target uses task graph + filter broken dependsOn during normalization#35367
FrozenPandaz merged 1 commit into
masterfrom
wry-splash

Conversation

@AgentEnder

Copy link
Copy Markdown
Member

Current Behavior

  • During project graph normalization, dependsOn entries whose target doesn't exist are left in place, which means downstream consumers have to re-validate against the real target set every time.
  • nx show target resolves the Depends On list using a heuristic on raw dependsOn configs. That heuristic doesn't fully match what createTaskGraph would schedule — e.g. a { projects: ['lib-a'] } entry is listed even if lib-a doesn't actually have the referenced target, and there's no indication of what transitively runs when the target is scheduled.

Expected Behavior

1. Normalize-project-nodes drops broken same-project dependsOn entries

A new normalizeTargetsDependsOn pass runs inside normalizeProjectNodes after target defaults have been merged. It filters:

  • Bare-string entries (e.g. "prebuild") when the referenced target doesn't exist on the same project.
  • Object entries with no projects, projects: 'self', or projects: '{self}' when the referenced target doesn't exist on the same project.

Cross-project entries are intentionally left alone — "^target", { target: 'X', dependencies: true }, and { projects: [...] } need the real project graph (and in some cases the dep edges) to validate, so they're resolved later during task graph creation.

2. nx show target is task-graph-driven

showTargetInfoHandler now builds a task graph rooted at the requested target via createTaskGraph. The Depends On list reads direct task dependencies off the graph, giving the same filtering and resolution behavior as nx run:

  • Non-existent targets disappear from the list.
  • ^target expands to real dependency-project task IDs.
  • { projects: [...] } entries drop projects that don't actually have the target.

A new transientTasks field on the JSON output surfaces everything that runs transitively. The text renderer shows a summary line beneath Depends On:

Depends On:
  lib-a:build
  and 5 build, compile transient tasks

With >3 unique target names, the summary collapses to a bare count (and 12 transient tasks) to stay scannable. Source-map hints for --verbose are preserved — each direct dep task ID is matched back to its originating depConfig entry.

Related Issue(s)

None — proactive correctness + observability improvement.

@AgentEnder
AgentEnder requested a review from a team as a code owner April 21, 2026 21:29
@AgentEnder
AgentEnder requested a review from leosvelperez April 21, 2026 21:29
@netlify

netlify Bot commented Apr 21, 2026

Copy link
Copy Markdown

Deploy Preview for nx-dev ready!

Name Link
🔨 Latest commit 8750bc5
🔍 Latest deploy log https://app.netlify.com/projects/nx-dev/deploys/69e99e3331266e0008fdf079
😎 Deploy Preview https://deploy-preview-35367--nx-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Apr 21, 2026

Copy link
Copy Markdown

Deploy Preview for nx-docs ready!

Name Link
🔨 Latest commit 8750bc5
🔍 Latest deploy log https://app.netlify.com/projects/nx-docs/deploys/69e99e33bcb91b000889ad22
😎 Deploy Preview https://deploy-preview-35367--nx-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@nx-cloud

nx-cloud Bot commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit 8750bc5

Command Status Duration Result
nx affected --targets=lint,test,build,e2e,e2e-c... ✅ Succeeded 49m 50s View ↗
nx run-many -t check-imports check-lock-files c... ✅ Succeeded 3s View ↗
nx-cloud record -- pnpm nx-cloud conformance:check ✅ Succeeded 17s View ↗
nx build workspace-plugin ✅ Succeeded <1s View ↗
nx-cloud record -- nx sync:check ✅ Succeeded 23s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 6s View ↗

☁️ Nx Cloud last updated this comment at 2026-04-23 05:14:41 UTC

nx-cloud[bot]

This comment was marked as outdated.

@nx-cloud nx-cloud Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ The fix from Nx Cloud was applied

We fix two bugs introduced in this PR: { target: X, dependencies: true } entries were incorrectly treated as same-project self-references and dropped by normalizeTargetsDependsOn, when they are actually cross-project references that must be left for task-graph creation. Additionally, the two new transient-summary tests used a $/m end-of-line anchor that fails because c.dim() appends an ANSI reset code after the summary text, so the anchor is dropped to make the assertions robust to ANSI wrapping.

Warning

We could not verify this fix.

Suggested Fix changes
diff --git a/packages/nx/src/command-line/show/show-target/info.spec.ts b/packages/nx/src/command-line/show/show-target/info.spec.ts
index 8982940d07..41536e23ae 100644
--- a/packages/nx/src/command-line/show/show-target/info.spec.ts
+++ b/packages/nx/src/command-line/show/show-target/info.spec.ts
@@ -268,7 +268,7 @@ describe('show target info', () => {
       .map((c) => c[0])
       .join('\n');
     // With ≤3 unique transient target names, list them.
-    expect(allLogged).toMatch(/and 1 compile transient task$/m);
+    expect(allLogged).toMatch(/and 1 compile transient task/m);
   });
 
   it('should collapse the transient-task summary to just a count when there are more than 3 unique target names', async () => {
@@ -319,7 +319,7 @@ describe('show target info', () => {
       .map((c) => c[0])
       .join('\n');
     // >3 unique target names collapses to bare count with no target names
-    expect(allLogged).toMatch(/and \d+ transient tasks$/m);
+    expect(allLogged).toMatch(/and \d+ transient tasks/m);
     expect(allLogged).not.toMatch(/and \d+ build,/);
   });
 
diff --git a/packages/nx/src/project-graph/utils/normalize-project-nodes.ts b/packages/nx/src/project-graph/utils/normalize-project-nodes.ts
index 52e3404dc5..329e5f7ff9 100644
--- a/packages/nx/src/project-graph/utils/normalize-project-nodes.ts
+++ b/packages/nx/src/project-graph/utils/normalize-project-nodes.ts
@@ -168,7 +168,7 @@ function isValidDependsOnEntry(
   // Anything that references other projects (via `projects` or
   // `dependencies: true`) is validated later during task graph creation.
   const selfRef =
-    dep.projects === undefined ||
+    (dep.projects === undefined && !dep.dependencies) ||
     dep.projects === 'self' ||
     dep.projects === '{self}';
   if (!selfRef) {

🔔 Heads up, your workspace has pending recommendations ↗ to auto-apply fixes for similar failures.

Revert fix via Nx Cloud  

View interactive diff ↗

➡️ This fix was applied by Craigory Coppola

🎓 Learn more about Self-Healing CI on nx.dev

Comment thread packages/nx/src/project-graph/utils/normalize-project-nodes.ts Outdated
Comment thread packages/nx/src/project-graph/utils/normalize-project-nodes.ts Outdated
Comment thread packages/nx/src/command-line/show/show-target/info.ts Outdated
Comment thread packages/nx/src/command-line/show/show-target/info.ts Outdated
Comment thread packages/nx/src/command-line/show/show-target/info.ts Outdated
…ive summary

`nx show target` now builds a task graph rooted at the requested target
via `createTaskGraph`. The `Depends On` list reads direct task
dependencies off the graph, giving the same filtering and resolution
behavior as `nx run`:

- Non-existent targets disappear from the list.
- `^target` expands to real dependency-project task IDs.
- `{ projects: [...] }` entries drop projects that don't actually have
  the target.

A new `transitiveTasks` field on the JSON output surfaces everything
that runs transitively. The text renderer shows a summary line beneath
`Depends On`:

    Depends On:
      lib-a:build
      and 5 build, compile transitive tasks

With >3 unique target names, the summary collapses to a bare count
(`and 12 transitive tasks`).

If `createTaskGraph` throws (e.g. circular dependencies), falls back to
resolving the configured `depConfigs` so the list isn't silently empty.

Source-map hints for `--verbose` are preserved — each direct dep task
ID is matched back to its originating `depConfig` entry.
@AgentEnder
AgentEnder requested a review from FrozenPandaz April 23, 2026 12:16
@FrozenPandaz FrozenPandaz added the priority: medium Medium Priority (not high, not low priority) label Apr 23, 2026
@FrozenPandaz
FrozenPandaz merged commit 41e2cb1 into master Apr 30, 2026
24 checks passed
@FrozenPandaz
FrozenPandaz deleted the wry-splash branch April 30, 2026 19:51
@github-actions

github-actions Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

This pull request has already been merged/closed. If you experience issues related to these changes, please open a new issue referencing this pull request.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators May 6, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

priority: medium Medium Priority (not high, not low priority)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants