This repository contains a set of tools that help you build robust highly scalable services in Rust.
These are the crates built out of this repo:
cargo-anvil- Opinionated, unified Rust build and cloud-workflow scaffolding for GitHub Actions and Azure DevOpscargo-aprz- A cargo subcommand that appraises the quality of Rust dependenciescargo-coverage-gate- A cargo subcommand that gates pull requests on per-package line coverage measured by cargo-llvm-covcargo-each- A cargo subcommand that runs a command over a cargo-style selection of workspace memberscargo-ensure-no-cyclic-deps- A cargo subcommand to detect cyclic dependencies in workspace cratescargo-ensure-no-default-features- A cargo subcommand that ensures dependencies are declared with default-features = falsecargo-gamma- Fast mutation testing for Rustcargo-heather- A cargo subcommand to validate license headers in Rust, TOML, PowerShell, Just, and env source files
The following sections explain the overall engineering process we use in this repo.
To set up a local PC environment capable of exercising all the tooling used by this repo's development processes, you can follow the guide in DEVELOPMENT.md.
Adding a new crate to this repo is done by running the scripts\add-crate.ps1 script.
It will prompt you for a few bits of state, and then will get everything wired up that
needs to be.
The add-crate script does the following:
-
Adds an entry for the crate to the Crates section in this README file.
-
Adds an entry for the crate to the top-level CHANGELOG.md file.
-
Prepares a
README.mdfile for the crate, setup for use withcargo-doc2readmewith a set of appropriate CI badges. -
Creates an empty
CHANGELOG.mdfile for the crate, which will later get populated by thescripts\release-crate.ps1script. -
Creates placeholder
logo.pngandfavicon.icofiles for the crate, which you're expected to replace with legit crab-themed logo and icon.
Releasing new versions of crates to crates.io is handled by an internal Microsoft automation process. To release a new version of any crate, follow this simple process:
-
Make sure the changes you want to release have all been committed to the repo.
-
Create a branch off of main.
-
Run
./scripts/release-crate.ps1 <crate_name> [new_version]to bump a crate's version and update the crate'sCHANGELOG.mdfile. Run the script many times if you want to release several crates in the same PR. -
Create a PR like normal to push changes out.
Once your PR is merged, automation will kick in. It will tag the commit and push the crate to crates.io.
We want our crates to have world-class documentation such that our customers can enjoy discovering and using our features. We expect our Rust code to be fully documented in the normal Rust way, and we introduce two doc-related automation processes:
-
The
README.mdfile in each crate's directory is auto-generated from the crate-level documentation. We use thecargo-doc2readmetool which reads the crate docs, resolves intra-doc links, and generates theREADME.mdfile using a shared template. A pull request gate ensures theREADME.mdfile always reflects the latest crate documentation. -
The
CHANGELOG.mdfile in each crate's directory is auto-generated from the commits to a crate's directory by thescripts/release-crate.ps1script.
To generate and open documentation locally with all features enabled, run:
just anvil-doc-build --openThe recipe generates documentation and opens it in your default browser.
We use the workflows generated and maintained by cargo-anvil:
-
Anvil. Runs impact-scoped validation on pull requests and merge-queue commits. Its aggregatePR Job / Required Anvil checkscontext blocks a merge when impact analysis or any check-group matrix does not succeed. -
anvil-scheduled. Runs full-workspace tests, advisory checks, runtime analysis, mutation testing, feature-powerset checks, and benchmark compilation. Failures are published to a durable tracking issue.
We strive to deliver high-quality code and as such, we've put in place a number of PR gates, described here:
Before submitting source, build, configuration, or CI changes, run the complete local PR tier:
just anvil-prFor documentation-only changes that cannot affect executable behavior, run the fast tier instead:
just anvil-pr-fastThe fast tier includes formatting, generated README, spelling, metadata, dependency-policy, and static-analysis checks. It deliberately omits tests and coverage, runtime analysis, and mutation testing. Generic developer operations are also provided by Anvil:
just anvil-build
just anvil-build --package cargo-anvil
just anvil-doc-build --open
just anvil-examples --run
just anvil-fmt --fix
just anvil-miri --package cargo-anvil --example basic
just anvil-readme --fixThese focused operations are not substitutes for either verification tier.
-
Build. We build affected crates for Windows and Linux on x86_64 and aarch64. The scheduled tier uses
cargo-hackto check the feature powerset across the full workspace. -
Testing. We run affected unit and integration tests through
cargo-nextestin both--all-featuresand--no-default-featuresconfigurations. Documentation tests run separately throughcargo test --docwith all features and default features. -
Code Coverage. We collect coverage using
cargo-llvm-covon Windows and Linux under the same all-features and no-default-features configurations. Pull requests measure affected packages; the scheduled tier measures the full workspace. The nightly compiler enablescoverage(off)annotations, and the local cargo-coverage-gate verdict enforces each package's configured threshold. -
Mutation Testing. We use
cargo-mutantsto help maintain high test quality. -
Source Linting. We run Clippy with most warnings enabled and all treated as errors.
-
Doc Linting. We lint documentation to help find bad links and other anti-patterns.
-
Source Formatting. We ensure the source code complies with the Rust standard format.
-
Cargo.toml Formatting. We use
cargo-sortto keep Cargo.toml files in a consistent format and layout. -
Unsafe Verification. We use Miri and
cargo-carefulto verify that our unsafe code doesn't induce undefined behaviors. -
External Type Exposure. We use
cargo-check-external-typesto track which external types our crates depend on. Exposing a 3P type from a crate creates a coupling between the crate and the exporter of the type which can be problematic over time. This check is there to prevent unintentional exposure. If the exposure is intentional, it's a simple matter of adding an exclusion for it to the crate'sCargo.tomlfile. -
Default Features. We use
cargo-ensure-no-default-featuresto make sure the dependencies pulled in by the top-level Cargo.toml are all annotated withdefault-features = false. Individual crates that use these dependencies are then responsible for stating exactly which features they need. This is designed to minimize build times for our customers. -
Cyclic Dependencies. We use
cargo-ensure-no-cyclic-depsto ensure the crates in the repo don't create funny referential cycles usingdev-dependencies. Things break or get difficult when these cycles exist. -
Unneeded Dependencies. We use
cargo-udepsto ensure our crates don't have superfluous dependencies. -
Dependency Validation. We use
cargo-denyto ensure our dependencies have acceptable licenses and don't contain known vulnerabilities. -
Semantic Version Compatibility. We use
cargo-semver-checksto report advisory findings about API compatibility against the pull request target. -
PR Title. Every PR submitted to this repo must follow the Conventional Commits specification. We use these PR titles as part of our automatic change log generation logic.
-
License Headers. We ensure all source files have the requisite license header. The expected header is described in the
.cargo-heather.tomlfile at the repo root and validated by the in-repocargo-heathertool. -
Spell Checking. We use cargo-spellcheck to help our docs have fewer typos.
-
README Content. We use
cargo-doc2readmeto ensure each crate'sREADME.mdfile matches the crate's current crate-level documentation.
Anvil's Rust nightly and cargo-tool pins live exclusively in
justfiles/anvil/versions.just. Because this
repository develops cargo-anvil itself, catalog updates start in
crates/cargo-anvil/templates/justfiles/anvil/versions.just and are applied by
running cargo anvil. The default stable toolchain remains in
rust-toolchain.toml, while the workspace MSRV remains
the rust-version in Cargo.toml.
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.