Skip to content
Latchkey

checker-config-coverage workflow (Ericsson/codechecker)

The checker-config-coverage workflow from Ericsson/codechecker, explained and optimized by Latchkey.

D

CI health: D - needs work

Point runs-on at Latchkey and get caching, run de-duplication, job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: Ericsson/codechecker.github/workflows/config_coverage.ymlLicense Apache-2.0View source

What it does

This is the checker-config-coverage workflow from the Ericsson/codechecker repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
name: checker-config-coverage

on:
  push:
    paths:
      - '.github/workflows/config_coverage.yml'
      - '.github/workflows/config_label_check.py'
      - 'config/labels/analyzers/clang-tidy.json'
      - 'config/labels/analyzers/clangsa.json'
      - 'config/labels/analyzers/cppcheck.json'
  pull_request:
    paths:
      - '.github/workflows/config_coverage.yml'
      - '.github/workflows/config_label_check.py'
      - 'config/labels/analyzers/clang-tidy.json'
      - 'config/labels/analyzers/clangsa.json'
      - 'config/labels/analyzers/cppcheck.json'
  schedule:
    # Run every Sunday at 21:30 (to latest master at that time).
    - cron: '30 21 * * SUN'
  # Allow running this job manually from either API or GitHub UI.
  workflow_dispatch:

permissions: read-all

