From e815ed20e963fa05773203a2fe7d77c4e82c77a4 Mon Sep 17 00:00:00 2001 From: Uilian Ries Date: Sun, 2 Jun 2024 20:15:26 +0200 Subject: [PATCH] Add static analysis to CI (#626) * Add pre-commit config file Signed-off-by: Uilian Ries * update revision Signed-off-by: Uilian Ries * Revert "update revision" This reverts commit 29be8ad9f44a5c6cb7b8a1e2899e3a28769ba5da. * Configure cppcheck Signed-off-by: Uilian Ries * Configure clang tidy Signed-off-by: Uilian Ries * Drop oclint and uwyi Signed-off-by: Uilian Ries * Do not specify code style for now Signed-off-by: Uilian Ries * use pytoml Signed-off-by: Uilian Ries * checkout Signed-off-by: Uilian Ries * Cache pip Signed-off-by: Uilian Ries * Single build Signed-off-by: Uilian Ries * Revert "use pytoml" This reverts commit dd80e4999f4be8cc9bf6b4244ec24819fbf63c24. * restore cache Signed-off-by: Uilian Ries * restore build folder Signed-off-by: Uilian Ries * Consider gtest as from system Signed-off-by: Uilian Ries * Cache build folder Signed-off-by: Uilian Ries * Try to restore conan cache Signed-off-by: Uilian Ries * Run coverate at same build step Signed-off-by: Uilian Ries * Show report Signed-off-by: Uilian Ries * clang tidy Signed-off-by: Uilian Ries * Do not run test branch Signed-off-by: Uilian Ries * Remove steps from pre-commit Signed-off-by: Uilian Ries * Suppress import error Signed-off-by: Uilian Ries * Ignore clang tidy errors Signed-off-by: Uilian Ries * Ignore clang tidy errors Signed-off-by: Uilian Ries --------- Signed-off-by: Uilian Ries --- .github/workflows/linux-clang-build.yml | 11 -- .github/workflows/linux-static-analysis.yml | 200 ++++++++++++++++++++ .pre-commit-config.yaml | 10 + tests/common/LuhnCheckTest.cpp | 2 +- tests/modules/airline/AirlineTest.cpp | 2 +- tests/modules/crypto/CryptoTest.cpp | 4 +- tests/modules/medicine/MedicineTest.cpp | 2 +- 7 files changed, 215 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/linux-static-analysis.yml create mode 100644 .pre-commit-config.yaml diff --git a/.github/workflows/linux-clang-build.yml b/.github/workflows/linux-clang-build.yml index 512826406..457a896cd 100644 --- a/.github/workflows/linux-clang-build.yml +++ b/.github/workflows/linux-clang-build.yml @@ -78,14 +78,3 @@ jobs: - name: Test run: ctest --preset=unixlike-clang-debug - - - name: Generate code coverage - working-directory: ${{github.workspace}}/build/unixlike-clang-debug - run: | - ninja faker-ccov-all \ - && llvm-cov-18 show `cat ccov/binaries.list` -instr-profile=ccov/all-merged.profdata > coverage.txt - - - name: Codecov - uses: codecov/codecov-action@v3.1.4 - with: - token: ${{ secrets.CODECOVTOKEN }} diff --git a/.github/workflows/linux-static-analysis.yml b/.github/workflows/linux-static-analysis.yml new file mode 100644 index 000000000..ef2143721 --- /dev/null +++ b/.github/workflows/linux-static-analysis.yml @@ -0,0 +1,200 @@ +name: static-analysis + +on: + push: + branches: + - 'main' + workflow_dispatch: + pull_request: + +jobs: + build_project: + name: ci-ubuntu-24.04-build-clang + runs-on: ubuntu-24.04 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Configure python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + cache: 'pip' + + - name: Install Python dependencies + run: pip install -r .github/requirements.txt + + - name: Install ccache + uses: hendrikmuhs/ccache-action@v1.2 + + - name: Cache Conan packages + id: cache-conan + uses: actions/cache@v4.0.2 + env: + cache-name: cache-conan-packages + with: + path: ~/.conan2 + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('conanfile.txt') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + + - name: Configure Conan profiles + run: | + CC=clang-18 \ + CXX=clang++-18 \ + conan profile detect --force --name clang-18 + + - name: Install Conan dependencies + run: | + conan install conanfile.txt \ + -r conancenter \ + -pr:b clang-18 \ + -pr:h clang-18 \ + -s compiler.cppstd=20 \ + -s build_type=Debug \ + -o "*:shared=True" \ + -c:b tools.build:compiler_executables="{'c': '/usr/bin/clang-18', 'cpp': '/usr/bin/clang++-18'}" \ + -c:h tools.build:compiler_executables="{'c': '/usr/bin/clang-18', 'cpp': '/usr/bin/clang++-18'}" \ + --build=missing \ + + - name: Configure CMake + run: | + cmake -S ${{github.workspace}} --preset=unixlike-clang-debug \ + -DCMAKE_C_COMPILER=/usr/bin/clang-18 \ + -DCMAKE_CXX_COMPILER=/usr/bin/clang++-18 \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DCODE_COVERAGE:BOOL=ON \ + -DBUILD_TESTING:BOOL=ON \ + -DUSE_SYSTEM_DEPENDENCIES:BOOL=ON \ + -DUSE_STD_FORMAT:BOOL=ON \ + -DCMAKE_TOOLCHAIN_FILE=build/Debug/generators/conan_toolchain.cmake \ + -DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld + + - name: Build + run: cmake --build --preset=unixlike-clang-debug + + - name: Generate code coverage + working-directory: ${{github.workspace}}/build/unixlike-clang-debug + run: | + ninja faker-ccov-all \ + && llvm-cov-18 show `cat ccov/binaries.list` -instr-profile=ccov/all-merged.profdata > coverage.txt \ + && llvm-cov-18 report `cat ccov/binaries.list` -instr-profile=ccov/all-merged.profdata + + - name: Store build artifacts + uses: actions/upload-artifact@v4 + with: + name: build-directory + path: ${{github.workspace}}/build + + cppcheck: + name: cppcheck + runs-on: ubuntu-24.04 + needs: build_project + outputs: + build_output: ${{ steps.build_project.outputs }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install and cache apt packages + uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: cppcheck + version: 1.0 + + - name: Download build directory + uses: actions/download-artifact@v4 + with: + name: build-directory + path: build + + - name: Run cppcheck + run: | + cppcheck \ + --template=gcc \ + --suppress=missingIncludeSystem \ + --suppress=variableScope \ + --suppress=cppcheckError \ + --suppress=internalAstError \ + --suppress=unmatchedSuppression \ + --suppress=passedByValue \ + --suppress=syntaxError \ + --suppress=preprocessorErrorDirective \ + --inconclusive \ + -I src \ + -I src/common \ + -I src/modules \ + -I include \ + --std=c++20 \ + --enable=style \ + --enable=performance \ + --enable=warning \ + --enable=portability \ + --inline-suppr \ + --cppcheck-build-dir=build/unixlike-clang-debug \ + --project=build/unixlike-clang-debug/compile_commands.json + + clang_tidy: + name: clang-tidy + runs-on: ubuntu-24.04 + needs: build_project + outputs: + build_output: ${{ steps.build_project.outputs }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Cache Conan packages + id: cache-conan + uses: actions/cache/restore@v4.0.2 + env: + cache-name: cache-conan-packages + with: + path: ~/.conan2 + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('conanfile.txt') }} + + - name: Download build directory + uses: actions/download-artifact@v4 + with: + name: build-directory + path: build + + - name: Run clang-tidy + run: | + run-clang-tidy \ + -p build/unixlike-clang-debug \ + -header-filter="include/*" \ + -extra-arg="-std=gnu++20" || true + + clang_format: + name: clang-format + runs-on: ubuntu-24.04 + needs: build_project + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download build directory + uses: actions/download-artifact@v4 + with: + name: build-directory + path: build + + - name: Configure python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + cache: 'pip' + + - name: Install Python dependencies + run: pip install pre-commit + + - name: Run clang-format + # FIXME: Ignore format errors for now + run: pre-commit run clang-format --all-files --color always --verbose || true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..16932abaf --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,10 @@ +fail_fast: false +repos: + - repo: https://github.com/pocc/pre-commit-hooks + rev: master + hooks: + - id: clang-format + - id: clang-tidy + args: ["-header-filter=include/.*", "-extra-arg=-std=c++20"] + - id: cppcheck + args: ["--template=gcc", "--suppress=missingIncludeSystem", "--suppress=variableScope", "--suppress=cppcheckError", "--suppress=internalAstError", "--suppress=unmatchedSuppression", "--suppress=passedByValue", "--suppress=syntaxError", "--suppress=preprocessorErrorDirective", "--inconclusive", "-I src", "-I src/common", "-I src/modules", "-I include", "--std=c++20", "--enable=style", "--enable=performance", "--enable=warning", "--enable=portability", "--inline-suppr"] diff --git a/tests/common/LuhnCheckTest.cpp b/tests/common/LuhnCheckTest.cpp index 3a2351209..82bbf8279 100644 --- a/tests/common/LuhnCheckTest.cpp +++ b/tests/common/LuhnCheckTest.cpp @@ -1,6 +1,6 @@ #include "LuhnCheck.h" -#include +#include "gtest/gtest.h" #include using namespace faker; diff --git a/tests/modules/airline/AirlineTest.cpp b/tests/modules/airline/AirlineTest.cpp index 4d8b161af..a767aad6f 100644 --- a/tests/modules/airline/AirlineTest.cpp +++ b/tests/modules/airline/AirlineTest.cpp @@ -181,6 +181,6 @@ TEST_F(AirlineTest, shouldGenerateFlightNumberLeadingZeros) TEST_F(AirlineTest, shouldGenerateFlightNumberByRange) { const auto flightNumber = Airline::flightNumberByRange(false, {1, 6}); - + ASSERT_TRUE(flightNumber.length() <= 6); } diff --git a/tests/modules/crypto/CryptoTest.cpp b/tests/modules/crypto/CryptoTest.cpp index ab72c070d..74318bd73 100644 --- a/tests/modules/crypto/CryptoTest.cpp +++ b/tests/modules/crypto/CryptoTest.cpp @@ -1,7 +1,7 @@ #include "faker-cxx/Crypto.h" #include -#include +#include #include "gtest/gtest.h" @@ -21,7 +21,7 @@ class CryptoTest : public Test static bool isSHA256Hash(const std::string& input) { const std::regex regexExp("^[a-f0-9]{64}$"); - + return std::regex_match(input, regexExp); } }; diff --git a/tests/modules/medicine/MedicineTest.cpp b/tests/modules/medicine/MedicineTest.cpp index a119b32d8..5665e7032 100644 --- a/tests/modules/medicine/MedicineTest.cpp +++ b/tests/modules/medicine/MedicineTest.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include "gtest/gtest.h" #include "medicine/MedicineData.h"