name: Test

on:
  push:
    branches:
    - main
    tags:
    - '**'
  pull_request:
  schedule:
    # Run weekly on Saturday
    - cron: '37 3 * * SAT'

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

permissions:
  contents: read

jobs:
  mysql:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      max-parallel: 5
      matrix:
        python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']

    services:
      mariadb:
        image: mariadb:11.8
        env:
          MARIADB_ROOT_PASSWORD: debug_toolbar
        options: >-
          --health-cmd "mariadb-admin ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
        - 3306:3306

    steps:
    - uses: actions/checkout@v5
      with:
        persist-credentials: false

    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v6
      with:
        python-version: ${{ matrix.python-version }}
        allow-prereleases: true

    - name: Get pip cache dir
      id: pip-cache
      run: |
        echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT

    - name: Cache
      uses: actions/cache@v4
      with:
        path: ${{ steps.pip-cache.outputs.dir }}
        key:
          ${{ matrix.python-version }}-v1-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/tox.ini') }}
        restore-keys: |
          ${{ matrix.python-version }}-v1-
        lookup-only: true

    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        python -m pip install --upgrade tox tox-gh-actions

    - name: Test with tox
      run: tox
      env:
        DB_BACKEND: mysql
        DB_USER: root
        DB_PASSWORD: debug_toolbar
        DB_HOST: 127.0.0.1
        DB_PORT: 3306
        COVERAGE_FILE: ".coverage.mysql.${{ matrix.python-version }}"

    - name: Store coverage file
      uses: actions/upload-artifact@v5
      with:
        name: coverage-mysql-${{ matrix.python-version }}
        path: .coverage.mysql.${{ matrix.python-version }}*
        include-hidden-files: true


  postgres:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      max-parallel: 5
      matrix:
        python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
        database: [postgresql, postgis, psycopg3]
        exclude:
            - python-version: '3.13'
              database: postgis
            - python-version: '3.13'
              database: postgresql
            - python-version: '3.14'
              database: postgis
            - python-version: '3.14'
              database: postgresql
        # Add postgis3 to our matrix for modern Python versions
        include:
            - python-version: '3.13'
              database: postgis3
            - python-version: '3.13'
              database: psycopg3
              env:
                DJANGO_SELENIUM_TESTS=true
            - python-version: '3.14'
              database: postgis3
            - python-version: '3.14'
              database: psycopg3
              env:
                DJANGO_SELENIUM_TESTS=true

    services:
      postgres:
        image: postgis/postgis:17-3.5
        env:
          POSTGRES_DB: debug_toolbar
          POSTGRES_USER: debug_toolbar
          POSTGRES_PASSWORD: debug_toolbar
        ports:
        - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    steps:
    - uses: actions/checkout@v5
      with:
        persist-credentials: false

    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v6
      with:
        python-version: ${{ matrix.python-version }}
        allow-prereleases: true

    - name: Get pip cache dir
      id: pip-cache
      run: |
        echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT

    - name: Cache
      uses: actions/cache@v4
      with:
        path: ${{ steps.pip-cache.outputs.dir }}
        key:
          ${{ matrix.python-version }}-v1-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/tox.ini') }}
        restore-keys: |
          ${{ matrix.python-version }}-v1-
        lookup-only: true

    - name: Install gdal-bin (for postgis)
      run: |
        sudo apt-get -qq update
        sudo apt-get -y install gdal-bin

    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        python -m pip install --upgrade tox tox-gh-actions

    - name: Test with tox
      run: tox
      env:
        DB_BACKEND: ${{ matrix.database }}
        DB_HOST: localhost
        DB_PORT: 5432
        DJANGO_SELENIUM_TESTS: ${{ matrix.env.DJANGO_SELENIUM_TESTS }}
        COVERAGE_FILE: ".coverage.${{ matrix.database }}.${{ matrix.python-version }}"

    - name: Store coverage file
      uses: actions/upload-artifact@v5
      with:
        name: coverage-${{ matrix.database }}-${{ matrix.python-version }}
        path: .coverage.${{ matrix.database }}.${{ matrix.python-version }}*
        include-hidden-files: true

  sqlite:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      max-parallel: 5
      matrix:
        python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']

    steps:
    - uses: actions/checkout@v5
      with:
        persist-credentials: false

    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v6
      with:
        python-version: ${{ matrix.python-version }}
        allow-prereleases: true

    - name: Get pip cache dir
      id: pip-cache
      run: |
        echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT

    - name: Cache
      uses: actions/cache@v4
      with:
        path: ${{ steps.pip-cache.outputs.dir }}
        key:
          ${{ matrix.python-version }}-v1-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/tox.ini') }}
        restore-keys: |
          ${{ matrix.python-version }}-v1-
        lookup-only: true

    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        python -m pip install --upgrade tox tox-gh-actions

    - name: Test with tox
      run: tox
      env:
        DB_BACKEND: sqlite3
        DB_NAME: ":memory:"
        COVERAGE_FILE: ".coverage.sqlite.${{ matrix.python-version }}"

    - name: Store coverage file
      uses: actions/upload-artifact@v5
      with:
        name: coverage-sqlite-${{ matrix.python-version }}
        path: .coverage.sqlite.${{ matrix.python-version }}*
        include-hidden-files: true

  lint:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false

    steps:
    - uses: actions/checkout@v5
      with:
        persist-credentials: false

    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v6
      with:
        python-version: '3.10'

    - name: Get pip cache dir
      id: pip-cache
      run: |
        echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT

    - name: Cache
      uses: actions/cache@v4
      with:
        path: ${{ steps.pip-cache.outputs.dir }}
        key:
          ${{ matrix.python-version }}-v1-${{ hashFiles('**/pyproject.toml') }}-${{ hashFiles('**/tox.ini') }}
        restore-keys: |
          ${{ matrix.python-version }}-v1-
        lookup-only: true

    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        python -m pip install --upgrade tox

    - name: Test with tox
      run: tox -e docs,packaging

  coverage:
    name: Coverage
    runs-on: ubuntu-latest
    needs:
      - mysql
      - postgres
      - sqlite
    permissions:
      pull-requests: write
      contents: write
    steps:
      - uses: actions/checkout@v4
        with:
          # Persist the credentials because coverage_comment needs them too.
          persist-credentials: true

      - uses: actions/download-artifact@v6
        id: download
        with:
          pattern: coverage-*
          merge-multiple: true

      - name: Coverage comment
        id: coverage_comment
        uses: py-cov-action/python-coverage-comment-action@e623398c19eb3853a5572d4a516e10b15b5cefbc # v3.39
        with:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          MERGE_COVERAGE_FILES: true

      - name: Store Pull Request comment to be posted
        uses: actions/upload-artifact@v5
        if: steps.coverage_comment.outputs.COMMENT_FILE_WRITTEN == 'true'
        with:
          name: python-coverage-comment-action
          path: python-coverage-comment-action.txt
