name: Cloud Hypervisor Quality Checks
on: [pull_request, create]

jobs:
  build:
    if: github.event_name == 'pull_request'
    name: Quality (clippy, rustfmt)
    runs-on: ubuntu-latest
    continue-on-error: ${{ matrix.experimental }}
    strategy:
      fail-fast: false
      matrix:
        rust:
          - stable
        target:
          - aarch64-unknown-linux-gnu
          - aarch64-unknown-linux-musl
          - x86_64-unknown-linux-gnu
          - x86_64-unknown-linux-musl

        experimental: [false]
        include:
          - rust: beta
            target: aarch64-unknown-linux-gnu
            experimental: true
          - rust: beta
            target: aarch64-unknown-linux-musl
            experimental: true
          - rust: beta
            target: x86_64-unknown-linux-gnu
            experimental: true
          - rust: beta
            target: x86_64-unknown-linux-musl
            experimental: true
    steps:
      - name: Code checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Install Rust toolchain (${{ matrix.rust }})
        uses: actions-rs/toolchain@v1
        with:
          toolchain: ${{ matrix.rust }}
          target: ${{ matrix.target }}
          override: true
          components: rustfmt, clippy

      - name: Debug Check (default features)
        if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }}
        run: |
          set -e
          commits=$(git rev-list origin/${{ github.base_ref }}..${{ github.sha }})
          for commit in $commits; do git checkout $commit; cargo check --tests --examples --all --target=${{ matrix.target }}; done
          git checkout ${{ github.sha }}

      - name: Formatting (rustfmt)
        run: cargo fmt -- --check

      - name: Clippy (kvm)
        uses: actions-rs/cargo@v1
        with:
          use-cross: ${{ matrix.target != 'x86_64-unknown-linux-gnu' }}
          command: clippy
          args: --target=${{ matrix.target }} --locked --all --all-targets --no-default-features --tests --examples --features "kvm" -- -D warnings -D clippy::undocumented_unsafe_blocks

      - name: Clippy (default features)
        uses: actions-rs/cargo@v1
        with:
          use-cross: ${{ matrix.target != 'x86_64-unknown-linux-gnu' }}
          command: clippy
          args: --target=${{ matrix.target }} --locked --all --all-targets --tests --examples -- -D warnings -D clippy::undocumented_unsafe_blocks

      - name: Clippy (default features + guest_debug)
        uses: actions-rs/cargo@v1
        with:
          use-cross: ${{ matrix.target != 'x86_64-unknown-linux-gnu' }}
          command: clippy
          args: --target=${{ matrix.target }} --locked --all --all-targets --tests --examples --features "guest_debug" -- -D warnings -D clippy::undocumented_unsafe_blocks

      - name: Clippy (default features + tracing)
        uses: actions-rs/cargo@v1
        with:
          use-cross: ${{ matrix.target != 'x86_64-unknown-linux-gnu' }}
          command: clippy
          args: --target=${{ matrix.target }} --locked --all --all-targets --tests --examples --features "tracing" -- -D warnings -D clippy::undocumented_unsafe_blocks

      - name: Clippy (mshv)
        if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }}
        uses: actions-rs/cargo@v1
        with:
          use-cross: ${{ matrix.target != 'x86_64-unknown-linux-gnu' }}
          command: clippy
          args: --target=${{ matrix.target }} --locked --all --all-targets --no-default-features --tests --examples --features "mshv" -- -D warnings -D clippy::undocumented_unsafe_blocks

      - name: Clippy (mshv + kvm)
        if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }}
        uses: actions-rs/cargo@v1
        with:
          use-cross: ${{ matrix.target != 'x86_64-unknown-linux-gnu' }}
          command: clippy
          args: --target=${{ matrix.target }} --locked --all --all-targets --no-default-features --tests --examples --features "mshv,kvm" -- -D warnings -D clippy::undocumented_unsafe_blocks

      - name: Clippy (sev_snp)
        if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }}
        uses: actions-rs/cargo@v1
        with:
          use-cross: ${{ matrix.target != 'x86_64-unknown-linux-gnu' }}
          command: clippy
          args: --target=${{ matrix.target }} --locked --all --all-targets --no-default-features --tests --examples --features "sev_snp" -- -D warnings -D clippy::undocumented_unsafe_blocks

      - name: Clippy (igvm)
        if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }}
        uses: actions-rs/cargo@v1
        with:
          use-cross: ${{ matrix.target != 'x86_64-unknown-linux-gnu' }}
          command: clippy
          args: --target=${{ matrix.target }} --locked --all --all-targets --no-default-features --tests --examples --features "igvm" -- -D warnings -D clippy::undocumented_unsafe_blocks

      - name: Clippy (kvm + tdx)
        if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }}
        uses: actions-rs/cargo@v1
        with:
          use-cross: ${{ matrix.target != 'x86_64-unknown-linux-gnu' }}
          command: clippy
          args: --target=${{ matrix.target }} --locked --all --all-targets --no-default-features --tests --examples --features "tdx,kvm" -- -D warnings -D clippy::undocumented_unsafe_blocks

      - name: Check build did not modify any files
        run: test -z "$(git status --porcelain)"

  typos:
    if: github.event_name == 'pull_request'
    name: Typos / Spellcheck
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      # Executes "typos ."
      - uses: crate-ci/typos@v1.16.11
