# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions
# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners
name: undefined behaviour sanitizers

on:
  push:
    branches:
      - 'main'
      - 'releases/**'
      - '2.*'
    tags:
      - '2.*'
  pull_request:

permissions:
  contents: read

jobs:
  build:

    runs-on: ubuntu-22.04

    env:
      QT_VERSION: 6.10.0
      UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1:report_error_type=1
      # TODO: figure out why there are cache misses with PCH enabled
      CCACHE_SLOPPINESS: pch_defines,time_macros

    steps:
      - uses: actions/checkout@v4
        with:
          persist-credentials: false

      - name: ccache
        uses: hendrikmuhs/ccache-action@v1.2
        with:
          key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }}

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.14'
          check-latest: true

      - name: Install missing software on ubuntu
        run: |
          sudo apt-get update
          sudo apt-get install -y cmake make libpcre3-dev libboost-container-dev libxml2-utils
          sudo apt-get install -y libcups2-dev  # required for Qt6PrintSupport in CMake since Qt 6.7.3

      - name: Install clang
        run: |
          sudo apt-get purge --auto-remove llvm python3-lldb-14 llvm-14
          wget https://apt.llvm.org/llvm.sh
          chmod +x llvm.sh
          sudo ./llvm.sh 22

      - name: Install Qt ${{ env.QT_VERSION }}
        uses: jurplel/install-qt-action@v4
        with:
          version: ${{ env.QT_VERSION }}
          modules: 'qtcharts'
          setup-python: 'false'
          cache: true

      - name: Install missing Python packages
        run: |
          python3 -m pip install pip --upgrade
          python3 -m pip install pytest
          python3 -m pip install pytest-timeout
          python3 -m pip install pytest-xdist
          python3 -m pip install psutil

      - name: CMake
        run: |
          cmake -S . -B cmake.output -Werror=dev -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTING=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DUSE_MATCHCOMPILER=Verify -DANALYZE_UNDEFINED=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DFILESDIR= -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
        env:
          CC: clang-22
          CXX: clang++-22

      - name: Build cppcheck
        run: |
          cmake --build cmake.output --target cppcheck -- -j $(nproc)

      - name: Build test
        run: |
          cmake --build cmake.output --target testrunner -- -j $(nproc)

      - name: Build GUI tests
        run: |
          cmake --build cmake.output --target gui-tests -- -j $(nproc)

      - name: Run tests
        run: ./cmake.output/bin/testrunner

      - name: Run cfg tests
        run: |
          cmake --build cmake.output --target checkcfg -- -j $(nproc)

      - name: Run CTest
        run: |
          ctest --test-dir cmake.output --output-on-failure -j$(nproc)

      - name: Run test/cli
        run: |
          pwd=$(pwd)
          TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv -n auto test/cli

      - name: Run test/cli (-j2)
        run: |
          pwd=$(pwd)
          TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv -n auto test/cli
        env:
          TEST_CPPCHECK_INJECT_J: 2

      - name: Run test/cli (--clang)
        if: false
        run: |
          pwd=$(pwd)
          TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv -n auto test/cli
        env:
          TEST_CPPCHECK_INJECT_CLANG: clang

      - name: Run test/cli (--cppcheck-build-dir)
        run: |
          pwd=$(pwd)
          TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv -n auto test/cli
        env:
          TEST_CPPCHECK_INJECT_BUILDDIR: injected

      - name: Generate dependencies
        run: |
          # make sure auto-generated GUI files exist
          make -C cmake.output autogen
          make -C cmake.output gui-build-deps triage-build-ui-deps

      # TODO: only fail the step on sanitizer issues - since we use processes it will only fail the underlying process which will result in an cppcheckError
      - name: Self check
        run: |
          ./selfcheck_san.sh ./cmake.output
