name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
RUSTFLAGS: -D warnings
RUSTDOCFLAGS: -D warnings
jobs:
detect:
runs-on: ubuntu-latest
outputs:
has_rust: ${{ steps.check.outputs.has_rust }}
steps:
- uses: actions/checkout@v6
- id: check
run: |
if [ -f Cargo.toml ]; then
echo "has_rust=true" >> "$GITHUB_OUTPUT"
else
echo "has_rust=false" >> "$GITHUB_OUTPUT"
echo "::notice::No Cargo.toml found — Rust jobs will be skipped until implementation starts (see README §11)."
fi
fmt:
needs: detect
if: needs.detect.outputs.has_rust == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
components: rustfmt
- run: cargo fmt --all --check
clippy:
needs: detect
if: needs.detect.outputs.has_rust == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
components: clippy
- run: cargo clippy --workspace --all-targets --all-features -- -D warnings
test:
needs: detect
if: needs.detect.outputs.has_rust == 'true'
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
toolchain: [stable, beta]
include:
- os: ubuntu-latest
toolchain: "1.95"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: ${{ matrix.toolchain }}
- uses: taiki-e/install-action@v2
with:
tool: cargo-nextest
- name: Build
run: cargo build --workspace --all-targets --all-features --locked
- name: Test (nextest)
run: cargo nextest run --workspace --all-features --locked
- name: Doctests
run: cargo test --workspace --doc --all-features --locked
docs:
needs: detect
if: needs.detect.outputs.has_rust == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
- run: cargo doc --workspace --all-features --no-deps
ci:
if: always()
needs: [detect, fmt, clippy, test, docs]
runs-on: ubuntu-latest
steps:
- name: Verify all required jobs passed (or were skipped when spec-only)
run: |
has_rust='${{ needs.detect.outputs.has_rust }}'
if [ "$has_rust" = "true" ]; then
for job in fmt clippy test docs; do
result=$(jq -r ".[\"$job\"].result" <<< '${{ toJSON(needs) }}')
if [ "$result" != "success" ]; then
echo "::error::$job failed: $result"
exit 1
fi
done
fi
echo "All required checks passed."