name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
merge_group:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
CARGO_INCREMENTAL: 0
CARGO_PROFILE_DEV_DEBUG: 0
jobs:
format:
name: Format check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.1
- uses: actions-rust-lang/setup-rust-toolchain@v1.15.2
with:
toolchain: nightly
components: rustfmt
- name: Check Rust
run: cargo fmt --all -- --check
- name: Check C++
run: find src include -name '*.cpp' -o -name '*.h' | xargs clang-format-18 --dry-run --Werror
lint:
name: Lint check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.1
with:
submodules: true
- uses: actions-rust-lang/setup-rust-toolchain@v1.15.2
with:
toolchain: nightly
components: clippy
- name: Check Rust
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Check C++
run: find src include -name '*.cpp' -o -name '*.h' | xargs clang-tidy-18
test:
name: Test
needs: [format, lint]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
rust: [stable, beta]
steps:
- uses: actions/checkout@v6.0.1
with:
submodules: true
- uses: actions-rust-lang/setup-rust-toolchain@v1.15.2
with:
toolchain: ${{ matrix.rust }}
- name: Run tests
run: cargo test --all-features --workspace
msrv:
name: MSRV
needs: [format, lint]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.1
with:
submodules: true
- uses: actions-rust-lang/setup-rust-toolchain@v1.15.2
- uses: taiki-e/install-action@v2.67.9
with:
tool: cargo-msrv
- name: Verify MSRV
run: cargo msrv verify
docs:
name: Documentation
needs: [format, lint]
runs-on: ubuntu-latest
env:
RUSTDOCFLAGS: -D warnings
steps:
- uses: actions/checkout@v6.0.1
with:
submodules: true
- uses: actions-rust-lang/setup-rust-toolchain@v1.15.2
with:
toolchain: nightly
- name: Build docs
run: cargo doc --no-deps --all-features --workspace
sanitizers:
name: Sanitizers
needs: [format, lint]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.1
with:
submodules: true
- uses: actions-rust-lang/setup-rust-toolchain@v1.15.2
with:
toolchain: nightly
components: rust-src
- name: Address sanitizer
run: cargo test --lib --tests --target x86_64-unknown-linux-gnu
env:
RUSTFLAGS: -Z sanitizer=address
- name: Clean
run: cargo clean
- name: Thread sanitizer
run: cargo test -Zbuild-std --lib --tests --target x86_64-unknown-linux-gnu
env:
RUSTFLAGS: -Z sanitizer=thread
coverage:
name: Coverage
needs: [test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions-rust-lang/setup-rust-toolchain@v1.15.2
with:
toolchain: nightly
components: llvm-tools-preview
- uses: taiki-e/install-action@v2.67.9
with:
tool: cargo-llvm-cov
- name: Generate report
run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info
env:
CXX: clang++
- name: Upload report
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: codecov/codecov-action@v4
with:
files: lcov.info
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
audit:
name: Security audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.1
with:
submodules: true
- uses: rustsec/audit-check@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
deny:
name: Dependency compliance
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.1
with:
submodules: true
- uses: EmbarkStudios/cargo-deny-action@v2.0.15
lockfile:
name: Lockfile integrity
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.1
with:
submodules: true
- uses: actions-rust-lang/setup-rust-toolchain@v1.15.2
with:
toolchain: nightly
- name: Verify lockfile
run: cargo update --locked --workspace
unused-deps:
name: Unused dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.1
with:
submodules: true
- uses: actions-rust-lang/setup-rust-toolchain@v1.15.2
with:
toolchain: nightly
- uses: taiki-e/install-action@v2.67.9
with:
tool: cargo-udeps
- name: Find unused
run: cargo udeps --all-targets
outdated-deps:
name: Outdated dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions-rust-lang/setup-rust-toolchain@v1.15.2
with:
toolchain: nightly
- uses: taiki-e/install-action@v2.67.9
with:
tool: cargo-outdated
- name: Find outdated
run: cargo outdated --exit-code 1
hack:
name: Feature combinations
needs: [format, lint]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions-rust-lang/setup-rust-toolchain@v1.15.2
with:
toolchain: nightly
- uses: taiki-e/install-action@v2.67.9
with:
tool: cargo-hack
- name: Check powerset
run: cargo hack test --feature-powerset --all-targets --workspace
bench:
name: Benchmarks
needs: [format, lint]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions-rust-lang/setup-rust-toolchain@v1.15.2
with:
toolchain: nightly
- uses: taiki-e/install-action@v2.67.9
with:
tool: critcmp
- name: Cache baseline
uses: actions/cache@v4
with:
path: target/criterion
key: criterion-${{ runner.os }}-${{ github.sha }}
restore-keys: criterion-${{ runner.os }}-
- name: Run benchmarks
run: cargo bench -- --save-baseline ${{ github.event_name == 'pull_request' && 'pr' || 'main' }}
- name: Compare against baseline
if: github.event_name == 'pull_request'
run: |
if [ -d target/criterion/main ]; then
critcmp main pr --threshold 5
else
echo "No baseline to compare against (first run)"
fi