name: "Create Python distributions and upload to PyPI"

on:
  release:
    types: [ published ]
  workflow_dispatch: {}


env:
  STAN_BACKEND: "CMDSTANPY"

jobs:
  make-wheels:
    name: Make ${{ matrix.os }} ${{ matrix.cibw_arch }} wheels
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: ["macos-latest", "ubuntu-latest", "windows-latest", "macos-latest-xlarge"]
        cibw_arch: ["native"]
        # Build one wheel (ABI = none) using first build spec, then test on all python versions.
        cibw_build: ["cp39-* cp310-* cp311-*"]
        include:
          - os: ubuntu-latest
            cibw_arch: aarch64
            # Each test takes 30 mins, which is too long to run sequentially, so we test once only.
            cibw_build: "cp39-*"
      fail-fast: false

    steps:
      - name: "Set environment variables (Windows)"
        if: startsWith(runner.os, 'Windows')
        shell: pwsh
        run: |
          (Get-ItemProperty "HKLM:System\CurrentControlSet\Control\FileSystem").LongPathsEnabled
          $os_version = (Get-CimInstance Win32_OperatingSystem).version
          Echo "OS_VERSION=$os_version" >> $env:GITHUB_ENV

      - name: "Checkout repo"
        uses: actions/checkout@v4

      # Temporary, until pipx is added to the macOS large runner image
      - name: "Install pipx"
        if: matrix.os == 'macos-latest-xlarge'
        run: |
          brew install pipx
          pipx ensurepath

      - name: "Restore RTools40"
        if: startsWith(runner.os, 'Windows')
        id: cache-rtools
        uses: actions/cache@v3
        with:
          path: C:/rtools40
          key: ${{ runner.os }}-${{ env.OS_VERSION }}-rtools-v1

      - name: Set up QEMU
        if: matrix.cibw_arch == 'aarch64'
        uses: docker/setup-qemu-action@v2
        with:
          platforms: arm64

      - name: "Build wheels"
        uses: pypa/cibuildwheel@v2.16.2
        with:
          package-dir: python
        env:
          CIBW_ENVIRONMENT: >
            STAN_BACKEND="${{ env.STAN_BACKEND }}"
          CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014
          CIBW_BUILD: ${{ matrix.cibw_build }}
          CIBW_SKIP: "*musllinux*"
          CIBW_ARCHS: ${{ matrix.cibw_arch }}
          CIBW_BUILD_FRONTEND: build
          CIBW_TEST_REQUIRES: pytest
          CIBW_TEST_COMMAND: pytest --pyargs prophet

      - name: "Upload wheel as artifact"
        uses: actions/upload-artifact@v3
        with:
          name: artifact-${{ matrix.os }}-${{ matrix.cibw_arch }}-wheel
          path: "./**/*.whl"

  make-sdist:
    name: Make source distribution
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3

    - run: pipx run build --sdist
      working-directory: python

    - uses: actions/upload-artifact@v3
      with:
        name: artifact-source-dist
        path: "./**/dist/*.tar.gz"

  upload:
    name: Upload to PyPI
    needs: [make-wheels, make-sdist]
    runs-on: ubuntu-latest
    if: github.event_name == 'release' && github.event.action == 'published'
    steps:
    - name: Download all artifacts
      uses: actions/download-artifact@v3

    - name: Copy artifacts to dist/ folder
      run: |
        find . -name 'artifact-*' -exec unzip '{}' \;
        mkdir -p dist/
        find . -name '*.tar.gz' -exec mv '{}' dist/ \;
        find . -name '*.whl' -exec mv '{}' dist/ \;

    - name: Upload
      uses: pypa/gh-action-pypi-publish@v1.4.2
      with:
        user: ${{ secrets.PYPI_USERNAME }}
        password: ${{ secrets.PYPI_PASSWORD }}
