cargo-rail 0.10.11

Graph-aware testing, dependency unification, and crate extraction for Rust monorepos
Documentation

cargo-rail

Deterministic Rust monorepo orchestration: run only impacted CI surfaces, unify dependency graphs, split/sync crates across repos, and automate releases.

Crates.io docs.rs CI MSRV

Why

Documented change-detection impact on real repos (tokio, helix, meilisearch, helix-db):

Metric Impact
Commits Measured 80 (20 per repo)
Could Skip Build 21%
Could Skip Tests 19%
Targeted (Not Full Run) 68%
Dependencies Unified 132 across 53 crates
Undeclared features Fixed 258 silent bugs prevented
MSRV Computation Automatic from dependency graph

Why this matters:

  1. Change Detection (plan/run) reduces what runs — 68% of measured commits avoided full-run behavior, with explicit plan traces.
  2. Dependency Unification (unify) reduces graph complexity — cleaner deps, smaller build units, fewer rebuilds.
  3. Toolchain Consolidation keeps workflows in one tool with 14 core dependencies, reducing repeated metadata fetches and plugin sprawl.

Before cargo-rail: run multiple plugins independently (hakari/workspace-hack, udeps, machete, shear, features-manager, msrv, sort, and others), often over separate metadata views.
After cargo-rail: run cargo rail unify --check with one metadata call.

Quick Start

# install
cargo install cargo-rail

# generate config
cargo rail init

# dependency hygiene
cargo rail unify --check

# deterministic planning + execution
cargo rail plan --merge-base
cargo rail run --merge-base --profile ci
cargo rail plan --merge-base --explain

Pre-built binaries: GitHub Releases

Workflows

Change Planning (detection) + Execution (plan / run)

Problem: CI/CD often runs full pipelines for small changes, or relies on custom scripts that drift from local behavior.

Solution: one planner contract used locally and in CI:

# Local: what would CI run if I pushed this branch?
cargo rail plan --merge-base

# CI: deterministic plan → selective execution
cargo rail plan --merge-base -f github  # outputs: build=true, test=false, docs=true, ...
cargo rail run --merge-base --profile ci  # runs ONLY what plan selected

How to use this effectively:

  1. Configure change detection rules in .config/rail.toml (infrastructure files, doc-only changes, custom, etc.)
  2. Run plan to see impact classification (which surfaces: build, test, bench, docs, infra, custom)
  3. Run run to execute only selected surfaces, locally or in CI, and integrate with justfile, makefile, xtask, or shell scripts.
  4. Use --explain to understand any decision: "why did this run?" / "why was this skipped?"

Result: 21% build skip, 19% test skip, 68% targeted/non-full runs across 80 measured commits (tokio/helix/meilisearch/helix-db). See: Examples.

Dependency Unification (unify)

Problem: dependency hygiene usually requires multiple plugins (hakari, udeps, machete, shear, features-manager, msrv, sort, and others), each with separate commands and metadata passes. Undeclared features borrowed from Cargo's resolver can break isolated builds silently.

Solution: cargo rail unify provides one command and one metadata pass for integrated analysis:

cargo rail unify --check    # preview all changes
cargo rail unify            # apply workspace-wide
cargo rail unify --explain  # understand each decision

What it does:

  • Unifies versions — writes to [workspace.dependencies], converts members to { workspace = true }
  • Fixes undeclared features — detects features borrowed via Cargo's unified resolution
  • Prunes dead features — removes features never enabled in resolved graph
  • Detects unused deps — flags dependencies not used anywhere
  • Computes MSRV — derives minimum Rust version from dependency graph
  • Replaces workspace-hack — enable pin_transitives for cargo-hakari equivalent
  • Configurable — tune behavior in rail.toml (unused removal, feature pruning, sorting, and more).

Unused detection combines resolved-graph analysis with rustc diagnostics (unused_crate_dependencies) so deps that are resolved but never referenced are also removed. Optional deps and unconfigured target-gated deps are conservatively skipped.

Validated impact on real repos:

Repository Crates Deps Unified Undeclared Features MSRV Computed
tokio-rs/tokio 10 13 7 1.85.0
helix-editor/helix 14 28 19 1.87.0
meilisearch/meilisearch 23 70 215 1.88.0
helixdb/helix-db 6 21 17 1.88.0
Aggregate 53 132 258

