name: Python

on:
  push:
    tags: ["v*"]
  pull_request:
    paths:
      - "src/python.rs"
      - "python/**"
      - "pyproject.toml"
      - "murk.pyi"
      - "Cargo.toml"
      - ".github/workflows/python.yaml"

permissions: read-all

env:
  PYO3_USE_ABI3_FORWARD_COMPATIBILITY: "1"

jobs:
  lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      - uses: astral-sh/ruff-action@4919ec5cf1f49eff0871dbcea0da843445b837e6 # v3
        with:
          src: python/

  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      - uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
      - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2

      - name: Build release binary (for test fixture)
        run: cargo build --release

      - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0

      - name: Install and test
        run: |
          uv venv
          source .venv/bin/activate
          uv pip install maturin pytest
          maturin develop --features python
          pytest python/tests -v

  wheels:
    name: Build wheels (${{ matrix.os }}, ${{ matrix.target }})
    needs: [lint, test]
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            target: x86_64
          - os: ubuntu-latest
            target: aarch64
            manylinux: manylinux_2_28
          - os: macos-14
            target: x86_64
          - os: macos-latest
            target: aarch64
          - os: windows-latest
            target: x64
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

      - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
        with:
          python-version: "3.12"

      - name: Set up QEMU
        if: runner.os == 'Linux' && matrix.target == 'aarch64'
        uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v3
        with:
          platforms: arm64

      - name: Build wheels
        uses: PyO3/maturin-action@04ac600d27cdf7a9a280dadf7147097c42b757ad # v1
        env:
          PYO3_USE_ABI3_FORWARD_COMPATIBILITY: "1"
        with:
          target: ${{ matrix.target }}
          args: --release --out dist --features python -i python3.12
          manylinux: ${{ matrix.manylinux || 'auto' }}
          docker-options: -e PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1

      - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
        with:
          name: wheels-${{ matrix.os }}-${{ matrix.target }}
          path: dist/

  sdist:
    name: Build sdist
    needs: [lint, test]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

      - name: Build sdist
        uses: PyO3/maturin-action@04ac600d27cdf7a9a280dadf7147097c42b757ad # v1
        with:
          command: sdist
          args: --out dist

      - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
        with:
          name: wheels-sdist
          path: dist/

  publish:
    name: Publish to PyPI
    if: startsWith(github.ref, 'refs/tags/v')
    needs: [wheels, sdist]
    runs-on: ubuntu-latest
    permissions:
      id-token: write
    steps:
      - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          pattern: wheels-*
          merge-multiple: true
          path: dist/

      - name: Publish to PyPI
        uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
        with:
          skip-existing: true
