name: build

on:
  push:
    branches:
      - main
      - develop
      - master
      - feature/*
    tags:
      - '*'
  
jobs:
  build-windows:
    runs-on: windows-2019
    strategy:
      matrix:
        python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] 
        cuda-version: ['10.2', '11.3', '11.4', '11.6', '11.7', '11.8', '12.0']
    steps:
      - uses: actions/checkout@master
      - uses: dorny/paths-filter@v2
        id: changes
        with:
          filters: |
            needbuild:
              - '.github/workflows/**'
              - 'setup.py'
              - 'spconv/csrc/**'
              - 'spconv/algo.py'
              - 'spconv/core.py'
              - 'pyproject.toml'
      - name: Install Boost
        env:
          CUDA_VERSION: ${{ matrix.cuda-version }}
          PYTHON_VERSION: ${{ matrix.python-version }}
          cuda: ${{ matrix.cuda-version }}
          BOOST_VERSION: boost_1_77_0
        if: |
          (
            (github.event_name == 'push' && (startsWith(github.ref, 'refs/tags')) ) || 
            (
              (steps.changes.outputs.needbuild == 'true') && 
              (env.PYTHON_VERSION == '3.10')
            )
          )
        shell: powershell
        run: |
          $ProgressPreference = 'SilentlyContinue'
          Invoke-WebRequest -Uri "https://boostorg.jfrog.io/artifactory/main/release/1.77.0/source/boost_1_77_0.zip" -UseBasicParsing -OutFile $HOME/boost.zip
          Expand-Archive $HOME/boost.zip -DestinationPath $HOME/boost

      - name: Install CUDA
        env:
          CUDA_VERSION: ${{ matrix.cuda-version }}
          PYTHON_VERSION: ${{ matrix.python-version }}
          cuda: ${{ matrix.cuda-version }}
        if: |
          (env.CUDA_VERSION != '') && (
            (github.event_name == 'push' && (startsWith(github.ref, 'refs/tags')) ) || 
            (
              (steps.changes.outputs.needbuild == 'true') && 
              (env.PYTHON_VERSION == '3.10')
            )
          )
        shell: powershell
        run: |
          .\tools\install_windows_cuda.ps1
        
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - uses: ilammy/msvc-dev-cmd@v1
      - name: Install pep build
        run: |
          python -m pip install build --user
          python -m pip install --upgrade pip twine wheel
          python -m pip install pytest setuptools

      - name: Build a windows binary wheel
        env:
          CUDA_VERSION: ${{ matrix.cuda-version }}
          PYTHON_VERSION: ${{ matrix.python-version }}
          BOOST_VERSION: boost_1_77_0
          CUMM_CUDA_VERSION: ${{ matrix.cuda-version }}
        if: |
          (env.CUDA_VERSION != '') && (
            (github.event_name == 'push' && (startsWith(github.ref, 'refs/tags')) ) || 
            (
              (steps.changes.outputs.needbuild == 'true') && 
              (env.PYTHON_VERSION == '3.10')
            )
          )
        run: |
          $Env:CUMM_CUDA_ARCH_LIST = "all"
          $Env:SPCONV_DISABLE_JIT = "1"
          pip install pccm pybind11
          # download boost header only
          $Env:BOOST_ROOT = "$HOME/boost/boost_1_77_0"
          # ls "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v${{ matrix.cuda-version }}\include\thrust"
          python -m build --wheel --outdir dist/ .
        shell: powershell

      - name: Publish a Python distribution to PyPI
        if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags'))
        run: |
          $Env:TWINE_USERNAME = "__token__"
          $Env:TWINE_PASSWORD = "${{ secrets.pypi_password }}"
          twine upload dist/*
        shell: powershell
  
  build:
    # needs: build-windows
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] # this version is only used for upload.
        cuda-version: ['102', '113', '114', '116', '117', '118', '120', '']

    steps:
      - uses: actions/checkout@master
      - uses: dorny/paths-filter@v2
        id: changes
        with:
          filters: |
            needbuild:
              - '.github/workflows/**'
              - 'setup.py'
              - 'spconv/csrc/**'
              - 'spconv/algo.py'
              - 'spconv/core.py'
              - 'pyproject.toml'

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}

      - name: Install pep build
        env:
          BOOST_VERSION: boost_1_77_0
        run: |
          python -m pip install build --user
          python -m pip install --upgrade pip twine wheel
          python -m pip install pytest setuptools
          mkdir -p third_party
          wget https://boostorg.jfrog.io/artifactory/main/release/1.77.0/source/$BOOST_VERSION.zip -O third_party/boost.zip
          unzip third_party/boost.zip -d third_party/boost

      - name: Build a cuda wheel
        env:
          CUDA_VERSION: ${{ matrix.cuda-version }}
          PYTHON_VERSION: ${{ matrix.python-version }}
          DOCKER_IMAGE: scrin/manylinux2014-cuda:cu${{ matrix.cuda-version }}-devel-1.0.0
          PLAT: manylinux2014_x86_64
          BOOST_VERSION: boost_1_77_0
        if: |
          (env.CUDA_VERSION != '') && (
            (github.event_name == 'push' && (startsWith(github.ref, 'refs/tags')) ) || 
            (
              (steps.changes.outputs.needbuild == 'true') && 
              (env.PYTHON_VERSION == '3.10')
            )
          )
        run: |
          chmod +x tools/build-wheels.sh
          docker run --rm -e PLAT=$PLAT -e CUMM_CUDA_VERSION=${{ matrix.cuda-version }} \
           -e SPCONV_PYTHON_LIST=${{env.PYTHON_VERSION}} \
           -e BOOST_ROOT=/io/third_party/boost/$BOOST_VERSION \
           -v `pwd`:/io $DOCKER_IMAGE bash -c "source /etc/bashrc && /io/tools/build-wheels.sh"

      - name: Build a cpu wheel
        env:
          CUDA_VERSION: ${{ matrix.cuda-version }}
          PYTHON_VERSION: ${{ matrix.python-version }}
          DOCKER_IMAGE: scrin/manylinux2014-cuda:cu114-devel-1.0.0
          PLAT: manylinux2014_x86_64
          BOOST_VERSION: boost_1_77_0
        if: |
          (env.CUDA_VERSION == '') && (
            (github.event_name == 'push' && (startsWith(github.ref, 'refs/tags')) ) || 
            (
              (steps.changes.outputs.needbuild == 'true') && 
              (env.PYTHON_VERSION == '3.10')
            )
          )
        run: |
          chmod +x tools/build-wheels.sh
          docker run --rm -e PLAT=$PLAT -e CUMM_CUDA_VERSION=${{ matrix.cuda-version }} \
            -e SPCONV_PYTHON_LIST=${{env.PYTHON_VERSION}} \
            -e BOOST_ROOT=/io/third_party/boost/$BOOST_VERSION \
            -v `pwd`:/io $DOCKER_IMAGE bash -c "source /etc/bashrc && /io/tools/build-wheels.sh"

      - name: Publish a Python distribution to PyPI
        if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          user: __token__
          password: ${{ secrets.pypi_password }}