name: tests

on:
  push:
    branches: [ main ]

  pull_request:
    branches: [ main ]

  # Run tests once a week on Sunday.
  schedule:
    - cron: "0 6 * * 0"

jobs:
  run-tests:
    strategy:
      fail-fast: false
      matrix:
        pytest: [ "8", "9" ]
        cmake: [ "3.20", "4.2" ]
        os: [ "ubuntu", "macos", "windows" ]
        python: [ "3.10", "3.14" ]
        bundled: [ false, true ]

    name: |
      v${{ matrix.pytest }}-${{ matrix.cmake }}
      [${{ matrix.os }}-py${{ matrix.python }}]
      ${{ matrix.bundled && '(bundled)' || '' }}

    runs-on: "${{ matrix.os }}-latest"

    steps:
      - uses: actions/setup-python@v5
        with:
          python-version: "${{ matrix.python }}"

      - uses: actions/checkout@v4

      - name: Setup CMake
        uses: jwlawson/actions-setup-cmake@v2.0
        if: ${{matrix.os != 'windows' || matrix.cmake != '3.20'}}
        with:
          cmake-version: "${{ matrix.cmake }}.x"

      - name: Setup CMake (Bump up CMake minimal version for Visual Studio 17 2022)
        uses: jwlawson/actions-setup-cmake@v2.0
        if: ${{matrix.os == 'windows' && matrix.cmake == '3.20'}}
        with:
          # Visual Studio 17 2022 requires at least CMake 3.21.
          # https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2017%202022.html
          cmake-version: "3.21.x"

      - name: Setup Environment
        shell: bash
        run: |
          cmake --version
          python -m pip install --upgrade pip
          python -m pip install nanobind==2.*
          python -m pip install . pytest==${{ matrix.pytest }}.*

      - name: Build and Run Unit Tests
        shell: bash
        run: |
          cmake -S ./test -B ./test/build
          cmake --build ./test/build
          ctest --test-dir ./test/build -VV -C Release

      - name: Configure Example
        shell: bash
        env:
            BUNDLE_PYTHON_TESTS: ${{ matrix.bundled }}
        run: |
          cmake \
              -D "CMAKE_BUILD_TYPE=Release" \
              -D "nanobind_ROOT=$(python -m nanobind --cmake_dir)" \
              -S ./example \
              -B ./build

      - name: Build without Python and Test
        shell: bash
        working-directory: build
        run: |
          cmake --build . --target foo CppTest --config Release
          ctest -VV -C Release -R "CppTest"

      - name: Build and Test
        shell: bash
        working-directory: build
        run: |
          cmake --build . --config Release
          ctest -VV -C Release
