name: Build and publish

on:
  push:
    branches:
      - main  # just build the sdist & wheel, skip release
    tags:
      - "*"
  pull_request:  # also build on PRs touching this file
    paths:
      - ".github/workflows/release.yml"
      - "ci/*"
      - "MANIFEST.in"
      - "pyproject.toml"
      - "setup.py"

jobs:
  build_sdist:
    name: Build sdist
    runs-on: ubuntu-latest

    steps:
      - name: Checkout source
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: "3.10"

      - name: Build a source tarball
        run: |
          python -m pip install --upgrade pip
          python -m pip install build twine
          python -m build --sdist
          twine check --strict dist/*

      - uses: actions/upload-artifact@v3
        with:
          path: ./dist/*.tar.gz
          retention-days: 30

  build_wheels:
    name: Build ${{ matrix.arch }} wheels on ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    env:
      GEOS_VERSION: "3.11.2"
    strategy:
      fail-fast: false
      matrix:
        include:
        - os: ubuntu-20.04
          arch: x86_64
        - os: ubuntu-20.04
          arch: i686
        # The aarch64 build has been transferred to Travis
        # - os: ubuntu-20.04
        #   arch: aarch64
        #   qemu_platform: arm64
        # Note: Numpy doesn't have ppc64le & s390x wheels
        # Also, some GEOS tests fail on s390x.
        - os: windows-2019
          arch: x86
          msvc_arch: x86
        - os: windows-2019
          arch: AMD64
          msvc_arch: x64
        - os: macos-11
          arch: x86_64
          cmake_osx_architectures: x86_64
        - os: macos-11
          arch: arm64
          cmake_osx_architectures: arm64
        - os: macos-11
          arch: universal2
          cmake_osx_architectures: "x86_64;arm64"

    steps:
      - name: Checkout source
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Cache GEOS build
        uses: actions/cache@v3
        with:
          path: ${{ runner.temp }}/geos-${{ env.GEOS_VERSION }}
          key: ${{ matrix.os }}-${{ matrix.arch }}-${{ env.GEOS_VERSION }}-${{ hashFiles('ci/*') }}

      - name: Add GEOS LICENSE
        run: |
          cp ci/wheelbuilder/LICENSE_GEOS .
        shell: bash

      - name: Add MSVC LICENSE
        run: |
          cp ci/wheelbuilder/LICENSE_win32 .
        shell: bash
        if: ${{ matrix.os == 'windows-2019' }}

      # - name: Set up QEMU
      #   uses: docker/setup-qemu-action@v1
      #   with:
      #     platforms: ${{ matrix.qemu_platform }}
      #   if: ${{ matrix.qemu_platform }}

      - name: Activate MSVC
        uses: ilammy/msvc-dev-cmd@v1
        with:
          arch: ${{ matrix.msvc_arch }}
        if: ${{ matrix.msvc_arch }}

      - name: Build wheels
        uses: pypa/cibuildwheel@v2.14.1
        env:
          CIBW_ARCHS: ${{ matrix.arch }}
          CIBW_SKIP: cp36-* pp* *musllinux* cp310-manylinux_i686
          CIBW_ENVIRONMENT_LINUX:
            GEOS_VERSION=${{ env.GEOS_VERSION }}
            GEOS_INSTALL=/host${{ runner.temp }}/geos-${{ env.GEOS_VERSION }}
            GEOS_CONFIG=/host${{ runner.temp }}/geos-${{ env.GEOS_VERSION }}/bin/geos-config
            LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/host${{ runner.temp }}/geos-${{ env.GEOS_VERSION }}/lib
          CIBW_ENVIRONMENT_MACOS:
            GEOS_INSTALL=${{ runner.temp }}/geos-${{ env.GEOS_VERSION }}
            GEOS_CONFIG=${{ runner.temp }}/geos-${{ env.GEOS_VERSION }}/bin/geos-config
            LDFLAGS=-Wl,-rpath,${{ runner.temp }}/geos-${{ env.GEOS_VERSION }}/lib
            MACOSX_DEPLOYMENT_TARGET=10.9
            CMAKE_OSX_ARCHITECTURES='${{ matrix.cmake_osx_architectures }}'
          CIBW_ENVIRONMENT_WINDOWS:
            GEOS_INSTALL='${{ runner.temp }}\geos-${{ env.GEOS_VERSION }}'
            GEOS_LIBRARY_PATH='${{ runner.temp }}\geos-${{ env.GEOS_VERSION }}\lib'
            GEOS_INCLUDE_PATH='${{ runner.temp }}\geos-${{ env.GEOS_VERSION }}\include'
          CIBW_BEFORE_ALL: ./ci/install_geos.sh
          CIBW_BEFORE_ALL_WINDOWS: ci\install_geos.cmd
          CIBW_BEFORE_BUILD_WINDOWS: pip install delvewheel
          CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: delvewheel repair --add-path ${{ runner.temp }}\geos-${{ env.GEOS_VERSION }}\bin -w {dest_dir} {wheel}
          CIBW_TEST_REQUIRES: pytest
          CIBW_TEST_COMMAND: pytest --pyargs shapely.tests

      - name: Upload artifacts
        uses: actions/upload-artifact@v3
        with:
          path: ./wheelhouse/*.whl
          retention-days: 5

  publish:
    name: Publish on GitHub and PyPI
    needs: [build_wheels, build_sdist]
    runs-on: ubuntu-latest
    # release on every tag
    if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/')
    steps:
      - uses: actions/download-artifact@v3
        with:
          name: artifact
          path: dist

      - name: Create GitHub Release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
        with:
          tag_name: ${{ github.ref }}
          release_name: ${{ github.ref }}
          draft: false
          prerelease: false

      - name: Get Asset name
        run: |
          export PKG=$(ls dist/ | grep tar)
          set -- $PKG
          echo "name=$1" >> $GITHUB_ENV

      - name: Upload Release Asset (sdist) to GitHub
        id: upload-release-asset
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: dist/${{ env.name }}
          asset_name: ${{ env.name }}
          asset_content_type: application/zip

      - name: Upload Release Assets to PyPI
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          user: __token__
          password: ${{ secrets.pypi_password }}
          skip_existing: true
          # To test: repository_url: https://test.pypi.org/legacy/
