-
Notifications
You must be signed in to change notification settings - Fork 89
165 lines (145 loc) · 5.9 KB
/
Copy pathpmd.yml
File metadata and controls
165 lines (145 loc) · 5.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: pmd
on:
push:
branches: [ "develop" ]
pull_request:
branches: [ "develop" ]
schedule:
- cron: '41 12 * * 3'
permissions:
contents: read
jobs:
pmd-code-scan:
permissions:
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
runs-on: ubuntu-latest
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0 # 必须拉取完整历史,才能比较分支差异
- name: Set up JDK 17
uses: actions/setup-java@v5
with:
java-version: '17'
distribution: 'temurin'
- name: Run PMD
id: pmd
env:
EVENT_BEFORE: ${{ github.event.before }}
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -euo pipefail
FILE_LIST="changed-files.txt"
rm -f "$FILE_LIST" pmd-report.sarif
trap 'rm -f "$FILE_LIST"' EXIT
case "$GITHUB_EVENT_NAME" in
pull_request)
git diff --name-only --diff-filter=ACMRT "$PR_BASE_SHA...$PR_HEAD_SHA" -- '*.java' > "$FILE_LIST"
SCAN_SCOPE="changed Java files in the pull request"
;;
push)
if [ -n "${EVENT_BEFORE:-}" ] && [ "$EVENT_BEFORE" != "0000000000000000000000000000000000000000" ]; then
git diff --name-only --diff-filter=ACMRT "$EVENT_BEFORE" "$GITHUB_SHA" -- '*.java' > "$FILE_LIST"
SCAN_SCOPE="Java files introduced by this push"
else
find . -type f \( -path '*/src/main/java/*.java' -o -path '*/src/test/java/*.java' \) -print | sed 's|^./||' | sort > "$FILE_LIST"
SCAN_SCOPE="all Java source and test files for an initial push"
fi
;;
schedule)
find . -type f \( -path '*/src/main/java/*.java' -o -path '*/src/test/java/*.java' \) -print | sed 's|^./||' | sort > "$FILE_LIST"
SCAN_SCOPE="all Java source and test files"
;;
*)
echo "Unsupported event: $GITHUB_EVENT_NAME"
exit 1
;;
esac
echo "PMD scan scope: $SCAN_SCOPE"
if [ ! -s "$FILE_LIST" ]; then
echo "No Java files to scan."
echo "violations=0" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "Java files to scan:"
cat "$FILE_LIST"
sed -i "s|^|$PWD/|" "$FILE_LIST"
PMD_VERSION="6.55.0"
curl -L "https://github.com/pmd/pmd/releases/download/pmd_releases%2F${PMD_VERSION}/pmd-bin-${PMD_VERSION}.zip" -o pmd.zip
unzip -q pmd.zip
mv pmd-bin-${PMD_VERSION} pmd
PMD_CMD="$PWD/pmd/bin/run.sh"
chmod +x "$PMD_CMD"
# PMD can use a non-zero exit code for rule violations. Validate the SARIF
# report below before treating that case differently from an execution error.
set +e
"$PMD_CMD" pmd --no-cache \
-filelist "$FILE_LIST" \
-f sarif \
-R rulesets/java/quickstart.xml \
-r pmd-report.sarif
pmd_exit=$?
set -e
if [ ! -s pmd-report.sarif ]; then
echo "PMD completed without producing a SARIF report."
exit 1
fi
if ! jq -e '
(.runs | type == "array" and length > 0)
and all(.runs[];
(.results | type == "array")
and ((.invocations? // []) | all(.[]; .executionSuccessful != false))
and ((.invocations? // []) | all(.[];
(.toolExecutionNotifications? // []) | all(.[]; .level != "error")
))
)
' pmd-report.sarif > /dev/null; then
echo "PMD produced an invalid or unsuccessful SARIF report."
exit 1
fi
violations=$(jq '[.runs[]?.results[]?] | length' pmd-report.sarif)
if [ "$pmd_exit" -ne 0 ] && [ "$violations" -eq 0 ]; then
echo "PMD exited with status $pmd_exit without reporting rule violations."
exit "$pmd_exit"
fi
echo "violations=$violations" >> "$GITHUB_OUTPUT"
- name: Install sarif-tools and convert to HTML
if: ${{ always() && hashFiles('pmd-report.sarif') != '' }}
run: |
pip install sarif-tools
sarif html pmd-report.sarif --output pmd-report.html
- name: Upload SARIF file
if: ${{ always() && hashFiles('pmd-report.sarif') != '' }}
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: pmd-report.sarif
- name: Upload SARIF file as artifact
if: ${{ always() && hashFiles('pmd-report.sarif') != '' }}
uses: actions/upload-artifact@v7
with:
name: pmd-sarif-report # 给工件起一个有意义的名字
path: pmd-report.sarif
- name: Upload HTML report
if: ${{ always() && hashFiles('pmd-report.html') != '' }}
uses: actions/upload-artifact@v7
with:
name: pmd-html-report
path: pmd-report.html
- name: Check PMD violations
run: |
if [[ ${{ steps.pmd.outputs.violations }} -eq 0 ]]; then
echo "✅ PMD 未发现代码问题,构建通过。"
exit 0
else
echo "❌ PMD 发现 ${{ steps.pmd.outputs.violations }} 个代码问题,构建失败。"
exit 1
fi