# This workflow builds release Python wheels for the 4.2 maintenance line.

name: Build Python Wheels for Release

on:
  release:
    types: [published]
  workflow_dispatch:

jobs:
  build_wheels:
    name: Build Wheels
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            python_version: "3.11"
            cibw_python_version: 311
            platform_id: manylinux_x86_64
            manylinux_image: manylinux2014
          - os: ubuntu-latest
            python_version: "3.12"
            cibw_python_version: 312
            platform_id: manylinux_x86_64
            manylinux_image: manylinux2014
          - os: ubuntu-latest
            python_version: "3.13"
            cibw_python_version: 313
            platform_id: manylinux_x86_64
            manylinux_image: manylinux2014
          - os: ubuntu-latest
            python_version: "3.14"
            cibw_python_version: 314
            platform_id: manylinux_x86_64
            manylinux_image: manylinux2014
          - os: ubuntu-24.04-arm
            python_version: "3.11"
            cibw_python_version: 311
            platform_id: manylinux_aarch64
            manylinux_image: manylinux2014
          - os: ubuntu-24.04-arm
            python_version: "3.12"
            cibw_python_version: 312
            platform_id: manylinux_aarch64
            manylinux_image: manylinux2014
          - os: ubuntu-24.04-arm
            python_version: "3.13"
            cibw_python_version: 313
            platform_id: manylinux_aarch64
            manylinux_image: manylinux2014
          - os: ubuntu-24.04-arm
            python_version: "3.14"
            cibw_python_version: 314
            platform_id: manylinux_aarch64
            manylinux_image: manylinux2014
          - os: macos-15
            python_version: "3.11"
            cibw_python_version: 311
            platform_id: macosx_arm64
            macos_arch: arm64
            boost_arch: arm
          - os: macos-15
            python_version: "3.12"
            cibw_python_version: 312
            platform_id: macosx_arm64
            macos_arch: arm64
            boost_arch: arm
          - os: macos-15
            python_version: "3.13"
            cibw_python_version: 313
            platform_id: macosx_arm64
            macos_arch: arm64
            boost_arch: arm
          - os: macos-15
            python_version: "3.14"
            cibw_python_version: 314
            platform_id: macosx_arm64
            macos_arch: arm64
            boost_arch: arm
          - os: macos-15-intel
            python_version: "3.11"
            cibw_python_version: 311
            platform_id: macosx_x86_64
            macos_arch: x86_64
            boost_arch: x86
          - os: macos-15-intel
            python_version: "3.12"
            cibw_python_version: 312
            platform_id: macosx_x86_64
            macos_arch: x86_64
            boost_arch: x86
          - os: macos-15-intel
            python_version: "3.13"
            cibw_python_version: 313
            platform_id: macosx_x86_64
            macos_arch: x86_64
            boost_arch: x86
          - os: macos-15-intel
            python_version: "3.14"
            cibw_python_version: 314
            platform_id: macosx_x86_64
            macos_arch: x86_64
            boost_arch: x86

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          ref: ${{ github.sha }}

      - name: Set up Python ${{ matrix.python_version }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python_version }}

      - name: Install Dependencies
        run: |
          python3 -m pip install -r python/dev_requirements.txt
          if [ "$RUNNER_OS" == "Linux" ]; then
            sudo apt update
            sudo apt-get install -y libicu-dev python3-pip python3-setuptools libboost-all-dev
          elif [ "$RUNNER_OS" == "macOS" ]; then
            brew install boost python-setuptools
          else
            echo "$RUNNER_OS not supported"
            exit 1
          fi

      - name: Run CMake
        run: |
          cmake -B build -G Ninja -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DGTSAM_BUILD_PYTHON=1 -DGTSAM_PYTHON_VERSION=${{ matrix.python_version }}

      - name: Uninstall Boost (MacOS)
        if: runner.os == 'macOS'
        run: |
          brew uninstall boost

      - name: Build and test wheels
        env:
          CIBW_BUILD: cp${{ matrix.cibw_python_version }}-${{ matrix.platform_id }}
          CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.manylinux_image }}
          CIBW_MANYLINUX_AARCH64_IMAGE: ${{ matrix.manylinux_image }}
          CIBW_ARCHS: all
          CIBW_ARCHS_MACOS: ${{ matrix.macos_arch }}
          GTSAM_BOOST_ARCH: ${{ matrix.boost_arch }}
          GTSAM_OSX_ARCHITECTURES: ${{ matrix.macos_arch }}
          MACOSX_DEPLOYMENT_TARGET: 10.15
          CIBW_REPAIR_WHEEL_COMMAND_MACOS: DYLD_LIBRARY_PATH=$REPAIR_LIBRARY_PATH delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}
          CIBW_BUILD_FRONTEND: "build"
          CIBW_BEFORE_ALL: bash .github/scripts/python_wheels/cibw_before_all.sh ${{ matrix.python_version }} {project}
          CIBW_BUILD_VERBOSITY: 1
        run: bash .github/scripts/python_wheels/build_wheels.sh

      - name: Test wheel
        run: |
          python3 -m pip install wheelhouse/*.whl
          python3 -c "import platform; print(platform.machine()); import gtsam"

      - name: Store artifacts
        uses: actions/upload-artifact@v4
        with:
          name: cibw-wheels-cp${{ matrix.cibw_python_version }}-${{ matrix.platform_id }}
          path: wheelhouse/*.whl

  upload_all:
    name: Upload All
    needs: build_wheels
    runs-on: ubuntu-latest
    permissions:
      id-token: write
    steps:
      - name: Download Artifacts
        uses: actions/download-artifact@v4
        with:
          path: dist/
          merge-multiple: true

      - name: Publish to PyPI
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          verbose: true
          packages-dir: dist/
          repository-url: https://test.pypi.org/legacy/
