Skip to content

Run clang-tidy on pull-request changed lines#4982

Open
matthargett wants to merge 1 commit into
bytecodealliance:mainfrom
rebeckerspecialties:ci/clang-tidy-on-prs
Open

Run clang-tidy on pull-request changed lines#4982
matthargett wants to merge 1 commit into
bytecodealliance:mainfrom
rebeckerspecialties:ci/clang-tidy-on-prs

Conversation

@matthargett

Copy link
Copy Markdown
Contributor

What

Run the repository's existing .clang-tidy on pull requests — but only on the lines the PR changes.

The root .clang-tidy is already a maintained, strict config (bugprone-*, cert-*, clang-analyzer-*, ... with WarningsAsErrors), but no workflow runs it today, so the null-deref / sign-conversion / use-after-move class of bug it catches is currently caught only by a reviewer reading the diff.

How

Mirrors the diff-scoping already used by the git-clang-format-14 gate in coding_guidelines.yml:

  • permissions: contents: read, fetch-depth: 0, diff computed from ${{ github.event.pull_request.base.sha }}..HEAD.
  • clang-tidy-diff.py (pinned to the llvm-14 release) turns the changed-line ranges into -line-filter, so a PR is only flagged for issues it introduces on the lines it touches — pre-existing issues on untouched lines stay silent.
  • compile_commands.json comes from the default linux iwasm build (interp + AOT runtime, no LLVM required), covering the highest-traffic loader / interpreter / common sources.

Fork / upstream safety

Same properties as coding_guidelines.yml: only contents: read, diff from the base SHA — so it behaves identically for in-repo and forked pull requests.

Notes

  • Scoped to the default linux config's translation units; changes to files not in that build are skipped. Coverage can be broadened with more configs.
  • clang-tidy version tracks the clang-format-14 already pinned by ci/coding_guidelines_check.py.
  • Trigger is pull_request only: the gate diffs against the PR base, so a manual (workflow_dispatch) run would have no meaningful base.

Verification

Verified on a pull request in a fork with clang-tidy-14: a violation on a changed line fails the job; a clean change passes; a pre-existing violation on an untouched line does not fire (diff-scoping). A PR that touches no C/C++ lines is a clean no-op.

The repository already ships a strict .clang-tidy (bugprone-*, cert-*,
clang-analyzer-*, ... with WarningsAsErrors) but no workflow runs it, so
the bug class it catches is currently caught only by a reviewer reading
the diff.

Add a pull_request workflow that runs clang-tidy-14 on the lines a PR
changes (clang-tidy-diff.py driven from the base SHA, the same
diff-scoping approach as the git-clang-format gate in
coding_guidelines.yml), so a PR is only flagged for issues it introduces
on the lines it touches. Like that gate it needs only contents:read and
computes the diff from the pull_request base SHA, so it behaves
identically for in-repo and forked pull requests.

compile_commands.json is produced from the default linux iwasm build (no
LLVM required), covering the highest-traffic loader / interpreter /
common sources.

@lum1n0us lum1n0us left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before turning this workflow into an enforced check, should we run a full  clang-tidy  scan on the current codebase and clean up any existing issues first? Otherwise, contributors may end up having to deal with pre-existing diagnostics while making unrelated changes in their PRs.

-G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build build --target iwasm --parallel

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For compile_commands.json, there is no need to cmake --build build

with:
# full history so the pull_request base SHA is available for the diff
fetch-depth: 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a quick-exit path for those PRs only affect documents, test cases, CIs to save action minutes?

cmake -S product-mini/platforms/linux -B build \
-G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generating  compile_commands.json  from the default Linux configuration does cover the highest-traffic sources, but it does not guarantee coverage of every file or every changed line in a PR. As a result, this workflow may miss some modified code paths or analyze files without the correct compilation context

-p1 -path build \
-clang-tidy-binary "$TIDY" \
-j "$(nproc)" 2>&1 \
| tee clang-tidy.log ; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When  clang-tidy  is asked to analyze a changed file that is not present in  compile_commands.json , it may fall back to analyzing the file directly without the proper build context. That can produce false failures due to missing macro definitions, wrong conditional-compilation branches, missing include paths, or even diagnostics on unchanged lines in the modified file.

with:
# full history so the pull_request base SHA is available for the diff
fetch-depth: 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be worth adding a quick-exit path for PRs that only change documentation, test data, or other non-source files. In those cases, the workflow could skip the  clang-tidy  step entirely and save GitHub Actions minutes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants