name: CI
on:
  push:
    branches: [main]
  pull_request:
  workflow_dispatch:
    # allow manual runs on branches without a PR

env:
  FORCE_COLOR: "1"

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

permissions: {}

jobs:
  build:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        python-version:
          - "3.10"
          - "3.12"
          - "3.14"
          - "3.15"
        include:
          - os: ubuntu-22.04
            python-version: "3.11"
          - os: ubuntu-22.04
            python-version: "3.13"
          - os: macos-15-intel
            python-version: "3.12"
    steps:
      - uses: actions/checkout@v7.0.0
        with:
          persist-credentials: false
      - name: Set up non-default Pythons
        uses: actions/setup-python@v6
        with:
          python-version: |
            3.10
            3.11
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v6
        with:
          python-version: ${{ matrix.python-version }}
          allow-prereleases: true
      - name: Setup uv
        uses: astral-sh/setup-uv@v8.2.0
      - name: Set up Miniconda
        uses: conda-incubator/setup-miniconda@v4
        if: matrix.python-version == '3.14'
        with:
          channels: conda-forge
          conda-remove-defaults: true
          conda-version: '26.5.2'
          activate-environment:
      - name: Install Nox-under-test (uv)
        run:  uv pip install --system .
      - name: Run tests on ${{ matrix.os }}
        run: nox --session "tests-${{ matrix.python-version }}" -- --durations=10
      - name: Run min-version tests on ${{ matrix.os }}
        run: nox --session minimums --force-python="${{ matrix.python-version }}" -- --durations=10
      - name: Run Conda tests
        if: matrix.python-version == '3.14'
        run: nox --session "conda_tests" -- --durations=5
      - name: Save coverage report
        uses: actions/upload-artifact@v7
        with:
          name: coverage-${{ github.job }}-${{ strategy.job-index }}
          path: .coverage.*
          include-hidden-files: true
          if-no-files-found: error

  # No uv CLI exists in any MSYS2 repo (the msys `uv` package only ships the
  # uv_build backend), so the uv backend is exercised via the standalone uv
  # binary from setup-uv
  msys2:
    runs-on: windows-latest
    continue-on-error: true
    defaults:
      run:
        shell: msys2 {0}
    steps:
      - uses: actions/checkout@v7.0.0
        with:
          persist-credentials: false
      - uses: msys2/setup-msys2@v2.32.0
        with:
          msystem: MINGW64
          update: true
          # Inherit the runner PATH so the standalone uv (added to GITHUB_PATH
          # by setup-uv, which runs after this step) is visible to MinGW Python
          path-type: inherit
          install: >-
            mingw-w64-x86_64-python
            mingw-w64-x86_64-python-pip
            mingw-w64-x86_64-python-virtualenv
            mingw-w64-x86_64-gcc
      - name: Setup uv
        uses: astral-sh/setup-uv@v8.2.0
      - name: Install Nox-under-test
        run: python -m pip install .
      # Force virtualenv so the session venv stays a MinGW interpreter
      # (_IS_MINGW=True). uv stays on PATH, so the uv-backend tests still
      # build real uv venvs from within MinGW
      - name: Run tests under MinGW
        run: |
          pyver=$(python -c "import sys; print('{}.{}'.format(*sys.version_info))")
          echo "MSYS2 MinGW Python: $pyver"
          python -c "import shutil; print('uv discovered at:', shutil.which('uv'))"
          nox --session "tests-$pyver" --force-venv-backend virtualenv -- --durations=10
      - name: Save coverage report
        uses: actions/upload-artifact@v7
        with:
          name: coverage-${{ github.job }}
          path: .coverage.*
          include-hidden-files: true
          if-no-files-found: error

  coverage:
    needs: [build, msys2]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7.0.0
        with:
          persist-credentials: false
      - name: Set up Python 3.12
        uses: actions/setup-python@v6
        with:
          python-version: "3.12"
      - name: Setup uv
        uses: astral-sh/setup-uv@v8.2.0
      - name: Install Nox-under-test
        run:  uv pip install --system .
      - name: Download individual coverage reports
        uses: actions/download-artifact@v8
        with:
          pattern: coverage-*
      - name: Display structure of downloaded files
        run: ls -aR
      - name: Run coverage
        run: nox --session "cover"

  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7.0.0
        with:
          persist-credentials: false
      - name: Set up Python 3.12
        uses: actions/setup-python@v6
        with:
          python-version: "3.12"
      - name: Install Nox-under-test
        run: python -m pip install --disable-pip-version-check .
      - name: Lint
        run: nox --session "lint"

  docs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7.0.0
        with:
          persist-credentials: false
      - name: Set up Python 3.12
        uses: actions/setup-python@v6
        with:
          python-version: "3.12"
      - name: Setup uv
        uses: astral-sh/setup-uv@v8.2.0
      - name: Install Nox-under-test
        run:  uv pip install --system .
      - name: Docs
        run: nox --session "docs"
