2020 name : Clang-Tidy
2121 runs-on : [runs-on, runner=16cpu-linux-x64, "run-id=${{ github.run_id }}", "extras=s3-cache"]
2222 container :
23- image : px4io/px4-dev:v1.17.0-beta1
23+ image : ghcr.io/px4/px4-dev:v1.17.0-rc2
24+ outputs :
25+ has_findings : ${{ steps.clang_tidy.outputs.has_findings }}
2426 steps :
2527 - uses : runs-on/action@v2
2628 - uses : actions/checkout@v4
@@ -31,39 +33,110 @@ jobs:
3133 - name : Configure Git Safe Directory
3234 run : git config --system --add safe.directory '*'
3335
34- - name : Restore Compiler Cache
35- id : cc_restore
36- uses : actions/cache/restore@v4
36+ - uses : ./.github/actions/setup-ccache
37+ id : ccache
3738 with :
38- path : ~/.ccache
39- key : ccache-clang-tidy-${{ github.head_ref || github.ref_name }}
40- restore-keys : |
41- ccache-clang-tidy-${{ github.head_ref || github.ref_name }}-
42- ccache-clang-tidy-main-
43- ccache-clang-tidy-
39+ cache-key-prefix : ccache-clang-tidy
40+ max-size : 120M
4441
45- - name : Configure Compiler Cache
46- run : |
47- mkdir -p ~/.ccache
48- echo "base_dir = ${GITHUB_WORKSPACE}" > ~/.ccache/ccache.conf
49- echo "compression = true" >> ~/.ccache/ccache.conf
50- echo "compression_level = 6" >> ~/.ccache/ccache.conf
51- echo "max_size = 120M" >> ~/.ccache/ccache.conf
52- echo "hash_dir = false" >> ~/.ccache/ccache.conf
53- echo "compiler_check = content" >> ~/.ccache/ccache.conf
54- ccache -s
55- ccache -z
42+ - name : Build - px4_sitl_default (Clang)
43+ run : make -j16 px4_sitl_default-clang
5644
5745 - name : Run Clang-Tidy Analysis
58- run : make -j16 clang-tidy
46+ id : clang_tidy
47+ run : |
48+ if [ "${{ github.event_name }}" != "pull_request" ]; then
49+ make -j$(nproc) clang-tidy
50+ echo "has_findings=false" >> $GITHUB_OUTPUT
51+ else
52+ output=$(python3 Tools/ci/run-clang-tidy-pr.py origin/${{ github.base_ref }} 2>&1)
53+ exit_code=$?
54+ echo "$output"
55+ # Helper prints this message on both early-exit paths
56+ # (no changed C++ files, or no matching TUs in the compile DB)
57+ if echo "$output" | grep -q "skipping clang-tidy"; then
58+ echo "has_findings=false" >> $GITHUB_OUTPUT
59+ else
60+ echo "has_findings=true" >> $GITHUB_OUTPUT
61+ fi
62+ exit $exit_code
63+ fi
5964
60- - name : Compiler Cache Stats
61- if : always()
62- run : ccache -s
65+ - name : Upload compile_commands.json
66+ if : always() && github.event_name == 'pull_request'
67+ uses : actions/upload-artifact@v4
68+ with :
69+ name : compile-commands
70+ path : build/px4_sitl_default-clang/compile_commands.json
71+ retention-days : 1
6372
64- - name : Save Compiler Cache
73+ - uses : ./.github/actions/save-ccache
6574 if : always()
66- uses : actions/cache/save@v4
6775 with :
68- path : ~/.ccache
69- key : ${{ steps.cc_restore.outputs.cache-primary-key }}
76+ cache-primary-key : ${{ steps.ccache.outputs.cache-primary-key }}
77+
78+ post_clang_tidy_comments :
79+ name : Clang-Tidy PR Annotations
80+ needs : [clang_tidy]
81+ runs-on : ubuntu-latest
82+ permissions :
83+ pull-requests : write
84+ contents : read
85+ if : >-
86+ always()
87+ && github.event.pull_request
88+ && github.event.pull_request.head.repo.full_name == github.repository
89+ && (needs.clang_tidy.result == 'success' || needs.clang_tidy.result == 'failure')
90+ && needs.clang_tidy.outputs.has_findings == 'true'
91+ steps :
92+ - uses : actions/checkout@v4
93+ with :
94+ fetch-depth : 0
95+
96+ - name : Install clang-tools (for clang-tidy-diff)
97+ run : sudo apt-get install -y clang-tools
98+
99+ - name : Download compile_commands.json
100+ uses : actions/download-artifact@v4
101+ with :
102+ name : compile-commands
103+ path : build/px4_sitl_default-clang
104+
105+ - name : Run clang-tidy-diff and export fixes
106+ run : |
107+ # WHY WE REWRITE compile_commands.json PATHS
108+ #
109+ # The clang_tidy job runs on a RunsOn/AWS runner where the workspace
110+ # root is "/__w/PX4-Autopilot/PX4-Autopilot". All absolute paths baked
111+ # into compile_commands.json (the "file" and "directory" fields, and
112+ # every -I include path in "command") use that prefix.
113+ #
114+ # This annotation job runs on a GitHub-hosted runner where the
115+ # workspace root is "/home/runner/work/PX4-Autopilot/PX4-Autopilot".
116+ # When clang-tidy-diff invokes clang-tidy, it reads the "directory"
117+ # field from compile_commands.json and calls chdir() on it. Since
118+ # the AWS-style path does not exist here, clang-tidy crashes with:
119+ # LLVM ERROR: Cannot chdir into "/__w/.../build/px4_sitl_default-clang"
120+ # and silently produces an empty fixes.yml, so no annotations are posted.
121+ #
122+ # Fix: rewrite all occurrences of the AWS workspace prefix to the
123+ # current runner workspace ($GITHUB_WORKSPACE) before invoking
124+ # clang-tidy-diff. Safe because compile_commands.json is a local
125+ # scratch file pulled from the artifact; no source file is modified.
126+ sed -i "s|/__w/PX4-Autopilot/PX4-Autopilot|${GITHUB_WORKSPACE}|g" \
127+ build/px4_sitl_default-clang/compile_commands.json
128+
129+ mkdir -p clang-tidy-result
130+ git diff -U0 origin/${{ github.base_ref }}...HEAD \
131+ | clang-tidy-diff-18.py -p1 \
132+ -path build/px4_sitl_default-clang \
133+ -export-fixes clang-tidy-result/fixes.yml \
134+ -j0 || true
135+
136+ - name : Annotate PR with clang-tidy findings
137+ uses : platisd/clang-tidy-pr-comments@v1
138+ with :
139+ github_token : ${{ secrets.GITHUB_TOKEN }}
140+ clang_tidy_fixes : clang-tidy-result/fixes.yml
141+ request_changes : true
142+ suggestions_per_comment : 10
0 commit comments