name: CI

on:
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
    branches: # Target branches
      - master

# default token permissions = none
permissions: {}

# If a new push is made to the branch, cancel the previous run
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:

  lint-commits:
    # condition: Execute IFF it is protected branch update, or a PR that is NOT in a draft state
    if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.draft }}
    runs-on: ubuntu-latest
    steps:
      - name: Setup | Checkout Repository
        uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8  # v6.0.1
        with:
          fetch-depth: 0

      - name: Lint | Commit Messages
        uses: wagoid/commitlint-github-action@b948419dd99f3fd78a6548d48f94e3df7f6bf3ed  # v6.2.1


  eval-changes:
    name: Evaluate changes
    # condition: Execute IFF it is protected branch update, or a PR that is NOT in a draft state
    if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.draft }}
    runs-on: ubuntu-latest

    steps:
      - name: Setup | Checkout Repository
        uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8  # v6.0.1
        with:
          fetch-depth: 0

      - name: Evaluate | Check common file types for changes
        id: core-changed-files
        uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891  #v47.0.1
        with:
          files_yaml_from_source_file: .github/changed-files-spec.yml

      - name: Evaluate | Check specific file types for changes
        id: ci-changed-files
        uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891  #v47.0.1
        with:
          files_yaml: |
            ci:
              - .github/workflows/ci.yml
              - .github/workflows/validate.yml

      - name: Evaluate | Detect if any of the combinations of file sets have changed
        id: all-changes
        run: |
          printf '%s\n' "any_changed=false" >> $GITHUB_OUTPUT
          if [ "${{ steps.core-changed-files.outputs.build_any_changed }}" == "true" ] || \
             [ "${{ steps.ci-changed-files.outputs.ci_any_changed }}" == "true" ] || \
             [ "${{ steps.core-changed-files.outputs.docs_any_changed }}" == "true" ] || \
             [ "${{ steps.core-changed-files.outputs.src_any_changed }}" == "true" ] || \
             [ "${{ steps.core-changed-files.outputs.tests_any_changed }}" == "true" ] || \
             [ "${{ steps.core-changed-files.outputs.gha_src_any_changed }}" == "true" ] || \
             [ "${{ steps.core-changed-files.outputs.gha_tests_any_changed }}" == "true" ]; then
              printf '%s\n' "any_changed=true" >> $GITHUB_OUTPUT
          fi

    outputs:
      # essentially casts the string output to a boolean for GitHub
      any-file-changes: ${{ steps.all-changes.outputs.any_changed }}
      build-changes: ${{ steps.core-changed-files.outputs.build_any_changed }}
      ci-changes: ${{ steps.ci-changed-files.outputs.ci_any_changed }}
      doc-changes: ${{ steps.core-changed-files.outputs.docs_any_changed }}
      src-changes: ${{ steps.core-changed-files.outputs.src_any_changed }}
      test-changes: ${{ steps.core-changed-files.outputs.tests_any_changed }}
      gha-src-changes: ${{ steps.core-changed-files.outputs.gha_src_any_changed }}
      gha-test-changes: ${{ steps.core-changed-files.outputs.gha_tests_any_changed }}


  validate:
    needs: eval-changes
    uses: ./.github/workflows/validate.yml
    with:
      # It was a bit of overkill before testing every minor version, and since this project is all about
      # SemVer, we should expect Python to adhere to that model to. Therefore Only test across 2 OS's but
      # the lowest supported minor version and the latest stable minor version (just in case).
      python-versions-linux: '["3.8", "3.14"]'
      # Since the test suite takes ~4 minutes to complete on windows, and windows is billed higher
      # we are only going to run it on the oldest version of python we support. The older version
      # will be the most likely area to fail as newer minor versions maintain compatibility.
      python-versions-windows: '["3.8"]'
      files-changed: ${{ needs.eval-changes.outputs.any-file-changes }}
      build-files-changed: ${{ needs.eval-changes.outputs.build-changes }}
      ci-files-changed: ${{ needs.eval-changes.outputs.ci-changes }}
      doc-files-changed: ${{ needs.eval-changes.outputs.doc-changes }}
      src-files-changed: ${{ needs.eval-changes.outputs.src-changes }}
      test-files-changed: ${{ needs.eval-changes.outputs.test-changes }}
      gha-src-files-changed: ${{ needs.eval-changes.outputs.gha-src-changes }}
      gha-test-files-changed: ${{ needs.eval-changes.outputs.gha-test-changes }}
    permissions: {}
    secrets: {}
