# This is a basic workflow to help you get started with Actions

name: XGBoost-CI

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on: [push, pull_request]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  gtest-cpu:
    name: Test Google C++ test (CPU)
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [macos-10.15]
    steps:
    - uses: actions/checkout@v2
      with:
        submodules: 'true'
    - name: Install system packages
      run: |
        brew install lz4 ninja libomp
    - name: Build gtest binary
      run: |
        mkdir build
        cd build
        cmake .. -DGOOGLE_TEST=ON -DUSE_OPENMP=ON -DUSE_DMLC_GTEST=ON -DPLUGIN_LZ4=ON -DPLUGIN_DENSE_PARSER=ON -GNinja
        ninja -v
    - name: Run gtest binary
      run: |
        cd build
        ctest --exclude-regex AllTestsInDMLCUnitTests --extra-verbose

  gtest-cpu-nonomp:
    name: Test Google C++ unittest (CPU Non-OMP)
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest]
    steps:
    - uses: actions/checkout@v2
      with:
        submodules: 'true'
    - name: Install system packages
      run: |
        sudo apt-get install -y --no-install-recommends ninja-build
    - name: Build and install XGBoost
      shell: bash -l {0}
      run: |
        mkdir build
        cd build
        cmake .. -GNinja -DGOOGLE_TEST=ON  -DUSE_DMLC_GTEST=ON -DUSE_OPENMP=OFF
        ninja -v
    - name: Run gtest binary
      run: |
        cd build
        ctest --extra-verbose

  python-sdist-test:
    name: Test installing XGBoost Python source package
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-10.15, windows-latest]
        python-version: ["3.8"]
    steps:
    - uses: actions/checkout@v2
      with:
        submodules: 'true'
    - name: Install osx system dependencies
      if: matrix.os == 'macos-10.15'
      run: |
        brew install ninja libomp
    - name: Install Ubuntu system dependencies
      if: matrix.os == 'ubuntu-latest'
      run: |
        sudo apt-get install -y --no-install-recommends ninja-build
    - uses: conda-incubator/setup-miniconda@v2
      with:
        auto-update-conda: true
        python-version: ${{ matrix.python-version }}
        activate-environment: test
    - name: Display Conda env
      shell: bash -l {0}
      run: |
        conda info
        conda list
    - name: Build and install XGBoost
      shell: bash -l {0}
      run: |
        cd python-package
        python --version
        python setup.py sdist
        pip install -v ./dist/xgboost-*.tar.gz
        cd ..
        python -c 'import xgboost'

  c-api-demo:
    name: Test installing XGBoost lib + building the C API demo
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: ["ubuntu-latest"]
        python-version: ["3.8"]
    steps:
    - uses: actions/checkout@v2
      with:
        submodules: 'true'
    - name: Install system packages
      run: |
        sudo apt-get install -y --no-install-recommends ninja-build
    - uses: conda-incubator/setup-miniconda@v2
      with:
        auto-update-conda: true
        python-version: ${{ matrix.python-version }}
        activate-environment: test
    - name: Display Conda env
      shell: bash -l {0}
      run: |
        conda info
        conda list
    - name: Build and install XGBoost
      shell: bash -l {0}
      run: |
        mkdir build
        cd build
        cmake .. -DBUILD_STATIC_LIB=ON -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -GNinja
        ninja -v install
    - name: Build and run C API demo
      shell: bash -l {0}
      run: |
        cd demo/c-api/
        mkdir build
        cd build
        cmake .. -GNinja -DCMAKE_PREFIX_PATH=$CONDA_PREFIX
        ninja -v
        cd ..
        ./build/api-demo

  test-with-jvm:
    name: Test JVM on OS ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [windows-latest, ubuntu-latest]

    steps:
    - uses: actions/checkout@v2
      with:
        submodules: 'true'

    - uses: actions/setup-python@v2
      with:
        python-version: '3.8'
        architecture: 'x64'

    - uses: actions/setup-java@v1
      with:
        java-version: 1.8

    - name: Install Python packages
      run: |
        python -m pip install wheel setuptools
        python -m pip install awscli

    - name: Cache Maven packages
      uses: actions/cache@v2
      with:
        path: ~/.m2
        key: ${{ runner.os }}-m2-${{ hashFiles('./jvm-packages/pom.xml') }}
        restore-keys: ${{ runner.os }}-m2

    - name: Test XGBoost4J
      run: |
        cd jvm-packages
        mvn test -B -pl :xgboost4j_2.12

    - name: Extract branch name
      shell: bash
      run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
      id: extract_branch
      if: |
        (github.ref == 'refs/heads/master' || contains(github.ref, 'refs/heads/release_')) &&
        matrix.os == 'windows-latest'

    - name: Publish artifact xgboost4j.dll to S3
      run: |
        cd lib/
        Rename-Item -Path xgboost4j.dll -NewName xgboost4j_${{ github.sha }}.dll
        dir
        python -m awscli s3 cp xgboost4j_${{ github.sha }}.dll s3://xgboost-nightly-builds/${{ steps.extract_branch.outputs.branch }}/ --acl public-read
      if: |
        (github.ref == 'refs/heads/master' || contains(github.ref, 'refs/heads/release_')) &&
        matrix.os == 'windows-latest'
      env:
        AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_IAM_S3_UPLOADER }}
        AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_IAM_S3_UPLOADER }}


    - name: Test XGBoost4J-Spark
      run: |
        rm -rfv build/
        cd jvm-packages
        mvn -B test
      if: matrix.os == 'ubuntu-latest'  # Distributed training doesn't work on Windows
      env:
        RABIT_MOCK: ON

  lint:
    runs-on: ubuntu-latest
    name: Code linting for Python and C++
    steps:
    - uses: actions/checkout@v2
      with:
        submodules: 'true'
    - uses: actions/setup-python@v2
      with:
        python-version: '3.7'
        architecture: 'x64'
    - name: Install Python packages
      run: |
        python -m pip install wheel setuptools
        python -m pip install pylint cpplint numpy scipy scikit-learn
    - name: Run lint
      run: |
        make lint

  mypy:
    runs-on: ubuntu-latest
    name: Type checking for Python
    steps:
    - uses: actions/checkout@v2
      with:
        submodules: 'true'
    - uses: actions/setup-python@v2
      with:
        python-version: '3.7'
        architecture: 'x64'
    - name: Install Python packages
      run: |
        python -m pip install wheel setuptools mypy dask[complete] distributed
    - name: Run mypy
      run: |
        make mypy

  doxygen:
    runs-on: ubuntu-latest
    name: Generate C/C++ API doc using Doxygen
    steps:
    - uses: actions/checkout@v2
      with:
        submodules: 'true'
    - uses: actions/setup-python@v2
      with:
        python-version: '3.7'
        architecture: 'x64'
    - name: Install system packages
      run: |
        sudo apt-get install -y --no-install-recommends doxygen graphviz ninja-build
        python -m pip install wheel setuptools
        python -m pip install awscli
    - name: Run Doxygen
      run: |
        mkdir build
        cd build
        cmake .. -DBUILD_C_DOC=ON -GNinja
        ninja -v doc_doxygen
    - name: Extract branch name
      shell: bash
      run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
      id: extract_branch
      if: github.ref == 'refs/heads/master' || contains(github.ref, 'refs/heads/release_')
    - name: Publish
      run: |
        cd build/
        tar cvjf ${{ steps.extract_branch.outputs.branch }}.tar.bz2 doc_doxygen/
        python -m awscli s3 cp ./${{ steps.extract_branch.outputs.branch }}.tar.bz2 s3://xgboost-docs/ --acl public-read
      if: github.ref == 'refs/heads/master' || contains(github.ref, 'refs/heads/release_')
      env:
        AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_IAM_S3_UPLOADER }}
        AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_IAM_S3_UPLOADER }}

  sphinx:
    runs-on: ubuntu-latest
    name: Build docs using Sphinx
    steps:
    - uses: actions/checkout@v2
      with:
        submodules: 'true'
    - uses: actions/setup-python@v2
      with:
        python-version: '3.8'
        architecture: 'x64'
    - name: Install system packages
      run: |
        sudo apt-get install -y --no-install-recommends graphviz
        python -m pip install wheel setuptools
        python -m pip install -r doc/requirements.txt
    - name: Extract branch name
      shell: bash
      run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
      id: extract_branch
      if: github.ref == 'refs/heads/master' || contains(github.ref, 'refs/heads/release_')
    - name: Run Sphinx
      run: |
        make -C doc html
      env:
        SPHINX_GIT_BRANCH: ${{ steps.extract_branch.outputs.branch }}
