Cargo-aware Nx release: version bump, internal dependency updates, dry-run, package validation, registries, and fixed/independent modes.
| ID | Owner | Status |
|---|---|---|
| RELEASE | eddacraft | Proposed |
v0.1 ships a release-publish executor that wraps cargo publish, plus a
release-version generator that bumps package.version in Cargo.toml.
Both work in isolation but neither participates fully in Nx release: there
is no internal-dep cascade ("bump crate b because it depends on crate
a's new version"), no cargo publish --dry-run ergonomics, no
changelog integration, no fixed-vs-independent mode toggle, and no
explicit private-registry support.
Spec §6.8 lays out the full Cargo-aware Nx release surface. This module brings nxrust into parity with how Nx release is expected to work in mixed JS+Rust monorepos.
Version handling (spec §6.8):
- Update
package.versionin each crate'sCargo.toml, preserving comments and formatting (v0.1release-versiongenerator). - Update workspace dependency versions across the workspace when an
internal crate is bumped — if
crate-bdeclarescrate-a = { version = "0.2", path = "../crate-a" }, theversionfield updates too. - Update
[workspace.dependencies]shared declarations if used. - Support fixed mode (all crates version together) and independent mode (crates version separately). Mode is a plugin / Nx release config option.
Publishing (spec §6.8):
release-publishexecutor (already in v0.1) gains:--dry-runplumbed through tocargo publish --dry-run.--registry <name>for private registries.cargo packagevalidation pass available as a siblingrelease-packageexecutor or as a dry-run pre-check.- Honour
package.metadata.nxrust.publish = falseto skip (private-only crates).
Nx release integration (spec §6.8):
- Plug into
nx release versionso Cargo crates participate in the release-group view that Nx release already shows for JS packages. - Plug into
nx release changelog— Cargo crates contribute toCHANGELOG.mdentries with conventional-commits filtered by Cargo-package directory rather than only by Nx project tag. - Plug into
nx release publishso a singlenx release publishcovers bothnpm publishfor JS andcargo publishfor Rust.
Release modes (spec §6.8):
- Fixed release group: all crates share one version, bumped together.
- Independent: crates version separately based on conventional commits scoped per crate.
- Mixed: a release group covering a subset of crates (e.g. Anvil kernel crates as one group, utility crates independent).
- The actual publish-credential management (npm token, crates.io token, registry token). That's a CI concern; the executor consumes whatever cargo can read from its env.
- Yanking —
cargo yankis rare and manual; not in scope for this module's first cut. - Workspace inheritance refactors (moving from per-crate
version = "x.y.z"toversion.workspace = true) — covered as an opt-in feature in 02-workspace-inference-and-graph if a consumer asks. - Migration of an existing JS-only Nx release config to mixed JS+Rust — covered in 15-monodon-migration for Monodon consumers; general migration is a docs item in 16-adoption-and-docs.
cargo publish,cargo package(Cargo public contract).@nx/devkit ^22.6.5and Nx release's release-group + changelog contracts.- v0.1's
release-publishexecutor andrelease-versiongenerator. - 02-workspace-inference-and-graph — workspace-dep edges drive the internal-dep cascade.
- 03-target-inference — inferred
release-publishtarget per crate.
- Cargo-aware
nx release version: bumpsCargo.tomlversions and cascades to internal dependents. - Cargo-aware
nx release publish: publishes crates in dependency order with dry-run and registry support. - Cargo-aware
nx release changelog: contributes entries from Cargo-package directories. package.metadata.nxrust.publishflag for crate-level publish opt-out.
- Internal-dep cascade must be order-correct. Publishes happen in topological order from the graph in 02-workspace-inference-and-graph. A dependent crate must not publish before its dependency.
- Dry-run is safe by default.
nx release publish --dry-runmust never callcargo publish(no--dry-runflag to cargo if Cargo's dry-run still hits the network — verify and document). - Failed publish leaves a recoverable state. Partial publishes (some crates succeeded, one failed) must produce a clear "resume here" instruction, not an opaque error.
- Comments and formatting preserved in
Cargo.toml. Inherits the v0.1 generator contract. - No publish without explicit auth. The plugin never silently picks up a credential it didn't expect.
- release-publish stays "unvalidated against a real token" per index open question 2 until a real consumer publishes. Promotion of release work items implies validating against a real consumer publish.
Promote individual Work Items to Ready when:
- A real consumer asks to publish a crate (per D-007).
- The consumer's release shape is captured (fixed vs independent, registry target, changelog expectations).
- A dry-run validation path is identified.
- A Work Item is drafted.
No work items yet — module is Proposed. Items promote individually on real-consumer asks per D-007.
| Risk | Impact | Likelihood | Mitigation |
|---|---|---|---|
| Partial publish leaves the workspace in an inconsistent versions state | high | medium | Topological publish; clear "resume from crate X" diagnostic on failure (14-diagnostics) |
Internal-dep cascade misses a path = "..." dep without an explicit version = "..." |
medium | medium | Detect path = "..." deps without version = and warn at version-bump time; document the require-version convention |
cargo publish --dry-run still hits the network in some versions |
medium | low | Verify per supported Cargo version; document the verification result; keep nx release publish --dry-run as a soft barrier with explicit consent for the cargo call |
| Mixed JS+Rust release-group ordering surprises consumers | medium | medium | Make ordering explicit in Nx release output; document the rule (JS first or Rust first based on dep direction) |
package.metadata.nxrust.publish = false collides with cargo publish = false already in [package] |
low | low | Honour both; document precedence (cargo's takes priority — it's the Cargo contract) |
- D-R1: Internal-dep cascade is order-correct via the graph from 02-workspace-inference-and-graph. Accepted.
- D-R2: Fixed and independent release modes are both supported. Mode is per release-group, not workspace-wide. Accepted (inherits spec §6.8).
- D-R3:
release-publishstays unvalidated against a real token until a real consumer publishes. Promotion of any work item in this module implies validating against that consumer. Accepted (inherits index open question 2).
- Does Anvil want fixed or independent release initially? Spec §6.8 says "Anvil may prefer fixed". Confirm at promotion.
- Should the Cargo changelog entries be parsed back into
CHANGELOG.mdfiles per crate, or aggregated workspace-wide? Nx release does per-project by default; mirror that. - Does the consumer want
cargo-release(the community tool) compatibility, or full Nx release integration? They are different models. Nx release is the spec direction. - What's the right error UX when
cargo packagevalidation fails (typically a missingdescription,license, etc.)? Surface directly via 14-diagnostics. - Should
release-versiongenerator be deprecated in favour ofnx release version? Once Nx release covers it, the generator becomes redundant. Defer to promotion + consumer feedback.