name: Python tests

on:
  push:
    branches:
      - stable
  pull_request:

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - run: |
          pipx install ruff
          ruff check
  test:
    needs: lint
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
    steps:
      - uses: actions/checkout@v6
      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: ${{ matrix.python-version }}
      - name: Set up Rust
        uses: dtolnay/rust-toolchain@stable
      - name: Install the latest version of uv
        uses: astral-sh/setup-uv@v7
      - name: Install dependencies
        run: uv sync
      - name: Run tests
        run: |
          uv run pytest --exitfirst --disable-warnings --log-cli-level=DEBUG --cov-report xml:cov.xml --cov=radixtarget .
      - name: Upload Code Coverage
        uses: codecov/codecov-action@v5
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          files: ./cov.xml
          verbose: true
  publish:
    runs-on: ubuntu-latest
    needs: test
    if: github.event_name == 'push' && github.ref == 'refs/heads/stable'
    steps:
      - uses: actions/checkout@v6
      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: "3.12"
      - name: Set up Rust
        uses: dtolnay/rust-toolchain@stable
      - name: Set up uv
        uses: astral-sh/setup-uv@v7
      - name: Build PyPi package
        run: uv run maturin build --release --out dist
      - name: Publish PyPi package
        run: uv run maturin publish --username __token__ --password ${{ secrets.PYPI_TOKEN }}

  linux:
    runs-on: ${{ matrix.platform.runner }}
    needs: publish
    if: github.event_name == 'push' && github.ref == 'refs/heads/stable'
    strategy:
      matrix:
        platform:
          - runner: ubuntu-22.04
            target: x86_64
          - runner: ubuntu-22.04
            target: x86
          - runner: ubuntu-22.04
            target: aarch64
          - runner: ubuntu-22.04
            target: armv7
          - runner: ubuntu-22.04
            target: s390x
          - runner: ubuntu-22.04
            target: ppc64le
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-python@v6
        with:
          python-version: 3.x
      - name: Build wheels
        uses: PyO3/maturin-action@v1
        with:
          target: ${{ matrix.platform.target }}
          args: --release --out dist --find-interpreter
          sccache: false
          manylinux: auto
      - name: Upload wheels
        uses: actions/upload-artifact@v5
        with:
          name: wheels-linux-${{ matrix.platform.target }}
          path: dist

  musllinux:
    runs-on: ${{ matrix.platform.runner }}
    needs: publish
    if: github.event_name == 'push' && github.ref == 'refs/heads/stable'
    strategy:
      matrix:
        platform:
          - runner: ubuntu-22.04
            target: x86_64
          - runner: ubuntu-22.04
            target: x86
          - runner: ubuntu-22.04
            target: aarch64
          - runner: ubuntu-22.04
            target: armv7
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-python@v6
        with:
          python-version: 3.x
      - name: Build wheels
        uses: PyO3/maturin-action@v1
        with:
          target: ${{ matrix.platform.target }}
          args: --release --out dist --find-interpreter
          sccache: false
          manylinux: musllinux_1_2
      - name: Upload wheels
        uses: actions/upload-artifact@v5
        with:
          name: wheels-musllinux-${{ matrix.platform.target }}
          path: dist

  windows:
    runs-on: ${{ matrix.platform.runner }}
    needs: publish
    if: github.event_name == 'push' && github.ref == 'refs/heads/stable'
    strategy:
      matrix:
        platform:
          - runner: windows-latest
            target: x64
          - runner: windows-latest
            target: x86
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-python@v6
        with:
          python-version: 3.x
          architecture: ${{ matrix.platform.target }}
      - name: Build wheels
        uses: PyO3/maturin-action@v1
        with:
          target: ${{ matrix.platform.target }}
          args: --release --out dist --find-interpreter
          sccache: false
      - name: Upload wheels
        uses: actions/upload-artifact@v5
        with:
          name: wheels-windows-${{ matrix.platform.target }}
          path: dist

  macos:
    runs-on: ${{ matrix.platform.runner }}
    needs: publish
    if: github.event_name == 'push' && github.ref == 'refs/heads/stable'
    strategy:
      matrix:
        platform:
          - runner: macos-15-intel
            target: x86_64
          - runner: macos-latest
            target: aarch64
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-python@v6
        with:
          python-version: 3.x
      - name: Build wheels
        uses: PyO3/maturin-action@v1
        with:
          target: ${{ matrix.platform.target }}
          args: --release --out dist --find-interpreter
          sccache: false
      - name: Upload wheels
        uses: actions/upload-artifact@v5
        with:
          name: wheels-macos-${{ matrix.platform.target }}
          path: dist

  sdist:
    runs-on: ubuntu-latest
    needs: publish
    if: github.event_name == 'push' && github.ref == 'refs/heads/stable'
    steps:
      - uses: actions/checkout@v6
      - name: Build sdist
        uses: PyO3/maturin-action@v1
        with:
          command: sdist
          args: --out dist
      - name: Upload sdist
        uses: actions/upload-artifact@v5
        with:
          name: wheels-sdist
          path: dist

  release:
    name: Release
    runs-on: ubuntu-latest
    needs: [linux, musllinux, windows, macos, sdist]
    if: github.event_name == 'push' && github.ref == 'refs/heads/stable'
    permissions:
      # Use to sign the release artifacts
      id-token: write
      # Used to upload release artifacts
      contents: write
      # Used to generate artifact attestation
      attestations: write
    steps:
      - uses: actions/download-artifact@v6
      - name: Generate artifact attestation
        uses: actions/attest-build-provenance@v3
        with:
          subject-path: 'wheels-*/*'
      - name: Publish wheels to PyPI
        uses: PyO3/maturin-action@v1
        env:
          MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
        with:
          command: upload
          args: --non-interactive --skip-existing wheels-*/*