jobs:
  checker-config-coverage:
    name: "Config coverage of checkers"
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: '3.10'
      - name: "Install dependencies"
        run: |
          # Some packages, e.g. build-essential and curl are available
          # implicitly in GitHub Actions-specific images.
          sudo apt-get -qy update
          sudo apt-get -y --no-install-recommends install \
            gcc-multilib    \
            python3-dev     \
            python3-venv
      # Unfortunately, there is no "daily" Cppcheck PPA or Linux binary source,
      # so we have to build this manually. Luckily, it seems to be a trivial
      # enough process.
      #
      # We do this BEFORE grabbing Clang, so a potentially broken Clang binary
      # won't miscompile Cppcheck itself.
      - name: "Download Cppcheck source code"
        uses: actions/checkout@v3
        with:
          repository: "danmar/cppcheck"
          path: "cppcheck"
      - name: "Build Cppcheck"
        run: |
          set +e # Do not hard exit on an erroring call!
          pushd cppcheck

          # Note: Cppcheck's compilation would require CMake, but a new enough
          # version is automatically present in the GitHub Actions-specific
          # image.

          echo "::group::Building Cppcheck"
          mkdir Build
          pushd Build

          cmake .. -DCMAKE_BUILD_TYPE=Release
          cmake --build . -- -j $(nproc)

          if [[ $? -eq 0 ]]
          then
            export CPPCHECK_BUILD_SUCCESSFUL=YES
          fi

          popd # Build

          if [[ x"$CPPCHECK_BUILD_SUCCESSFUL"y == "xYESy" ]]
          then
            sudo update-alternatives --install \
              /usr/bin/cppcheck cppcheck "$(pwd)/Build/bin/cppcheck" 10000
            echo "::endgroup::"

            echo "Installed Cppcheck:"
            update-alternatives --query cppcheck
          else
            echo "::endgroup::"
            echo "::notice title=Cppcheck failed to build locally::Coverage will check using Ubuntu official Cppcheck release instead."

            sudo apt-get install -y --no-install-recommends \
              cppcheck
          fi

          popd # cppcheck
      - name: "Get latest LLVM binary package from the community PPA"
        run: |
          export DISTRO_FANCYNAME="$(lsb_release -c | awk '{ print $2 }')"

          echo "::group::Setup LLVM PPA"
          curl -sL http://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
          sudo add-apt-repository -y "deb http://apt.llvm.org/$DISTRO_FANCYNAME/ llvm-toolchain-$DISTRO_FANCYNAME main"
          echo "::endgroup::"

          # Get the largest Clang package number available.
          export LLVM_VER="$(apt-cache search --full 'clang-[[:digit:]]*$' | grep '^Package: clang' | cut -d ' ' -f 2 | sort -V | tail -n 1 | sed 's/clang-//')"
          echo "::group::Install Clang and Clang-Tidy version ${LLVM_VER}"
          sudo apt-get -y --no-install-recommends install \
            clang-$LLVM_VER \
            clang-tidy-$LLVM_VER
          sudo update-alternatives --install \
            /usr/bin/clang clang /usr/bin/clang-$LLVM_VER 10000
          sudo update-alternatives --install \
            /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-$LLVM_VER 10000
          echo "::endgroup::"

          echo "Installed Clang:"
          update-alternatives --query clang
          update-alternatives --query clang-tidy
      - name: "Package CodeChecker"
        id: codechecker
        run: |
          pushd analyzer

          echo "::group::venv"
          make venv
          source venv/bin/activate
          echo "::endgroup::"

          echo "::group::CodeChecker package"
          make standalone_package
          deactivate
          echo "::endgroup::"

          echo "CODECHECKER_PATH=$(readlink -f ./build/CodeChecker/bin)" >> "$GITHUB_OUTPUT"
          popd # analyzer
      - name: "Dump checker list"
        run: |
          export PATH="${{ steps.codechecker.outputs.CODECHECKER_PATH }}:$PATH"
          CodeChecker analyzers --details
          CodeChecker checkers \
            --analyzer clangsa clang-tidy cppcheck \
            --output rows \
              > checker_list_normal.txt
          CodeChecker checkers \
            --analyzer clangsa clang-tidy cppcheck \
            --warnings \
            --output rows \
              > checker_list_diagnostics.txt
      - name: "Perform checker config coverage check (--warnings)"
        continue-on-error: true
        run: |
          set +e # Do not hard exit on an erroring call!
          .github/workflows/config_label_check.py \
            "checker_list_diagnostics.txt" \
            "config/labels/analyzers/clangsa.json" \
            "config/labels/analyzers/clang-tidy.json" \
            "config/labels/analyzers/cppcheck.json" \
            --existing-filter "clang-diagnostic-" \
            --new-filter "clang-diagnostic-"
          EXIT_STATUS=$?
          echo "Coverage check returned: $EXIT_STATUS."
          # Explicitly check if the bit for "8" is set in the result,
          # indicating new checkers without severity set.
          if [[ $(($EXIT_STATUS & 8)) -eq 8 ]]
          then
            echo "::warning title=New unconfigured diagnostics::The checker label config files lack some new diagnostic report (\"warning\") kinds."
            exit 0
          elif [[ $EXIT_STATUS -eq 1 || $EXIT_STATUS -eq 2 ]]
          then
            # Script execution error.
            exit $EXIT_STATUS
          else
            # We do not wish to fail if only removed checkers are reported.
            exit 0
          fi
      - name: "Perform checker config coverage check"
        run: |
          set +e # Do not hard exit on an erroring call!
          .github/workflows/config_label_check.py \
            "checker_list_normal.txt" \
            "config/labels/analyzers/clangsa.json" \
            "config/labels/analyzers/clang-tidy.json" \
            "config/labels/analyzers/cppcheck.json" \
            --existing-ignore "clang-diagnostic-" \
            --new-ignore \
              "clang-diagnostic-" \
              "alpha." \
              "apiModeling." \
              "debug." \
              "optin.osx." \
              "osx." \
              "darwin-" \
              "objc-"
          EXIT_STATUS=$?
          echo "Coverage check returned: $EXIT_STATUS."
          # Explicitly check if the bit for "8" is set in the result,
          # indicating new checkers without severity set.
          if [[ $(($EXIT_STATUS & 8)) -eq 8 ]]
          then
            exit 8
          elif [[ $EXIT_STATUS -eq 1 || $EXIT_STATUS -eq 2 ]]
          then
            # Script execution error.
            exit $EXIT_STATUS
          else
            # We do not wish to fail if only removed checkers are reported.
            exit 0
          fi

