name: Utoipa build

on:
  push:
    paths:
      - "**.rs"
      - "**Cargo.toml"
  pull_request:
    branches: [master]
    paths:
      - "**.rs"
      - "**Cargo.toml"
env:
  CARGO_TERM_COLOR: always

jobs:
  test:
    strategy:
      matrix:
        crate:
          - utoipa
          - utoipa-gen
          - utoipa-swagger-ui-vendored
          - utoipa-swagger-ui
          - utoipa-redoc
          - utoipa-rapidoc
          - utoipa-scalar
          - utoipa-axum
          - utoipa-config
          - utoipa-actix-web
      fail-fast: true
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 2

      - uses: actions/cache@v3
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            target/
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

      - name: Resolve changed paths
        id: changes
        run: |
          if [[ $GITHUB_EVENT_NAME != "pull_request" ]]; then
            echo "changes=true" >> $GITHUB_OUTPUT
            exit 0
          fi
          changes=false
          while read -r change; do
            if [[ "$change" == "utoipa-gen" && "${{ matrix.crate }}" == "utoipa-gen" && $changes == false ]]; then
              changes=true
            elif [[ "$change" == "utoipa-swagger-ui-vendored" && "${{ matrix.crate }}" == "utoipa-swagger-ui-vendored" && $changes == false ]]; then
              changes=true
            elif [[ "$change" == "utoipa-swagger-ui" && "${{ matrix.crate }}" == "utoipa-swagger-ui" && $changes == false ]]; then
              changes=true
            elif [[ "$change" == "utoipa" && "${{ matrix.crate }}" == "utoipa" && $changes == false ]]; then
              changes=true
            elif [[ "$change" == "utoipa-redoc" && "${{ matrix.crate }}" == "utoipa-redoc" && $changes == false ]]; then
              changes=true
            elif [[ "$change" == "utoipa-rapidoc" && "${{ matrix.crate }}" == "utoipa-rapidoc" && $changes == false ]]; then
              changes=true
            elif [[ "$change" == "utoipa-scalar" && "${{ matrix.crate }}" == "utoipa-scalar" && $changes == false ]]; then
              changes=true
            elif [[ "$change" == "utoipa-axum" && "${{ matrix.crate }}" == "utoipa-axum" && $changes == false ]]; then
              changes=true
            elif [[ "$change" == "utoipa-config" && "${{ matrix.crate }}" == "utoipa-config" && $changes == false ]]; then
              changes=true
            elif [[ "$change" == "utoipa-actix-web" && "${{ matrix.crate }}" == "utoipa-actix-web" && $changes == false ]]; then
              changes=true
            fi
          done < <(git diff --name-only ${{ github.sha }}~ ${{ github.sha }} | grep .rs | awk -F \/ '{print $1}')
          echo "${{ matrix.crate }} changes: $changes"
          echo "changes=$changes" >> $GITHUB_OUTPUT

      - name: Check format
        run: |
          if [[ ${{ steps.changes.outputs.changes }} == true ]]; then
            cargo fmt --check --package ${{ matrix.crate }}
          fi

      - name: Check clippy
        run: |
          if [[ ${{ steps.changes.outputs.changes }} == true ]]; then
            cargo clippy --quiet --package ${{ matrix.crate }}
          fi

      - name: Run tests
        run: |
          if [[ ${{ steps.changes.outputs.changes }} == true ]]; then
            ./scripts/test.sh ${{ matrix.crate }}
          fi

  check-typos:
    name: typos
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: taiki-e/install-action@v2
        with:
          tool: typos
      - run: typos

  test-examples-compile:
    name: "test (examples)"
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 2

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

      - name: Install nightly Rust
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: nightly
          components: clippy, rustfmt

      - uses: actions/cache@v3
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            examples/**/target/
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}_examples

      - name: Test that examples compile
        run: |
          ./scripts/validate-examples.sh