name: Test & Lint Python

permissions:
  contents: read

on:
  push:
    branches: ["main"]
  pull_request:

jobs:
  ruff:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

      - name: Install uv
        uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0

      - name: Set up Python
        uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
        with:
          python-version: "3.14"

      - name: Run ruff check
        run: uvx ruff check src/

  pytest:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        python-version: ["3.13", "3.14"]
    steps:
      - name: Checkout
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

      - name: Install uv
        uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
        with:
          python-version: ${{ matrix.python-version }}

      - name: Install dependencies
        run: uv sync --extra test

      # On windows-latest, bash tests auto-skip unless Git-for-Windows
      # bash (MSYS2/MINGW) is detected. The WSL launcher is rejected
      # because it cannot handle native Windows paths in test fixtures.
      # See tests/conftest.py::_has_working_bash() for details.
      - name: Run tests
        run: uv run pytest
