name: Tests

# Controls when the action will run.
on:
  pull_request:
  push:
    branches: [ $default-branch ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

concurrency:
  group: tests-${{ github.head_ref }}
  cancel-in-progress: true

jobs:
  style-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python 3.8
        uses: actions/setup-python@v5
        with:
          python-version: 3.8
      - name: Install black
        run: pip install black==22.3.0
      - name: Check diff
        run: black --diff --check .
  docs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python 3.10
        uses: actions/setup-python@v5
        with:
          python-version: "3.10"
      - name: Install nox.
        run: python -m pip install nox
      - name: Build the documentation.
        run: nox -s docs
  unit:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        # See https://github.com/actions/setup-python?tab=readme-ov-file#basic-usage
        # for the format of the entries in 'python'.
        # See https://downloads.python.org/pypy/ for the current supported versions of PyPy.
        python: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13', '3.14', 'pypy3.10']
        variant: ['cpp', 'python', 'upb']
        # TODO(https://github.com/googleapis/proto-plus-python/issues/389):
        # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped.
        # The 'cpp' implementation requires Protobuf == 3.x however version 3.x
        # does not support Python 3.11 and newer. The 'cpp' implementation
        # must be excluded from the test matrix for these runtimes.
        exclude:
          - variant: "cpp"
            python: 3.11
          - variant: "cpp"
            python: 3.12
          - variant: "cpp"
            python: 3.13
          - variant: "cpp"
            python: 3.14
            # In PyPy 3.10, we see the following warning
            # UserWarning: Selected implementation upb is not available. Falling back to the python implementation.
          - variant: "upb"
            python: 'pypy3.10'
            # In PyPy 3.10, we see the following warning
            # UserWarning: PyPy does not work yet with cpp protocol buffers. Falling back to the python implementation.
          - variant: "cpp"
            python: 'pypy3.10'
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python ${{ matrix.python }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python }}
      - name: Install nox
        run: |
          pip install nox
      - name: Run unit tests
        env:
          COVERAGE_FILE: .coverage-${{ matrix.variant }}-${{ matrix.python }}
        run: |
          nox -s "unit-${{ matrix.python }}(implementation='${{ matrix.variant }}')"
      - name: Upload coverage results
        uses: actions/upload-artifact@v4
        with:
          name: coverage-artifact-${{ matrix.variant }}-${{ matrix.python }}
          path: .coverage-${{ matrix.variant }}-${{ matrix.python }}
          include-hidden-files: true
  prerelease:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        python: ['3.14']
        variant: ['python', 'upb']
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python ${{ matrix.python }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python }}
          allow-prereleases: true
      - name: Install nox
        run: |
          pip install nox
      - name: Run unit tests
        env:
          COVERAGE_FILE: .coverage-prerelease-${{ matrix.variant }}
        run: |
          nox -s "prerelease_deps(implementation='${{ matrix.variant }}')"
      - name: Upload coverage results
        uses: actions/upload-artifact@v4
        with:
          name: coverage-artifact-prerelease-${{ matrix.variant }}
          path: .coverage-prerelease-${{ matrix.variant }}
  cover:
    runs-on: ubuntu-latest
    needs:
        - unit
    steps:
    - name: Checkout
      uses: actions/checkout@v4
    - name: Setup Python
      uses: actions/setup-python@v5
      with:
        python-version: "3.10"
    - name: Install coverage
      run: |
        python -m pip install --upgrade setuptools pip wheel
        python -m pip install coverage
    - name: Download coverage results
      uses: actions/download-artifact@v4
      with:
        path: .coverage-results/
    - name: Report coverage results
      run: |
        find .coverage-results -type f -name '*.zip' -exec unzip {} \;
        coverage combine .coverage-results/**/.coverage*
        coverage report --show-missing --fail-under=100
