Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: Add CodeChecker #836

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 0 additions & 32 deletions .github/workflows/clang-static-analyzer.yaml

This file was deleted.

53 changes: 53 additions & 0 deletions .github/workflows/codechecker.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: CodeChecker

on: [push, pull_request]

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

jobs:
codechecker_static_analyzer:
runs-on: ubuntu-24.04

steps:
- name: Checkout code including full history and submodules
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
fetch-depth: 0

- name: Install CodeChecker
run: |
sudo apt-get update
sudo apt-get install clang-tools-18 cmake cppcheck libcunit1-dev ninja-build
pip install --require-hashes -r tools/requirements-codechecker.txt

- name: Run CodeChecker
run: |
tools/ci/run_ci.sh --run-build --run-code-checker --code-checker diff
env:
CC: clang-18

- name: Upload CodeChecker reports
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: CodeChecker Reports
path: build-wakaama/code_checker_report/
if-no-files-found: error
if: failure()

- name: Create baseline for Upload
run: |
bash -x tools/ci/run_ci.sh --run-build --run-code-checker --code-checker baseline
env:
CC: clang-18
if: failure()

- name: Upload CodeChecker baseline (for debugging)
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: CodeChecker Baseline
path: tools/code_checker/reports.baseline
if-no-files-found: error
if: failure()
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,12 @@ Wakaama provides a simple CLI library. It can be enabled with:
- Unit testing: CUnit

On Ubuntu 24.04, used in CI, the dependencies can be installed as such:
- `apt install build-essential clang-format clang-format-18 clang-tools-18 cmake gcovr git libcunit1-dev ninja-build python3-pip`
- `apt install build-essential clang-format clang-format-18 clang-tools-18 cmake cppcheck gcovr git libcunit1-dev ninja-build python3-pip`
- `pip3 install -r tools/requirements-compliance.txt`

For macOS the development dependencies can be installed as such:

`brew install automake clang-format cmake cunit gcc gitlint gnu-getopt make ninja`
`brew install automake clang-format cmake cppcheck cunit gcc gitlint gnu-getopt make ninja`

### Code formatting
#### C
Expand Down
39 changes: 39 additions & 0 deletions doc/code_checker.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
Static Code analysis with CodeChecker
=====================================

Wakaama uses ```CodeChecker`` <https://codechecker.readthedocs.io/>`__
for static code analysis.

It’s possible to run ``CodeChecker`` in two different modes: ``full``
and ``diff``

In ``full`` mode all found issues are reported. In ``diff`` mode only
new issues are shown.

The ``diff`` mode compares found issues with a ‘base line’ and shows
only newly found issues.

Running ``CodeChecker``
-----------------------

The ``CodeChecker`` is run as part of the CI GitHub Actions. But it can
be run manually:

To show new issues:

::

tools/ci/run_ci.sh --run-build --run-code-checker --code-checker diff

To show *all* issues:

::

tools/ci/run_ci.sh --run-build --run-code-checker --code-checker full

Create new ‘base line’:

::

tools/ci/run_ci.sh --run-build --run-code-checker --code-checker baseline

72 changes: 72 additions & 0 deletions tools/ci/run_ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ OPT_SONARQUBE=""
OPT_SOURCE_DIRECTORY="${REPO_ROOT_DIR}"
OPT_BUILD_DIRECTORY="build-wakaama"
OPT_TEST_COVERAGE_REPORT=""
OPT_CODE_CHECKER="full"
OPT_VERBOSE=0
OPT_WRAPPER_CMD=""
RUN_BUILD=0
Expand All @@ -41,6 +42,7 @@ RUN_GITLINT=0
RUN_GIT_BLAME_IGNORE=0
RUN_TESTS=0
RUN_DOXYGEN=0
RUN_CODE_CHECKER=0

HELP_MSG="usage: ${SCRIPT_NAME} <OPTIONS>...
Runs build and test steps in CI.
Expand Down Expand Up @@ -72,6 +74,9 @@ Options:
(WRAPPER: path to build-wrapper)
--test-coverage REPORT Enable code coverage measurement, output REPORT
(REPORT: xml html text none)
--code-checker ACTION Run the CodeChecker code analyzer to create a baseline,
do a full check or a PR check (show just difference to baseline)
(TYPE: full, diff, baseline)
-v, --verbose Verbose output
-a, --all Run all steps required for a MR
-h, --help Display this help and exit
Expand All @@ -85,6 +90,7 @@ Available steps (executed by --all):
--run-build Build all targets
--run-tests Execute tests (works only for top level project)
--run-doxygen Build the Doxygen documentation of the code
--run-code-checker Run the CodeChecker code analyzer
"

