Prove the plugin end-to-end on a real consumer workspace, then ship the first npm release.
| ID | Owner | Status |
|---|---|---|
| NXRUST | eddacraft | Complete |
The nxrust plugin is feature-complete for v0.1: seven executors, five
generators, a working createNodesV2 + createDependencies graph
plugin, a unit-test suite, and review findings addressed. What it has
not done yet:
- Been driven end-to-end against a real Rust crate in a real Nx 22 workspace outside this repo
- Shipped to npm
- Replaced any in-place workspace-link copies in validation consumers
This module closes the gap between implementation and a supported public release.
Why this matters:
- Downstream consumers depend on this. Workspaces validating nxrust via a pnpm workspace link cannot bump Nx independently of the plugin until a real release is on npm.
- Nx 22 needs a maintained Rust plugin. Shipping nxrust under Apache-2.0 gives mixed TypeScript + Rust workspaces a current option.
- Review findings need real-world validation.
target/caching andcargo metadataperformance need validation in a real workspace.
- Smoke-test the plugin end-to-end in a consumer workspace via pnpm workspace protocol; run one representative crate through the full executor set; assert cache hit on second run
- Roll the validation shape out to the remaining crates in the consumer workspace
- CI smoke test in this repo (nxrust): build + run all unit tests + run
the executor smoke test against a fixture crate held inside
e2e/ - Add a dependent-repo smoke job to the consumer workspace's CI that runs
pnpm exec nx run <crate>:checkagainst the linked plugin - First npm publish of
@eddacraft/nxrust@0.1.0 - Consumer switches from
workspace:*link to the published version
- Adding any new executor or generator beyond what already exists in
src/executors/**andsrc/generators/** napi,wasm-pack,preset,add-napi,add-wasm— monodon-parity items deferred to module02-monodon-paritycargo-nextestexecutor,benchexecutor, glob edge cases in workspace-member detection — deferred to module03-v0.2-polishcrates.iopublishing — therelease-publishexecutor exists and is unit-tested; it stays "unvalidated against a real token" until a consumer exercises it
@nx/devkit ^22.6.5(already inpackage.json)- A real Nx 22 consumer workspace to validate against
- npm publish credentials for the chosen scope — needed only at R4
@eddacraft/nxrust@0.1.0on npm- A dependent-repo smoke job in the consumer workspace's CI that fails loud if a nxrust release breaks the consumer
- The consumer workspace running on the plugin-inferred project graph
(no per-crate
project.jsonfiles required)
- Zero regressions on the consumer. Every
cargo check/test/clippy/fmtcall that passes today must still pass after the plugin wraps it. If validation shows a regression, the consumer change reverts — it does not press on. - No code changes to nxrust during validation unless validation exposes a real defect. Cosmetic edits wait for v0.2.
- Consumer switchover happens in one PR, reversible with a single git revert. Do not interleave the switchover with unrelated consumer-side work.
- Published package ships
LICENSE,README.md,CHANGELOG.md,dist/**, and the top-levelexecutors.json/generators.json— nothing else.
- Plugin unit tests green (
pnpm test) - Plugin typechecks (
pnpm typecheck/tsc --noEmit) - Plugin builds to
./distwithpnpm build - Entrypoint smoke:
createNodesV2+createDependenciesloadable; all 7 executors and 5 generatorsrequire.resolvecleanly - Review findings addressed or documented
-
LICENSE(Apache-2.0),README.md,CHANGELOG.mdat repo root - This APS plan written
- Consumer workspace reachable with a clean working tree
- Intent: Drive the full plugin end-to-end against the smallest real crate before touching any of the others
- Expected Outcome: the consumer workspace's
nx.jsonregistersnxrustas a plugin;pnpm exec nx run <crate>:<target>matchescargo <cmd> -p <crate>for check/test/clippy/fmt-check; second local run reports cache hit;nx graph --focus=<crate>renders the correct edges - Scope: consumer workspace —
nx.json(register plugin), rootpackage.json+pnpm-lock.yaml(add nxrust dev-dep) - Validation: All four checks above pass
- Confidence: medium
- Risks:
target/caching is notoriously fragile. If the second run rebuilds instead of cache-hitting, narrow theoutputsdeclaration on the affected target rather than abandon the cache. - Non-scope: Other crates in the workspace
- Resolution: Linked into the consumer workspace via
pnpm add -Dw nxrust@file:../../nxrust; registered{"plugin": "nxrust", "options": {}}in itsnx.json.pnpm exec nx show projectslisted every Rust crate alongside the TS projects. Ran check (cold → cache hit on re-run), test, clippy, fmt-check — all clean. Graph focus matched cargo dependency reality. No plugin defects surfaced. Two reconciliations captured: (a) Cargo package names map directly to Nx project keys; (b) the plugin auto-infers projects fromCargo.toml— no manualproject.jsonfiles needed. Workspace-specific timings, branch names, and crate names are intentionally omitted from the public plan.
- Intent: Confirm every Rust crate in the consumer workspace
participates correctly in the inferred project graph, then exercise
nx run-manyandnx affectedacross the workspace - Expected Outcome:
pnpm exec nx show projectslists every Rust project;pnpm exec nx run-many -t checkand:testcomplete green; a targetednx affected -t check --files=<crate>/src/lib.rsruns that crate and its dependents only - Scope: consumer workspace — validation only; no per-crate
project.jsonfiles needed - Dependencies: NXRUST-R1
- Validation: Both
run-manycommands exit 0; theaffectedprobe excludes unrelated crates from the task list - Confidence: high (R1 already proved the shape on one crate)
- Non-scope: Feature flags, profiles, cross-compile matrix; any
project.jsonoverrides - Resolution: Pilot workspace dependencies installed cleanly and
pnpm exec nx show projectslisted the inferred Rust projects. Fullpnpm exec nx run-many -t checkcompleted green for all 16 Rust check targets. Fullpnpm exec nx run-many -t testcompleted green across the workspace. A targetednx affected -t checkprobe ran only the changed crate and its dependent crate, excluding unrelated crates.
- Intent: Catch nxrust regressions before they reach consumers, and catch consumer drift before it reaches a release
- Expected Outcome:
- In nxrust: A GitHub Actions workflow runs
pnpm install,pnpm build,pnpm test, and a fixture-driven end-to-end that runsnx run <fixture>:checkagainst a tiny crate held ine2e/ - In the validation consumer: the consumer's Rust CI workflow gains a
job that runs
pnpm exec nx run <crate>:checkagainst the linked plugin
- In nxrust: A GitHub Actions workflow runs
- Scope:
nxrust/.github/workflows/**,nxrust/e2e/**(new fixture crate + project.json), consumer Rust CI workflow - Dependencies: NXRUST-R2
- Validation: Both workflows green on a canary PR; package metadata and executor resolution failures are caught by CI
- Confidence: high
- Resolution: Added nxrust CI with
pnpm install --frozen-lockfile,pnpm build,pnpm test, andpnpm e2e. The e2e smoke packs the publishable@eddacraft/nxrusttarball, installs it into a checked-in fixture workspace via a frozen fixture lockfile, clears fixture Nx state, and runsnx run smoke:check --skip-nx-cache. Added the consumer Rust workflow smoke job that runs an Nx-backed Rust check target against the linked plugin. Local validation passed forpnpm build,pnpm test,pnpm e2e, and the consumer smoke command. CI smoke subsequently validated by the 0.1.1 release flow (prepublishOnlyrunsbuild+test+e2ebefore every publish).
- Intent: Ship v0.1.0 to npm so consumers can install it without pnpm workspace protocol or git refs
- Expected Outcome:
@eddacraft/nxrust@0.1.0published;npm view <package> versionsshows0.1.0; package tarball containsdist/**,executors.json,generators.json,LICENSE,THIRD-PARTY-NOTICES.md(if any monodon code was borrowed during R1–R3),README.md,CHANGELOG.mdand nothing else - Scope: nxrust — package publish scripts, CI default-branch trigger,
CHANGELOG.mdentry - Dependencies: NXRUST-R3
- Validation:
pnpm release:dry-runpasses;npm whoamiconfirms a logged-in publisher; freshpnpm dlx create-nx-workspace+pnpm add -D @eddacraft/nxrust, thenpnpm exec nx g @eddacraft/nxrust:initexits 0 - Confidence: medium
- Risks: Scope ownership — confirm scope is registered and publishable from the CI runner or a local account before attempting
- Non-scope: Semantic-release automation — v0.1 is a manual
pnpm publish; automation is a v0.2 concern - Resolution:
@eddacraft/nxrust@0.1.0published to npm on 2026-05-08;npm view @eddacraft/nxrust dist-tagsreportslatest: 0.1.0. Defects discovered post-publish are tracked in NXRUST-R4.1.
- Intent: Ship a patch release fixing two defects surfaced in 0.1.0 by the downstream Anvil consumer. 0.1.0 cannot be republished (npm forbids overwriting a published version), so the fixes ship as 0.1.1.
- Expected Outcome:
@eddacraft/nxrust@0.1.1published withdist-tags.latest = 0.1.1. Anvil's previously failing CI jobs (Check/Format and Test/Unit Tests) re-run green against@eddacraft/nxrust@^0.1.1. - Scope: nxrust —
package.jsonversion bump, CHANGELOG entry,inferProjectConfig(pin cargo package on every target),buildCargoArgs(per-subcommand option allowlist), specs for both. PR #6 againstmain. - Dependencies: NXRUST-R4
- Validation:
pnpm test47/47 green (including new specs);pnpm typecheckclean;pnpm buildclean; CI smoke green on PR #6;pnpm publishfrommainafter merge; Anvil's failing CI jobs re-run green against the patched version. - Confidence: high
- Risks: Anvil's CI may surface a third defect. If so, treat the same way — patch nxrust, ship 0.1.2, before unblocking R5.
- Defects fixed:
cargo -pgot the Nx project name. When@nx/jsclaimed a siblingpackage.json's name (napi-rs bindings), the cargo executor fed-p @scope/nameto cargo and got backunexpected prerelease field. Fixed by pinning{ package: pkg.name }on every inferred target.buildCargoArgsemitted every option key as a cargo flag.nx run-many -t test --run --coveragein a mixed JS+Rust workspace leaked vitest's--run/--coverageintocargo test --run --coverage [object Object]. Fixed by adding a per-subcommand allowlist that's unioned with the base cargo keys; everything outside that union is dropped.
- Resolution: PR #6 merged to
main2026-05-08;pnpm publishshipped@eddacraft/nxrust@0.1.1on 2026-05-08.npm view @eddacraft/nxrust dist-tagsreportslatest: 0.1.1andversionslists[0.1.0, 0.1.1]. Consumer re-run against^0.1.1confirmed under R5. An ancillary defect was found and fixed during the release: the e2e smoke (tools/e2e-smoke.mjs) hard-coded the 0.1.0 tarball filename, so the version bump initially broke the smoke job — the script now derives the tarball name from package.json.
- Intent: Remove the consumer's in-place workspace link and consume the published package instead, so the consumer can bump Nx independently
- Expected Outcome: Consumer root
package.jsonpulls@eddacraft/nxrust@^0.1.0from npm; the in-place link directory is deleted;pnpm install && pnpm exec nx run-many -t test,lint,buildpasses - Scope: consumer workspace — root
package.json,pnpm-lock.yaml, the in-place plugin directory (delete),pnpm-workspace.yamlif needed - Dependencies: NXRUST-R4
- Validation: Above; single-revert rollback verified on a throwaway branch
- Confidence: medium
- 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: Consumer switched from
workspace:*link to@eddacraft/nxrust@^0.1.0(resolving to0.1.1). Switchover confirmed by the package owner; the in-place link directory is gone.
| Risk | Impact | Likelihood | Mitigation |
|---|---|---|---|
| Consumer validation exposes a defect that forces nxrust code changes mid-module | medium | medium | Patch nxrust, re-link, and rerun validation rather than suppressing real defects. |
| npm scope not registered | medium | low | Verify before R4; fall back to a different scope or unscoped if unavailable |
| Consumer switchover PR pulls in unrelated changes | low | medium | Keep R5 to one PR, scoped strictly to package.json + lockfile + in-place plugin deletion |
target/ caching defeats the affected story on rollout |
high | medium | Narrow outputs per target; cache reports not binaries where binaries embed absolute paths. Resolved 2026-05-12 for test (now outputs: []); build retains target/ outputs deliberately. |
- D-M1: Validate first on the smallest crate (no internal deps) rather than a crate that touches everything. Accepted.
- D-M2: Publish and consume via npm, not via git ref. Git refs work but hide drift. Accepted.
- Do we want a
release-please/changesets-driven release flow from v0.1, or is manualpnpm publishfine until v0.2? - Should the
e2e/fixture crate be generated at CI time via thecrategenerator (more realistic) or checked in (faster, more deterministic)?