name: CI

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

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1

jobs:
  check:
    name: Check
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install mold linker
        run: sudo apt-get install -y mold
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy, rustfmt
      - uses: Swatinem/rust-cache@v2
      - name: Format
        run: cargo fmt --check
      - name: Clippy
        run: cargo clippy --all-targets -- -D warnings
      - name: Build
        run: cargo build
      - name: Test
        run: cargo test

  deny:
    name: Deny
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: EmbarkStudios/cargo-deny-action@v2

  secrets:
    name: Secret scan
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  compliance:
    name: Compliance
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Wordlist check
        run: |
          # Fail when a word from .github/blocked-words.txt appears in tracked files.
          if git grep -nI -f .github/blocked-words.txt -- ':!.github/'; then
            echo "::error::Blocked word found."
            exit 1
          fi
      - name: Author email check
        if: github.event_name == 'pull_request'
        run: |
          # New commits must use a GitHub noreply author email.
          range="${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}"
          bad=$(git log --format='%an <%ae>' "$range" | grep -viE '@users\.noreply\.github\.com>$' || true)
          if [ -n "$bad" ]; then
            echo "::error::Commits must use a GitHub noreply author email:"
            printf '%s\n' "$bad"
            exit 1
          fi
