name: Build

# on: [push, pull_request, release]

on:
  push:
    branches:
  release:
    types: [created]
  pull_request:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  sdist:
    name: Build source distribution
    runs-on: ubuntu-latest
    steps:
      - name: Check out repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 0 # To ensure tags are retrieved to enable setuptools_scm to work
      - name: Install Python 3.x
        uses: actions/setup-python@v6
        with:
          python-version: 3.x
      - name: Build sdist
        run: pipx run build --sdist
      - name: Save sdist
        uses: actions/upload-artifact@v5
        with:
          name: cibw-sdist.tar.gz
          path: dist/*.tar.gz

  wheels:
    name: Build wheels on ${{ matrix.os }} CIBW_BUILD=${{ matrix.cibw_build }}
    runs-on: ${{ matrix.os }}
    strategy:
      # since multiple builds run at the same time, cancelling them all when one
      # fails is wasteful and forces handling build problems one by one instead
      # of showing a "full picture"
      fail-fast: false
      matrix:
        os:
          - ubuntu-latest
          - macos-15-intel # x86
          - macos-latest # arm
          - windows-latest
        cibw_build: [cp39-*, cp310-*, cp311-*, cp312-*, cp313-*, cp313t-*, cp314-*, cp314t-*]
    steps:
      - name: Check out repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 0 # To ensure tags are retrieved to enable setuptools_scm to work
      - name: Install Python 3.x
        uses: actions/setup-python@v6
        with:
          python-version: 3.x
      - name: Set up QEMU # Needed to build aarch64 wheels
        if: runner.os == 'Linux'
        uses: docker/setup-qemu-action@v3
        with:
          platforms: all

      - name: Setup free-threading variables
        if: ${{ endsWith(matrix.cibw_build, 't-*') }}
        shell: bash -l {0}
        run: |
          echo "CIBW_BEFORE_TEST=pip install pytest pytest-run-parallel" >> "$GITHUB_ENV"
          echo "CIBW_ENVIRONMENT=PYLZ4_USE_SYSTEM_LZ4=False PYTEST_ADDOPTS=--parallel-threads=4" >> "$GITHUB_ENV"
          echo "CIBW_TEST_COMMAND=tox -x testenv.deps+=pytest-run-parallel -x testenv.pass_env+=PYTEST_ADDOPTS -c {project}" >> "$GITHUB_ENV"
      - name: Setup environment
        if: ${{ !endsWith(matrix.cibw_build, 't-*') }}
        shell: bash -l {0}
        run: |
          echo "CIBW_ENVIRONMENT=PYLZ4_USE_SYSTEM_LZ4=False" >> "$GITHUB_ENV"
          echo "CIBW_TEST_COMMAND=tox -c {project}" >> "$GITHUB_ENV"
      - name: Build wheels
        uses: pypa/cibuildwheel@v3.3.0
        env:
          # CIBW_ARCHS_LINUX: "x86_64 i686 aarch64"
          CIBW_ARCHS_LINUX: "x86_64 i686"
          CIBW_ARCHS_MACOS: "auto64" # since we have both runner arches
          CIBW_ARCHS_WINDOWS: "AMD64 x86 ARM64"
          CIBW_ENABLE: cpython-freethreading
          CIBW_BUILD: ${{ matrix.cibw_build }}
          CIBW_SKIP: "cp*-musllinux*"
          CIBW_TEST_SKIP: "*-macosx_arm64 *-macosx_universal2:arm64 *-*linux_{ppc64le,s390x} *-win_arm64"
          CIBW_BEFORE_BUILD: "python -m pip install -U pip && python -m pip install tox"
      - name: Save wheels
        uses: actions/upload-artifact@v5
        with:
          name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
          path: ./wheelhouse/*.whl

  wheels_linux_arm:
    name: Build wheels on ${{ matrix.os }} CIBW_BUILD=${{ matrix.cibw_build }}
    runs-on: ${{ matrix.os }}
    strategy:
      # since multiple builds run at the same time, cancelling them all when one
      # fails is wasteful and forces handling build problems one by one instead
      # of showing a "full picture"
      fail-fast: false
      matrix:
        os:
          - ubuntu-24.04-arm
        cibw_build: [cp39-*, cp310-*, cp311-*, cp312-*, cp313-*, cp313t-*, cp314-*, cp314t-*]
    steps:
      - name: Check out repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 0 # To ensure tags are retrieved to enable setuptools_scm to work
      - name: Install Python 3.x
        uses: actions/setup-python@v6
        with:
          python-version: 3.x
      - name: Setup environment
        shell: bash -l {0}
        run: |
          echo "CIBW_ENVIRONMENT=PYLZ4_USE_SYSTEM_LZ4=False" >> "$GITHUB_ENV"
          echo "CIBW_TEST_COMMAND=tox -c {project}" >> "$GITHUB_ENV"
      - name: Build wheels
        uses: pypa/cibuildwheel@v3.3.0
        env:
          CIBW_ARCHS_LINUX: "aarch64"
          CIBW_BUILD: ${{ matrix.cibw_build }}
          CIBW_SKIP: "cp*-musllinux*"
          CIBW_ENABLE: cpython-freethreading
          CIBW_BEFORE_BUILD: "python -m pip install -U pip && python -m pip install tox"
      - name: Save wheels
        uses: actions/upload-artifact@v5
        with:
          name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
          path: ./wheelhouse/*.whl

  upload_pypi:
    name: Upload to PyPI
    needs: [sdist, wheels, wheels_linux_arm]
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/')
    steps:
      - uses: actions/download-artifact@v6
        with:
          pattern: cibw-*
          path: dist
          merge-multiple: true
      - uses: pypa/gh-action-pypi-publish@release/v1
        with:
          password: ${{ secrets.PYPI_API_TOKEN }}
          skip-existing: true