name: Check and Test

on:
  push:
    branches:
      - main
  pull_request:

env:
  CARGO_TERM_COLOR: always
  CARGO_INCREMENTAL: 0
  SCCACHE_GHA_ENABLED: "true"
  RUSTC_WRAPPER: "sccache"

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
      - name: Set up compilation cache (sccache)
        uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
      - name: Install nextest
        uses: taiki-e/install-action@0631aa6515c7d545823c67cfae7ef4fc7f490154 # v2.81.8
        with:
          tool: nextest
      - name: Unit tests
        run: cargo ci-test
  
  lint:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
        with:
          components: clippy
      - name: Set up compilation cache (sccache)
        uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
      - name: Clippy check
        run: cargo ci-lint

  coverage:
    runs-on: ubuntu-latest
    if: github.actor != 'dependabot[bot]'
    environment: github-actions
    steps:
      - name: Checkout code
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
      - name: Set up compilation cache (sccache)
        uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
      - name: Install cargo-llvm-cov
        uses: taiki-e/install-action@0631aa6515c7d545823c67cfae7ef4fc7f490154 # v2.81.8
        with:
          tool: cargo-llvm-cov
      - name: Install nextest
        uses: taiki-e/install-action@0631aa6515c7d545823c67cfae7ef4fc7f490154 # v2.81.8
        with:
          tool: nextest
      - name: Generate coverage
        run: cargo llvm-cov nextest --features compare,simulate,profile-adjacency --no-tests=pass --lcov --output-path lcov.info
      - name: Upload to Codecov
        uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v6.0.2
        with:
          files: lcov.info
          fail_ci_if_error: true
          token: ${{ secrets.CODECOV_TOKEN }}

  format:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
        with:
          components: rustfmt
      - name: Set up compilation cache (sccache)
        uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
      - name: Rustfmt check
        run: cargo ci-fmt

  security:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
      - name: Install cargo-audit
        uses: taiki-e/install-action@0631aa6515c7d545823c67cfae7ef4fc7f490154 # v2.81.8
        with:
          tool: cargo-audit
      - name: Audit dependencies for known vulnerabilities
        run: cargo audit

  publish-dry-run:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
      - name: Set up compilation cache (sccache)
        uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
      - name: Package every workspace crate (dry-run)
        # Validates manifest health for every publishable crate: declared
        # dependency versions on path deps, include = [...] paths, features
        # referring to real deps/features, no-publish flags, etc. Uses
        # --no-verify because cargo's workspace dry-run with --verify hits
        # an internal "no hash listed" error (cargo 1.93) when a later
        # crate transitively depends on an earlier crate's freshly packaged
        # tarball. Real-CI publish doesn't hit this -- each predecessor
        # resolves from crates.io with a real hash before the next verify.
        run: cargo publish --workspace --dry-run --allow-dirty --no-verify
      - name: Simulate publish-verify for crates with default-off optional deps
        # `cargo publish --verify` compiles the packaged tarball with DEFAULT
        # features only. For crates whose default feature set does NOT enable
        # every optional dependency, that build path is not exercised by the
        # regular workspace build (other crates often enable the optional
        # feature transitively), so "optional dep used unconditionally" bugs
        # can ship unnoticed and break publish mid-release.
        #
        # Add a crate to this list whenever it gains a default-off optional
        # dep. Current members:
        #   - fgumi-raw-bam: default = [], `noodles`/`anyhow` behind feature
        run: cargo check -p fgumi-raw-bam --no-default-features --all-targets

  no-default-features-check:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
      - name: Set up compilation cache (sccache)
        uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
      - name: cargo check --workspace --no-default-features --all-targets
        # The regular test/lint jobs run with default features enabled, which
        # pulls in every optional dependency transitively. That hides two
        # classes of bug from CI:
        #   1. Optional deps used unconditionally (library behind a feature
        #      gate referenced from non-gated code).
        #   2. Modules behind a non-default feature referenced from
        #      always-compiled code.
        # Both manifest as compile failures only under
        # `default-features = false`, which is exactly what downstream
        # consumers can opt into. This job compiles every workspace crate
        # (lib + tests + benches) with no default features to surface
        # regressions at PR time.
        run: cargo check --workspace --no-default-features --all-targets