The same workflow, on Latchkey

Estimated ~20% faster on cache hits, plus fewer wasted runs and a safer supply chain. Added and changed lines are highlighted.

name: checker-config-coverage
 
on:
  push:
    paths:
      - '.github/workflows/config_coverage.yml'
      - '.github/workflows/config_label_check.py'
      - 'config/labels/analyzers/clang-tidy.json'
      - 'config/labels/analyzers/clangsa.json'
      - 'config/labels/analyzers/cppcheck.json'
  pull_request:
    paths:
      - '.github/workflows/config_coverage.yml'
      - '.github/workflows/config_label_check.py'
      - 'config/labels/analyzers/clang-tidy.json'
      - 'config/labels/analyzers/clangsa.json'
      - 'config/labels/analyzers/cppcheck.json'
  schedule:
    # Run every Sunday at 21:30 (to latest master at that time).
    - cron: '30 21 * * SUN'
  # Allow running this job manually from either API or GitHub UI.
  workflow_dispatch:
 
permissions: read-all
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  checker-config-coverage:
    timeout-minutes: 30
    name: "Config coverage of checkers"
    runs-on: latchkey-small
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          cache: 'pip'
          python-version: '3.10'
      - name: "Install dependencies"
        run: |
          # Some packages, e.g. build-essential and curl are available
          # implicitly in GitHub Actions-specific images.
          sudo apt-get -qy update
          sudo apt-get -y --no-install-recommends install \
            gcc-multilib    \
            python3-dev     \
            python3-venv
      # Unfortunately, there is no "daily" Cppcheck PPA or Linux binary source,
      # so we have to build this manually. Luckily, it seems to be a trivial
      # enough process.
      #
      # We do this BEFORE grabbing Clang, so a potentially broken Clang binary
      # won't miscompile Cppcheck itself.
      - name: "Download Cppcheck source code"
        uses: actions/checkout@v3
        with:
          repository: "danmar/cppcheck"
          path: "cppcheck"
      - name: "Build Cppcheck"
        run: |
          set +e # Do not hard exit on an erroring call!
          pushd cppcheck
 
          # Note: Cppcheck's compilation would require CMake, but a new enough
          # version is automatically present in the GitHub Actions-specific
          # image.
 
          echo "::group::Building Cppcheck"
          mkdir Build
          pushd Build
 
          cmake .. -DCMAKE_BUILD_TYPE=Release
          cmake --build . -- -j $(nproc)
 
          if [[ $? -eq 0 ]]
          then
            export CPPCHECK_BUILD_SUCCESSFUL=YES
          fi
 
          popd # Build
 
          if [[ x"$CPPCHECK_BUILD_SUCCESSFUL"y == "xYESy" ]]
          then
            sudo update-alternatives --install \
              /usr/bin/cppcheck cppcheck "$(pwd)/Build/bin/cppcheck" 10000
            echo "::endgroup::"
 
            echo "Installed Cppcheck:"
            update-alternatives --query cppcheck
          else
            echo "::endgroup::"
            echo "::notice title=Cppcheck failed to build locally::Coverage will check using Ubuntu official Cppcheck release instead."
 
            sudo apt-get install -y --no-install-recommends \
              cppcheck
          fi
 
          popd # cppcheck
      - name: "Get latest LLVM binary package from the community PPA"
        run: |
          export DISTRO_FANCYNAME="$(lsb_release -c | awk '{ print $2 }')"
 
          echo "::group::Setup LLVM PPA"
          curl -sL http://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
          sudo add-apt-repository -y "deb http://apt.llvm.org/$DISTRO_FANCYNAME/ llvm-toolchain-$DISTRO_FANCYNAME main"
          echo "::endgroup::"
 
          # Get the largest Clang package number available.
          export LLVM_VER="$(apt-cache search --full 'clang-[[:digit:]]*$' | grep '^Package: clang' | cut -d ' ' -f 2 | sort -V | tail -n 1 | sed 's/clang-//')"
          echo "::group::Install Clang and Clang-Tidy version ${LLVM_VER}"
          sudo apt-get -y --no-install-recommends install \
            clang-$LLVM_VER \
            clang-tidy-$LLVM_VER
          sudo update-alternatives --install \
            /usr/bin/clang clang /usr/bin/clang-$LLVM_VER 10000
          sudo update-alternatives --install \
            /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-$LLVM_VER 10000
          echo "::endgroup::"
 
          echo "Installed Clang:"
          update-alternatives --query clang
          update-alternatives --query clang-tidy
      - name: "Package CodeChecker"
        id: codechecker
        run: |
          pushd analyzer
 
          echo "::group::venv"
          make venv
          source venv/bin/activate
          echo "::endgroup::"
 
          echo "::group::CodeChecker package"
          make standalone_package
          deactivate
          echo "::endgroup::"
 
          echo "CODECHECKER_PATH=$(readlink -f ./build/CodeChecker/bin)" >> "$GITHUB_OUTPUT"
          popd # analyzer
      - name: "Dump checker list"
        run: |
          export PATH="${{ steps.codechecker.outputs.CODECHECKER_PATH }}:$PATH"
          CodeChecker analyzers --details
          CodeChecker checkers \
            --analyzer clangsa clang-tidy cppcheck \
            --output rows \
              > checker_list_normal.txt
          CodeChecker checkers \
            --analyzer clangsa clang-tidy cppcheck \
            --warnings \
            --output rows \
              > checker_list_diagnostics.txt
      - name: "Perform checker config coverage check (--warnings)"
        continue-on-error: true
        run: |
          set +e # Do not hard exit on an erroring call!
          .github/workflows/config_label_check.py \
            "checker_list_diagnostics.txt" \
            "config/labels/analyzers/clangsa.json" \
            "config/labels/analyzers/clang-tidy.json" \
            "config/labels/analyzers/cppcheck.json" \
            --existing-filter "clang-diagnostic-" \
            --new-filter "clang-diagnostic-"
          EXIT_STATUS=$?
          echo "Coverage check returned: $EXIT_STATUS."
          # Explicitly check if the bit for "8" is set in the result,
          # indicating new checkers without severity set.
          if [[ $(($EXIT_STATUS & 8)) -eq 8 ]]
          then
            echo "::warning title=New unconfigured diagnostics::The checker label config files lack some new diagnostic report (\"warning\") kinds."
            exit 0
          elif [[ $EXIT_STATUS -eq 1 || $EXIT_STATUS -eq 2 ]]
          then
            # Script execution error.
            exit $EXIT_STATUS
          else
            # We do not wish to fail if only removed checkers are reported.
            exit 0
          fi
      - name: "Perform checker config coverage check"
        run: |
          set +e # Do not hard exit on an erroring call!
          .github/workflows/config_label_check.py \
            "checker_list_normal.txt" \
            "config/labels/analyzers/clangsa.json" \
            "config/labels/analyzers/clang-tidy.json" \
            "config/labels/analyzers/cppcheck.json" \
            --existing-ignore "clang-diagnostic-" \
            --new-ignore \
              "clang-diagnostic-" \
              "alpha." \
              "apiModeling." \
              "debug." \
              "optin.osx." \
              "osx." \
              "darwin-" \
              "objc-"
          EXIT_STATUS=$?
          echo "Coverage check returned: $EXIT_STATUS."
          # Explicitly check if the bit for "8" is set in the result,
          # indicating new checkers without severity set.
          if [[ $(($EXIT_STATUS & 8)) -eq 8 ]]
          then
            exit 8
          elif [[ $EXIT_STATUS -eq 1 || $EXIT_STATUS -eq 2 ]]
          then
            # Script execution error.
            exit $EXIT_STATUS
          else
            # We do not wish to fail if only removed checkers are reported.
            exit 0
          fi
 

What changed

What Latchkey heals here

This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:

This workflow runs 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow