feat(core): derive stable repo key from normalized remote and relative path - #36439
Conversation
…e path Adds deriveRepoKey: sha256(domain/slug + '#' + git-root-relative path), using getVcsRemoteInfo for protocol-independent remote normalization (ssh, https, and token URLs of one repo all yield the same key) and including the workspace's path inside the repo so nested workspaces get distinct keys. Falls back to the first-commit SHA when no remote exists (null for shallow clones - their truncated history has no stable root; sorted-first root when merged histories produce several). Not wired into any caller yet - this is the W1 foundation for the repoTelemetry registry.
✅ 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 46032e1
☁️ Nx Cloud last updated this comment at |
…e path [Self-Healing CI Rerun]
generateWorkspaceId now uses deriveRepoKey instead of hashing the raw remote URL: ssh/https/token URL forms of one repo converge on one GA client id, and nested workspaces in one repo get distinct ids. nxCloudId precedence is unchanged, so Cloud-connected workspaces keep identity continuity. For URL-hash workspaces this is a one-time GA identity reset, bundled with the CI uid change in this branch so the discontinuity lands once.
A CI fleet is not a user: runners built from one image share a baked /etc/machine-id, so machineId x workspaceId collapses the whole fleet into a single GA user - the source of GA's single-user-ID warning and of per-user daily collection caps silently discarding events. uid (and up.user_id) are now omitted when isCI(); GA's Blended identity falls back to cid = workspace, so CI activity still attributes to the repo.
Hosts route case-insensitively and hold one canonical casing, so git@GitHub.com:NRWL/Nx.git and git@github.com:nrwl/nx.git are one repo and must produce one key - otherwise a hand-typed remote yields a record the claim flow can never match, since it derives keys from canonically-cased host API repo lists.
The git-root-relative path, shallow check, and first-commit lookup are git concerns, so they join the other standalone helpers in git-utils rather than living in repo-key. GitRepository.getGitRootPath now delegates to an exported function instead of holding a second copy of the rev-parse call, and the relative path uses the file's existing sep/posix imports. repo-key keeps only identity selection and hashing.
…t root deriveRepoKey no longer defaults its directory to workspaceRoot - callers pass it, so the module holds no implicit global state. generateWorkspaceId moves here from analytics-prompt (which is about consent prompting, not identity) and likewise takes an explicit root. The new git helpers use execFileSync rather than execSync: the commands are constant today, but an argv array keeps a later edit from interpolating a variable into a shell string, and it skips the shell entirely.
A repo with several root commits (merged unrelated histories) would keep a trailing carriage return on the first line when git output is CRLF, silently forking the derived key on that platform.
startAnalytics read it three times: isAnalyticsEnabled, the local nxJson, and generateWorkspaceId. Both now take the config the caller already has, so workspace-id does no file IO of its own.
There was a problem hiding this comment.
Important
At least one additional CI pipeline execution has run since the conclusion below was written and it may no longer be applicable.
Nx Cloud has identified a possible root cause for your failed CI:
We investigated this E2E timeout and determined it is unrelated to the PR changes. Our changes are scoped entirely to the nx project (a new deriveRepoKey() utility), while the failing test exercises Angular ESM Module Federation browser loading — a completely separate concern. We recommend rerunning the task, as the failure appears to be a transient environment/infrastructure timeout.
No code changes were suggested for this issue.
Trigger a rerun:
🔔 Heads up, your workspace has pending recommendations ↗ to auto-apply fixes for similar failures.
🎓 Learn more about Self-Healing CI on nx.dev
…e path (#36439) ## Current Behavior The CLI has no stable, protocol-independent identifier for a workspace's repository. `generateWorkspaceId()` hashes the raw remote URL, so ssh, https, and CI token-authenticated URLs of the same repo produce different ids, and two nx workspaces nested in one repository collide on the same id. ## Expected Behavior New `deriveRepoKey()` utility (`packages/nx/src/utils/repo-key.ts`) derives the claimable-record key for the repoTelemetry registry: - `sha256(domain/slug + '#' + workspace-relative-path)`, unsalted. - The remote is normalized via `getVcsRemoteInfo()`, so every URL form of the same repo yields the same key. - The workspace's path relative to the git root ('' at the root, posix-separated on every OS) distinguishes nested workspaces. - Fallback when no remote exists: the first-commit SHA as the identity (deterministically the sorted-first root when merged histories produce several). Shallow clones without a remote return null — their truncated history has no stable root commit. - Not wired into any caller yet — this is the W1 foundation the per-run telemetry event (NXC-4677) and the registry ingestion endpoint (CLOUD-4727) build on. Covered by unit tests exercising protocol-independence (ssh/https/token URLs → one key), nested-workspace distinction, the first-commit fallback, and the null cases, against real temporary git repos. ## Related Issue(s) Linear: NXC-4650 <!-- polygraph-session-start --> --- [View session information ↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/Repo-key-derivation-in-the-CLI-NXC-4650-94f75f84) <!-- polygraph-session-end --> --------- Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com> (cherry picked from commit 9c735d4)
Current Behavior
The CLI has no stable, protocol-independent identifier for a workspace's repository.
generateWorkspaceId()hashes the raw remote URL, so ssh, https, and CI token-authenticated URLs of the same repo produce different ids, and two nx workspaces nested in one repository collide on the same id.Expected Behavior
New
deriveRepoKey()utility (packages/nx/src/utils/repo-key.ts) derives the claimable-record key for the repoTelemetry registry:sha256(domain/slug + '#' + workspace-relative-path), unsalted.getVcsRemoteInfo(), so every URL form of the same repo yields the same key.Covered by unit tests exercising protocol-independence (ssh/https/token URLs → one key), nested-workspace distinction, the first-commit fallback, and the null cases, against real temporary git repos.
Related Issue(s)
Linear: NXC-4650
View session information ↗