Tags: nrwl/nx
Tags
fix(angular-rspack): ensure rebuild chunks emitted summary accurate (#… …34979) ## Current Behavior Currently, rebuilds produce a summary table that is not accurate. A key difference in how Rspack sets `chunks.rendered` compared to Webpack resulted in the logic for determining rebuilt chunks to be incorrect. ## Expected Behavior Ensure the summary table for emitted chunks is accurate on rebuild ## Related Issues It does not _fully_ solve #34936, however it should be a good first step to finding out if too many chunks are being emitted
fix(core): add explicit exports entry for nx/src/native directory (#3… …4967) ## Current Behavior After the nodenext PR (#34111) added an `exports` map to `packages/nx/package.json`, the nx-cloud light client (ocean) fails to import `nx/src/native`. The wildcard exports pattern `"./src/*"` resolves `nx/src/native` to `./dist/src/native.js` — but the actual file is `./dist/src/native/index.js` (it's a directory with an index file). Node's exports map does literal `*` substitution and does **not** perform CJS-style directory/index resolution. The cloud client wraps all its nx imports in a single try/catch, so when the native import fails, `getDbConnection` is never assigned either, causing `getDbConnection is not a function` errors in CI. This was not an issue with `nx@22.7.0-beta.1` because that version had no `exports` map — Node fell back to normal CJS resolution which handles directory/index lookups. ## Expected Behavior `require('nx/src/native')` correctly resolves to `dist/src/native/index.js` via an explicit export entry, and the cloud client can load the native module and `getDbConnection` without errors. ## Related Issue(s) N/A — discovered during version bump CI failure investigation. --------- Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
fix(core): split-target should handle projects with colons in name be… …tter (#34725) ## Current Behavior - `splitTarget` causes issues when a project name has more than one colon - Project name substitution is triggered when a project depends on the orginal name of a renamed project, even if the renamed project was renamed before the dep was registered That second one is hard to understand. Imagine the real scenario below: - @nx/gradle was reading settings.gradle.kts and naming the root project `nx` - The package.json inference plugin renames it to `@nx/nx-source` - The package.json inference plugin infers the `nx` project in `packages/nx` - The package.json inference plugin reads a config that has `dependsOn: [nx:build]` - The substitutors run, and update the dependsOn to `@nx/nx-source:build` ## Expected Behavior splitTarget follows the below precedence: - If splitting a target string thats embedded in a specific project configuration, targets on that project are preferred - Targets belonging to the project with the longest name that is valid from joining segments left to right - Targets that have the longest name from joining segments are preferred - Configuration is the remaining segments after picking off the longest valid project containing a valid target. Substitutors prefer registering by root if a project with a given name exists, and only register by name if no project with that root exists (e.g. if a plugin adds a dependsOn to a project that was inferred by a later plugin, this would be common if a custom plugin is reading project.json to get a name or smth). ## AI Summary > # Branch Analysis: `fix/split-target-fixes` vs `master` > > ## Summary > > | Metric | Lines | > |--------|------:| > | **Total raw diff (added+removed, non-test)** | 2,840 + 1,221 = 4,061 | > | **Lines that were just moved (file split)** | ~960 | > | **Truly new/changed lines (non-test)** | ~570 | > | **Test file changes (raw diff)** | 3,109 added / 2,242 removed | > > ## Commits > > | SHA | Message | > |-----|---------| > | `57ec87b3c4` | fix(core): split-target should handle projects with colons in name better | > | `af1ebc90ab` | fix(core): avoid renaming projects based on former name if they were rooted when dep is drawn | > | `b2fffc60c7` | cleanup(core): split project-configuration-utils into focused modules | > | `3bae3048d8` | fix(core): fixup name substitution manager | > > ## File Split: `project-configuration-utils.ts` -> 4 modules > > The original `project-configuration-utils.ts` (1,407 lines) was split into focused modules. **~960 lines were moved as-is** (identical minus whitespace/formatting) into the new files. The remaining changes are actual logic modifications. > > | File | Total Lines | Moved from original | Truly new/changed | > |------|------------:|--------------------:|------------------:| > | `project-configuration-utils.ts` (remaining) | 444 | ~395 | ~49 | > | `target-merging.ts` | 494 | ~430 | } | > | `target-normalization.ts` | 282 | ~250 | } ~111 combined | > | `project-nodes-manager.ts` | 365 | ~285 | } | > | **Subtotal** | 1,585 | ~1,360 | ~160 | > > Additionally, ~39 lines were removed from the original and not moved anywhere (dead code removal or refactored away). > > ## Actual Code Changes (non-test, excluding moved lines) > > ### Major changes > > | File | New | Removed | Net | Description | > |------|----:|--------:|----:|-------------| > | `split-target.ts` | ~211 | ~38 | +173 | New logic for handling projects with colons in names | > | `name-substitution-manager.ts` | ~152 | ~85 | +67 | Fix: avoid renaming rooted projects based on former name | > | Split files (combined, new logic only) | ~111 | — | +111 | New code introduced during the split refactor | > | `project-configuration-utils.ts` (new logic only) | ~49 | ~39 | +10 | Residual new code after split | > > ### Minor edits (import path updates, small fixes) > > | File | Added | Removed | > |------|------:|--------:| > | `parse-target-string.ts` | 7 | 1 | > | `command-line/show/target.ts` | 11 | 7 | > | `devkit-internals.ts` | 3 | 5 | > | `tasks-runner/utils.ts` | 5 | 3 | > | `build-project-graph.ts` | 2 | 4 | > | `error-types.ts` | 2 | 4 | > | `command-line/run/run-one.ts` | 2 | 1 | > | `ngcli-adapter.ts` | 1 | 1 | > | `convert-nx-executor.ts` | 1 | 1 | > | `project-configuration.ts` (generators) | 1 | 1 | > | `package-json.ts` | 1 | 1 | > | `settings.gradle.kts` | 1 | 1 | > | **Minor edits subtotal** | **37** | **30** | > > ### Other new files > > | File | Lines | Description | > |------|------:|-------------| > | `packages/devkit/CLAUDE.md` | 62 | Dev documentation | > | `__fixtures__/merge-create-nodes-args.json` | 100 | Test fixture data | > > ## Final Tally: True Non-Test Changes > > | Category | Lines | > |----------|------:| > | New logic in `split-target.ts` | ~211 | > | New logic in `name-substitution-manager.ts` | ~152 | > | New logic in split module files | ~111 | > | New logic in remaining `project-configuration-utils.ts` | ~49 | > | Minor import/path updates across 12 files | ~37 added / ~30 removed | > | New non-code files (CLAUDE.md, fixture JSON) | 162 | > | **Total truly new/changed lines** | **~570 added, ~160 removed** | > | Moved lines (file split, not real changes) | **~960** | ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes # --------- Co-authored-by: FrozenPandaz <jasonjean1993@gmail.com> Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
chore(repo): update nx to 22.7.0-beta.1 (#34932) ## Current Behavior Workspace uses nx 22.7.0-beta.0 and related @nx/* packages at 22.7.0-beta.0. ## Expected Behavior Workspace uses nx 22.7.0-beta.1 and related @nx/* packages at 22.7.0-beta.1. ## Related Issue(s) N/A — routine version bump. --------- Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com> Co-authored-by: FrozenPandaz <FrozenPandaz@users.noreply.github.com> (cherry picked from commit ef3a517)
fix(core): prevent DB corruption from concurrent initialization (#34861) ## Current Behavior When multiple processes call `connectToNxDb()` concurrently (plugin workers via `startAnalytics()`, daemon, main CLI), two bugs can corrupt the workspace database: **Bug 1: Lock file inode race.** `unlock_file()` deletes the lock file after unlocking, allowing a subsequent `File::create()` to produce a new file with a different inode. Two processes can hold "the lock" simultaneously on different file objects, breaking mutual exclusion. **Bug 2: Partial file cleanup on version mismatch/connection failure.** The `reason` arm and `Err` arm in `initialize_db` call `remove_file(db_path)` which only deletes `.db`, leaving stale `.db-wal` and `.db-shm` on disk. The recursive `initialize_db` creates a fresh `.db`, but SQLite detects the stale WAL (different inode salt) and deletes it — destroying all data that existed only in the WAL. Both bugs lead to: ``` Database file exists but has no metadata table. ``` ## Expected Behavior 1. Lock file persists across lock/unlock cycles — all processes serialize through the same inode 2. When DB recreation is needed, all auxiliary files (`.db`, `.db-wal`, `.db-shm`) are cleaned up together via `remove_all_database_files` --------- Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
fix(core): pass collectInputs flag through daemon IPC for task hashing ( #34915) When the daemon handles task hashing, the `NativeTaskHasherImpl` checked `hasTaskInputSubscribers()` in the daemon process where no subscribers exist, causing the native Rust hasher to skip input collection entirely. This resulted in empty input arrays in IO tracing signals. The fix passes collectInputs from the client process (where subscribers are registered) through the daemon IPC to the hasher, so the daemon uses the client's subscriber state instead of its own.
fix(core): wrap CNW normalize args function in error handler (#34905) This is a follow-up to #34902, where we throw `CnwError` for known problems. We need to wrap `normalizeArgsMiddleware` in a try-catch to invoke the shared (extracted) error handler, since these errors are not within the `main` function body but happens prior. Before this PR: <img width="1339" height="277" alt="image" src="https://github.com/user-attachments/assets/911ecd4d-7117-434b-bff7-ff20dddfd84d" /> After: <img width="1258" height="112" alt="image" src="https://github.com/user-attachments/assets/f9c15bed-2df4-4e78-ac95-11f67cb9d4f5" /> --------- Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Revert "feat(js): add deps-sync generator (#34407)" (#34888) This reverts commit 8d71d5b. ## Current Behavior <!-- This is the behavior we have today --> This generator causes unnecessary changes ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> The generator is removed for now and will be reintroduced when it is refined. ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
fix(core): avoid overwhelming DB with connections during analytics in… …it (#34881) ## Current Behavior Every process that initializes analytics opens its own DB connection to get/create a session ID. This includes the CLI, the daemon, and **every plugin worker**. In workspaces with many plugins, dozens of plugin workers spawn simultaneously, each opening a DB connection and querying/writing session metadata. This overwhelms the SQLite database with concurrent connections and causes failures. ## How This Fixes It The root cause is that plugin workers each independently open a DB connection just to read the session ID. The fix eliminates this by having the parent process (CLI or daemon) fetch the session ID once and pass it to child processes via the `NX_ANALYTICS_SESSION_ID` environment variable. Plugin workers inherit this env var and initialize telemetry without touching the DB at all. | Process | Before | After | |---------|--------|-------| | CLI | Opens DB connection | Opens DB connection (1x) | | Daemon | Opens DB connection | Opens DB connection (1x) | | Plugin worker (×N) | Each opens DB connection | Reads env var, **no DB connection** | In a workspace with 20 plugins, this reduces DB connections from 22 (CLI + daemon + 20 workers) down to 2 (CLI + daemon only). ## Two Initialization Paths - **`initializeTelemetry(dbConnection, ...)`** — Used by CLI and daemon. Gets/creates the session ID from the DB via a transaction, stores the connection for persisting session refreshes on flush, and returns the session ID so the caller can set it as an env var for child processes. - **`initializeTelemetryWithSessionId(sessionId, ...)`** — Used by plugin workers. Takes the session ID inherited from the parent process env var. No DB connection, no DB queries. ## Session Refresh for Long-Lived Processes The daemon is long-lived and could hold a stale session ID for hours. The telemetry background thread now tracks activity and generates a new session ID after 30 minutes of inactivity (matching the existing GA4 session timeout). When a session refreshes, the background thread notifies the main thread via a channel, which persists the new session to the DB in a transaction on flush. ## Other Changes - Extracted `TelemetryOptions` struct to replace the long parameter list in `TelemetryService::new` - Moved `SESSION_TIMEOUT_SECS` to `constants.rs` so it can be shared between modules - Extracted `init_service` helper to deduplicate between the two init paths - Extracted `persist_session_to_db` helper that wraps both metadata writes in a transaction - Separated session ID retrieval (`get_or_create_session_id`) from telemetry service initialization ## Related Issue(s) Fixes database connection exhaustion when many plugin workers initialize analytics simultaneously.
fix(core): add .claude/settings.local.json to .gitignore (#34870) ## Current Behavior When configuring AI agents via `nx polygraph`, a `.claude/settings.local.json` file is created containing user-specific settings. This file is not gitignored by Nx, so it can accidentally be committed to the repository. ## Expected Behavior `.claude/settings.local.json` should be gitignored by default, similar to how `.claude/worktrees` is already handled. ## Changes - Added a migration that adds `.claude/settings.local.json` to existing workspaces' `.gitignore` - Updated all three `.gitignore` templates so new workspaces include it from the start - Follows the same pattern as the existing `add-claude-worktrees-to-git-ignore` migration
PreviousNext