function usage() {
Expand Down Expand Up @@ -229,6 +235,46 @@ function run_doxygen() {
GIT_REVISION=$(git rev-parse @) WORKING_DIR=$(pwd) DOXYGEN_OUT_DIR=build-wakaama/doxygen \
doxygen doc/doxygen/Doxyfile
}

function run_code_checker() {
readonly config_file="${REPO_ROOT_DIR}/tools/code_checker/config.json"
readonly ignore_file="${REPO_ROOT_DIR}/tools/code_checker/ignore.txt"
readonly baseline_file="${REPO_ROOT_DIR}/tools/code_checker/reports.baseline"
readonly code_checker_result_dir="build-wakaama/code_checker_result/"
readonly code_checker_report="build-wakaama/code_checker_report/"

set +e +o pipefail
CodeChecker check --logfile build-wakaama/compile_commands.json \
--config "${config_file}" \
--ignore "${ignore_file}" \
--output ${code_checker_result_dir} \
|| true # Always returns a non-zero status if issues are found
set -e -o pipefail

if [ "${OPT_CODE_CHECKER}" = "diff" ]; then
CodeChecker cmd diff -b "${baseline_file}" \
-n $code_checker_result_dir \
-o html \
--export "${code_checker_report}" \
--new
else
if [ "${OPT_CODE_CHECKER}" = "baseline" ]; then
output_format="baseline"
output_location="${baseline_file}"
else
output_format="html"
output_location="${code_checker_report}"
fi

CodeChecker parse -e "${output_format}" \
-o "${output_location}" \
--config "${config_file}" \
--ignore "${ignore_file}" \
--trim-path-prefix="${REPO_ROOT_DIR}" \
"${code_checker_result_dir}"
fi
}

# Parse Options

if [[ "$OSTYPE" == "darwin"* ]]; then
Expand Down Expand Up @@ -260,12 +306,14 @@ if ! PARSED_OPTS=$($getopt -o vah \
-l run-git-blame-ignore \
-l run-tests \
-l run-doxygen \
-l run-code-checker \
-l sanitizer: \
-l scan-build: \
-l sonarqube: \
-l source-directory: \
-l build-directory: \
-l test-coverage: \
-l code-checker: \
-l verbose \
--name "${SCRIPT_NAME}" -- "$@");
then
Expand Down Expand Up @@ -328,6 +376,12 @@ while true; do
RUN_DOXYGEN=1
shift
;;
--run-code-checker)
RUN_CODE_CHECKER=1
# Analyzing works only when code gets actually built
RUN_CLEAN=1
shift
;;
--sanitizer)
OPT_SANITIZER=$2
shift 2
Expand Down Expand Up @@ -356,6 +410,10 @@ while true; do
OPT_TEST_COVERAGE_REPORT=$2
shift 2
;;
--code-checker)
OPT_CODE_CHECKER=$2
shift 2
;;
--)
shift
break
Expand Down Expand Up @@ -411,6 +469,11 @@ if [ -n "${OPT_SCAN_BUILD}" ] && [ -n "${OPT_SONARQUBE}" ]; then
exit 1
fi

if [ "${RUN_CODE_CHECKER}" = "1" ] && [ -n "${OPT_SONARQUBE}" ]; then
echo "--sonarqube and --code-checker can not be enabled at the same time"
exit 1
fi

if [ -n "${OPT_SONARQUBE}" ]; then
OPT_TEST_COVERAGE_REPORT="${OPT_TEST_COVERAGE_REPORT:-none}"
OPT_WRAPPER_CMD="${OPT_SONARQUBE} \
Expand All @@ -431,6 +494,10 @@ if [ -n "${OPT_SCAN_BUILD}" ]; then
--exclude examples/shared/tinydtls"
fi

if [ "${RUN_CODE_CHECKER}" = "1" ]; then
CMAKE_ARGS="${CMAKE_ARGS} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug"
fi

# Run Steps

if [ "${RUN_GITLINT}" -eq 1 ]; then
Expand Down Expand Up @@ -464,3 +531,8 @@ fi
if [ "${RUN_DOXYGEN}" -eq 1 ]; then
run_doxygen
fi

if [ "${RUN_CODE_CHECKER}" = "1" ]; then
run_code_checker
fi

12 changes: 12 additions & 0 deletions tools/code_checker/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"analyze": [
"--disable=cplusplus",
"--disable=cppcheck-exceptDeallocThrow",
"--disable=cppcheck-exceptThrowInDestructor",
"--disable=cppcheck-leakUnsafeArgAlloc",
"--disable=cppcheck-rethrowNoCurrentException",
"--disable=cppcheck-thisSubtraction",
"--disable=cppcheck-throwInNoexceptFunction",
"--clean"
]
}
2 changes: 2 additions & 0 deletions tools/code_checker/ignore.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-*/transport/tinydtls/third_party/*
-*/tests/*
Loading
Loading