This repository contains a set of crates that help you build robust highly scalable services in Rust.
These are the crates built out of this repo:
bytesbuf- Manipulate sequences of bytes for efficient I/O.data_privacy- Mechanisms to classify, manipulate, and redact sensitive data.data_privacy_macros- Macros for thedata_privacycrate.fundle- Compile-time safe dependency injection for Rust.fundle_macros- Macros for thefundlecrate.fundle_macros_impl- Macros for thefundlecrate.ohno- High-quality Rust error handling.ohno_macros- Macros for theohnocrate.thread_aware- Facilities to support thread-isolated state.thread_aware_macros- Macros for thethread_awarecrate.thread_aware_macros_impl- Macros for thethread_awarecrate.
The following sections explain the overall engineering process we use in this repo.
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-rdmewith 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-rdmetool which reads the crate docs, patches links, and then inserts the results into theREADME.mdfile. 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 documentation locally with all features enabled (including feature-gated items), run:
.\scripts\generate-docs.ps1This requires the Rust nightly toolchain to be installed. The script will generate documentation and open it in your default browser.
We have two primary workflows:
-
main. Runs on all pull requests and commits to the main branch. This performs quite a bit of validation to ensure high-quality outcomes. Any issues found by this workflow blocks the pull request from being merged. -
nightly. Runs nightly on the main branch. This executes repo-wide mutation testing (as opposed to the main workflow which does incremental testing). Any issues found by this workflow result in an issue being opened reporting the problem.
We strive to deliver high-quality code and as such, we've put in place a number of PR gates, described here:
-
Build. We build all the crates in the repo for Windows and Linux. We use
cargo-hackto iterate through different crate feature combinations to make sure everything builds properly. -
Testing. We run
cargo test --all-featuresto run every normal test and documentation test in the repo. -
Code Coverage. We calculate code coverage for the whole repo using
cargo-llvm-cov. We capture coverage for Windows and Linux, with--all-featuresand--no-features. Coverage is collected using the nightly Rust compiler which makes it possible to usecoverage(off)annotations in the source code to suppress coverage collection for a chunk of code. We require 100% coverage for any checked in code. -
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.
-
Dependency Auditing. We use
cargo-auditto be alerted of any security vulnerabilities in our dependencies. -
Unsafe Verification. We use Miri to verify that our unsafe code doesn't induce undefined behaviors.
-
External Type Exposure. We use
cargo-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. -
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 headers are described in the
.github\license-checkdirectory. -
README Content. We use
cargo-rdmeto ensure each crate'sREADME.mdfile matches the crate's current crate-level documentation.
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.