name: ci-test

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main
  workflow_dispatch:
    inputs:
      tmate_debug_enabled:
        description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
        required: false
        default: false

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: true

permissions:
  contents: read

jobs:
  ci:
    runs-on: ${{ matrix.os }}
    env:
      UV_SYSTEM_PYTHON: 1
      DEFAULT_PYTHON_VERSION: 3.12
    strategy:
      fail-fast: false
      matrix:
        os:
          - ubuntu-latest
          - macOS-latest
          - windows-latest
        python-version:
          - "3.11"
          - "3.12"
          - "3.13"
          - "3.14"
    name: Test Python ${{ matrix.python-version }} ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v7
      - name: Set up Python
        uses: actions/setup-python@v7
        with:
          python-version: ${{ matrix.python-version }}
      - uses: astral-sh/setup-uv@v7
        with:
          enable-cache: true
      - name: Install dependencies
        run: uv pip install --system -e ".[test]"
      - name: Setup tmate session
        uses: mxschmitt/action-tmate@v3
        if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.tmate_debug_enabled }}
        timeout-minutes: 15
      - name: Run tests
        if: ${{ !startsWith(matrix.python-version, env.DEFAULT_PYTHON_VERSION) }}
        run: |
          python -m xonsh run-tests.xsh test -- --timeout=600
      - name: Run tests with coverage
        if: ${{ startsWith(matrix.python-version, env.DEFAULT_PYTHON_VERSION) }}
        run: |
          python -m xonsh run-tests.xsh test --report-coverage -- --timeout=600

  freebsd:
    # FreeBSD has no GitHub-hosted runner; the VM is launched on a Linux
    # host via vmactions/freebsd-vm (https://github.com/marketplace/actions/freebsd-vm).
    # 15.0-RELEASE + python312 mirrors the target the FreeBSD port is built
    # against (see CLAUDE.md "Running tests in a FreeBSD poudriere jail"
    # and issue #6374). The Python flavor must track FreeBSD's PYTHON_DEFAULT
    # (Mk/bsd.default-versions.mk): only default-flavor pyXY-* binary packages
    # are built for the `latest` repo, so a stale flavor makes `pkg install`
    # fail to resolve py3XX-pip / py3XX-cryptography. Bump when the default moves.
    runs-on: ubuntu-latest
    name: Test Python 3.12 FreeBSD 15.0
    timeout-minutes: 60
    steps:
      - uses: actions/checkout@v7
      - name: Test in FreeBSD VM
        uses: vmactions/freebsd-vm@v1
        with:
          release: "15.0"
          usesh: true
          copyback: false
          # Package set mirrors the FreeBSD port's test recipe in #6374:
          # - python312 / py312-pip: interpreter + installer
          # - py312-sqlite3 / py312-cryptography: stdlib-adjacent extras the
          #   FreeBSD base python ships unbundled
          # - bash / bash-completion: drive test_bash_completer.py and the
          #   foreign-shell bridge tests (skipped if missing, but we want
          #   them to actually run on this matrix)
          # - git: needed by tests/api/test_os.xsh and a few integration tests
          # - gmake: GNU make for the one @skip_if_no_make integration test
          prepare: |
            pkg install -y \
              python312 \
              py312-pip \
              py312-sqlite3 \
              py312-cryptography \
              bash \
              bash-completion \
              git \
              gmake
          run: |
            # PEP 668 — the system Python is externally-managed; the VM is
            # throwaway, so --break-system-packages is safe.
            python3.12 -m pip install --break-system-packages -e ".[test,full]"
            python3.12 -m pytest --timeout=600
