name: PR Checks

on:
  push:
  pull_request:
    # Run checks on reopened draft PRs to support triggering PR checks on draft PRs that were opened
    # by other workflows.
    types: [opened, synchronize, reopened, ready_for_review]
  workflow_dispatch:

defaults:
  run:
    shell: bash

jobs:
  unit-tests:
    name: Unit Tests
    if: github.triggering_actor != 'dependabot[bot]'
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        node-version: [20, 24]
    permissions:
      contents: read
      security-events: write # needed to upload ESLint results
    runs-on: ${{ matrix.os }}
    timeout-minutes: 45

    steps:
      - name: Prepare git (Windows)
        if: runner.os == 'Windows'
        run: git config --global core.autocrlf false

      - uses: actions/checkout@v6

      - name: Set up Node.js
        uses: actions/setup-node@v6
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: 3.11

      - name: Install dependencies
        run: |
          # Use the system Bash shell to ensure we can run commands like `npm ci`
          # that are not available in the default shell on Windows.
          npm config set script-shell bash
          npm ci

      - name: Verify compiled JS up to date
        run: .github/workflows/script/check-js.sh

      - name: Verify PR checks up to date
        if: always()
        run: .github/workflows/script/verify-pr-checks.sh

      - name: Run unit tests
        if: always()
        run: npm test

      - name: Run pr-checks tests
        if: always()
        working-directory: pr-checks
        run: python -m unittest discover

      - name: Lint
        if: always() && matrix.os != 'windows-latest'
        run: npm run lint-ci

      - name: Upload sarif
        uses: github/codeql-action/upload-sarif@v4
        if: matrix.os == 'ubuntu-latest' && matrix.node-version == 24
        with:
          sarif_file: eslint.sarif
          category: eslint

  check-node-version:
    if: github.event.pull_request && github.triggering_actor != 'dependabot[bot]'
    name: Check Action Node versions
    runs-on: ubuntu-latest
    timeout-minutes: 45
    env:
      BASE_REF: ${{ github.base_ref }}

    permissions:
      contents: read

    steps:
      - uses: actions/checkout@v6
      - id: head-version
        name: Verify all Actions use the same Node version
        run: |
          NODE_VERSION=$(find . -name "action.yml" -exec yq -e '.runs.using' {} \; | grep node | sort | uniq)
          echo "NODE_VERSION: ${NODE_VERSION}"
          if [[ $(echo "$NODE_VERSION" | wc -l) -gt 1 ]]; then
            echo "::error::More than one node version used in 'action.yml' files."
            exit 1
          fi
          echo "node_version=${NODE_VERSION}" >> $GITHUB_OUTPUT

      - id: checkout-base
        name: 'Backport: Check out base ref'
        if: ${{ startsWith(github.head_ref, 'backport-') }}
        uses: actions/checkout@v6
        with:
          ref: ${{ env.BASE_REF }}

      - name: 'Backport: Verify Node versions unchanged'
        if: steps.checkout-base.outcome == 'success'
        env:
          HEAD_VERSION: ${{ steps.head-version.outputs.node_version }}
        run: |
          BASE_VERSION=$(find . -name "action.yml" -exec yq -e '.runs.using' {} \; | grep node | sort | uniq)
          echo "HEAD_VERSION: ${HEAD_VERSION}"
          echo "BASE_VERSION: ${BASE_VERSION}"
          if [[ "$BASE_VERSION" != "$HEAD_VERSION" ]]; then
            echo "::error::Cannot change the Node version of an Action in a backport PR."
            exit 1
          fi
