evlib 0.8.6

Event Camera Data Processing Library
Documentation
name: Python

on:
  push:
    branches: [main, master]
    paths:
      - "**.py"
      - "**.rs"
      - "**.ipynb"
      - "docs/**"
      - "README.md"
      - "pyproject.toml"
      - "Cargo.toml"
      - ".github/workflows/pytest.yml"
      - "pytest.ini"
  pull_request:
    paths:
      - "**.py"
      - "**.rs"
      - "**.ipynb"
      - "docs/**"
      - "README.md"
      - "pyproject.toml"
      - "Cargo.toml"
      - ".github/workflows/pytest.yml"
      - "pytest.ini"
  workflow_dispatch:

jobs:
  python-tests:
    name: Python ${{ matrix.python-version }} (${{ matrix.os }})
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        python-version: ["3.10", "3.11", "3.12"]

    steps:
      - uses: actions/checkout@v4

      - name: Cache Rust dependencies
        uses: Swatinem/rust-cache@v2
        with:
          key: test-${{ matrix.os }}-${{ matrix.python-version }}

      - name: Setup dependencies
        uses: ./.github/actions/setup-dependencies
        with:
          python-version: ${{ matrix.python-version }}
          enable-gstreamer: "true"
          os: ${{ matrix.os }}

      - name: Set up Rust
        uses: dtolnay/rust-toolchain@nightly

      - name: Install maturin
        run: uv pip install maturin>=1.7.4

      - name: Build Rust extension
        run: |
          # Build with platform-appropriate features
          # Cargo.toml has platform-specific dependencies for Unix (HDF5, tracing)
          uv run maturin develop --release
        shell: bash

      - name: Install Python dependencies
        run: |
          # On macOS, build h5py from source to ensure compatibility with system HDF5
          if [[ "${{ matrix.os }}" == "macos-latest" ]]; then
            export HDF5_DIR="${HDF5_DIR}"
            uv pip install --no-binary h5py "h5py>=3.8.0"
          fi
          # Install extra dependencies (evlib already installed by maturin develop above)
          # This will only install the dependencies from [all], not rebuild evlib
          uv pip install .[all]
        shell: bash

      - name: Debug - Find .pyd file location (Windows only)
        if: matrix.os == 'windows-latest'
        run: |
          echo "=== Searching entire workspace for evlib .pyd files ==="
          find . -name "evlib*.pyd" 2>/dev/null || echo "No evlib .pyd files found with find"
          echo ""
          echo "=== Checking sys.prefix/Lib/site-packages ==="
          python -c "import sys, os; sp = os.path.join(sys.prefix, 'Lib', 'site-packages'); print('Path:', sp); print('Exists:', os.path.isdir(sp))"
          python -c "import sys, os, glob; sp = os.path.join(sys.prefix, 'Lib', 'site-packages'); print('PYD files there:', glob.glob(os.path.join(sp, '*.pyd')))"
        shell: bash

      - name: Run tests
        run: |
          # Run pytest directly from venv instead of 'uv run' which creates isolated env
          pytest -v tests/ -m "not slow and not integration"
          pytest --nbmake examples/*.ipynb -v --no-cov
        shell: bash

      # Temporarily disabled - documentation tests need fixing
      # - name: Test documentation examples
      #   run: |
      #     source .venv/bin/activate
      #     uv run pytest --markdown-docs README.md docs/ -v --tb=short

      - name: Generate coverage report
        if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest'
        run: pytest --cov=evlib --cov-report=xml -v tests/ -m "not slow and not integration"
        shell: bash

      - name: Upload coverage to Codecov
        if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest'
        uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          file: ./coverage.xml
          fail_ci_if_error: false