# The contents below are based on sample configuration from CodeQL
# and on the variant of that file used in the main NUT repository.
#
name: "CodeQL"

on:
  push:
    branches: [ "master" ]
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [ "master" ]
  schedule:
    - cron: "18 2 * * 0"
  workflow_dispatch:
    # Allow manually running the action, e.g. if disabled after some quietness in the source

jobs:
  analyze:
    name: Analyze
    runs-on: ${{ matrix.os }}
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs
        language: [ 'cpp' ]
          # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
          # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
        nutsrc: [ 'pkg280', 'trunk' ]
          # Build with OS-provided NUT package (or build v2.8.0 if pkg is too old), or NUT trunk?
        os: [ 'ubuntu-latest' ]
          # TOTHINK: windows-latest, macos-latest?
        compiler: [ 'CC=gcc CXX=g++', 'CC=clang CXX=clang++' ]

    steps:
    - name: Checkout repository
      uses: actions/checkout@v3

    # https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
    - if: matrix.language == 'cpp' && matrix.os == 'ubuntu-latest'
      name: Initialize dependencies (Ubuntu)
      run: |
        sudo apt-get update
        case x"${{matrix.compiler}}" in x*clang*) sudo apt install clang ;; x*) sudo apt install gcc g++ ;; esac
        sudo apt-get install libxpm-dev libxext-dev libupsclient-dev libc6-dev-amd64-cross libgcc-s1-amd64-cross ccache

    - name: Prepare ccache
      # Based on https://docs.github.com/en/actions/reference/workflows-and-actions/dependency-caching#example-using-the-cache-action example
      id: cache-ccache
      uses: actions/cache@v4
      env:
        cache-name: cache-ccache-${{ matrix.nutsrc }}-${{ matrix.compiler }}
      with:
        path: |
            ~/.ccache
            ~/.cache/ccache
            ~/.config/ccache/ccache.conf
        key: ${{ runner.os }}-build-${{ env.cache-name }}
        restore-keys: |
          ${{ runner.os }}-build-${{ env.cache-name }}
          ${{ runner.os }}-build-
          ${{ runner.os }}-

    - name: CCache stats before build
      run: ccache -sv || ccache -s || echo "FAILED to read ccache info, oh well"

    - if: matrix.language == 'cpp' && matrix.os == 'ubuntu-latest'
      name: Initialize dependencies (ensure NUT 2.8.0+)
      run: |
        GITVER=''
        case "${{matrix.nutsrc}}" in
            "pkg280")
                case "`pkg-config --modversion libupsclient | tee -a /dev/stderr`" in
                    [01].*|2.[01234567].*)
                        echo "WARNING: System-packaged NUT seems too old, will build dev profile from scratch" >&2
                        GITVER='v2.8.0'
                        ;;
                esac ;;
            "trunk") GITVER="master" ;;
        esac
        if [ x"$GITVER" != x ] ; then
                PATH="/usr/lib/ccache:$PATH" ; export PATH
                set -e    ### abort on any non-zero exit code below
                ### Follow nut::docs/config-prereqs.txt chapter for Debian/Ubuntu
                ### to be sure, with a minimal set of third-party dependencies for
                ### a faster and practically useless build. Most or all of these
                ### are pre-installed in the image or by the above init, so there
                ### is little run-time impact of the APT operation here normally;
                ### these explicit installations help bolt down some auto-deps so
                ### they are surely not "apt-get remove"'d with the operation below:
                sudo apt-get install build-essential git python3 perl curl make autoconf automake libtool pkg-config gcc ### g++ libltdl-dev python-is-python3
                git clone -b "$GITVER" -o upstream https://github.com/networkupstools/nut
                cd nut
                ./autogen.sh
                ./configure ${{matrix.compiler}} --prefix=/usr --sysconfdir=/etc --with-user=nut --with-group=nut --with-dev --without-all --without-docs --without-nut-scanner --enable-silent-rules
                make -j 8 -s
                sudo apt-get remove libupsclient-dev    ### avoid conflicts/confusion just in case
                sudo apt-get remove libupsclient4 || true
                sudo make -s install    ### overwrite system packaged files as too old
                echo "=== Checking NUT libupsclient version seen by pkg-config:"
                pkg-config --modversion libupsclient
        fi

    - name: Initialize CodeQL
      uses: github/codeql-action/init@v3
      with:
        languages: ${{ matrix.language }}
        queries: +security-and-quality

    # https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
    #- name: Autobuild
    #  uses: github/codeql-action/autobuild@v3
    #  env:
    #    ### Avoid installing obsolete libupsclient-dev
    #    CODEQL_EXTRACTOR_CPP_AUTOINSTALL_DEPENDENCIES: false

    # For CodeQL scanning, it seems we should actually pass the build of
    # tested code base -- not skip it thanks to unmodified-object caching
    - if: matrix.language == 'cpp'
      name: WMNut CI Build
      run: |
        #PATH="/usr/lib/ccache:$PATH" ; export PATH
        #ccache --version || true
        ( ${{matrix.compiler}} ; echo "=== CC: $CC => `command -v $CC` =>" ; $CC --version ; echo "=== CXX: $CXX => `command -v $CXX` =>" ; $CXX --version ) || true
        ./autogen.sh
        ./configure ${{matrix.compiler}} --enable-debug --enable-Werror
        make -s -j 8 || exit

    - if: matrix.language == 'cpp'
      name: WMNut CI check
      run: make -s -j 8 check || exit

    - name: CCache stats after build
      run: ccache -sv || ccache -s || echo "FAILED to read ccache info, oh well"

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v3
      with:
        category: "/language:${{matrix.language}}"
