name: Rust

permissions:
  contents: read

env:
  CACHE_VERSION: 0

  CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
  CARGO_TERM_COLOR: always

  RUST_BACKTRACE: full

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

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
  rust-checks:
    permissions:
      actions: write
    name: Task cargo ${{ matrix.action }}
    runs-on: ubuntu-latest

    strategy:
      matrix:
        action: [clippy, fmt, nextest]

    steps:
      - name: Fetch latest code
        uses: actions/checkout@v6

      - name: Setup build environment
        if: matrix.action != 'fmt'
        run: rustup show

      - name: Cache cargo target
        if: matrix.action != 'fmt'
        uses: Swatinem/rust-cache@v2
        with:
          prefix-key: ${{ env.CACHE_VERSION }}
          key: ${{ matrix.action }}

      - name: Cargo clippy
        if: matrix.action == 'clippy'
        uses: giraffate/clippy-action@v1
        with:
          clippy_flags: --workspace --all-features --all-targets --locked -- -Dwarnings

      - name: Cargo fmt
        if: matrix.action == 'fmt'
        run: |
          rustup toolchain install nightly
          rustup component add rustfmt --toolchain nightly
          cargo +nightly fmt --all -- --check

      - name: Install cargo-nextest
        if: matrix.action == 'nextest'
        uses: taiki-e/install-action@nextest

      - name: Cargo nextest
        if: matrix.action == 'nextest'
        run: |
          cargo nextest run --no-tests pass --cargo-profile ci-dev --workspace --all-features --all-targets --locked
