Introduce clang-tidy and Lizard via PR-delta ratchet strategy
Table of Contents
This page is a capture in the inbox bucket of the product backlog — a pre-sprint idea, not yet pulled into a sprint as a story.
What
Introduce Clang-Tidy and Lizard into the CI pipeline using a ratchet strategy: both tools enforce standards only on lines or files that are new or changed in the current PR, leaving the existing codebase untouched. Technical debt is frozen in place and decreases naturally every time a developer touches a file.
The implementation has two parts:
- Lizard (complexity: CCN, length, arguments, nesting) — use
dorny/paths-filterto build the list of modified.cpp=/.hppfiles and pass it tolizard --warnings_only. Nothing runs if no C++ files changed. Note:dorny/paths-filterwithlist-files: shellproduces a space-separated list suitable for shell expansion; without that option the output is newline-separated and requirestr '\n' ' 'before passing to Lizard as arguments. - Clang-Tidy — use
cpp-linter/cpp-linter-actionwithlines-changed-only: trueandfiles-changed-only: true. The action compiles every modified file againstcompile_commands.jsonbut only fails the build and posts PR comments for lines actually added or changed. A legacy file with 500 pre-existing warnings on unmodified lines passes clean.
Rollout happens in three phases:
- Observation (week 1–2): run both jobs with
continue-on-error: true. Developers see inline PR comments without build breakage. - Soft enforcement (week 3–4): remove
continue-on-error; enable Lizard and Clang-Tidy readability/modernize checks as hard failures for new lines. - Hard enforcement (month 2+): add
bugprone-*andcppcoreguidelines-*checks.
The story task list would be: add Lizard job (with paths-filter delta
guard), add Clang-Tidy job (cpp-linter-action, lines-changed-only),
wire both into the pr-gate check, write the .clang-tidy config
(include per-file suppressions for generated code — OreStudio generates
C++ and generated files touching a PR must not trigger ratchet
failures), tune thresholds, run the observation phase, flip to hard
enforcement.
Why
OreStudio has a large, accumulated C++ codebase. Turning on Clang-Tidy
or Lizard against the whole tree today would produce hundreds of
failures, forcing a multi-week freeze to fix them before CI is green
again — unacceptable while features are shipping. The ratchet approach
avoids that entirely: the debt is frozen, not ignored, and shrinks
with every PR. The existing clang_tidy_static_analysis capture
describes the general setup; this capture records the specific safe
rollout strategy needed to act on it without disrupting the team.
References
cpp-linter/cpp-linter-action— GitHub Action with built-inlines-changed-onlysupport (key parameter for legacy repos).dorny/paths-filter— GitHub Action; uselist-files: shellto get a space-separated list directly usable as Lizard arguments.- Suggested Lizard thresholds:
--length 150 --CCN 15 --arguments 8 --nested_level 4.
See also
- Set up clang-tidy static analysis — general clang-tidy setup capture (CMake targets, compile_commands, nightly workflow); this capture is the how-to-introduce-it-safely companion.