cleanup(core): move the affected touched-project locators into rust - #36825
Draft
AgentEnder wants to merge 4 commits into
Draft
cleanup(core): move the affected touched-project locators into rust#36825AgentEnder wants to merge 4 commits into
AgentEnder wants to merge 4 commits into
Conversation
Contributor
Nx Cloud AI Fix could not be generatedView your CI Pipeline Execution ↗ for commit 55d1656
☁️ Nx Cloud last updated this comment at |
FrozenPandaz
force-pushed
the
feat/nxc-4861-files-input
branch
from
August 28, 2026 14:26
8ab1d7a to
f19bb81
Compare
Ports getTouchedProjects, getImplicitlyTouchedProjects and getTouchedProjectsFromProjectGlobChanges to a native locateTouchedProjects. No behavior change: the existing affected specs pass untouched. The lockfile, npm-package and tsconfig locators stay in TypeScript because they depend on the npm/yarn/pnpm/bun lockfile parsers. They are passed across the boundary as ThreadsafeFunction callbacks and invoked once per run, so the locator set stays extensible from JS. Graph pruning stays in TypeScript too: the native ProjectGraph models dependencies as HashMap<String, Vec<String>>, with no edge type or source, so it cannot rebuild what filterAffected returns. Also deletes workspace-json-changes.ts, the angular.json locator that was already unregistered and had no remaining referents.
AgentEnder
force-pushed
the
feat/nxc-4859-task-based-affected
branch
from
August 28, 2026 20:01
9f62051 to
d191117
Compare
getTaskOutputs and getExpandedTaskInputs both call loadIoSnapshotsForHead, which reads a bundle off disk. Neither spec mocked it, so the snapshot branch was skipped locally, where no bundle exists, and taken on CI, where Nx Cloud has fetched one. Taking it reached customHasherTaskIds, whose call to readProjectsConfigurationFromProjectGraph the project-graph mock does not provide, and 5 tests across the two files failed. Pin the bundle absent so the result no longer depends on ambient cache state. Confirmed by forcing the bundle present locally, which reproduces the CI failure exactly.
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.
Groundwork for NXC-4859 (task-level
nx affected). This is "PR 0": move the locators, change nothing else.Current Behavior
filterAffectedruns fourTouchedProjectLocators in TypeScript, then reverse-walks the project graph. Three of them (getTouchedProjects,getImplicitlyTouchedProjects,getTouchedProjectsFromProjectGlobChanges) are pure path and glob matching, and they re-runminimatchper (pattern, file) pair — minimatch recompiles the pattern on every call, so the cost grows with changeset size times the number of distinct{workspaceRoot}filesets.Expected Behavior
Those three move to a native
locateTouchedProjects. Same results, same locator order, same duplicate-emitting contract.The lockfile, npm-package and tsconfig locators stay in TypeScript — they depend on the npm/yarn/pnpm/bun lockfile parsers. They cross the boundary as
ThreadsafeFunctioncallbacks invoked once per run, so the locator set is still extensible from JS rather than hardcoded.Graph pruning also stays in TypeScript: the native
ProjectGraphmodelsdependenciesasHashMap<String, Vec<String>>, with no edgetypeorsource, so it cannot rebuild whatfilterAffectedreturns.Also deletes
workspace-json-changes.ts— theangular.jsonlocator was already unregistered and has no remaining referents anywhere in the repo.Behavior deltas worth knowing
Small, and all of them widen or correct rather than break:
{workspaceRoot}/config/now matchesconfig/app.json; minimatch did not.{workspaceRoot}/!(dist)/**no longer matchesdist/a.ts; minimatch's leading-!handling did.{workspaceRoot}/some-dir/fileset becomessome-dir/**.implicits[input] ??= []on a plain object silently dropped any fileset named{workspaceRoot}/__proto__,constructorortoString, because the inherited property is non-nullish. TheBTreeMapremoves that quirk.Performance
Measured on a synthetic 3000-project graph (30k files, 10k external nodes), min of 11, comparing this branch against its base. The trade is a variable cost for a fixed one, so which way it goes depends on how many distinct
{workspaceRoot}filesets a workspace declares.Many distinct filesets — the nx repo itself has 151 across 149 projects:
Few, shared filesets:
So a large win where the pattern set is big, and a ~30 ms regression on a small-pattern workspace, from the fixed cost of walking the graph natively.
filterAffectedalso marshals the project graph, which is memoized per graph identity —nx releasecallsfilterAffectedonce per commit, and without the memo that re-marshalled the whole graph every time.Related Issue(s)
NXC-4859