Skip to content

Commit 5a849ed

Browse files
committed
ci: Add clang-tidy comments for PR's
There are two seperate actions: One for running clang-tidy with no secrets, and another with secrets. This ensures that if the former is compromised, the latter secrets should be safe. Signed-off-by: Urmas Rist <urmas@leil.io>
1 parent 717f178 commit 5a849ed

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Secure workflow with access to repository secrets and GitHub token for posting analysis results
2+
name: Post the static analysis results
3+
4+
on:
5+
workflow_run:
6+
workflows: [ "Static analysis" ]
7+
types: [ completed ]
8+
9+
jobs:
10+
clang-tidy-results:
11+
# Trigger the job only if the previous (insecure) workflow completed successfully
12+
if: ${{ github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' }}
13+
runs-on: ubuntu-22.04
14+
permissions:
15+
pull-requests: write
16+
# OPTIONAL: auto-closing conversations requires the `contents` permission
17+
contents: write
18+
steps:
19+
- name: Download analysis results
20+
uses: actions/github-script@v7
21+
with:
22+
script: |
23+
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
24+
owner: context.repo.owner,
25+
repo: context.repo.repo,
26+
run_id: ${{ github.event.workflow_run.id }},
27+
});
28+
const matchArtifact = artifacts.data.artifacts.filter((artifact) => {
29+
return artifact.name == "clang-tidy-result"
30+
})[0];
31+
const download = await github.rest.actions.downloadArtifact({
32+
owner: context.repo.owner,
33+
repo: context.repo.repo,
34+
artifact_id: matchArtifact.id,
35+
archive_format: "zip",
36+
});
37+
const fs = require("fs");
38+
fs.writeFileSync("${{ github.workspace }}/clang-tidy-result.zip", Buffer.from(download.data));
39+
- name: Extract analysis results
40+
run: |
41+
mkdir clang-tidy-result
42+
unzip -j clang-tidy-result.zip -d clang-tidy-result
43+
- name: Set environment variables
44+
uses: actions/github-script@v7
45+
with:
46+
script: |
47+
const assert = require("node:assert").strict;
48+
const fs = require("fs");
49+
function exportVar(varName, fileName, regEx) {
50+
const val = fs.readFileSync("${{ github.workspace }}/clang-tidy-result/" + fileName, {
51+
encoding: "ascii"
52+
}).trimEnd();
53+
assert.ok(regEx.test(val), "Invalid value format for " + varName);
54+
core.exportVariable(varName, val);
55+
}
56+
exportVar("PR_ID", "pr-id.txt", /^[0-9]+$/);
57+
exportVar("PR_HEAD_REPO", "pr-head-repo.txt", /^[-./0-9A-Z_a-z]+$/);
58+
exportVar("PR_HEAD_SHA", "pr-head-sha.txt", /^[0-9A-Fa-f]+$/);
59+
- uses: actions/checkout@v4
60+
with:
61+
repository: ${{ env.PR_HEAD_REPO }}
62+
ref: ${{ env.PR_HEAD_SHA }}
63+
persist-credentials: false
64+
- name: Redownload analysis results
65+
uses: actions/github-script@v7
66+
with:
67+
script: |
68+
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
69+
owner: context.repo.owner,
70+
repo: context.repo.repo,
71+
run_id: ${{ github.event.workflow_run.id }},
72+
});
73+
const matchArtifact = artifacts.data.artifacts.filter((artifact) => {
74+
return artifact.name == "clang-tidy-result"
75+
})[0];
76+
const download = await github.rest.actions.downloadArtifact({
77+
owner: context.repo.owner,
78+
repo: context.repo.repo,
79+
artifact_id: matchArtifact.id,
80+
archive_format: "zip",
81+
});
82+
const fs = require("fs");
83+
fs.writeFileSync("${{ github.workspace }}/clang-tidy-result.zip", Buffer.from(download.data));
84+
- name: Extract analysis results
85+
run: |
86+
mkdir clang-tidy-result
87+
unzip -j clang-tidy-result.zip -d clang-tidy-result
88+
- name: Run clang-tidy-pr-comments action
89+
uses: platisd/clang-tidy-pr-comments@v1
90+
with:
91+
github_token: ${{ secrets.GITHUB_TOKEN }}
92+
clang_tidy_fixes: clang-tidy-result/fixes.yml
93+
pull_request_id: ${{ env.PR_ID }}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Insecure workflow with limited permissions that should provide analysis results through an artifact
2+
name: Static analysis
3+
4+
on: pull_request
5+
6+
jobs:
7+
clang-tidy:
8+
runs-on: ubuntu-24.04
9+
steps:
10+
11+
- uses: actions/checkout@v4
12+
with:
13+
ref: ${{ github.event.pull_request.head.sha }}
14+
submodules: true
15+
fetch-depth: 0
16+
17+
- name: Setup anew (or from cache) vcpkg
18+
uses: lukka/run-vcpkg@v11
19+
20+
- name: Install packages
21+
run: |
22+
sudo ./tests/install-packages.sh
23+
24+
- name: Fetch base branch
25+
run: |
26+
git remote add upstream "https://github.com/${{ github.event.pull_request.base.repo.full_name }}"
27+
git fetch --no-tags --no-recurse-submodules upstream "${{ github.event.pull_request.base.ref }}"
28+
29+
- name: Install clang-tidy
30+
run: |
31+
sudo apt-get update
32+
sudo apt-get install -y clang-tidy python3-yaml
33+
34+
- name: Prepare compile_commands.json
35+
run: |
36+
mkdir -p build
37+
cmake -B build \
38+
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
39+
-DCMAKE_TOOLCHAIN_FILE="${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" \
40+
-DENABLE_CLIENT_LIB=ON \
41+
-DENABLE_DOCS=ON \
42+
-DENABLE_NFS_GANESHA=ON \
43+
-DENABLE_POLONAISE=OFF \
44+
-DENABLE_URAFT=ON \
45+
-DGSH_CAN_HOST_LOCAL_FS=ON \
46+
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
47+
-DCMAKE_INSTALL_PREFIX="${GITHUB_WORKSPACE}/install/saunafs/" \
48+
-DENABLE_TESTS=ON \
49+
-DCODE_COVERAGE=OFF \
50+
-DSAUNAFS_TEST_POINTER_OBFUSCATION=ON \
51+
-DENABLE_WERROR=ON \
52+
53+
- name: Create results directory
54+
run: |
55+
mkdir clang-tidy-result
56+
57+
- name: Analyze
58+
run: |
59+
git diff -U0 "$(git merge-base HEAD "upstream/${{ github.event.pull_request.base.ref }}")" | clang-tidy-diff -p1 -path build -export-fixes clang-tidy-result/fixes.yml
60+
61+
- name: Save PR metadata
62+
run: |
63+
echo "${{ github.event.number }}" > clang-tidy-result/pr-id.txt
64+
echo "${{ github.event.pull_request.head.repo.full_name }}" > clang-tidy-result/pr-head-repo.txt
65+
echo "${{ github.event.pull_request.head.sha }}" > clang-tidy-result/pr-head-sha.txt
66+
67+
- uses: actions/upload-artifact@v4
68+
with:
69+
name: clang-tidy-result
70+
path: clang-tidy-result/

0 commit comments

Comments
 (0)