name: NEURON Code Coverage

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

on:
  push:
    branches:
      - master
      - release/**
  pull_request:
    branches:
      - master
      - release/**
# TODO : https://github.com/neuronsimulator/nrn/issues/1063
#    paths-ignore:
#      - '**.md'
#      - '**.rst'
#      - 'docs/**'

env:
  PY_MIN_VERSION: '3.9'
  PY_MAX_VERSION: '3.12'

jobs:
  coverage:
    runs-on: ubuntu-22.04

    name: Code Coverage

    timeout-minutes: 45

    steps:

      - name: Install apt packages
        run: |
          sudo apt-get install  build-essential doxygen lcov libopenmpi-dev libmpich-dev libx11-dev libxcomposite-dev mpich openmpi-bin patchelf gpg
        shell: bash

      - name: Setup Caliper profiler
        run: |
          git clone https://github.com/LLNL/Caliper.git
          cd Caliper
          mkdir build && cd build
          cmake ..
          make && sudo make install

      - name: Set up Python@${{ env.PY_MIN_VERSION }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ env.PY_MIN_VERSION }}

      - name: Set up Python@${{ env.PY_MAX_VERSION }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ env.PY_MAX_VERSION }}

      - uses: actions/checkout@v4
        with:
          fetch-depth: 2

      - name: Install Python@${{ env.PY_MIN_VERSION }} dependencies
        working-directory: ${{runner.workspace}}/nrn
        run: |
          python${PY_MIN_VERSION} -m pip install --upgrade pip -r nrn_requirements.txt

      - name: Install Python@${{ env.PY_MAX_VERSION }} dependencies
        working-directory: ${{runner.workspace}}/nrn
        run: |
          python${PY_MAX_VERSION} -m pip install --upgrade pip -r nrn_requirements.txt

      - name: Build & Test
        id: build-test
        shell: bash
        working-directory: ${{runner.workspace}}/nrn
        run:  |
          export SHELL="/bin/bash"

          # Compiler setup
          export CC=gcc
          export CXX=g++

          # Python setup
          export PYTHON_MIN=$(which $PYTHON_MIN_NAME);
          export PYTHON_MAX=$(which $PYTHON_MAX_NAME);

          mkdir build && cd build;

          # CMake options & flags
          export COVERAGE_FLAGS="--coverage -O0 -fno-inline -g";
          export CMAKE_OPTION="-DNRN_ENABLE_MPI=ON -DNRN_ENABLE_INTERVIEWS=ON -DNRN_ENABLE_PYTHON=ON -DNRN_ENABLE_PYTHON_DYNAMIC=ON -DNRN_PYTHON_DYNAMIC=${PYTHON_MIN};${PYTHON_MAX} -DNRN_ENABLE_CORENEURON=ON -DNRN_ENABLE_PROFILING=ON";
          cmake $CMAKE_OPTION -DCMAKE_C_COMPILER=$CC -DCMAKE_CXX_COMPILER=$CXX -DNRN_ENABLE_TESTS=ON -DCMAKE_C_FLAGS="${COVERAGE_FLAGS}" -DCMAKE_CXX_FLAGS="${COVERAGE_FLAGS}" ..;

          # Coverage
          # The Linux runners apparently have 2 cores, but jobs were being killed when we did not specify this explicitly.
          # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
          # By default we get a modern version of CMake that understands --parallel.
          cmake --build . --parallel 2
          (cd ..;  lcov --capture  --initial --directory . --no-external --output-file build/coverage-base.info)
          export PATH=`pwd`/bin:$PATH;
          ctest -VV;
          (cd ..; lcov --capture  --directory . --no-external --output-file build/coverage-run.info)
          lcov --add-tracefile coverage-base.info --add-tracefile coverage-run.info --output-file coverage-combined.info

          # Download codecov script and perform integrity checks
          curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --import # One-time step 
          curl -Os https://uploader.codecov.io/latest/linux/codecov 
          curl -Os https://uploader.codecov.io/latest/linux/codecov.SHA256SUM 
          curl -Os https://uploader.codecov.io/latest/linux/codecov.SHA256SUM.sig 
          gpg --verify codecov.SHA256SUM.sig codecov.SHA256SUM 
          shasum -a 256 -c codecov.SHA256SUM 
          chmod +x codecov 

          # Prefer auto-discovery for now. Specify reports once all python testing is unified under single report (-f option).
          ./codecov
        env:
          MATRIX_EVAL: "CC=gcc CXX=g++"
          PYTHON_MIN_NAME: "python${{ env.PY_MIN_VERSION }}"
          PYTHON_MAX_NAME: "python${{ env.PY_MAX_VERSION }}"

      # This step will set up an SSH connection on tmate.io for live debugging.
      # To enable it, you have to:
      #   * add 'live-debug-coverage' to your PR title
      #   * push something to your PR branch (note that just re-running the pipeline disregards the title update)
      - name: live debug session on failure (manual steps required, check `.github/coverage.yml`)
        if: failure() && contains(github.event.pull_request.title, 'live-debug-coverage')
        uses: mxschmitt/action-tmate@v3
