name: CI
on:
push:
branches: [master]
pull_request:
branches: [master]
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
test:
name: Test Suite
runs-on: ubuntu-latest
strategy:
matrix:
rust: [stable, beta, nightly]
features:
- --no-default-features
- --all-features
- steps:
- name: Checkout sources
uses: actions/checkout@v5
- name: Install toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust }}
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ matrix.rust }}-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-${{ matrix.rust }}-
${{ runner.os }}-cargo-
- name: Run tests
run: cargo test --verbose ${{ matrix.features }}
- name: Run doctests
run: cargo test --doc ${{ matrix.features }}
fmt:
name: Rustfmt
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v5
- name: Install stable toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: Run cargo fmt
run: cargo fmt --all -- --check
clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v5
- name: Install stable toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-clippy-${{ hashFiles('**/Cargo.lock') }}
- name: Run cargo clippy
run: cargo clippy --all-targets --all-features -- -D warnings
security:
name: Security Audit
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v5
- name: Install stable toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install cargo-audit
run: cargo install cargo-audit --locked
- name: Run cargo audit
run: cargo audit
coverage:
name: Code Coverage
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
steps:
- name: Checkout sources
uses: actions/checkout@v5
- name: Install stable toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-coverage-${{ hashFiles('**/Cargo.lock') }}
- name: Install grcov
run: cargo install grcov
- name: Generate coverage data
run: |
CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' \
LLVM_PROFILE_FILE='cargo-test-%p-%m.profraw' \
cargo test --all-features
- name: Generate coverage report
run: |
grcov . --binary-path ./target/debug/ -s . -t lcov \
--branch --ignore-not-existing \
--ignore "target/*" \
--ignore "examples/*" \
--ignore "benches/*" \
-o coverage.lcov
- name: Upload to codecov
uses: codecov/codecov-action@v5
with:
file: coverage.lcov
fail_ci_if_error: true
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
benchmark:
name: Benchmark
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
steps:
- name: Checkout sources
uses: actions/checkout@v5
- name: Install stable toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-bench-${{ hashFiles('**/Cargo.lock') }}
- name: Run benchmarks
run: cargo bench --all-features
- name: Store benchmark result
uses: benchmark-action/github-action-benchmark@v1
if: github.ref == 'refs/heads/master'
with:
tool: "cargo"
output-file-path: target/criterion/router_bench/base/estimates.json
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: true
comment-on-alert: true
alert-threshold: "200%"
fail-on-alert: true
msrv:
name: Minimum Supported Rust Version
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v5
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.85.0
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-msrv-${{ hashFiles('**/Cargo.lock') }}
- name: Check with MSRV
run: cargo check --all-features
docs:
name: Documentation
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v5
- name: Install stable toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-docs-${{ hashFiles('**/Cargo.lock') }}
- name: Build documentation
run: cargo doc --all-features --no-deps
env:
RUSTDOCFLAGS: -D warnings
- name: Deploy to GitHub Pages
if: github.ref == 'refs/heads/master'
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: target/doc
force_orphan: true
integration:
name: Integration Tests
runs-on: ubuntu-latest
needs: [test, clippy, fmt]
steps:
- name: Checkout sources
uses: actions/checkout@v5
- name: Install stable toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-integration-${{ hashFiles('**/Cargo.lock') }}
- name: Build examples
run: |
cargo build --example cbor_server --all-features
cargo build --example raw_server --all-features
cargo build --example cbor_client --all-features
cargo build --example raw_client --all-features
- name: Run integration test script
run: |
# Start server in background
timeout 30s cargo run --example cbor_server &
SERVER_PID=$!
# Wait for server to start
sleep 5
# Run client test
timeout 10s cargo run --example cbor_client || true
# Clean up
kill $SERVER_PID || true
ci-success:
name: CI Success
runs-on: ubuntu-latest
needs: [test, fmt, clippy, security, msrv, docs, integration]
if: always()
steps:
- name: Check all jobs
run: |
if [[ "${{ needs.test.result }}" != "success" ]]; then
echo "Test job failed"
exit 1
fi
if [[ "${{ needs.fmt.result }}" != "success" ]]; then
echo "Format job failed"
exit 1
fi
if [[ "${{ needs.clippy.result }}" != "success" ]]; then
echo "Clippy job failed"
exit 1
fi
if [[ "${{ needs.security.result }}" != "success" ]]; then
echo "Security audit failed"
exit 1
fi
if [[ "${{ needs.msrv.result }}" != "success" ]]; then
echo "MSRV check failed"
exit 1
fi
if [[ "${{ needs.docs.result }}" != "success" ]]; then
echo "Documentation build failed"
exit 1
fi
if [[ "${{ needs.integration.result }}" != "success" ]]; then
echo "Integration tests failed"
exit 1
fi
echo "All required jobs passed!"