name: Build and Release

on:
  push:
    branches:
      - master
      - maintenance/*
  create:
    tags:
      - 'v[0-9]+.[0-9]+.[0-9]+*'

env:
  PACKAGE_NAME: labscript
  SCM_LOCAL_SCHEME: no-local-version
  ANACONDA_USER: labscript-suite

  # Configuration for a package with compiled extensions:
  # PURE: false
  # NOARCH: false

  # Configuration for a package with no extensions, but with dependencies that differ by
  # platform or Python version:
  # PURE: true
  # NOARCH: false

  # Configuration for a package with no extensions and the same dependencies on all
  # platforms and Python versions. For this configuration you should comment out all but
  # the first entry in the job matrix of the build job since multiple platforms are not
  # needed.
  PURE: true
  NOARCH: true

jobs:
  build:
    name: Build
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        include:
          - { os: ubuntu-latest,   python: '3.11',  arch: x64, conda: true}
         # - { os: ubuntu-latest,   python: '3.10',  arch: x64, conda: true }
         # - { os: ubuntu-latest,   python: '3.9',  arch: x64, conda: true }
         # - { os: ubuntu-latest,   python: '3.8',  arch: x64, conda: true }
         # - { os: ubuntu-latest,   python: '3.7',  arch: x64, conda: true }

         # - { os: macos-11,    python: '3.11',  arch: x64, conda: true }
         # - { os: macos-11,    python: '3.10',  arch: x64, conda: true }
         # - { os: macos-11,    python: '3.9',  arch: x64, conda: true }
         # - { os: macos-11,    python: '3.8',  arch: x64, conda: true }
         # - { os: macos-11,    python: '3.7',  arch: x64, conda: true }

         # - { os: windows-latest,  python: '3.11',  arch: x64, conda: true }
         # - { os: windows-latest,  python: '3.10',  arch: x64, conda: true }
         # - { os: windows-latest,  python: '3.9',  arch: x64, conda: true }
         # - { os: windows-latest,  python: '3.8',  arch: x64, conda: true }
         # - { os: windows-latest,  python: '3.7',  arch: x64, conda: true }

         # - { os: windows-latest,  python: '3.11',  arch: x86, conda: false } # conda not yet available
         # - { os: windows-latest,  python: '3.10',  arch: x86, conda: true }
         # - { os: windows-latest,  python: '3.9',  arch: x86, conda: true }
         # - { os: windows-latest,  python: '3.8',  arch: x86, conda: true }
         # - { os: windows-latest,  python: '3.7',  arch: x86, conda: true }

    if: github.repository == 'labscript-suite/labscript' && (github.event_name != 'create' || github.event.ref_type != 'branch')
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Ignore Tags
        if: github.event.ref_type != 'tag'
        run: git tag -d $(git tag --points-at HEAD)

      - name: Install Python
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python }}
          architecture: ${{ matrix.arch }}

      - name: Source Distribution
        if: strategy.job-index == 0
        run: |
          python -m pip install --upgrade pip setuptools wheel build
          python -m build -s .

      - name: Wheel Distribution
        # Impure Linux wheels are built in the manylinux job.
        if: (env.PURE == 'true' && strategy.job-index == 0) || (env.PURE == 'false' && runner.os != 'Linux')
        run: |
          python -m pip install --upgrade pip setuptools wheel build
          python -m build -w .

      - name: Upload Artifact
        if: strategy.job-index == 0 || (env.PURE == 'false' && runner.os != 'Linux')
        uses: actions/upload-artifact@v3
        with:
          name: dist
          path: ./dist

      - name: Set Variables for Conda Build
        if: matrix.conda
        shell: bash
        run: |
          if [ $NOARCH == true ]; then
              CONDA_BUILD_ARGS="--noarch"
          else
              CONDA_BUILD_ARGS=""
          fi
          echo "CONDA_BUILD_ARGS=$CONDA_BUILD_ARGS" >> $GITHUB_ENV

      - name: Install Miniconda
        if: matrix.conda
        uses: conda-incubator/setup-miniconda@v2
        with:
          auto-update-conda: true
          python-version: ${{ matrix.python }}
          architecture: ${{ matrix.arch }}
          miniconda-version: "latest"

      - name: Workaround conda-build incompatibility with xcode 12+
        if: runner.os == 'macOS'
        uses: maxim-lobanov/setup-xcode@v1
        with:
          xcode-version: 11.7

      - name: Conda package (Unix)
        if: (matrix.conda && runner.os != 'Windows')
        shell: bash -l {0}
        run: |
          conda install -c labscript-suite setuptools-conda
          setuptools-conda build $CONDA_BUILD_ARGS .

      - name: Conda Package (Windows)
        if: (matrix.conda && runner.os == 'Windows')
        shell: cmd /C CALL {0}
        run: |
          conda install -c labscript-suite setuptools-conda && ^
          setuptools-conda build %CONDA_BUILD_ARGS% --croot ${{ runner.temp }}\cb .

      - name: Upload Artifact
        if: matrix.conda
        uses: actions/upload-artifact@v3
        with:
          name: conda_packages
          path: ./conda_packages


  manylinux:
    name: Build Manylinux
    runs-on: ubuntu-latest
    if: github.repository == 'labscript-suite/labscript' && (github.event_name != 'create' || github.event.ref_type != 'branch')
    steps:
      - name: Checkout
        if: env.PURE == 'false'
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Ignore Tags
        if: github.event.ref_type != 'tag' && env.PURE == 'false'
        run: git tag -d $(git tag --points-at HEAD)

      - name: Build Manylinux Wheels
        if: env.PURE == 'false'
        uses: RalfG/python-wheels-manylinux-build@v0.4.2
        with:
          python-versions: 'cp37-cp37m cp38-cp38 cp39-cp39 cp310-cp310 cp311-cp311'
          pre-build-command: 'git config --global --add safe.directory "*"'

      - name: Upload Artifact
        if: env.PURE == 'false'
        uses: actions/upload-artifact@v3
        with:
          name: dist
          path: dist/*manylinux*.whl

  release:
    name: Release
    runs-on: ubuntu-latest
    needs: [build, manylinux]
    steps:

      - name: Download Artifact
        uses: actions/download-artifact@v3
        with:
          name: dist
          path: ./dist

      - name: Download Artifact
        uses: actions/download-artifact@v3
        with:
          name: conda_packages
          path: ./conda_packages

      - name: Get Version Number
        if: github.event.ref_type == 'tag'
        run: |
          VERSION="${GITHUB_REF/refs\/tags\/v/}"
          echo "VERSION=$VERSION" >> $GITHUB_ENV

      - name: Create GitHub Release and Upload Release Asset
        if: github.event.ref_type == 'tag'
        uses: softprops/action-gh-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.event.ref }}
          name: ${{ env.PACKAGE_NAME }} ${{ env.VERSION }}
          draft: true
          prerelease: ${{ contains(github.event.ref, 'rc') }}
          files: ./dist/${{ env.PACKAGE_NAME }}-${{ env.VERSION }}.tar.gz

      - name: Publish on TestPyPI
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          user: __token__
          password: ${{ secrets.testpypi }}
          repository-url: https://test.pypi.org/legacy/

      - name: Publish on PyPI
        if: github.event.ref_type == 'tag'
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          user: __token__
          password: ${{ secrets.pypi }}

      - name: Install Miniconda
        uses: conda-incubator/setup-miniconda@v2
        with:
          auto-update-conda: true

      - name: Install Anaconda cloud client
        shell: bash -l {0}
        run: conda install anaconda-client

      - name: Publish to Anaconda test label
        if: github.event.ref_type != 'tag'
        shell: bash -l {0}
        run: |
          anaconda \
            --token ${{ secrets.ANACONDA_API_TOKEN }} \
            upload \
            --user $ANACONDA_USER \
            --label test \
            conda_packages/*/*

      - name: Publish to Anaconda main label
        shell: bash -l {0}
        if: github.event.ref_type == 'tag'
        run: |
          anaconda \
            --token ${{ secrets.ANACONDA_API_TOKEN }} \
            upload \
            --user $ANACONDA_USER \
            conda_packages/*/*