Update Fix #54
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| pull_request: | |
| branches: [ main, develop ] | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUST_BACKTRACE: 1 | |
| # For benchmark consistency | |
| CARGO_BUILD_JOBS: 2 | |
| RUST_TEST_THREADS: 2 | |
| jobs: | |
| # Cross-platform build and test matrix | |
| build-test: | |
| name: Build & Test (${{ matrix.os }}) | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| rust: [stable] | |
| include: | |
| - os: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| - os: macos-latest | |
| target: x86_64-apple-darwin | |
| - os: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| toolchain: ${{ matrix.rust }} | |
| targets: ${{ matrix.target }} | |
| components: rustfmt, clippy | |
| - name: Cache cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo- | |
| - name: Build (debug) | |
| run: cargo build --verbose | |
| - name: Build (release) | |
| run: cargo build --release --verbose | |
| - name: Run tests | |
| run: cargo test --workspace --verbose | |
| - name: Run tests (release mode) | |
| run: cargo test --workspace --release --verbose | |
| # Feature matrix testing | |
| feature-test: | |
| name: Feature Testing | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| features: | |
| - "" # no default features (no_std build) | |
| - "benchmark" # timing only | |
| - "collector" # collector + histogram | |
| - "metrics" # production metrics | |
| - "high-precision" # high-precision backend (collector implied) | |
| - "hdr" # external HDR backend (high-precision implied) | |
| - "metrics high-precision" # metrics + high-precision | |
| - "metrics hdr" # metrics + hdr backend | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Test feature combination | |
| run: | | |
| echo "Testing with features: ${{ matrix.features }}" | |
| if [ -z "${{ matrix.features }}" ]; then | |
| cargo test --workspace --no-default-features | |
| else | |
| cargo test --workspace --no-default-features --features "${{ matrix.features }}" | |
| fi | |
| # Optimization-level matrix to catch codegen-sensitive issues | |
| opt-matrix: | |
| name: Opt-Level Matrix | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| opt: ["0", "1", "2", "3", "s", "z"] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Test workspace (opt=${{ matrix.opt }}) | |
| env: | |
| RUSTFLAGS: -C opt-level=${{ matrix.opt }} | |
| run: | | |
| echo "RUSTFLAGS=$RUSTFLAGS" | |
| cargo test --workspace -q | |
| - name: Test workspace all-features (opt=${{ matrix.opt }}) | |
| env: | |
| RUSTFLAGS: -C opt-level=${{ matrix.opt }} | |
| run: | | |
| echo "RUSTFLAGS=$RUSTFLAGS" | |
| cargo test --workspace --all-features -q | |
| # Assembly inspection (artifacts for manual review) | |
| assembly: | |
| name: Assembly Inspection | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Build disabled (rlib) | |
| run: | | |
| cargo clean | |
| cargo build --release --lib --no-default-features | |
| cp target/release/libbenchmark.rlib libbenchmark_disabled.rlib || true | |
| - name: Build benchmark (rlib) | |
| run: | | |
| cargo clean | |
| cargo build --release --lib --features "benchmark" | |
| cp target/release/libbenchmark.rlib libbenchmark_enabled.rlib || true | |
| - name: Dump symbols and disassembly (GNU objdump) | |
| run: | | |
| set -e | |
| if command -v objdump >/dev/null 2>&1; then | |
| if [ -f libbenchmark_disabled.rlib ]; then | |
| objdump -t libbenchmark_disabled.rlib > symbols_disabled.txt || true | |
| objdump -d libbenchmark_disabled.rlib > disasm_disabled.txt || true | |
| fi | |
| if [ -f libbenchmark_enabled.rlib ]; then | |
| objdump -t libbenchmark_enabled.rlib > symbols_enabled.txt || true | |
| objdump -d libbenchmark_enabled.rlib > disasm_enabled.txt || true | |
| fi | |
| else | |
| echo "objdump not available, skipping" | |
| fi | |
| - name: Dump disassembly (LLVM objdump fallback) | |
| run: | | |
| if command -v llvm-objdump >/dev/null 2>&1; then | |
| if [ -f libbenchmark_disabled.rlib ]; then | |
| llvm-objdump -t libbenchmark_disabled.rlib > symbols_disabled_llvm.txt || true | |
| llvm-objdump -d libbenchmark_disabled.rlib > disasm_disabled_llvm.txt || true | |
| fi | |
| if [ -f libbenchmark_enabled.rlib ]; then | |
| llvm-objdump -t libbenchmark_enabled.rlib > symbols_enabled_llvm.txt || true | |
| llvm-objdump -d libbenchmark_enabled.rlib > disasm_enabled_llvm.txt || true | |
| fi | |
| else | |
| echo "llvm-objdump not available, skipping" | |
| fi | |
| - name: Upload assembly artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: assembly-artifacts | |
| path: | | |
| symbols_*.txt | |
| disasm_*.txt | |
| # Code quality checks | |
| quality: | |
| name: Code Quality | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt, clippy | |
| - name: Check formatting | |
| run: cargo fmt --all -- --check | |
| - name: Clippy analysis | |
| run: | | |
| cargo clippy --workspace --all-features --all-targets -- -D warnings | |
| cargo clippy --workspace --no-default-features --all-targets -- -D warnings | |
| # Commented out failing check | |
| # - name: Check for unused dependencies | |
| # run: | | |
| # cargo install cargo-machete | |
| # cargo machete | |
| # Security audit | |
| security: | |
| name: Security Audit | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install cargo-audit | |
| run: cargo install cargo-audit | |
| - name: Run security audit | |
| run: cargo audit | |
| # Zero-overhead verification | |
| zero-overhead: | |
| name: Zero Overhead Verification | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Build without benchmarking | |
| run: | | |
| cargo build --release --lib --no-default-features | |
| # For a library crate, check the size of the rlib file | |
| if [ -f target/release/libbenchmark.rlib ]; then | |
| mv target/release/libbenchmark.rlib target/release/libbenchmark_disabled.rlib | |
| else | |
| # Fallback: measure the target directory size | |
| du -sb target/release > disabled_size.txt | |
| fi | |
| - name: Build with benchmarking | |
| run: | | |
| cargo build --release --lib --features "benchmark" | |
| if [ -f target/release/libbenchmark.rlib ]; then | |
| mv target/release/libbenchmark.rlib target/release/libbenchmark_enabled.rlib | |
| else | |
| du -sb target/release > enabled_size.txt | |
| fi | |
| - name: Compare binary sizes | |
| run: | | |
| if [ -f target/release/libbenchmark_disabled.rlib ] && [ -f target/release/libbenchmark_enabled.rlib ]; then | |
| SIZE_DISABLED=$(stat -c%s target/release/libbenchmark_disabled.rlib 2>/dev/null || stat -f%z target/release/libbenchmark_disabled.rlib) | |
| SIZE_ENABLED=$(stat -c%s target/release/libbenchmark_enabled.rlib 2>/dev/null || stat -f%z target/release/libbenchmark_enabled.rlib) | |
| echo "Size without benchmarking: $SIZE_DISABLED bytes" | |
| echo "Size with benchmarking: $SIZE_ENABLED bytes" | |
| echo "Overhead: $((SIZE_ENABLED - SIZE_DISABLED)) bytes" | |
| else | |
| echo "Using directory size comparison as fallback" | |
| if [ -f disabled_size.txt ] && [ -f enabled_size.txt ]; then | |
| SIZE_DISABLED=$(cut -f1 disabled_size.txt) | |
| SIZE_ENABLED=$(cut -f1 enabled_size.txt) | |
| echo "Build size without benchmarking: $SIZE_DISABLED bytes" | |
| echo "Build size with benchmarking: $SIZE_ENABLED bytes" | |
| echo "Overhead: $((SIZE_ENABLED - SIZE_DISABLED)) bytes" | |
| fi | |
| fi | |
| # Documentation checks | |
| docs: | |
| name: Documentation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Check documentation | |
| env: | |
| RUSTDOCFLAGS: -D warnings | |
| run: cargo doc --workspace --all-features --no-deps | |
| - name: Test documentation examples | |
| run: cargo test --workspace --all-features --doc | |
| # Build benchmark and examples across feature modes to catch regressions | |
| build-benchmark-examples: | |
| name: Build benchmark/examples (all feature modes) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo- | |
| - name: Build default features | |
| run: | | |
| cargo build --benches -q | |
| cargo build --examples -q | |
| - name: Build all features | |
| run: | | |
| cargo build --benches --all-features -q | |
| cargo build --examples --all-features -q | |
| - name: Build no default features | |
| run: | | |
| cargo build --benches --no-default-features -q | |
| cargo build --examples --no-default-features -q | |
| # Performance benchmarks (only on main branch) | |
| benchmarks: | |
| name: Performance Benchmarks | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Run benchmarks | |
| run: | | |
| # Test zero-overhead claim | |
| echo "Testing zero-overhead when disabled..." | |
| cargo build --release --no-default-features | |
| cargo build --release --features "benchmark" | |
| # Run actual benchmarks if they exist | |
| if [ -d "benches" ]; then | |
| cargo bench --all-features -- --output-format bencher | tee output.txt | |
| else | |
| echo "No benchmarks found, skipping..." | |
| fi | |
| - name: Check benchmark results | |
| if: github.event_name == 'pull_request' | |
| run: | | |
| # TODO: Add regression detection once baselines are established | |
| echo "Benchmark results would be compared here" | |
| # Memory safety checks with Miri (nightly) | |
| miri: | |
| name: Miri (Memory Safety) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install Rust nightly with Miri | |
| uses: dtolnay/rust-toolchain@nightly | |
| with: | |
| components: miri | |
| - name: Setup Miri | |
| run: cargo miri setup | |
| - name: Run Miri tests | |
| run: cargo miri test --test miri_ub --features "std" | |
| env: | |
| MIRIFLAGS: -Zmiri-strict-provenance -Zmiri-symbolic-alignment-check | |
| # Minimum Supported Rust Version check | |
| msrv: | |
| name: MSRV Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install MSRV Rust (retry) | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| MSRV=1.75.0 | |
| echo "Installing Rust $MSRV with retry..." | |
| for attempt in 1 2 3; do | |
| if rustup toolchain install "$MSRV" -c rustfmt -c clippy; then | |
| break | |
| fi | |
| echo "rustup install attempt $attempt failed; retrying after backoff..." | |
| sleep $((10 * attempt)) | |
| done | |
| rustup default "$MSRV" | |
| rustc --version | |
| # Regenerate Cargo.lock to ensure compatibility | |
| - name: Delete existing Cargo.lock | |
| run: rm -f Cargo.lock | |
| - name: Regenerate Cargo.lock with MSRV | |
| run: cargo generate-lockfile | |
| - name: Check MSRV compatibility (lib only, no default features) | |
| run: cargo check --lib --no-default-features | |
| - name: Check MSRV compatibility (lib with metrics) | |
| run: cargo check --lib --no-default-features --features "metrics" | |
| - name: Check MSRV compatibility (HDR backend) | |
| run: cargo check --lib --no-default-features --features "hdr" |