name: "test"
on:
  workflow_dispatch:
  pull_request:
  push:
    branches:
      - main

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

permissions: {}

jobs:
  lint:
    runs-on: ubuntu-latest
    permissions:
      security-events: write # for zizmor
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Actionlint
        uses: eifinger/actionlint-action@447fbfe7533062b7a9ea55f790f2396fba6d052a  # v1.10.0
      - name: Run zizmor
        uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
        with:
          node-version: "20"
      - run: |
          npm ci --ignore-scripts
      - run: |
          npm run all
      - name: Check all jobs are in all-tests-passed.needs
        run: |
          tsc check-all-tests-passed-needs.ts
          node check-all-tests-passed-needs.js
        working-directory: .github/scripts
      - name: Make sure no changes from linters are detected
        run: |
          git diff --exit-code || (echo "::error::Please run 'npm run all' to fix the issues" && exit 1)
  test-latest-version:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, macos-14, windows-latest]
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Use latest version
        uses: ./
        with:
          src: __tests__/fixtures/python-project
          version: latest
  test-specific-version:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        ruff-version: ["0.1.7", "0.1.8", "0.4.7", "0.4.10", "0.7", "0.7.x", ">=0.7.0"]
        os: [ ubuntu-latest, ubuntu-24.04-arm, macos-latest, macos-14, windows-latest ]
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Use version ${{ matrix.ruff-version }}
        uses: ./
        with:
          version: ${{ matrix.ruff-version }}
          src: __tests__/fixtures/python-project
  test-unsupported-version:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Try install old version
        id: install
        continue-on-error: true
        uses: ./
        with:
          version: 0.0.246
          src: __tests__/fixtures/python-project
      - name: Check if the action failed
        run: |
          if [ "${INSTALL_OUTCOME}" == "success" ]; then
            exit 1
          fi
        env:
          INSTALL_OUTCOME: ${{ steps.install.outcome }}
  test-version-from-version-file-pyproject:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Use version from pyproject.toml
        id: ruff-action
        uses: ./
        with:
          src: __tests__/fixtures/python-project
          version-file: __tests__/fixtures/pyproject.toml
      - name: Correct version gets installed
        run: |
          if [ "$RUFF_VERSION" != "0.9.3" ]; then
            exit 1
          fi
        env:
          RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}
  test-default-version-from-pyproject:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Use default version from pyproject.toml
        id: ruff-action
        uses: ./
        with:
          src: __tests__/fixtures/python-project
      - name: Correct version gets installed
        run: |
          if [ "$RUFF_VERSION" != "0.6.2" ]; then
            exit 1
          fi
        env:
          RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}
  test-default-version-from-pyproject-dev-group:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Use default version from pyproject.toml dev group
        id: ruff-action
        uses: ./
        with:
          src: __tests__/fixtures/pyproject-dependency-dev-project
          version-file: __tests__/fixtures/pyproject-dependency-dev-project/pyproject.toml
      - name: Correct version gets installed
        run: |
          if [ "$RUFF_VERSION" != "0.8.3" ]; then
            exit 1
          fi
        env:
          RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}
  test-default-version-from-pyproject-dependency-groups:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Use default version from pyproject.toml dependency groups
        id: ruff-action
        uses: ./
        with:
          src: __tests__/fixtures/pyproject-dependency-groups-project
          version-file: __tests__/fixtures/pyproject-dependency-groups-project/pyproject.toml
      - name: Correct version gets installed
        run: |
          if [ "$RUFF_VERSION" != "0.8.3" ]; then
            exit 1
          fi
        env:
          RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}
  test-default-version-from-pyproject-dependency-groups-with-env-marker:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Use default version from pyproject.toml with environment marker
        id: ruff-action
        uses: ./
        with:
          src: __tests__/fixtures/python-project
          version-file: __tests__/fixtures/pyproject-dependency-groups-with-env-marker/pyproject.toml
      - name: Correct version gets installed
        run: |
          if [ "$RUFF_VERSION" != "0.13.3" ]; then
            echo "Expected version 0.13.3 but got $RUFF_VERSION"
            exit 1
          fi
        env:
          RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}
  test-default-version-from-pyproject-poetry-groups:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Use default version from pyproject.toml poetry group dependencies
        id: ruff-action
        uses: ./
        with:
          src: __tests__/fixtures/pyproject-dependency-poetry-grouped-project
          version-file: __tests__/fixtures/pyproject-dependency-poetry-grouped-project/pyproject.toml
      - name: Correct version gets installed
        run: |
          if [ "$RUFF_VERSION" != "0.8.3" ]; then
            exit 1
          fi
        env:
          RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}
  test-default-version-from-pyproject-poetry:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Use default version from pyproject.toml poetry dependencies
        id: ruff-action
        uses: ./
        with:
          src: __tests__/fixtures/pyproject-dependency-poetry-project
          version-file: __tests__/fixtures/pyproject-dependency-poetry-project/pyproject.toml
      - name: Correct version gets installed
        run: |
          if [ "$RUFF_VERSION" != "0.8.6" ]; then
            exit 1
          fi
        env:
          RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}
  test-default-version-from-pyproject-optional-dependencies:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Use default version from pyproject.toml optional dependencies
        id: ruff-action
        uses: ./
        with:
          src: __tests__/fixtures/pyproject-optional-dependencies-project
          version-file: __tests__/fixtures/pyproject-optional-dependencies-project/pyproject.toml
      - name: Correct version gets installed
        run: |
          if [ "$RUFF_VERSION" != "0.8.3" ]; then
            exit 1
          fi
        env:
          RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}
  test-default-version-from-requirements:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Use default version from requirements.txt
        id: ruff-action
        uses: ./
        with:
          src: __tests__/fixtures/python-project
          version-file: __tests__/fixtures/requirements.txt
      - name: Correct version gets installed
        run: |
          if [ "$RUFF_VERSION" != "0.9.0" ]; then
            exit 1
          fi
        env:
          RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}
  test-default-version-from-requirements-with-hash:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Use default version from requirements-with-hash.txt
        id: ruff-action
        uses: ./
        with:
          src: __tests__/fixtures/python-project
          version-file: __tests__/fixtures/requirements-with-hash.txt
      - name: Correct version gets installed
        run: |
          if [ "$RUFF_VERSION" != "0.9.0" ]; then
            exit 1
          fi
        env:
          RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}
  test-semver-range:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Use version 0.7
        id: ruff-action
        uses: ./
        with:
          version: "0.7"
          src: __tests__/fixtures/python-project
      - name: Correct version gets installed
        run: |
          if [ "$RUFF_VERSION" != "0.7.4" ]; then
            exit 1
          fi
        env:
          RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}
  test-pep440-version-specifier:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Install version 0.9.10
        id: ruff-action
        uses: ./
        with:
          version: ">=0.9.9,<0.10.0"
          src: __tests__/fixtures/python-project
      - name: Correct version gets installed
        run: |
          if [ "$RUFF_VERSION" != "0.9.10" ]; then
            exit 1
          fi
        env:
          RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}
  test-checksum:
    runs-on: ${{ matrix.inputs.os }}
    strategy:
      matrix:
        inputs:
          - os: ubuntu-latest
            checksum: "0de731c669b9ece77e799ac3f4a160c30849752714d9775c94cc4cfaf326860c"
          - os: macos-latest
            checksum: "af9583bff12afbca5d5670334e0187dd60c4d91bc71317d1b2dde70cb1200ba9"
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Checksum matches expected
        uses: ./
        with:
          version: "0.7.4"
          checksum: ${{ matrix.inputs.checksum }}
          src: __tests__/fixtures/python-project
  test-with-explicit-token:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Use default version
        uses: ./
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          src: __tests__/fixtures/python-project
  test-args:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Use args
        uses: ./
        with:
          args: format --check
          src: __tests__/fixtures/python-project
  test-failure:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Format should fail
        id: format-should-fail
        continue-on-error: true
        uses: ./
        with:
          args: format --check
          src: __tests__/fixtures/malformed-python-project
      - name: Check if the action failed
        run: |
          if [ "${FORMAT_SHOULD_FAIL_OUTCOME}" == "success" ]; then
            exit 1
          fi
        env:
          FORMAT_SHOULD_FAIL_OUTCOME: ${{ steps.format-should-fail.outcome }}
      - name: Check should fail
        id: check-should-fail
        continue-on-error: true
        uses: ./
        with:
          src: __tests__/fixtures/malformed-python-project
      - name: Check if the action failed
        run: |
          if [ "${CHECK_SHOULD_FAIL_OUTCOME}" == "success" ]; then
            exit 1
          fi
        env:
          CHECK_SHOULD_FAIL_OUTCOME: ${{ steps.check-should-fail.outcome }}
  test-multiple-src:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ ubuntu-latest, windows-latest ]
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Use args
        uses: ./
        with:
          args: format --check
          src: >-
            __tests__/fixtures/python-project/src/python_project/__init__.py
            __tests__/fixtures/python-project/src/python_project/hello_world.py
  test-parent-directory-pyproject:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Use version from parent directory pyproject.toml
        id: ruff-action
        uses: ./
        with:
          src: __tests__/fixtures/parent-config-project/subproject
      - name: Correct version gets installed
        run: |
          if [ "$RUFF_VERSION" != "0.10.0" ]; then
            echo "Expected version 0.10.0 but got $RUFF_VERSION"
            exit 1
          fi
        env:
          RUFF_VERSION: ${{ steps.ruff-action.outputs.ruff-version }}

  all-tests-passed:
    runs-on: ubuntu-latest
    needs:
      - lint
      - test-latest-version
      - test-specific-version
      - test-unsupported-version
      - test-version-from-version-file-pyproject
      - test-default-version-from-pyproject
      - test-default-version-from-pyproject-dev-group
      - test-default-version-from-pyproject-dependency-groups
      - test-default-version-from-pyproject-dependency-groups-with-env-marker
      - test-default-version-from-pyproject-poetry-groups
      - test-default-version-from-pyproject-poetry
      - test-default-version-from-pyproject-optional-dependencies
      - test-default-version-from-requirements
      - test-default-version-from-requirements-with-hash
      - test-semver-range
      - test-pep440-version-specifier
      - test-checksum
      - test-with-explicit-token
      - test-args
      - test-failure
      - test-multiple-src
      - test-parent-directory-pyproject
    if: always()
    steps:
      - name: All tests passed
        run: |
          echo "All jobs passed: ${{ !(contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) }}"
          # shellcheck disable=SC2242
          exit ${{ (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) && 1 || 0 }}