Config files and validation artifacts: Examples | Validation Forks

Split + Sync (Copybara Alternative)

Problem: teams often need to develop in a monorepo but publish crates from standalone repos with full history. Existing tools (git subtree, git-filter-repo) are mostly one-way and manual.

Solution: cargo rail split + cargo rail sync — bidirectional sync with 3-way conflict resolution:

# Extract a crate to a standalone repo with full git history
cargo rail split init crates/my-crate  # configure once
cargo rail split run crates/my-crate   # extract with history preserved

# Bidirectional sync
cargo rail sync crates/my-crate --to-remote    # push monorepo changes to split repo
cargo rail sync crates/my-crate --from-remote  # pull split repo changes (creates PR branch)

Three modes:

  • single: one crate → one repo (most common)
  • combined: multiple crates → one repo (shared utilities)
  • workspace: multiple crates → workspace structure (mirrors monorepo)

Built on system git (not libgit2) for deterministic SHAs and full git fidelity with less attack surface/weight in the graph.

Release Automation (release)

Release checks, versioning, changelogs, tags, and dependency-order publish in one flow, with a lean dependency footprint.

# Cut a new release
cargo rail release run cargo-rail --bump patch --yes  # swap 'patch', 'minor', or 'major' as needed
git push origin main --follow-tags   # follow up

This produces changelog entries, tags, crates.io publish, and GitHub release metadata.

GitHub Actions Integration

For CI/CD integration, use cargo-rail-action (uses: loadingalias/cargo-rail-action@v3) — a thin transport over cargo rail plan -f github that handles installation, checksum verification, and output publishing for job gating.

The action keeps CI behavior aligned with local plan + run workflows.

Config

  • cargo rail init generates .config/rail.toml.
  • cargo rail config sync updates .config/rail.toml with latest defaults from new releases installed.
  • cargo rail config validate validates .config/rail.toml for when you're unsure.

By default, on cargo rail init, the rail.toml file is written to the .config/ directory. It's created if it doesn't exist. However, you can move/change it to the workspace root if you prefer it there. You can also 'unhide' the file if you'd like. Reference

Full documentation:

Migration Guides

Tested & Proven On Large Repos

All core workflows (plan/run, unify) validated on production repos with full git history:

Repository Crates Validation Fork
tokio-rs/tokio 10 Unify (13 deps, 7 features), Plan/run Fork
helix-editor/helix 14 Unify (28 deps, 19 features), Plan/run Fork
meilisearch/meilisearch 23 Unify (70 deps, 215 features), Plan/run Fork
helixdb/helix-db 6 Unify (21 deps, 17 features), Plan/run Fork

Validation forks: cargo-rail-testing — full configs, integration guides, and reproducible artifacts.

How to Validate:

  1. Reproducibility: Every command in examples/validation-protocol.md runs on forked repos with real merge history
  2. Metrics collection: Automated scripts measure execution reduction, surface accuracy, plan duration, unify impact
  3. Quality audit: Heuristics flag potential false positives/negatives for human review
  4. Real-world scenarios: Tests run on actual merge commits and real dependency graphs, not synthetic fixtures

Unify results (4 repos, 53 crates):

  • 132 dependencies unified to [workspace.dependencies]
  • 258 undeclared features fixed (silent bugs prevented)
  • 2 dead features pruned
  • MSRV computed for all repos (1.85.0 - 1.88.0)

Full protocol and raw artifacts: Validation protocol | Unify results

Examples

Each workflow includes working config files and reproducible command sequences:

Workflow Examples Real-World Configs
Change detection examples/change_detection/ tokio, helix, meilisearch
Unify examples/unify/ Validation results
Split/sync examples/split-sync/
Release examples/release/

Full validation configs: Each fork in cargo-rail-testing includes:

  • .config/rail.toml — production-ready config
  • docs/cargo-rail-integration-guide.md — step-by-step integration
  • docs/CHANGE_DETECTION_METRICS.md — measured impact analysis

Getting Help

Contributing

See CONTRIBUTING.md.

Security

See SECURITY.md.

Code of Conduct

See CODE_OF_CONDUCT.md.

License

Licensed under MIT.