From 3f6a9626ecc5e87f12ea7041eea05f0a902e8718 Mon Sep 17 00:00:00 2001 From: Josh Boys Date: Tue, 12 May 2026 15:18:21 +0800 Subject: [PATCH 1/2] fix(cache): drop target/ outputs from test target cargo test reuses the workspace target/ dir that build already populates, so per-crate test targets do not own that output. Snapshotting the full dir into .nx/cache for every test target dominated wall-clock with disk I/O on real workspaces. Test results remain cacheable by exit code. Bumps the package to 0.1.2. Fix ported from eddacraft/anvil. --- CHANGELOG.md | 10 ++++++++++ package.json | 2 +- plans/index.aps.md | 16 ++++++++-------- plans/modules/01-v0.1-shakedown.aps.md | 19 ++++++++++++++----- src/utils/target-configs.ts | 12 +++++++----- 5 files changed, 40 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3ff56f..41bfa71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 0.1.2 — Unreleased + +- `test` target now declares `outputs: []` instead of caching the + workspace `target/` directory. `cargo test` reuses the `target/` + populated by `build`, so per-crate test targets do not own that + output; snapshotting the full dir into `.nx/cache` for every test + target dominated wall-clock with disk I/O on real workspaces. Test + results remain cacheable by exit code. Fix ported from + eddacraft/anvil. + ## 0.1.0 — Unreleased Initial release. diff --git a/package.json b/package.json index 9b2fb1d..5d0ae5f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@eddacraft/nxrust", - "version": "0.1.0", + "version": "0.1.2", "description": "Nx plugin that wraps Cargo — executors, generators, and project-graph integration for Rust workspaces inside Nx monorepos.", "keywords": [ "nx", diff --git a/plans/index.aps.md b/plans/index.aps.md index 2a4f5ec..fdea0b9 100644 --- a/plans/index.aps.md +++ b/plans/index.aps.md @@ -1,11 +1,11 @@ - + # nxrust — Nx 22 plugin for Rust | Field | Value | |-------|-------| -| Status | In Progress | +| Status | Complete | | Owner | @joshuaboys | | Created | 2026-04-21 | | Licence | Apache-2.0 | @@ -40,13 +40,13 @@ TypeScript + Rust monorepos. Rust crate nodes + cross-crate edges from `cargo metadata` - [x] Unit test suite green via Vitest - [x] Council + adversarial review findings addressed or documented -- [ ] End-to-end pilot against a real Rust crate in a real Nx 22 +- [x] End-to-end pilot against a real Rust crate in a real Nx 22 workspace passes and caches -- [ ] Rollout to every crate in the pilot workspace completes green on +- [x] Rollout to every crate in the pilot workspace completes green on `nx run-many` -- [ ] CI smoke test job in nxrust + dependent-repo smoke in the pilot +- [x] CI smoke test job in nxrust + dependent-repo smoke in the pilot workspace -- [ ] First `@eddacraft/nxrust@0.1.0` published to npm +- [x] First `@eddacraft/nxrust@0.1.0` published to npm ## Constraints @@ -68,7 +68,7 @@ TypeScript + Rust monorepos. | Module | Purpose | Status | Dependencies | |--------|---------|--------|--------------| -| [01-v0.1-shakedown](./modules/01-v0.1-shakedown.aps.md) | Prove the plugin end-to-end on a pilot consumer, ship first npm release | In Progress | — | +| [01-v0.1-shakedown](./modules/01-v0.1-shakedown.aps.md) | Prove the plugin end-to-end on a pilot consumer, ship first npm release | Complete | — | Deferred (not yet active modules): @@ -87,7 +87,7 @@ Deferred (not yet active modules): | Risk | Impact | Mitigation | |------|--------|------------| -| `target/` caching yields stale artefacts under remote cache | high | Narrow `outputs` — cache test/clippy reports and binaries, not the whole `target/` tree; verify second-run cache hits on the pilot crate before rollout | +| `target/` caching yields stale artefacts under remote cache | high | Narrow `outputs` — cache test/clippy reports and binaries, not the whole `target/` tree; verify second-run cache hits on the pilot crate before rollout. **Resolved 2026-05-12** for `test` (now `outputs: []`); `build` retains `target/` deliberately. | | Nx 22 project-graph plugin API drifts on minor upgrades | medium | Small public surface (`createNodesV2` + `createDependencies` only); CI smoke test pins the contract | | `cargo metadata` performance on large workspaces | medium | Mtime-keyed `Cargo.lock` cache already in `graph.ts`; re-evaluate if the pilot hits a slowdown | | Pilot switchover breaks the consumer's pnpm graph mid-flight | medium | Switch only after pilot + rollout + CI smoke are all green; keep a revert commit ready | diff --git a/plans/modules/01-v0.1-shakedown.aps.md b/plans/modules/01-v0.1-shakedown.aps.md index b98638e..fbee450 100644 --- a/plans/modules/01-v0.1-shakedown.aps.md +++ b/plans/modules/01-v0.1-shakedown.aps.md @@ -1,5 +1,5 @@ - + # v0.1 Shakedown @@ -100,7 +100,7 @@ that gap. - [x] Council + adversarial findings addressed or documented - [x] `LICENSE` (Apache-2.0), `README.md`, `CHANGELOG.md` at repo root - [x] This APS plan written -- [ ] Pilot consumer workspace reachable with a clean working tree +- [x] Pilot consumer workspace reachable with a clean working tree --- @@ -161,7 +161,7 @@ that gap. `eddacraft-anvil-policy` and dependent `eddacraft-anvil`, excluding unrelated crates. -### NXRUST-R3: CI smoke test in both repos [In Review] +### NXRUST-R3: CI smoke test in both repos [Complete: 2026-05-08] - **Intent:** Catch nxrust regressions before they reach consumers, and catch consumer drift before it reaches a release @@ -189,7 +189,7 @@ that gap. `pnpm test`, `pnpm e2e`, and the pilot smoke command. Final completion is pending the canary PR workflow results from the R3 pull requests. -### NXRUST-R4: First npm publish of `@eddacraft/nxrust@0.1.0` [Draft] +### NXRUST-R4: First npm publish of `@eddacraft/nxrust@0.1.0` [Complete: 2026-05-08] - **Intent:** Ship v0.1.0 to npm so consumers can install it without pnpm workspace protocol or git refs @@ -217,8 +217,13 @@ that gap. 2026-05-07 release-prep added `prepublishOnly` (`build`, `test`, `e2e`), `release:dry-run`, manual CI dispatch, and switched push CI from the old `main` branch to the new default `dev` branch. +- **Resolution:** `@eddacraft/nxrust@0.1.0` published 2026-05-08 05:34 UTC + under maintainer `joshuaboys`. A follow-up `0.1.1` published the same day + (07:02 UTC) and is now `dist-tag latest`. `npm view @eddacraft/nxrust` + confirms Apache-2.0 licence, `executors`/`generators` entrypoints, and + the expected `@nx/devkit >=22.0.0` peer. -### NXRUST-R5: Switch pilot consumer onto published package [Draft] +### NXRUST-R5: Switch pilot consumer onto published package [Complete: 2026-05-12] - **Intent:** Remove the pilot consumer's in-place workspace link and consume the published package instead, so the consumer can bump Nx @@ -236,6 +241,10 @@ that gap. - **Risks:** Drift between the in-place copy and the extracted nxrust repo — treat any drift as a bug feeding back into NXRUST-R1, patch nxrust, and re-publish before deleting the in-place copy +- **Resolution:** Pilot consumer switched from `workspace:*` link to + `@eddacraft/nxrust@^0.1.0` (now resolving to `0.1.1`). Switchover + confirmed by the package owner; verification lives in the pilot + consumer repo. --- diff --git a/src/utils/target-configs.ts b/src/utils/target-configs.ts index 8be98d5..97f1af6 100644 --- a/src/utils/target-configs.ts +++ b/src/utils/target-configs.ts @@ -5,10 +5,12 @@ import type { TargetConfiguration } from '@nx/devkit'; * the executor + cache + outputs wiring. Each accepts optional option * overrides that get merged into the target's `options`. * - * Only `build`, `test`, and `run` actually produce binary artefacts we want - * to cache — everything else (check, clippy, fmt-check) is exit-code-only. - * Caching the full `target/` dir for lint-style targets wastes remote cache - * bandwidth without correctness benefit. + * Only `build` actually produces binary artefacts we want to cache. + * `test` is exit-code-only — cargo test reuses the workspace `target/` dir + * that `build` already populates, and snapshotting the full dir into + * `.nx/cache` (and pushing it to the remote cache) for every per-crate test + * target dominates wall-clock with disk I/O. `check`, `clippy`, and + * `fmt-check` are exit-code-only for the same reason. */ type AnyOpts = Record; @@ -85,7 +87,7 @@ export function testTargetConfig( return { executor: '@eddacraft/nxrust:test', cache: true, - outputs: BINARY_OUTPUTS, + outputs: [], options, configurations: { production: { release: true }, From bd4b23e779b27767bd3429a65f56e76cdecc7769 Mon Sep 17 00:00:00 2001 From: Josh Boys Date: Tue, 12 May 2026 15:20:02 +0800 Subject: [PATCH 2/2] fix(e2e): derive tarball version from package.json Hardcoded 0.1.0 broke the e2e smoke as soon as the package bumped to 0.1.2. Read the version from the root package.json so the script tracks the package automatically. --- tools/e2e-smoke.mjs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/e2e-smoke.mjs b/tools/e2e-smoke.mjs index ae20a24..6d27bd5 100644 --- a/tools/e2e-smoke.mjs +++ b/tools/e2e-smoke.mjs @@ -6,7 +6,10 @@ const root = process.cwd(); const packDir = join(root, '.e2e-pack'); const fixtureDir = join(root, 'e2e', 'fixture'); const fixturePackage = join(fixtureDir, 'package.json'); -const tarball = '../../.e2e-pack/eddacraft-nxrust-0.1.0.tgz'; +const { version } = JSON.parse( + readFileSync(join(root, 'package.json'), 'utf8'), +); +const tarball = `../../.e2e-pack/eddacraft-nxrust-${version}.tgz`; function run(command, args, options = {}) { const result = spawnSync(command, args, {