name: Build and publish Python package

on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:

jobs:
  build:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [macos-11.0, ubuntu-18.04, windows-2019, self-hosted-linux-arm64, self-hosted-macos-arm64]
        python: [3.8, 3.9, '3.10']
    steps:
      - uses: actions/checkout@v1

      - name: Set up Python (x64)
        if: runner.name != 'linux-arm64' && runner.name != 'macos-arm64'
        uses: actions/setup-python@v1
        with:
          python-version: ${{ matrix.python }}
          architecture: 'x64'
      - name: Set up Python (Linux ARM64)
        if: runner.name == 'linux-arm64'
        run: |
          export PYENV_ROOT="$HOME/.pyenv"
          export PATH="$PYENV_ROOT/bin:$PATH"
          eval "$(pyenv init --path)"
          pyenv install -s ${{ matrix.python }}:latest
          pyenv global $(pyenv versions --bare | grep -F '${{ matrix.python }}.')
      - name: Set up Python (macOS ARM64)
        if: runner.name == 'macos-arm64'
        run: |
          brew unlink python
          brew link python@${{ matrix.python }}

      - name: Set up Rust
        if: runner.name != 'macos-arm64'
        uses: actions-rs/toolchain@v1
        with:
          toolchain: stable
          profile: minimal
          default: true

      - name: Run prebuild steps
        shell: bash
        run: bash ./prebuild.sh

      - name: Build native module
        working-directory: ./python
        run: cargo build --release

      - name: Install Python build tools (macOS x64)
        if: runner.os == 'macOS' && runner.name != 'macos-arm64'
        run: sudo pip install --upgrade maturin setuptools wheel twine
      - name: Install Python build tools (Linux x64, Windows x64)
        if: runner.os != 'macOS' && runner.name != 'linux-arm64'
        run: pip install --upgrade maturin setuptools wheel twine
      - name: Install Python build tools (Linux ARM64)
        if: runner.name == 'linux-arm64'
        run: |
          export PYENV_ROOT="$HOME/.pyenv"
          export PATH="$PYENV_ROOT/bin:$PATH"
          eval "$(pyenv init --path)"
          pip3 install --upgrade maturin setuptools wheel twine
      - name: Install Python build tools (macOS ARM64)
        if: runner.name == 'macos-arm64'
        run: /opt/homebrew/bin/pip3 install --upgrade maturin setuptools wheel twine

      - name: Pack and publish package
        shell: bash
        working-directory: ./python
        run: |
          cat << 'EOF' > "$HOME/.pypirc"
          [pypi]
          username = __token__
          password = ${{ secrets.PYPI_API_TOKEN }}
          EOF
          if [[ "${{ runner.name }}" == linux-arm64 ]]; then
            export PYENV_ROOT="$HOME/.pyenv"
            export PATH="$PYENV_ROOT/bin:$PATH"
            eval "$(pyenv init --path)"
          fi
          if [[ "${{ runner.name }}" == macos-arm64 ]]; then
            pathToPython="/opt/homebrew/bin/python3"
            # Ensure correct maturin and twine are used.
            export PATH="/opt/homebrew/bin:$PATH"
          else
            pathToPython="$(which python)"
          fi
          # On macOS ARM64 this may emit a warning like "Couldn't find the symbol `PyInit_minify_html` in the native library. Python will fail to import this module." Ignore this message.
          maturin build --release --strip -i "$pathToPython"
          if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
            # For idempotency, ignore any existing built wheels that have already been successfully uploaded.
            twine upload --skip-existing target/wheels/*
          else
            ls -al target/wheels/*
          fi
