Continuous integration
GitHub Actions owns triggers, permissions, runners, caches, artifacts, matrices, and job dependencies. The justfile
owns validation commands so each CI command also runs from a checkout.
Pull requests
The required workflow runs these job groups:
source: Rust formatting,cargo check, Clippy, and dependency policyautomation: repository hooks and workflow validationcontracts: snapshots, the release plan, and Cargo discovery of publishable packagessemver: public API compatibility for each publishable packageplatform: platform-boundary tests on macOS and Windowscoverage: the native workspace suite with all featuresfrontend: native and Wasm browser coveragedocs: rustdoc, Markdown, Mermaid regeneration, and the site build
The coverage jobs reject uncovered source lines. ci-gate gives branch protection one check name and fails unless every
required job succeeds.
CodSpeed runs the ecosystem benchmark packages on standard GitHub-hosted runners in
simulation mode. This avoids quota-limited Macro Runners. Run the same benchmark path with
just codspeed.
Test synchronization
Tests wait for observable state changes. Child-process cases use ProcessHarness::spawn_until_event,
Node::await_event, or the topology event stream. In-process async cases use channels or
tokio::sync::Notify. Code that measures elapsed time uses Tokio's paused clock.
Deadlines bound failed waits, and the CI profile supplies a per-test termination guard.
Nightly analysis
The nightly workflow runs feature combinations, direct dependency lower bounds, Miri, Loom, AddressSanitizer, mutation testing, each cargo-fuzz target, and the live PyPI client boundary. Each matrix leg invokes a public Just recipe.
Sanitizer and mutation jobs build Nextest archives once, then run partitions from those archives.
AddressSanitizer follows Rust's -Zsanitizer and -Zbuild-std invocation. Nextest 0.9.143
classifies Rust's gnuasan target as a custom target, but Rust does not publish custom
target JSON for that built-in target. The workflow uses the standard Linux target.
The async suite does not run under ThreadSanitizer. Tokio issue 7299 records internal false positives and identifies Miri and Loom as its race-analysis tools; nightly CI runs both.
Local commands
Install the locked tools, then run the recipe named by a CI job:
mise install --locked
just lint
just platform-test
just coverage-native
just frontend-deps
just frontend-browser-deps
just coverage-frontend
just docs
just test is hermetic. just storage-s3 and just coverage-native require a running Docker daemon for the MinIO
boundary tests.
Nightly commands are local too:
just features
just direct-minimum
just miri
just loom
just sanitizer-address
just mutation-baseline
just mutation 1/8
just fuzz peryx-ecosystem-oci oci_reference 60
just e2e-live
Generated files stay under .tox/. just coverage-clean, just clean, and just clean-all remove increasing amounts
of local build state.