name: Build and publish

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

permissions: {}

jobs:
  main:
    name: sdist + pure wheel
    runs-on: ubuntu-latest
    if: github.event_name == 'release'
    environment:
      name: release
      url: https://pypi.org/p/black

    permissions:
      id-token: write # Required for PyPI trusted publishing

    steps:
      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
        with:
          persist-credentials: false

      - name: Set up latest Python
        uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
        with:
          python-version: "3.13"
          allow-prereleases: true

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

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

      - if: github.event_name == 'release'
        name: Publish package distributions to PyPI
        uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
        with:
          verbose: true

  generate_wheels_matrix:
    name: generate wheels matrix
    runs-on: ubuntu-latest
    outputs:
      include: ${{ steps.set-matrix.outputs.include }}
    steps:
      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
        with:
          persist-credentials: false
      # Keep cibuildwheel version in sync with below
      - name: Install cibuildwheel and pypyp
        run: |
          pipx install cibuildwheel==3.2.1
          pipx install pypyp==1.3.0
      - name: generate matrix
        if: |
          github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'ci: build all wheels')
        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"})' \
            && cibuildwheel --print-build-identifiers --platform windows --archs ARM64 \
            | pyp 'json.dumps({"only": x, "os": "windows-11-arm"})'
          } | 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' && !contains(github.event.pull_request.labels.*.name, 'ci: build all wheels')
        run: |
          {
            CIBW_BUILD="cp310-*" cibuildwheel --print-build-identifiers --platform linux | pyp 'json.dumps({"only": x, "os": "ubuntu-latest"})'
            CIBW_BUILD="cp314-*" 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
      - 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 }}
    if: github.event_name == 'release'
    environment:
      name: release
      url: https://pypi.org/p/black
    permissions:
      id-token: write # Required for PyPI trusted publishing
    strategy:
      fail-fast: false
      matrix:
        include: ${{ fromJson(needs.generate_wheels_matrix.outputs.include) }}

    steps:
      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
        with:
          persist-credentials: false
      # Keep cibuildwheel version in sync with above
      - uses: pypa/cibuildwheel@63fd63b352a9a8bdcc24791c9dbee952ee9a8abc # v3.3.0
        with:
          only: ${{ matrix.only }}

      - name: Upload wheels as workflow artifacts
        uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
        with:
          name: ${{ matrix.only }}-mypyc-wheels
          path: ./wheelhouse/*.whl

      - if: github.event_name == 'release'
        name: Publish package distributions to PyPI
        uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
        with:
          packages-dir: wheelhouse/
          verbose: true

  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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
        with:
          ref: stable
          fetch-depth: 0
          persist-credentials: true # needed for `git push` below

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