name: Test When Python PR

on:
  pull_request:
    paths:
      - "swanlab/**"
      - "tests/**"
      - "pyproject.toml"
      - "uv.lock"
      - ".github/workflows/test-python-pr.yml"

jobs:
  type-check:
    name: Type check / Python 3.9
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v7
      - name: Install uv and set up Python
        uses: astral-sh/setup-uv@v10.0.0
        with:
          python-version: "3.9"
          enable-cache: true
      - name: Install dependencies
        run: uv sync --all-extras --group dev
      - name: Run ruff
        run: uv run ruff check .
      - name: Run basedpyright
        run: uv run basedpyright
  test:
    needs: type-check
    name: Test on ${{ matrix.os }} / Python ${{ matrix.python-version }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false # 设为 false,这样如果 Windows 挂了,Ubuntu 的测试依然会跑完,方便一次性排查所有系统的问题
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]

    steps:
      - name: Checkout code
        uses: actions/checkout@v7

      - name: Install uv and set up Python
        uses: astral-sh/setup-uv@v10.0.0
        with:
          python-version: ${{ matrix.python-version }}
          # 开启缓存,进一步加速后续的 CI 运行
          enable-cache: true

      - name: Install dependencies
        run: uv sync --all-extras

      - name: Run tests with pytest
        # uv run 会自动识别当前的虚拟环境并执行 pytest
        run: uv run pytest

  check:
    # 聚合所有前置 job 的结果,供 GitHub ruleset 配置单一 required status check
    name: Check
    needs: [type-check, test]
    # always() 确保前置失败时本 job 依然运行,从而汇报 failure 而不是被 skip
    if: always()
    runs-on: ubuntu-latest
    steps:
      - name: Fail if any required job failed or was cancelled
        if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
        run: exit 1