name: Quality
on:
push:
branches: [main, "feat/**"]
pull_request:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
jobs:
coverage-gate:
name: coverage (98% lines)
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 with:
toolchain: nightly
components: llvm-tools-preview
- uses: Swatinem/rust-cache@f0d9c3887740aee45f6153b24b3a6b815192ec16 - uses: taiki-e/install-action@e67fa11c4b9316fa714ddf0abed07a0c3143b95b with:
tool: cargo-llvm-cov
- run: cargo llvm-cov --all-features --locked --fail-under-lines 98
miri:
name: miri
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 with:
toolchain: nightly
components: miri
- uses: Swatinem/rust-cache@f0d9c3887740aee45f6153b24b3a6b815192ec16 - run: cargo +nightly miri test --lib
fuzz-replay:
name: fuzz build + corpus replay
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 with:
toolchain: nightly
- uses: Swatinem/rust-cache@f0d9c3887740aee45f6153b24b3a6b815192ec16 with:
workspaces: fuzz
- run: cargo install --locked cargo-fuzz
- name: Build every target and replay the corpus
working-directory: fuzz
run: |
set -euo pipefail
cargo +nightly fuzz build
for target in $(cargo +nightly fuzz list); do
echo "== $target"
dirs=("corpus/$target")
[ -d "regressions/$target" ] && dirs+=("regressions/$target")
cargo +nightly fuzz run "$target" -- -runs=0 "${dirs[@]}"
done
docs-lint:
name: docs lint (markdownlint, codespell, REUSE)
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 with:
persist-credentials: false
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d - run: npx --yes markdownlint-cli2 "**/*.md" "!target/**" "!fuzz/target/**"
- run: uvx codespell
- run: uvx --with chardet reuse lint
cargo-vet:
name: cargo-vet
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 with:
toolchain: stable
- uses: Swatinem/rust-cache@f0d9c3887740aee45f6153b24b3a6b815192ec16 - uses: taiki-e/install-action@e67fa11c4b9316fa714ddf0abed07a0c3143b95b with:
tool: cargo-vet@0.10.2
- run: cargo vet --locked
- name: Exemption ratchet
run: |
set -euo pipefail
baseline="$(tr -d '[:space:]' < supply-chain/exemptions-baseline.txt)"
current="$(cargo vet --locked 2>&1 | grep -oE '[0-9]+ exempted' | grep -oE '[0-9]+')"
echo "exempted: $current (baseline $baseline)"
if [ "$current" -gt "$baseline" ]; then
echo "::error::exemptions grew from $baseline to $current"
exit 1
fi
release-hygiene:
name: versions, examples, benches
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 with:
toolchain: stable
- uses: Swatinem/rust-cache@f0d9c3887740aee45f6153b24b3a6b815192ec16 - run: ./scripts/verify-release-versions.sh
- run: make examples
- run: cargo bench --all-features -- --test
- name: rustdoc with warnings denied
env:
RUSTDOCFLAGS: -D warnings
run: cargo doc --no-deps --all-features --locked