# This workflow runs all workflows to check, build and test the project on
# various Linux flavors, as well as on MacOS and Windows, on every push to a
# user branch. However, it will not run if the pull request is a draft unless it
# has the 'DraftRunCI' label.
name: PR

on:
  merge_group:
    types:
      - checks_requested
  pull_request:
    types:
      - opened
      - reopened
      - synchronize
      - ready_for_review

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

defaults:
  run:
    shell: bash

jobs:
  # This job determines whether the rest of the workflow should run. It runs
  # when the PR is not a draft (which should also cover merge-group) or
  # has the 'DraftRunCI' label.
  should-run:
    if: ${{ !github.event.pull_request.draft || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
      - name: Determine changed files
        # This step checks whether any files have changed that should
        # cause the next jobs to run. We do it this way rather than
        # using `paths` in the `on:` section, because all required
        # checks must pass, even for changes that do not modify anything
        # that affects those checks. We would therefore like to make the
        # checks required only if the job runs, but GitHub does not
        # support that directly. By always executing the workflow on new
        # commits and by using the changed-files action below, we ensure
        # that Github considers any skipped jobs to have passed, and in
        # turn the required checks as well.
        id: changes
        uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
        with:
          files: |
            # These paths are unique to `on-pr.yml`.
            .github/scripts/levelization/**
            .github/workflows/reusable-check-levelization.yml
            .github/workflows/reusable-notify-clio.yml
            .github/workflows/on-pr.yml

            # Keep the paths below in sync with those in `on-trigger.yml`.
            .github/actions/build-deps/**
            .github/actions/build-test/**
            .github/actions/setup-conan/**
            .github/scripts/strategy-matrix/**
            .github/workflows/reusable-build.yml
            .github/workflows/reusable-build-test-config.yml
            .github/workflows/reusable-build-test.yml
            .github/workflows/reusable-strategy-matrix.yml
            .github/workflows/reusable-test.yml
            .codecov.yml
            cmake/**
            conan/**
            external/**
            include/**
            src/**
            tests/**
            CMakeLists.txt
            conanfile.py
            conan.lock
      - name: Check whether to run
        # This step determines whether the rest of the workflow should
        # run. The rest of the workflow will run if this job runs AND at
        # least one of:
        # * Any of the files checked in the `changes` step were modified
        # * The PR is NOT a draft and is labeled "Ready to merge"
        # * The workflow is running from the merge queue
        id: go
        env:
          FILES: ${{ steps.changes.outputs.any_changed }}
          DRAFT: ${{ github.event.pull_request.draft }}
          READY: ${{ contains(github.event.pull_request.labels.*.name, 'Ready to merge') }}
          MERGE: ${{ github.event_name == 'merge_group' }}
        run: |
          echo "go=${{ (env.DRAFT != 'true' && env.READY == 'true') || env.FILES == 'true' || env.MERGE == 'true' }}" >> "${GITHUB_OUTPUT}"
          cat "${GITHUB_OUTPUT}"
    outputs:
      go: ${{ steps.go.outputs.go == 'true' }}

  check-levelization:
    needs: should-run
    if: ${{ needs.should-run.outputs.go == 'true' }}
    uses: ./.github/workflows/reusable-check-levelization.yml

  build-test:
    needs: should-run
    if: ${{ needs.should-run.outputs.go == 'true' }}
    uses: ./.github/workflows/reusable-build-test.yml
    strategy:
      fail-fast: false
      matrix:
        os: [linux, macos, windows]
    with:
      os: ${{ matrix.os }}
    secrets:
      CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

  notify-clio:
    needs:
      - should-run
      - build-test
    if: ${{ needs.should-run.outputs.go == 'true' && contains(fromJSON('["release", "master"]'), github.ref_name) }}
    uses: ./.github/workflows/reusable-notify-clio.yml
    secrets:
      clio_notify_token: ${{ secrets.CLIO_NOTIFY_TOKEN }}
      conan_remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
      conan_remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}

  passed:
    if: failure() || cancelled()
    needs:
      - build-test
      - check-levelization
    runs-on: ubuntu-latest
    steps:
      - name: Fail
        run: false
