Skip to content

loadingalias/cargo-rail

Repository files navigation

cargo-rail

Replace the Rust workspace maintenance stack with one graph-aware Cargo tool.

Crates.io CI MSRV

cargo-rail unifies dependencies, selects affected CI work, releases crates, and maintains standalone crate repositories from the same Cargo graph and git history.

One binary. One rail.toml. No hosted service, workspace-hack crate, embedded git implementation, or separate workflow runtime.

Replace the stack

Replace With
cargo-hakari, dependency-unification scripts cargo rail unify
cargo-udeps, cargo-shear, cargo-machete Built-in compiler-backed unused-dependency detection and removal
cargo-unused-features, cargo-features-manager, cargo-autoinherit, cargo-msrv, feature-audit scripts Dead-feature pruning, borrowed-feature repair, inheritance enforcement, and MSRV computation
release-plz, cargo-release, git-cliff cargo rail change + cargo rail release
dorny/paths-filter, path globs, package-selection scripts cargo rail plan + cargo rail run
Hand-maintained publish ordering Dependency-ordered workspace releases
Copybara, git subtree, split/sync scripts cargo rail split + cargo rail sync

These are not disconnected wrappers. Every workflow consumes the same resolved workspace model, so a dependency change can select CI work, drive a release, order publication, and remain traceable into a standalone repository.

Install

cargo install cargo-rail
cargo rail init
cargo rail config sync

Pre-built archives for Linux, Windows, and Apple Silicon macOS, SHA-256 checksums, and signed provenance are available from GitHub Releases. cargo-binstall cargo-rail is supported.

Run cargo rail config sync after every cargo-rail upgrade. It materializes new policy fields and detected targets without overwriting existing choices; review the diff, then run cargo rail config validate --strict.

Unify

Make workspace manifests agree. unify detects version drift, fragmented features, unused dependencies, dead features, undeclared feature borrowing, and MSRV mismatches. It can replace a generated workspace-hack crate with explicit workspace dependencies.

Unused-edge decisions combine Cargo's resolved graph with workspace-only rustc evidence across configured targets and source-derived feature selections. Results are cached by compilation-unit identity, and apply revalidates the exact manifest edits and portable graph delta before committing them. Destructive cleanup of dormant private features and optional dependencies requires consumer_scope = "workspace"; published packages remain open-world.

cargo rail unify --check --explain  # inspect every decision
cargo rail unify                    # apply the plan
cargo rail unify undo               # restore the last backup

The check path writes nothing and exits non-zero when manifests need changes.

Change detection

Turn git changes into an executable Cargo scope. plan maps files to owning crates, walks reverse dependencies, classifies build, test, docs, bench, and infrastructure surfaces, then emits a stable machine-readable contract.

cargo rail plan --merge-base --explain
cargo rail run --merge-base --profile ci

Use run directly or feed plan -f github into existing CI jobs. No duplicated package-selection logic and no path-filter graph to keep synchronized with Cargo.

Release

Record release intent in the pull request that introduces the change. release combines reviewed change files with conventional commits, dependency cascades, changelog generation, readiness checks, publish ordering, tags, and forge releases.

cargo rail change add my-crate --bump minor --message "Added graph-aware planning."
cargo rail change check --merge-base --required
cargo rail release run --all --bump auto --pr --check

After the release PR merges:

cargo rail release finalize --all --yes

Interrupted releases are resumable. Optional cargo-semver-checks analysis runs as an external command instead of expanding cargo-rail's installed dependency graph.

Split and sync

Develop crates in a monorepo and publish them from focused standalone repositories. split filters crate history and rewrites workspace-relative manifests; sync maps later commits in either direction.

cargo rail split init my-crate
cargo rail split run my-crate --check
cargo rail split run my-crate
cargo rail sync my-crate --to-remote

Conflicts use explicit manual, ours, theirs, or union strategies with resumable receipts. Copybara configuration and subtree choreography are unnecessary.

Why one tool?

Cargo already owns the package graph. Git already owns change history. cargo-rail uses those sources directly instead of rebuilding partial models in a collection of plugins, actions, bots, and shell scripts.

The result is one install graph, one configuration surface, and one set of decisions to inspect. See the architecture for the internal model and the planner contract for its stable CI interface.

Commands

Command Purpose
init Create or update rail.toml
unify Inspect and repair workspace dependency state
plan / run Select and execute work affected by a change
change / release Review release intent and run graph-ordered releases
split / sync Maintain standalone repositories from monorepo crates
config, graph, hash Validate configuration and explain planner state

Documentation

Project

cargo-rail is actively maintained, requires Rust 1.95.0 or newer, and is licensed under MIT.