name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

env:
  # Use the same Rust toolchain across jobs so they can share a cache.
  toolchain: nightly-2026-01-22

jobs:
  # Run tests.
  test:
    name: Tests
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@master
        with:
          components: rustc-codegen-cranelift-preview
          toolchain: ${{ env.toolchain }}

      - name: Set LD_LIBRARY_PATH
        run: |
          echo "LD_LIBRARY_PATH=$(rustc --print target-libdir)" >> $GITHUB_ENV

      - name: Populate target directory from cache
        uses: Swatinem/rust-cache@v2
        with:
          save-if: ${{ github.ref == 'refs/heads/main' }}
          cache-directories: ${{ env.LD_LIBRARY_PATH }}

      - name: Install dependencies
        run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev

      - name: Activate CI cargo config
        run: mv .cargo/config_ci.toml .cargo/config.toml

      - name: Install cargo binstall
        uses: cargo-bins/cargo-binstall@main

      - name: Install Wild
        run: cargo binstall wild-linker --locked --force

      - name: Install nextest
        run: cargo binstall cargo-nextest --locked --force

      - name: Run tests
        run: cargo nextest run --locked --workspace --all-targets --no-fail-fast --no-tests warn

      - name: Run doctests
        run: cargo test --locked --workspace --doc
        continue-on-error: true

  # Run clippy lints.
  clippy:
    name: Clippy
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@master
        with:
          components: clippy, rustc-codegen-cranelift-preview
          toolchain: ${{ env.toolchain }}

      - name: Set LD_LIBRARY_PATH
        run: echo "LD_LIBRARY_PATH=$(rustc --print target-libdir)" >> $GITHUB_ENV

      - name: Activate CI cargo config
        run: mv .cargo/config_ci.toml .cargo/config.toml

      - name: Install cargo binstall
        uses: cargo-bins/cargo-binstall@main

      - name: Install Wild
        run: cargo binstall wild-linker --locked --force

      - name: Install dependencies
        run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev

      - name: Populate target directory from cache
        uses: Swatinem/rust-cache@v2
        with:
          save-if: false
          shared-key: lints

      - name: Run clippy lints
        run: cargo clippy --locked --workspace --all-targets -- --deny warnings

  # Check formatting.
  format:
    name: Format
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@master
        with:
          components: rustfmt
          toolchain: ${{ env.toolchain }}

      - name: Run cargo fmt
        run: cargo fmt --all -- --check

  # Check documentation.
  doc:
    name: Docs
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@master
        with:
          components: rustc-codegen-cranelift-preview
          toolchain: ${{ env.toolchain }}

      - name: Set LD_LIBRARY_PATH
        run: echo "LD_LIBRARY_PATH=$(rustc --print target-libdir)" >> $GITHUB_ENV

      - name: Activate CI cargo config
        run: mv .cargo/config_ci.toml .cargo/config.toml

      - name: Install cargo binstall
        uses: cargo-bins/cargo-binstall@main

      - name: Install Wild
        run: cargo binstall wild-linker --locked --force

      - name: Install dependencies
        run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev

      - name: Populate target directory from cache
        uses: Swatinem/rust-cache@v2
        with:
          save-if: false
          shared-key: lints

      - name: Check documentation
        run: cargo doc --locked --workspace --document-private-items --no-deps
