name: Release

on:
  push:
    tags:
      - 'v[0-9]+.[0-9]+.[0-9]+'
  workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
  contents: read
  pages: write
  id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  test:
    name: 🧪 Tests
    uses: ./.github/workflows/test.yml

  build:
    name: 📦 Build 🐍
    needs: test
    strategy:
      matrix:
        os:
          - ubuntu-latest
          - windows-latest
          - macos-latest
        target:
          - x86_64
          - aarch64
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-python@v6
      - uses: actions-rust-lang/setup-rust-toolchain@v1
      - name: Python stub generation
        run: cargo run --bin stub-gen
      - name: Build wheels
        uses: PyO3/maturin-action@v1
        with:
          target: ${{ matrix.target }}
          args: --release --out dist --interpreter 3.10 3.11 3.12 3.13 3.13t 3.14 3.14t
          sccache: 'true'
          manylinux: auto
      - name: Upload wheels
        uses: actions/upload-artifact@v5
        with:
          name: wheels-${{ matrix.os }}-${{ matrix.target }}
          path: dist

  sdist:
    name: 📦 Packaging source dist 🐍
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions-rust-lang/setup-rust-toolchain@v1
      - run: cargo run --bin stub-gen
      - name: Build sdist
        uses: PyO3/maturin-action@v1
        with:
          command: sdist
          args: --out dist
      - name: Upload sdist
        uses: actions/upload-artifact@v4
        with:
          name: wheels-sdist
          path: dist

  release:
    name: 📤 Release to PyPI 🐍
    runs-on: ubuntu-latest
    needs: [build, sdist]
    steps:
      - uses: actions/download-artifact@v4
      - name: Publish to PyPI
        uses: PyO3/maturin-action@v1
        env:
          MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
        with:
          command: upload
          args: --non-interactive --skip-existing wheels-*/*

  docs:
    name: 📚 Build docs
    needs: release
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Setup Pages
        uses: actions/configure-pages@v5
      - uses: actions/setup-python@v5
        with:
          python-version: 3.14
      - uses: actions-rust-lang/setup-rust-toolchain@v1
      - run: cargo run --bin stub-gen
      - name: Install UV
        uses: yezz123/setup-uv@v4
        with:
          uv-version: 0.10.2
      - name: Install dependencies
        run: |
          uv sync
          uv run maturin dev
          uv run pdoc python/lle -o ./docs --docformat=google
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          # Upload entire repository
          path: './docs'
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

  package:
    name: 📦 Package and publish to crates.io
    runs-on: ubuntu-latest
    needs: release
    steps:
      - uses: actions/checkout@v4
      - name: Install Rust
        uses: actions-rust-lang/setup-rust-toolchain@v1
      - name: Build and publish
        run: |
          cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
