name: Build and publish

on:
  release:
    types: [published]
  pull_request:
  push:
    branches:
      - main

permissions:
  contents: read

jobs:
  main:
    name: sdist + pure wheel
    runs-on: ubuntu-latest
    if: github.event_name == 'release'

    steps:
      - uses: actions/checkout@v4

      - name: Set up latest Python
        uses: actions/setup-python@v4
        with:
          python-version: "*"

      - name: Install latest pip, build, twine
        run: |
          python -m pip install --upgrade --disable-pip-version-check pip
          python -m pip install --upgrade build twine

      - name: Build wheel and source distributions
        run: python -m build

      - if: github.event_name == 'release'
        name: Upload to PyPI via Twine
        env:
          TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
        run: twine upload --verbose -u '__token__' dist/*

  generate_wheels_matrix:
    name: generate wheels matrix
    runs-on: ubuntu-latest
    outputs:
      include: ${{ steps.set-matrix.outputs.include }}
    steps:
      - uses: actions/checkout@v4
      - name: Install cibuildwheel and pypyp
        run: |
          pipx install cibuildwheel==2.15.0
          pipx install pypyp==1
      - name: generate matrix
        if: github.event_name != 'pull_request'
        run: |
          {
            cibuildwheel --print-build-identifiers --platform linux \
            | pyp 'json.dumps({"only": x, "os": "ubuntu-latest"})' \
            && cibuildwheel --print-build-identifiers --platform macos \
            | pyp 'json.dumps({"only": x, "os": "macos-latest"})' \
            && cibuildwheel --print-build-identifiers --platform windows \
            | pyp 'json.dumps({"only": x, "os": "windows-latest"})'
          } | pyp 'json.dumps(list(map(json.loads, lines)))' > /tmp/matrix
        env:
          CIBW_ARCHS_LINUX: x86_64
          CIBW_ARCHS_MACOS: x86_64 arm64
          CIBW_ARCHS_WINDOWS: AMD64
      - name: generate matrix (PR)
        if: github.event_name == 'pull_request'
        run: |
          cibuildwheel --print-build-identifiers --platform linux \
          | pyp 'json.dumps({"only": x, "os": "ubuntu-latest"})' \
          | pyp 'json.dumps(list(map(json.loads, lines)))' > /tmp/matrix
        env:
          CIBW_BUILD: "cp38-* cp311-*"
          CIBW_ARCHS_LINUX: x86_64
      - id: set-matrix
        run: echo "include=$(cat /tmp/matrix)" | tee -a $GITHUB_OUTPUT

  mypyc:
    name: mypyc wheels ${{ matrix.only }}
    needs: generate_wheels_matrix
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include: ${{ fromJson(needs.generate_wheels_matrix.outputs.include) }}

    steps:
      - uses: actions/checkout@v4
      - uses: pypa/cibuildwheel@v2.16.1
        with:
          only: ${{ matrix.only }}

      - name: Upload wheels as workflow artifacts
        uses: actions/upload-artifact@v3
        with:
          name: ${{ matrix.name }}-mypyc-wheels
          path: ./wheelhouse/*.whl

      - if: github.event_name == 'release'
        name: Upload wheels to PyPI via Twine
        env:
          TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
        run: pipx run twine upload --verbose -u '__token__' wheelhouse/*.whl

  update-stable-branch:
    name: Update stable branch
    needs: [main, mypyc]
    runs-on: ubuntu-latest
    if: github.event_name == 'release'
    permissions:
      contents: write

    steps:
      - name: Checkout stable branch
        uses: actions/checkout@v4
        with:
          ref: stable
          fetch-depth: 0

      - if: github.event_name == 'release'
        name: Update stable branch to release tag & push
        run: |
          git reset --hard ${{ github.event.release.tag_name }}
          git push
