name: CI
permissions:
contents: read
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
lint:
name: Lint and Format
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
components: rustfmt, clippy
cache: true
- name: Cache just installation
uses: actions/cache@v4
with:
path: ~/.local/bin
key: ${{ runner.os }}-just-${{ hashFiles('justfile') }}
restore-keys: |
${{ runner.os }}-just-
- name: Install just
uses: taiki-e/install-action@just
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Check formatting
run: cargo fmt --all -- --check
- name: Run clippy
run: cargo clippy --all-targets --all-features -- -D warnings
security:
name: Security Audit
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
cache: true
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Install cargo-audit
run: cargo install cargo-audit
- name: Run security audit
run: cargo audit
test:
name: Test
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
rust: [stable]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: ${{ matrix.rust }}
components: rustfmt, clippy
cache: true
- name: Cache just installation
uses: actions/cache@v4
with:
path: ~/.local/bin
key: ${{ runner.os }}-just-${{ hashFiles('justfile') }}
restore-keys: |
${{ runner.os }}-just-
- name: Install just
uses: taiki-e/install-action@just
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Install cargo-tarpaulin
run: cargo install cargo-tarpaulin@0.32.8
- name: Run tests with coverage
shell: bash
run: |
mkdir -p coverage
cargo tarpaulin --out Xml --all-features
if [ -f cobertura.xml ]; then
cp cobertura.xml coverage/junit.xml
echo "Created coverage/junit.xml from cobertura.xml"
elif [ -f coverage/cobertura.xml ]; then
cp coverage/cobertura.xml coverage/junit.xml
echo "Created coverage/junit.xml from coverage/cobertura.xml"
else
echo "Error: cobertura.xml not found"
find . -name "*.xml" -type f 2>/dev/null || echo "No XML files found"
exit 1
fi
ls -lh coverage/junit.xml
- name: Upload test results to Codecov
if: ${{ !cancelled() }}
uses: codecov/test-results-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
coverage:
name: Coverage
runs-on: ubuntu-latest
needs: [lint, security, test]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
cache: true
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Install cargo-tarpaulin
run: cargo install cargo-tarpaulin@0.32.8
- name: Generate coverage report
run: cargo tarpaulin --out Xml --output-dir coverage
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
directory: coverage/
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false