name: Test

on:
  push:
  pull_request:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
  cancel-in-progress: true

env:
  FORCE_COLOR: 1

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        include:
          - db: "mariadb:12"  # rolling release
            py: "3.13"
            # pynacl 1.5 doesn't support Python 3.14 yet.
            # https://github.com/pyca/pynacl/commit/d33028e43b814615a33e231925eaddb0f679fa2b

          - db: "mariadb:11.8"
            py: "3.12"

          - db: "mariadb:11.4"
            py: "3.11"

          - db: "mariadb:10.11"
            py: "3.10"

          - db: "mariadb:10.6"
            py: "3.9"

          - db: "mysql:8.0"
            py: "pypy3.11"
            mysql_auth: true

          - db: "mysql:9"
            py: "3.14"
            mysql_auth: true

          - db: "mysql:8.4"
            py: "3.9"
            mysql_auth: true

          - db: "mysql:5.7"
            py: "3.9"

    services:
      mysql:
        image: "${{ matrix.db }}"
        ports:
          - 3306:3306
        env:
          MYSQL_ALLOW_EMPTY_PASSWORD: yes
          MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: yes
        options: "--name=mysqld"
        volumes:
          - /run/mysqld:/run/mysqld

    steps:
      - uses: actions/checkout@v5

      - name: Workaround MySQL container permissions
        if: startsWith(matrix.db, 'mysql')
        run: |
          sudo chown 999:999 /run/mysqld
          /usr/bin/docker ps --all --filter status=exited --no-trunc --format "{{.ID}}" | xargs -r /usr/bin/docker start

      - name: Set up Python ${{ matrix.py }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.py }}
          allow-prereleases: true
          cache: 'pip'
          cache-dependency-path: 'requirements-dev.txt'

      - name: Install dependency
        run: |
          pip install --upgrade -r requirements-dev.txt

      - name: Set up MySQL
        run: |
          while :
          do
              sleep 1
              mysql -h127.0.0.1 -uroot -e 'select version()' && break
          done
          mysql -h127.0.0.1 -uroot -e "SET GLOBAL local_infile=on"
          mysql -h127.0.0.1 -uroot --comments < ci/docker-entrypoint-initdb.d/init.sql
          mysql -h127.0.0.1 -uroot --comments < ci/docker-entrypoint-initdb.d/mysql.sql
          mysql -h127.0.0.1 -uroot --comments < ci/docker-entrypoint-initdb.d/mariadb.sql
          cp ci/docker.json pymysql/tests/databases.json

      - name: Run test
        run: |
          pytest -v --cov --cov-config .coveragerc pymysql
          pytest -v --cov-append --cov-config .coveragerc --doctest-modules pymysql/converters.py

      - name: Run MySQL8 auth test
        if: ${{ matrix.mysql_auth }}
        run: |
          docker cp mysqld:/var/lib/mysql/public_key.pem "${HOME}"
          docker cp mysqld:/var/lib/mysql/ca.pem "${HOME}"
          docker cp mysqld:/var/lib/mysql/server-cert.pem "${HOME}"
          docker cp mysqld:/var/lib/mysql/client-key.pem "${HOME}"
          docker cp mysqld:/var/lib/mysql/client-cert.pem "${HOME}"
          pytest -v --cov-append --cov-config .coveragerc tests/test_auth.py;

      - name: Upload coverage reports to Codecov
        if: github.repository == 'PyMySQL/PyMySQL'
        uses: codecov/codecov-action@v5
