name: Quicktest

on:
  # Run on pushes, including merges, to all branches except `stable` and `develop`.
  push:
    branches-ignore:
      - stable
      - develop
    paths-ignore:
      - '**.md'
      - 'docs/**'
  # Allow manually triggering the workflow.
  workflow_dispatch:

# Cancels all previous workflow runs for the same branch that have not yet completed.
concurrency:
  # The concurrency group contains the workflow name and the branch name.
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  #### QUICK TEST STAGE ####
  # This is a much quicker test which only runs the unit tests and linting against the low/high
  # supported PHP/PHPCS combinations.
  # These are basically the same builds as in the Test->Coverage workflow, but then without doing
  # the code-coverage.
  quicktest:
    runs-on: ubuntu-latest

    env:
      # - COMPOSER_ROOT_VERSION is needed to get round the recursive dependency when using CI.
      COMPOSER_ROOT_VERSION: '1.99.99'

    strategy:
      matrix:
        php: ['5.4', 'latest']
        phpcs_version: ['lowest', '3.x-dev']

        include:
          - php: '7.2'
            phpcs_version: '4.0.1'
          - php: '7.2'
            phpcs_version: '4.x-dev'
          - php: 'latest'
            phpcs_version: '4.0.1'
          - php: 'latest'
            phpcs_version: '4.x-dev'

    name: "QTest: PHP ${{ matrix.php }} - PHPCS ${{ matrix.phpcs_version }}"

    steps:
      - name: Checkout code
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
        with:
          persist-credentials: false

      # On stable PHPCS versions, allow for PHP deprecation notices.
      # Unit tests don't need to fail on those for stable releases where those issues won't get fixed anymore.
      - name: Setup ini config
        id: set_ini
        run: |
          if [ "${{ contains( matrix.phpcs_version, 'dev') }}" == "false" ]; then
            echo 'PHP_INI=error_reporting=E_ALL & ~E_DEPRECATED, display_errors=On, display_startup_errors=On' >> "$GITHUB_OUTPUT"
          else
            echo 'PHP_INI=error_reporting=-1, display_errors=On, display_startup_errors=On' >> "$GITHUB_OUTPUT"
          fi

      - name: Install PHP
        uses: shivammathur/setup-php@bf6b4fbd49ca58e4608c9c89fba0b8d90bd2a39f # 2.35.5
        with:
          php-version: ${{ matrix.php }}
          ini-values: ${{ steps.set_ini.outputs.PHP_INI }}
          coverage: none

      # Remove PHPCSDevCS as it would (for now) prevent the tests from being able to run against PHPCS "lowest".
      - name: 'Composer: remove PHPCSDevCS'
        run: composer remove --dev phpcsstandards/phpcsdevcs --no-update --no-interaction

      - name: "Composer: set PHPCS version for tests"
        if: ${{ matrix.phpcs_version != 'lowest' }}
        run: composer require squizlabs/php_codesniffer:"${{ matrix.phpcs_version }}" --no-update --no-scripts --no-interaction

      - name: "Composer: use lock file when necessary"
        if: ${{ matrix.phpcs_version == 'lowest' }}
        run: composer config --unset lock

      # Install dependencies and handle caching in one go.
      # @link https://github.com/marketplace/actions/install-php-dependencies-with-composer
      - name: Install Composer dependencies
        uses: "ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520" # 3.1.1
        with:
          # Bust the cache at least once a month - output format: YYYY-MM.
          custom-cache-suffix: $(date -u "+%Y-%m")

      - name: "Composer: set PHPCS version for tests (lowest)"
        if: ${{ matrix.phpcs_version == 'lowest' }}
        run: composer update squizlabs/php_codesniffer --prefer-lowest --no-scripts --no-interaction

      - name: Lint against parse errors (PHP < 7.2)
        if: ${{ matrix.php == '5.4' && matrix.phpcs_version == '3.x-dev' }}
        run: composer lint-lt72

      - name: Lint against parse errors (PHP 7.2+)
        if: ${{ matrix.phpcs_version == '4.x-dev' }}
        run: composer lint

      - name: Grab PHPUnit version
        id: phpunit_version
        # yamllint disable-line rule:line-length
        run: echo "VERSION=$(vendor/bin/phpunit --version | grep --only-matching --max-count=1 --extended-regexp '\b[0-9]+\.[0-9]+')" >> "$GITHUB_OUTPUT"

      - name: Determine PHPUnit config file to use
        id: phpunit_config
        run: |
          if [ "${{ startsWith( steps.phpunit_version.outputs.VERSION, '11.' ) }}" == "true" ]; then
            echo 'FILE=phpunit10.xml.dist' >> "$GITHUB_OUTPUT"
            echo 'EXTRA_ARGS=' >> "$GITHUB_OUTPUT"
          elif [ "${{ startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) }}" == "true" ]; then
            echo 'FILE=phpunit10.xml.dist' >> "$GITHUB_OUTPUT"
            echo 'EXTRA_ARGS=' >> "$GITHUB_OUTPUT"
          else
            echo 'FILE=phpunit.xml.dist' >> "$GITHUB_OUTPUT"
            echo 'EXTRA_ARGS= --repeat 2' >> "$GITHUB_OUTPUT"
          fi

      - name: Run the unit tests without caching
        run: vendor/bin/phpunit -c ${{ steps.phpunit_config.outputs.FILE }} --no-coverage
        env:
          PHPCS_VERSION: ${{ matrix.phpcs_version }}
          PHPCSUTILS_USE_CACHE: false

      - name: Run the unit tests with caching
        run: >
          vendor/bin/phpunit -c ${{ steps.phpunit_config.outputs.FILE }}
          --testsuite PHPCSUtils --no-coverage ${{ steps.phpunit_config.outputs.EXTRA_ARGS }}
        env:
          PHPCS_VERSION: ${{ matrix.phpcs_version }}
          PHPCSUTILS_USE_CACHE: true
