diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 69c45e8..c1e3a36 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,202 +6,203 @@ name: CI on: - push: - branches: [main, develop] - pull_request: - branches: [main] - schedule: - # Run every Monday at 2:00 AM UTC to catch dependency issues early - - cron: "0 2 * * 1" + push: + branches: [main, develop] + pull_request: + branches: [main] + schedule: + # Run every Monday at 2:00 AM UTC to catch dependency issues early + - cron: "0 2 * * 1" env: - CARGO_TERM_COLOR: always - RUST_BACKTRACE: 1 - # Minimum supported Rust version - MSRV: "1.90.0" + CARGO_TERM_COLOR: always + RUST_BACKTRACE: 1 + # Minimum supported Rust version + MSRV: "1.90.0" # Cancel in-progress runs for the same branch concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: - # ========================================================================== - # Formatting check (fast, run first) - # ========================================================================== - fmt: - name: Rustfmt - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@nightly - with: - components: rustfmt - - name: Check formatting - run: cargo fmt --all -- --check - - # ========================================================================== - # Clippy linting - # ========================================================================== - clippy: - name: Clippy - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - with: - components: clippy - - uses: Swatinem/rust-cache@v2 - - name: Run Clippy - run: cargo clippy --all-targets --all-features -- -D warnings - - # ========================================================================== - # Test matrix across OS and Rust versions - # ========================================================================== - test: - name: Test (${{ matrix.os }}, ${{ matrix.rust }}) - runs-on: ${{ matrix.os }} - needs: [fmt] - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - rust: [stable, beta] - include: - # MSRV check on Ubuntu only - - os: ubuntu-latest - rust: "1.90.0" - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust }} - - uses: Swatinem/rust-cache@v2 - with: - key: ${{ matrix.os }}-${{ matrix.rust }} - - - name: Build - run: cargo build --all-features - - - name: Run unit tests - run: cargo test --lib --all-features - - - name: Run doc tests - run: cargo test --doc --all-features - - # ========================================================================== - # Integration tests (requires Docker for testcontainers) - # ========================================================================== - integration: - name: Integration Tests - runs-on: ubuntu-latest - needs: [fmt, clippy] - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - - - name: Run integration tests - run: cargo test --test '*' --all-features - env: - # Testcontainers will pull and run Iggy server automatically - TESTCONTAINERS: true - - # ========================================================================== - # Code coverage - # ========================================================================== - coverage: - name: Code Coverage - runs-on: ubuntu-latest - needs: [test] - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - with: - components: llvm-tools-preview - - uses: Swatinem/rust-cache@v2 - - - name: Install cargo-llvm-cov - uses: taiki-e/install-action@cargo-llvm-cov - - - name: Generate coverage report - run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 - with: - files: lcov.info - fail_ci_if_error: false - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - - # ========================================================================== - # Documentation build - # ========================================================================== - docs: - name: Documentation - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - - - name: Build documentation - run: cargo doc --no-deps --all-features - env: - RUSTDOCFLAGS: -D warnings - - # ========================================================================== - # Security audit - # ========================================================================== - audit: - name: Security Audit - runs-on: ubuntu-latest - permissions: - checks: write - contents: read - steps: - - uses: actions/checkout@v4 - - uses: rustsec/audit-check@v2 - with: - token: ${{ secrets.GITHUB_TOKEN }} - - # ========================================================================== - # Dependency license check - # ========================================================================== - licenses: - name: License Check - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - - - name: Install cargo-deny - uses: taiki-e/install-action@cargo-deny - - - name: Check licenses - run: cargo deny check licenses - continue-on-error: true # Don't fail CI on license issues, just warn - - # ========================================================================== - # Final status check (for branch protection) - # ========================================================================== - ci-success: - name: CI Success - runs-on: ubuntu-latest - needs: [fmt, clippy, test, integration, docs, audit] - if: always() - steps: - - name: Check all jobs passed - run: | - if [[ "${{ needs.fmt.result }}" != "success" ]] || \ - [[ "${{ needs.clippy.result }}" != "success" ]] || \ - [[ "${{ needs.test.result }}" != "success" ]] || \ - [[ "${{ needs.integration.result }}" != "success" ]] || \ - [[ "${{ needs.docs.result }}" != "success" ]] || \ - [[ "${{ needs.audit.result }}" != "success" ]]; then - echo "One or more jobs failed" - exit 1 - fi - echo "All CI checks passed!" + # ========================================================================== + # Formatting check (fast, run first) + # ========================================================================== + fmt: + name: Rustfmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + with: + components: rustfmt + - name: Check formatting + run: cargo fmt --all -- --check + + # ========================================================================== + # Clippy linting + # ========================================================================== + clippy: + name: Clippy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + components: clippy + - uses: Swatinem/rust-cache@v2 + - name: Run Clippy + run: cargo clippy --all-targets --all-features -- -D warnings + + # ========================================================================== + # Test matrix across OS and Rust versions + # ========================================================================== + test: + name: Test (${{ matrix.os }}, ${{ matrix.rust }}) + runs-on: ${{ matrix.os }} + needs: [fmt] + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + rust: [stable, beta] + include: + # MSRV check on Ubuntu only + - os: ubuntu-latest + rust: "1.90.0" + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust }} + - uses: Swatinem/rust-cache@v2 + with: + key: ${{ matrix.os }}-${{ matrix.rust }} + + - name: Build + run: cargo build --all-features + + - name: Run unit tests + run: cargo test --lib --all-features + + - name: Run doc tests + run: cargo test --doc --all-features + + # ========================================================================== + # Integration tests (requires Docker for testcontainers) + # ========================================================================== + integration: + name: Integration Tests + runs-on: ubuntu-latest + needs: [fmt, clippy] + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + + - name: Run integration tests + run: cargo test --test '*' --all-features + env: + # Testcontainers will pull and run Iggy server automatically + TESTCONTAINERS: true + + # ========================================================================== + # Code coverage + # ========================================================================== + coverage: + name: Code Coverage + runs-on: ubuntu-latest + needs: [test] + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + components: llvm-tools-preview + - uses: Swatinem/rust-cache@v2 + + - name: Install cargo-llvm-cov + uses: taiki-e/install-action@cargo-llvm-cov + + - name: Generate coverage report + run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4 + with: + files: lcov.info + fail_ci_if_error: false + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + # ========================================================================== + # Documentation build + # ========================================================================== + docs: + name: Documentation + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + + - name: Build documentation + run: cargo doc --no-deps --all-features + env: + RUSTDOCFLAGS: -D warnings + + # ========================================================================== + # Security audit + # ========================================================================== + audit: + name: Security Audit + runs-on: ubuntu-latest + permissions: + checks: write + contents: read + issues: write + steps: + - uses: actions/checkout@v4 + - uses: rustsec/audit-check@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + # ========================================================================== + # Dependency license check + # ========================================================================== + licenses: + name: License Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + + - name: Install cargo-deny + uses: taiki-e/install-action@cargo-deny + + - name: Check licenses + run: cargo deny check licenses + continue-on-error: true # Don't fail CI on license issues, just warn + + # ========================================================================== + # Final status check (for branch protection) + # ========================================================================== + ci-success: + name: CI Success + runs-on: ubuntu-latest + needs: [fmt, clippy, test, integration, docs, audit] + if: always() + steps: + - name: Check all jobs passed + run: | + if [[ "${{ needs.fmt.result }}" != "success" ]] || \ + [[ "${{ needs.clippy.result }}" != "success" ]] || \ + [[ "${{ needs.test.result }}" != "success" ]] || \ + [[ "${{ needs.integration.result }}" != "success" ]] || \ + [[ "${{ needs.docs.result }}" != "success" ]] || \ + [[ "${{ needs.audit.result }}" != "success" ]]; then + echo "One or more jobs failed" + exit 1 + fi + echo "All CI checks passed!" diff --git a/CHANGELOG.md b/CHANGELOG.md index bdb4084..d885c2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated `docker-compose.yaml` with full observability stack configuration - Simplified documentation section in README.md to reference `docs/` directory +### Fixed + +- Added `issues: write` permission to CI security audit job to allow creating advisory issues + +### Security + +- Ignored unmaintained transitive dependency advisories in `deny.toml`: + - `RUSTSEC-2024-0384` (instant): from iggy -> reqwest-retry -> parking_lot v0.11 + - `RUSTSEC-2025-0134` (rustls-pemfile): from testcontainers -> bollard (dev-dep only) + ## [0.1.0] - 2024-12-01 ### Added diff --git a/deny.toml b/deny.toml index 071a9b1..1bc6ccc 100644 --- a/deny.toml +++ b/deny.toml @@ -80,8 +80,17 @@ unmaintained = "warn" # Lint level for yanked crates yanked = "warn" -# Ignore specific advisories (add IDs if needed) -ignore = [] +# Ignore specific advisories +# These are transitive dependencies we cannot directly update +ignore = [ + # instant is unmaintained, but comes from iggy -> reqwest-retry -> parking_lot v0.11.2 + # Upstream needs to update parking_lot to v0.12+ + "RUSTSEC-2024-0384", + + # rustls-pemfile is unmaintained, but comes from testcontainers -> bollard (dev-dependency only) + # Upstream needs to migrate to rustls-pki-types + "RUSTSEC-2025-0134", +] # ============================================================================= # Sources