name: CI

on:
  push:
    branches:
      - main
  pull_request:
  workflow_dispatch:

permissions:
  contents: read

env:
  FORCE_COLOR: "1"
  PIP_DISABLE_PIP_VERSION_CHECK: "1"
  PIP_NO_PYTHON_VERSION_WARNING: "1"

jobs:

  lint:
    name: Run linter
    runs-on: ubuntu-latest

    steps:
      - name: Checkout 🛎️
        uses: actions/checkout@v4
        with:
          persist-credentials: false

      - name: Install uv 🌟
        uses: astral-sh/setup-uv@22695119d769bdb6f7032ad67b9bca0ef8c4a174 #v5.4.0
        with:
            version: ">=0.0.1"

      - name: Lint 🧹
        run: |
          uv tool install ruff
          ruff check

  tests:
    name: Run tests
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.11", "3.12", "3.13", "3.14"]

    {% raw %}
    steps:
      - name: Checkout 🛎️
        uses: actions/checkout@v4
        with:
          persist-credentials: false

      - name: Install uv 🌟
        uses: astral-sh/setup-uv@22695119d769bdb6f7032ad67b9bca0ef8c4a174 #v5.4.0
        with:
            python-version: ${{ matrix.python-version }}
            version: ">=0.0.1"

      - name: Test with python ${{ matrix.python-version }} 🧪
        run: |
          uv run --frozen coverage run \
            --data-file .coverage.${{ matrix.python-version }} \
            -m pytest

      - name: Upload coverage data 📤
        uses: actions/upload-artifact@v4
        with:
          name: coverage-data-${{ matrix.python-version }}
          path: .coverage.*
          include-hidden-files: true
          if-no-files-found: ignore
    {% endraw %}

  coverage:
    # https://hynek.me/articles/ditch-codecov-python/
    name: Combine coverage reports & fail if below threshold
    runs-on: ubuntu-latest
    needs: tests
    if: always()

    steps:
      - name: Checkout 🛎️
        uses: actions/checkout@v4
        with:
          persist-credentials: false

      - name: Install uv 🌟
        uses: astral-sh/setup-uv@22695119d769bdb6f7032ad67b9bca0ef8c4a174 #v5.4.0
        with:
          version: '>=0.0.1'

      - name: Download coverage data 📥
        uses: actions/download-artifact@v4
        with:
          pattern: coverage-data-*
          merge-multiple: true

      - name: Generate coverage report 📊
        run: |
          uv tool install 'coverage[toml]'

          coverage combine
          coverage html --skip-covered --skip-empty
          coverage report --format=markdown >> $GITHUB_STEP_SUMMARY

          # Generate report again, this time with a fail-under threshold
          coverage report --fail-under=80

      - name: Upload HTML report if coverage check fails
        uses: actions/upload-artifact@v4
        with:
            name: html-cov-report
            path: htmlcov
        {%- raw %}
        if: ${{ failure() }}
        {%- endraw %}
