name: CI

on:
  pull_request:
  push:
    branches:
      - main
      - release/**
  workflow_dispatch:

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  CARGO_TERM_COLOR: always

jobs:
  stable-quality:
    runs-on: ubuntu-latest
    timeout-minutes: 25
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install Rust (stable)
        uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy

      - name: Cache cargo
        uses: Swatinem/rust-cache@v2
        with:
          shared-key: ci-${{ runner.os }}-stable
          save-if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) }}

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

      - name: Lint
        run: cargo clippy --all-targets --all-features --locked -- -D warnings

      - name: Minimal feature build check
        run: cargo check --no-default-features --locked

      - name: Unit tests
        run: cargo test --lib --locked

      - name: Public API snapshot
        run: cargo test --test public_api_snapshot_test --locked

      - name: Public API offline contract
        run: cargo test --test public_api_offline_test --locked -- --test-threads=1

      - name: Binary tests
        run: cargo test --bin fx_fetcher --locked

      - name: Doc tests
        run: cargo test --doc --locked

  compatibility:
    runs-on: ubuntu-latest
    timeout-minutes: 20
    strategy:
      fail-fast: false
      matrix:
        toolchain: [beta, "1.83.0"]
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install Rust (${{ matrix.toolchain }})
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: ${{ matrix.toolchain }}

      - name: Cache cargo
        uses: Swatinem/rust-cache@v2
        with:
          shared-key: ci-${{ runner.os }}-${{ matrix.toolchain }}
          save-if: ${{ github.event_name == 'push' }}

      - name: Build check
        run: cargo check --all-targets --all-features --locked

  supply-chain:
    runs-on: ubuntu-latest
    timeout-minutes: 20
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install Rust (stable)
        uses: dtolnay/rust-toolchain@stable

      - name: Cache cargo
        uses: Swatinem/rust-cache@v2
        with:
          shared-key: ci-${{ runner.os }}-supply-chain
          save-if: ${{ github.event_name == 'push' }}

      - name: Install cargo-audit and cargo-deny
        uses: taiki-e/install-action@v2
        with:
          tool: cargo-audit,cargo-deny
          fallback: none

      - name: Cargo audit (non-blocking)
        run: cargo audit || echo "::warning title=cargo-audit::advisories found (non-blocking)"

      - name: Cargo deny
        run: cargo deny --all-features check
