name: Pull Request CI
on:
pull_request:
branches:
- main
permissions:
contents: read
id-token: write
security-events: write
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
changes:
name: Detect Changed Files
runs-on: ubuntu-latest
outputs:
code: ${{ steps.filter.outputs.code }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Check for changes
uses: dorny/paths-filter@v4
id: filter
with:
filters: |
code:
- 'src/**'
- 'tests/**'
- 'benches/**'
- 'Cargo.toml'
- 'Cargo.lock'
- '.github/workflows/pr.yml'
license-check:
name: Verify SPDX License Headers
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.code == 'true'
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Check license headers
uses: firestoned/github-actions/security/license-check@v1.3.4
with:
copyright-holder: "Erick Bourgeois, firestoned"
license-id: "MIT"
verify-commits:
name: Verify Signed Commits
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.code == 'true'
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Verify all commits are signed
uses: firestoned/github-actions/security/verify-signed-commits@v1.3.4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
base-ref: origin/${{ github.base_ref }}
verify-mode: pr
format:
name: Check Formatting
runs-on: ubuntu-latest
needs: [license-check, verify-commits]
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: Check formatting
run: make fmt-check
clippy:
name: Clippy
runs-on: ubuntu-latest
needs: format
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- name: Cache cargo dependencies
uses: firestoned/github-actions/rust/cache-cargo@v1.3.4
- name: Run clippy
run: make clippy
build:
name: Build - ${{ matrix.platform.name }}
runs-on: ${{ matrix.platform.os }}
needs: [format, clippy]
strategy:
fail-fast: false
matrix:
platform:
- name: Linux x86_64
os: ubuntu-latest
target: x86_64-unknown-linux-gnu
artifact_name: hornet-linux-amd64
binary_name: hornet
- name: Linux ARM64
os: ubuntu-latest
target: aarch64-unknown-linux-gnu
artifact_name: hornet-linux-arm64
binary_name: hornet
- name: macOS ARM64
os: macos-latest
target: aarch64-apple-darwin
artifact_name: hornet-macos-arm64
binary_name: hornet
- name: macOS x86_64
os: macos-latest
target: x86_64-apple-darwin
artifact_name: hornet-macos-amd64
binary_name: hornet
- name: Windows x86_64
os: windows-latest
target: x86_64-pc-windows-msvc
artifact_name: hornet-windows-amd64
binary_name: hornet.exe
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Rust build environment (Linux)
if: runner.os == 'Linux'
uses: firestoned/github-actions/rust/setup-rust-build@v1.3.4
with:
target: ${{ matrix.platform.target }}
- name: Setup Rust toolchain (macOS/Windows)
if: runner.os != 'Linux'
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.platform.target }}
- name: Add x86_64 target for cross-compilation (macOS)
if: matrix.platform.target == 'x86_64-apple-darwin'
run: rustup target add x86_64-apple-darwin
- name: Cache cargo dependencies (macOS/Windows)
if: runner.os != 'Linux'
uses: firestoned/github-actions/rust/cache-cargo@v1.3.4
- name: Build binary (Linux)
if: runner.os == 'Linux'
uses: firestoned/github-actions/rust/build-binary@v1.3.4
with:
target: ${{ matrix.platform.target }}
- name: Build binary (macOS/Windows)
if: runner.os != 'Linux'
shell: bash
run: cargo build --release --target ${{ matrix.platform.target }}
- name: Generate SBOM (Linux only)
if: runner.os == 'Linux'
uses: firestoned/github-actions/rust/generate-sbom@v1.3.4
with:
target: ${{ matrix.platform.target }}
- name: Upload binary and SBOM artifacts
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.platform.artifact_name }}
path: |
target/${{ matrix.platform.target }}/release/${{ matrix.platform.binary_name }}
*.cdx.*
retention-days: 1
if-no-files-found: error
test:
name: Test
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo dependencies
uses: firestoned/github-actions/rust/cache-cargo@v1.3.4
- name: Run tests
run: make test
security:
name: Security Vulnerability Scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Run security scan
uses: firestoned/github-actions/rust/security-scan@v1.3.4
with:
cargo-audit-version: "0.22.0"
coverage:
name: Code Coverage
runs-on: ubuntu-latest
needs: test
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo dependencies
uses: firestoned/github-actions/rust/cache-cargo@v1.3.4
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@v2
with:
tool: cargo-llvm-cov
- name: Generate coverage report
run: make coverage-lcov
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
files: lcov.info
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
- name: Generate HTML coverage report
run: make coverage-html
- name: Upload HTML coverage as artifact
uses: actions/upload-artifact@v7
with:
name: coverage-report
path: target/llvm-cov/html/
retention-days: 7
bench-compile:
name: Compile Benchmarks
runs-on: ubuntu-latest
needs: format
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo dependencies
uses: firestoned/github-actions/rust/cache-cargo@v1.3.4
- name: Compile benchmarks (no run)
run: make bench-compile