name: HighFive_CI

concurrency:
  group: ${{ github.workflow }}#${{ github.ref }}
  cancel-in-progress: true

on:
  push:
    branches:
      - ci_test
      - release/**
  pull_request:
    branches:
      - master
      - release/**
    paths-ignore:
      - '**.md'
      - '**.rst'
      - 'doc/**'

env:
  HOMEBREW_NO_AUTO_UPDATE: 1  # for reproducibility, dont autoupdate
  BUILD_TYPE: RelWithDebInfo
  INSTALL_DIR: install

jobs:

  # Job testing compiling on several Ubuntu systems + MPI
  # =========================================================
  #
  # For 20.04:  bare and activate Boost, OpenCV
  # For latest: activate Boost, Eigen, OpenCV, with Ninja
  #
  # XTensor tests are run for conda/mamba and MacOS
  Linux_MPI:
    runs-on: ${{matrix.config.os}}
    name: Linux_MPI (${{toJson(matrix.config)}})
    strategy:
      matrix:
        include:
          - config:
              os: ubuntu-20.04
              pkgs: ''
              flags: '-DHIGHFIVE_USE_BOOST:Bool=OFF'
          - config:
              os: ubuntu-20.04
              pkgs: 'libboost-all-dev libopencv-dev'
              flags: '-DHIGHFIVE_USE_OPENCV:Bool=ON -GNinja'
          - config:
              os: ubuntu-latest
              pkgs: 'libboost-all-dev libeigen3-dev libopencv-dev'
              flags: '-DHIGHFIVE_USE_EIGEN:Bool=ON -DHIGHFIVE_USE_OPENCV:Bool=ON -GNinja'
          - config:
              os: ubuntu-20.04
              pkgs: 'libboost-all-dev'
              flags: '-DCMAKE_CXX_STANDARD=17'
          - config:
              os: ubuntu-22.04
              flags: '-DHIGHFIVE_USE_BOOST=Off -DCMAKE_CXX_STANDARD=20'

    steps:
    - uses: actions/checkout@v3
      with:
        submodules: true

    - name: "Setup MPI"
      uses: mpi4py/setup-mpi@v1
      with:
        mpi: openmpi

    - name: "Install libraries"
      run: |
        sudo apt-get -qq update
        sudo apt-get -qq install libhdf5-openmpi-dev libsz2 ninja-build ${{ matrix.config.pkgs }}

    - name: Build
      run: |
        CMAKE_OPTIONS=(-DHIGHFIVE_PARALLEL_HDF5:BOOL=ON ${{ matrix.config.flags }})
        source $GITHUB_WORKSPACE/.github/build.sh

    - name: Test
      working-directory: ${{github.workspace}}/build
      run: ctest -j2 --output-on-failure -C $BUILD_TYPE


  # Job testing several versions of hdf5
  # ===================================================
  Linux_HDF5_Versions:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        hdf5_version : [ hdf5-1_8_23, hdf5-1_10_11, hdf5-1_12_2, hdf5-1_14_3 ]

    steps:
    - uses: actions/checkout@v3
      with:
        submodules: true
    - name: "Install libraries"
      run: |
        sudo apt-get -qq update
        sudo apt-get -qq install ninja-build libsz2 zlib1g-dev libboost-all-dev

    - name: Build HDF5
      run: |
        wget https://github.com/HDFGroup/hdf5/archive/refs/tags/${{ matrix.hdf5_version }}.tar.gz --output-document hdf5.tar.gz
        tar xf hdf5.tar.gz
        mkdir -p hdf5-${{ matrix.hdf5_version }}/BUILD && cd hdf5-${{ matrix.hdf5_version }}/BUILD
        cmake .. -DCMAKE_BUILD_TYPE=Release -GNinja -DCMAKE_INSTALL_PREFIX=$HOME/${{ matrix.hdf5_version }} -DHDF5_ENABLE_Z_LIB_SUPPORT=ON -DUSE_LIBAEC=ON -DHDF5_BUILD_EXAMPLES=OFF -DBUILD_STATIC_LIBS=OFF -DBUILD_TESTING=OFF
        ninja && ninja install

    - name: Build
      run: |
        CMAKE_OPTIONS=(
          -GNinja
          -DHDF5_ROOT=$HOME/${{ matrix.hdf5_version }}
        )
        source $GITHUB_WORKSPACE/.github/build.sh

    - name: Test
      working-directory: ${{github.workspace}}/build
      run: ctest -j2 --output-on-failure -C $BUILD_TYPE


    - name: Examples
      working-directory: ${{github.workspace}}/build/src/examples
      run: $GITHUB_WORKSPACE/.github/run_examples.sh

  # Job testing several compilers on a stable Linux
  # ====================================================
  Linux_Compilers:
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        env: [
          {CC: clang-10, CXX: clang++-10},
          {CC: clang-12, CXX: clang++-12},
          {CC: gcc-9, CXX: g++-9},
          {CC: gcc-10, CXX: g++-10},
        ]

    steps:
    - uses: actions/checkout@v3
      with:
        submodules: true

    - name: "Install libraries"
      run: |
        sudo apt-get -qq update
        sudo apt-get -qq install libboost-all-dev libhdf5-dev libsz2 ninja-build

    - name: Build
      env: ${{matrix.env}}
      run: |
        CMAKE_OPTIONS=(-GNinja)
        source $GITHUB_WORKSPACE/.github/build.sh

    - name: Test
      working-directory: ${{github.workspace}}/build
      run: ctest -j2 --output-on-failure -C $BUILD_TYPE

    - name: Examples
      working-directory: ${{github.workspace}}/build/src/examples
      run: $GITHUB_WORKSPACE/.github/run_examples.sh

  # Job running unit-test with sanitizers
  # =====================================
  Linux_Sanitizers:
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        env: [
          {CC: clang-12, CXX: clang++-12, HIGHFIVE_SANITIZER: address},
          {CC: clang-12, CXX: clang++-12, HIGHFIVE_SANITIZER: undefined},
          {CC: gcc-10, CXX: g++-10, HIGHFIVE_GLIBCXX_ASSERTIONS: On},
        ]

    steps:
    - uses: actions/checkout@v3
      with:
        submodules: true

    - name: "Install libraries"
      run: |
        sudo apt-get -qq update
        sudo apt-get -qq install libboost-all-dev libeigen3-dev libhdf5-dev libsz2 ninja-build

    - name: Build
      env: ${{matrix.env}}
      run: |
        CMAKE_OPTIONS=(
          -GNinja
          -DHIGHFIVE_USE_BOOST:BOOL=ON
          -DHIGHFIVE_USE_EIGEN:BOOL=ON
          -DHIGHFIVE_BUILD_DOCS:BOOL=FALSE
          -DHIGHFIVE_GLIBCXX_ASSERTIONS=${HIGHFIVE_GLIBCXX_ASSERTIONS:-OFF}
          -DHIGHFIVE_SANITIZER=${HIGHFIVE_SANITIZER:-OFF}
        )
        source $GITHUB_WORKSPACE/.github/build.sh

    - name: Test
      working-directory: ${{github.workspace}}/build
      run: ctest -j2 --output-on-failure -C $BUILD_TYPE

    - name: Examples
      working-directory: ${{github.workspace}}/build/src/examples
      run: $GITHUB_WORKSPACE/.github/run_examples.sh


  # Job to check using HighFive from other CMake projects
  # =====================================================
  CMake_Project:
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        parallelism: [ serial, parallel ]
    steps:
    - uses: actions/checkout@v3
      with:
        submodules: true

    - name: "Update Ubuntu"
      run: |
        sudo apt-get -qq update

    - name: "Install common libraries"
      run: |
        sudo apt-get -qq install libboost-all-dev libsz2 ninja-build

    - name: "Install serial HDF5"
      if: matrix.parallelism == 'serial'
      run: |
        sudo apt-get -qq install libhdf5-dev


    - name: "Install parallel HDF5"
      if: matrix.parallelism == 'parallel'
      run: |
        sudo apt-get -qq install libhdf5-openmpi-dev

    - name: "CMake Project Integration"
      run: bash tests/test_project_integration.sh


  # Job checking the benchmarks work
  # ================================
  Benchmarks:
    runs-on: ubuntu-20.04
    steps:
    - uses: actions/checkout@v3
      with:
        submodules: true

    - name: "Install libraries"
      run: |
        sudo apt -y update
        sudo apt -y  install --no-install-recommends  libhdf5-dev pkg-config

    - name: "Build benchmarks"
      working-directory: ${{github.workspace}}/src/benchmarks
      run: make

    - run: time ${{github.workspace}}/src/benchmarks/highfive_bench


  # Job testing in OSX
  # ==================
  OSX:
    runs-on: ${{matrix.os}}
    strategy:
      matrix:
        os: [ "macOS-12" ]
        cxxstd: ["14", "17", "20"]

    steps:
    - uses: actions/checkout@v3
      with:
        submodules: true

    - name: "Install libraries (OSX)"
      run: brew install boost eigen hdf5 ninja xtensor

    - name: Build
      run: |
        CMAKE_OPTIONS=(
          -GNinja
          -DHIGHFIVE_USE_BOOST:BOOL=ON
          -DHIGHFIVE_USE_EIGEN:BOOL=ON
          -DHIGHFIVE_USE_XTENSOR:BOOL=ON
          -DHIGHFIVE_BUILD_DOCS:BOOL=FALSE
          -DHIGHFIVE_TEST_SINGLE_INCLUDES=ON
          -DCMAKE_CXX_FLAGS="-coverage -O0"
          -DCMAKE_CXX_STANDARD=${{matrix.cxxstd}}
        )
        source $GITHUB_WORKSPACE/.github/build.sh

    - name: Test
      working-directory: ${{github.workspace}}/build
      run: ctest -j2 --output-on-failure -C $BUILD_TYPE

    - name: Examples
      working-directory: ${{github.workspace}}/build/src/examples
      run: $GITHUB_WORKSPACE/.github/run_examples.sh


  # Job testing in Windows
  # ======================
  Windows:
    runs-on:  ${{matrix.os}}
    strategy:
      matrix:
        os: [ "windows-2022"]
        vs-toolset: [ "v141", "v143" ]
        cxxstd: ["14", "17", "20"]

        include:
          - os: "windows-2019"
            vs-toolset: "v142"
            cxxstd: "14"

          - os: "windows-2019"
            vs-toolset: "v142"
            cxxstd: "17"

    steps:
    - uses: actions/checkout@v3
      with:
        submodules: true

    - uses: mamba-org/setup-micromamba@v1
      with:
        environment-file: doc/environment.yaml
        environment-name: win-test

    - name: Build
      shell: bash -l {0}
      run: |
        CMAKE_OPTIONS=(
          -T ${{matrix.vs-toolset}}
          -DCMAKE_CXX_STANDARD=${{matrix.cxxstd}}
          -DHIGHFIVE_UNIT_TESTS=ON
          -DHIGHFIVE_USE_BOOST:BOOL=ON
          -DHIGHFIVE_USE_EIGEN:BOOL=ON
          -DHIGHFIVE_USE_XTENSOR:BOOL=ON
          -DHIGHFIVE_TEST_SINGLE_INCLUDES=ON
        )
        source $GITHUB_WORKSPACE/.github/build.sh

    - name: Test
      working-directory: ${{github.workspace}}/build
      shell: bash -l {0}
      run: ctest -j2 --output-on-failure -C $BUILD_TYPE
