name: Python Tests

on:
  push:
    branches: ["master", "v**"]
  pull_request:
  workflow_dispatch:

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

defaults:
  run:
    shell: bash -eux {0}

jobs:

  static:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
        with:
          persist-credentials: false
      - name: Install uv
        uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b # v5
        with:
          enable-cache: true
          python-version: "3.9"
      - name: Install just
        run: uv tool install rust-just
      - name: Install Python dependencies
        run: |
          just install
      - name: Run linters
        run: |
          just lint-manual
      - name: Run compilation
        run: |
          export PYMONGO_C_EXT_MUST_BUILD=1
          pip install -v -e .
          python tools/fail_if_no_c.py
      - name: Run typecheck
        run: |
          just typing
      - run: |
          sudo apt-get install -y cppcheck
      - run: |
          cppcheck --force bson
          cppcheck pymongo

  build:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        # Tests currently only pass on ubuntu on GitHub Actions.
        os: [ubuntu-latest]
        python-version: ["3.9", "pypy-3.10", "3.13t"]
        mongodb-version: ["8.0"]

    name: CPython ${{ matrix.python-version }}-${{ matrix.os }}
    steps:
      - uses: actions/checkout@v5
        with:
          persist-credentials: false
      - name: Install uv
        uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b # v5
        with:
          enable-cache: true
          python-version: ${{ matrix.python-version }}
      - id: setup-mongodb
        uses: mongodb-labs/drivers-evergreen-tools@master
        with:
          version: "${{ matrix.mongodb-version }}"
      - name: Run tests
        run: uv run --extra test pytest -v

  doctest:
    runs-on: ubuntu-latest
    name: DocTest
    steps:
      - uses: actions/checkout@v5
        with:
          persist-credentials: false
      - name: Install uv
        uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b # v5
        with:
          enable-cache: true
          python-version: "3.9"
      - name: Install just
        run: uv tool install rust-just
      - id: setup-mongodb
        uses: mongodb-labs/drivers-evergreen-tools@master
        with:
          version: "8.0"
      - name: Install dependencies
        run: just install
      - name: Run tests
        run:  |
          just setup-tests doctest
          just run-tests

  docs:
    name: Docs Checks
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
        with:
          persist-credentials: false
      - name: Install uv
        uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b # v5
        with:
          enable-cache: true
          python-version: "3.9"
      - name: Install just
        run: uv tool install rust-just
      - name: Install dependencies
        run: just install
      - name: Build docs
        run: just docs

  linkcheck:
    name: Link Check
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
        with:
          persist-credentials: false
      - name: Install uv
        uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b # v5
        with:
          enable-cache: true
          python-version: "3.9"
      - name: Install just
        run: uv tool install rust-just
      - name: Install dependencies
        run: just install
      - name: Build docs
        run: just docs-linkcheck

  typing:
    name: Typing Tests
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python: ["3.9", "3.11"]
    steps:
      - uses: actions/checkout@v5
        with:
          persist-credentials: false
      - name: Install uv
        uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b # v5
        with:
          enable-cache: true
          python-version: "${{matrix.python}}"
      - name: Install just
        run: uv tool install rust-just
      - name: Install dependencies
        run: |
          just install
      - name: Run typecheck
        run: |
          just typing

  make_sdist:
    runs-on: ubuntu-latest
    name: "Make an sdist"
    steps:
      - uses: actions/checkout@v5
        with:
          persist-credentials: false
      - uses: actions/setup-python@v5
        with:
          cache: 'pip'
          cache-dependency-path: 'pyproject.toml'
          # Build sdist on lowest supported Python
          python-version: '3.9'
      - name: Build SDist
        shell: bash
        run: |
          pip install build
          python -m build --sdist
      - uses: actions/upload-artifact@v4
        with:
          name: "sdist"
          path: dist/*.tar.gz

  test_sdist:
      runs-on: ubuntu-latest
      needs: [make_sdist]
      name: Install from SDist and Test
      timeout-minutes: 20
      steps:
        - name: Download sdist
          uses: actions/download-artifact@v4
        - name: Unpack SDist
          shell: bash
          run: |
            cd sdist
            ls
            mkdir test
            tar --strip-components=1 -zxf *.tar.gz -C ./test
            ls test
        - uses: actions/setup-python@v5
          with:
            cache: 'pip'
            cache-dependency-path: 'sdist/test/pyproject.toml'
            # Test sdist on lowest supported Python
            python-version: '3.9'
        - id: setup-mongodb
          uses: mongodb-labs/drivers-evergreen-tools@master
        - name: Run connect test from sdist
          shell: bash
          run: |
            cd sdist/test
            ls
            which python
            pip install -e ".[test]"
            PYMONGO_MUST_CONNECT=1 pytest -v -k client_context

  test_minimum:
      permissions:
        contents: read
      runs-on: ubuntu-latest
      name: Test using minimum dependencies and supported Python
      steps:
        - uses: actions/checkout@v5
          with:
            persist-credentials: false
        - name: Install uv
          uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b # v5
          with:
            python-version: '3.9'
        - id: setup-mongodb
          uses: mongodb-labs/drivers-evergreen-tools@master
          with:
            version: "8.0"
        # Async and our test_dns do not support dnspython 1.X, so we don't run async or dns tests here
        - name: Run tests
          shell: bash
          run: |
            uv venv
            source .venv/bin/activate
            uv pip install -e ".[test]" --resolution=lowest-direct
            pytest -v test/test_srv_polling.py

  test_minimum_for_async:
      permissions:
        contents: read
      runs-on: ubuntu-latest
      name: Test async's minimum dependencies and Python
      steps:
        - uses: actions/checkout@v5
          with:
            persist-credentials: false
        - name: Install uv
          uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b # v5
          with:
            python-version: '3.9'
        - id: setup-mongodb
          uses: mongodb-labs/drivers-evergreen-tools@master
          with:
            version: "8.0"
        # The lifetime kwarg we use in srv resolution was added to the async resolver API in dnspython 2.1.0
        - name: Run tests
          shell: bash
          run: |
            uv venv
            source .venv/bin/activate
            uv pip install -e ".[test]" --resolution=lowest-direct dnspython==2.1.0 --force-reinstall
            pytest -v test/test_srv_polling.py test/test_dns.py test/asynchronous/test_srv_polling.py test/asynchronous/test_dns.py
