feat(core): show target uses task graph + filter broken dependsOn during normalization - #35367
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. |
|
View your CI Pipeline Execution ↗ for commit 8750bc5
☁️ Nx Cloud last updated this comment at |
There was a problem hiding this comment.
✅ 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.
View interactive diff ↗➡️ This fix was applied by Craigory Coppola
🎓 Learn more about Self-Healing CI on nx.dev
…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.
|
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. |
Current Behavior
nx show targetresolves theDepends Onlist using a heuristic on rawdependsOnconfigs. That heuristic doesn't fully match whatcreateTaskGraphwould schedule — e.g. a{ projects: ['lib-a'] }entry is listed even iflib-adoesn'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
normalizeTargetsDependsOnpass runs insidenormalizeProjectNodesafter target defaults have been merged. It filters:"prebuild") when the referenced target doesn't exist on the same project.projects,projects: 'self', orprojects: '{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 targetis task-graph-drivenshowTargetInfoHandlernow builds a task graph rooted at the requested target viacreateTaskGraph. TheDepends Onlist reads direct task dependencies off the graph, giving the same filtering and resolution behavior asnx run:^targetexpands to real dependency-project task IDs.{ projects: [...] }entries drop projects that don't actually have the target.A new
transientTasksfield on the JSON output surfaces everything that runs transitively. The text renderer shows a summary line beneathDepends On:With >3 unique target names, the summary collapses to a bare count (
and 12 transient tasks) to stay scannable. Source-map hints for--verboseare preserved — each direct dep task ID is matched back to its originatingdepConfigentry.Related Issue(s)
None — proactive correctness + observability improvement.