name: Wheel build

on:
  push:
    paths-ignore:
      - ".devcontainer/**"
      - ".vscode/**"
      - "doc/**"
      - "*.md"
    branches:
      - "main"
    tags:
      - "v*"
  pull_request_review:
    types: [submitted, edited]
  workflow_dispatch:

jobs:
  wheel-build:
    name: Python wheel build
    if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event.review.state == 'approved' }}
    strategy:
      fail-fast: false
      matrix:
        os-arch:
          ["manylinux_x86_64", "win_amd64", "macosx_x86_64", "macosx_arm64"]
        cibw-python: ["cp39", "cp310", "cp311", "cp312", "cp313"]
        # Documentation for `include`: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrixinclude
        include:
          - os-arch: "manylinux_x86_64"
            os: "ubuntu-24.04"
          - os-arch: "win_amd64"
            os: "windows-2022"
          - os-arch: "macosx_x86_64"
            os: "macos-13"
          - os-arch: "macosx_arm64"
            os: "macos-14"
          - cibw-python: "cp39"
            python-version: "3.9"
          - cibw-python: "cp310"
            python-version: "3.10"
          - cibw-python: "cp311"
            python-version: "3.11"
          - cibw-python: "cp312"
            python-version: "3.12"
          - cibw-python: "cp313"
            python-version: "3.13"
        exclude:
          # since `pip install 'openfermion<1.7.0'` fails: https://github.com/qulacs/qulacs/actions/runs/13757608985
          - os-arch: "win_amd64"
            cibw-python: "cp313"

    runs-on: ${{ matrix.os }}
    env:
      CIBW_BUILD: ${{ matrix.cibw-python }}-${{ matrix.os-arch }}
      PYTHON: ${{ matrix.python-version }}
      TWINE_USERNAME: "__token__"
    steps:
      - uses: actions/checkout@v4

      - name: Setup cmake
        uses: lukka/get-cmake@latest

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

      - name: Install Python dependencies
        run: python -m pip install cibuildwheel twine

      - name: Install boost if ubuntu
        if: ${{ contains(matrix.os, 'ubuntu') }}
        run: sudo apt update && sudo apt install libboost-dev

      - name: Install boost if macos
        if: ${{ contains(matrix.os, 'macos') }}
        run: |
          brew update
          brew install boost
          brew link boost

      - name: Install boost if windows
        if: ${{ contains(matrix.os, 'windows') }}
        uses: MarkusJx/install-boost@v2.4.0
        id: install-boost
        with:
          boost_version: 1.77.0

      - name: Run cibuildwheel for Windows
        if: ${{ contains(matrix.os, 'windows') }}
        run: python -m cibuildwheel --output-dir wheels
        env:
          BOOST_ROOT: ${{ steps.install-boost.outputs.BOOST_ROOT }}

      - name: Run cibuildwheel for Mac, Linux
        if: ${{ !contains(matrix.os, 'windows') }}
        run: python -m cibuildwheel --output-dir wheels

      - name: Upload wheel to GitHub
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.cibw-python }}-${{ matrix.os-arch }}
          path: ./wheels/*.whl

      - name: Upload wheel data if the Git tag is set
        run: python -m twine upload wheels/*.whl
        if: ${{ contains(github.ref, '/tags/') }}
        env:
          TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD_QULACS }}

  sdist:
    name: Source distribution
    if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event.review.state == 'approved' }}
    strategy:
      matrix:
        python-version: ["3.10.8"]
        os: ["ubuntu-24.04"]
    runs-on: ${{ matrix.os }}
    env:
      PYTHON: ${{ matrix.python-version }}
      COVERAGE: "ON"
      TWINE_USERNAME: "__token__"
    steps:
      - uses: actions/checkout@v4

      - name: Setup cmake
        uses: lukka/get-cmake@latest

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
          architecture: x64

      - name: Install boost
        run: sudo apt update && sudo apt install libboost-dev

      - name: Install Python dependencies
        run: python -m pip install twine build

      - name: create sdist
        run: python -m build --sdist

      - name: Upload sdist data if the Git tag is set
        run: python -m twine upload dist/*.tar.gz
        if: ${{ contains(github.ref, '/tags/') }}
        env:
          TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD_QULACS }}
