name: Build wheels and sdist and upload to PyPI

on:
  release:
    types:
      - published
  workflow_dispatch:

jobs:
  build_many_wheels:
    name: Standard linux
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: actions/setup-python@v5

      - name: Install cibuildwheel
        run: python -m pip install cibuildwheel==2.16.5

      - name: Build wheels
        run: python -m cibuildwheel --output-dir wheelhouse
        env:
          CIBW_ARCHS: "x86_64"
          CIBW_BUILD: "*manylinux*"
          CIBW_SKIP: cp36* cp37* pp*
          CIBW_BUILD_VERBOSITY: 3
          CIBW_BEFORE_BUILD: pip install -U pybind11-global
          CIBW_BEFORE_TEST: pip install -U pytest pytest-timeout pytest-cov pytest-xdist
          CIBW_TEST_COMMAND: pytest --skip_gha {package}/tests

      - uses: actions/upload-artifact@v4
        with:
          name: manylinux-artifacts
          path: ./wheelhouse/*.whl

  build_musl_wheels:
    name: Musl linux
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: actions/setup-python@v5

      - name: Install cibuildwheel
        run: python -m pip install cibuildwheel==2.16.5

      - name: Build wheels
        run: python -m cibuildwheel --output-dir wheelhouse
        env:
          CIBW_ARCHS: "x86_64"
          CIBW_BUILD: "*musllinux*"
          CIBW_SKIP: cp36* cp37* pp*
          CIBW_BUILD_VERBOSITY: 3
          CIBW_BEFORE_BUILD: >-
            pip install -U pybind11-global &&
            apk add --no-cache openblas-dev
          CIBW_BEFORE_TEST: pip install -U pytest pytest-timeout pytest-cov pytest-xdist
          CIBW_TEST_COMMAND: pytest --skip_gha {package}/tests

      - uses: actions/upload-artifact@v4
        with:
          name: musllinux-artifacts
          path: ./wheelhouse/*.whl

  build_macosx_x86_wheels:
    name: MacOS x86
    runs-on: macos-13
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: actions/setup-python@v5

      - name: Install cibuildwheel
        run: python -m pip install cibuildwheel==2.16.5

      - name: Build wheels
        run: python -m cibuildwheel --output-dir wheelhouse
        env:
          CIBW_ARCHS: "x86_64"
          CIBW_BUILD: "*macosx*"
          CIBW_SKIP: cp36* cp37* pp*
          CIBW_BUILD_VERBOSITY: 3
          CIBW_BEFORE_BUILD: >-
            pip install -U pybind11-global &&
            brew install llvm libomp fftw eigen
          CIBW_ENVIRONMENT: >-
            CC=/usr/local/opt/llvm/bin/clang
            CXX=/usr/local/opt/llvm/bin/clang++
            LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib"
            CPPFLAGS="-I/usr/local/opt/llvm/include"
          CIBW_BEFORE_TEST: pip install -U pytest pytest-timeout pytest-cov pytest-xdist
          CIBW_TEST_COMMAND: pytest --skip_gha {package}/tests

      - uses: actions/upload-artifact@v4
        with:
          name: macosx-x86-artifacts
          path: ./wheelhouse/*.whl

  build_macosx_arm_wheels:
    name: MacOS ARM
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: actions/setup-python@v5

      - name: Install cibuildwheel
        run: python -m pip install cibuildwheel==2.16.5

      - name: Build wheels
        run: python -m cibuildwheel --output-dir wheelhouse
        env:
          CIBW_ARCHS: "arm64"
          CIBW_BUILD: "*macosx*"
          CIBW_SKIP: cp36* cp37* pp*
          CIBW_BUILD_VERBOSITY: 3
          CIBW_BEFORE_BUILD: >-
            pip install -U pybind11-global &&
            brew install llvm libomp fftw eigen
          CIBW_ENVIRONMENT: >-
            CC=/opt/homebrew/opt/llvm/bin/clang
            CXX=/opt/homebrew/opt/llvm/bin/clang++
            LDFLAGS="-L/opt/homebrew/opt/llvm/lib -Wl,-rpath,/opt/homebrew/opt/llvm/lib"
            CPPFLAGS="-I/opt/homebrew/opt/llvm/include"
            PATH="/opt/homebrew/opt/llvm/bin:$PATH"
            FFTW_DIR="/opt/homebrew"
          CIBW_BEFORE_TEST: pip install -U pytest pytest-timeout pytest-cov pytest-xdist
          CIBW_TEST_COMMAND: pytest --skip_gha {package}/tests

      - uses: actions/upload-artifact@v4
        with:
          name: macosx-arm-artifacts
          path: ./wheelhouse/*.whl

  merge_wheels:
    name: Merge wheels
    needs: [build_many_wheels, build_musl_wheels, build_macosx_x86_wheels, build_macosx_arm_wheels]
    runs-on: ubuntu-latest
    steps:
      - name: Merge wheels
        uses: actions/upload-artifact/merge@v4
        with:
          name: wheels
          pattern: "*-artifacts"

  build_sdist:
    name: Build sdist and upload to PyPI
    needs: [merge_wheels]
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Install dependencies
        run: |
          python -m pip install -U pip
          pip install build setuptools_scm
          pip install -U numpy setuptools
          pip install -U -r requirements.txt
          pip install -U pybind11-global

      - name: Extract version
        run: |
          echo "PACKAGE_VERSION=$(python -c 'from setuptools_scm import get_version; print(get_version())')" >> $GITHUB_ENV

      - name: Download wheels
        uses: actions/download-artifact@v4
        with:
          path: ./wheels

      - name: Build sdist
        run: |
          python -m build --sdist
          ls -l dist
          tar tvfz dist/batoid-*.tar.gz

      - name: Copy wheels
        run: |
          echo ls -l wheels
          ls -l wheels
          echo ls -l wheels/wheels
          ls -l wheels/wheels
          cp wheels/wheels/*.whl dist
          echo ls -l dist
          ls -l dist

      - name: Publish to TestPyPI if alpha
        if: "contains(env.PACKAGE_VERSION, 'a')"
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          verbose: true
          password: ${{ secrets.TESTPYPI_PASSWORD }}
          repository-url: https://test.pypi.org/legacy/

      - name: Publish to PyPI if stable release
        if: "!contains(env.PACKAGE_VERSION, 'a') && !contains(env.PACKAGE_VERSION, '.dev')"
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          password: ${{ secrets.PYPI_PASSWORD }}
          verbose: true
