44 branches : [master]
55 pull_request :
66jobs :
7- pmd :
7+ static-analysis :
88 runs-on : ubuntu-24.04
99 steps :
1010 - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
@@ -14,20 +14,114 @@ jobs:
1414 java-version : ' 21'
1515 - name : Set up Workspace Environment Variable
1616 run : echo "WORKSPACE=${{ github.workspace }}" >> $GITHUB_ENV
17- - name : PMD Check
18- run : mvn pmd:pmd pmd:cpd pmd:check pmd:cpd-check -f ./ddk-parent/pom.xml --batch-mode --fail-at-end
19- checkstyle :
20- runs-on : ubuntu-24.04
21- steps :
22- - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
23- - uses : actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
17+ - name : Cache Maven dependencies
18+ uses : actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
2419 with :
25- distribution : ' temurin'
26- java-version : ' 21'
27- - name : Set up Workspace Environment Variable
28- run : echo "WORKSPACE=${{ github.workspace }}" >> $GITHUB_ENV
29- - name : Checkstyle Check
30- run : mvn checkstyle:checkstyle checkstyle:check -f ./ddk-parent/pom.xml --batch-mode --fail-at-end
20+ path : /home/runner/.m2/repository
21+ key : ${{ runner.os }}-maven-0-${{ hashFiles('**/pom.xml') }}
22+ - name : Compile + generate PMD/Checkstyle reports
23+ # Report goals (pmd:pmd, pmd:cpd, checkstyle:checkstyle) never fail the build, so
24+ # every module's XML is produced — no Maven cascade-skip. Compile first for PMD's
25+ # type-resolving rules. Note: pmd:pmd may miss a few edge-case rules that only
26+ # surface in pmd:check (see PR description for the maven-pmd-plugin quirk).
27+ run : |
28+ mvn -T 2C -f ./ddk-parent/pom.xml --batch-mode --fail-at-end \
29+ compile \
30+ pmd:pmd pmd:cpd \
31+ checkstyle:checkstyle
32+ - name : Annotate + count PMD/Checkstyle violations
33+ # Parse every pmd.xml and checkstyle-result.xml in one Python pass. Emits a GitHub
34+ # workflow-command annotation per violation (visible inline in PR Files-changed) and
35+ # exits 1 if total > 0 — fail-fast that bypasses SpotBugs (slow) when there are
36+ # already known PMD/Checkstyle issues. Runs even if a previous step failed.
37+ if : always()
38+ run : |
39+ python3 - <<'EOF'
40+ import os, sys
41+ from xml.etree import ElementTree as ET
42+ from pathlib import Path
43+
44+ root = Path(os.environ.get('GITHUB_WORKSPACE', '.'))
45+ count = 0
46+
47+ def annot(level, file, line, title, msg):
48+ global count
49+ count += 1
50+ msg = (msg or '').strip().replace('\n', ' ')[:1000]
51+ try:
52+ rel = Path(file).relative_to(root)
53+ except ValueError:
54+ rel = file
55+ print(f"::{level} file={rel},line={line},title={title}::{msg}")
56+
57+ for xml in root.rglob('target/pmd.xml'):
58+ for f in ET.parse(xml).getroot().findall('file'):
59+ for v in f.findall('violation'):
60+ level = 'error' if v.attrib.get('priority') == '1' else 'warning'
61+ annot(level, f.attrib['name'], v.attrib.get('beginline', '1'),
62+ f"PMD/{v.attrib.get('rule','')}", v.text)
63+
64+ for xml in root.rglob('target/checkstyle-result.xml'):
65+ for f in ET.parse(xml).getroot().findall('file'):
66+ for e in f.findall('error'):
67+ level = 'error' if e.attrib.get('severity') == 'error' else 'warning'
68+ annot(level, f.attrib['name'], e.attrib.get('line', '1'),
69+ f"Checkstyle/{e.attrib.get('source','').split('.')[-1]}",
70+ e.attrib.get('message',''))
71+
72+ print(f"PMD/Checkstyle violations: {count}")
73+ if count > 0:
74+ sys.exit(1)
75+ EOF
76+ - name : Enforce PMD/Checkstyle thresholds (Maven safety-net)
77+ # Redundant in the success case (Python check above already passed). Provides
78+ # official-tool validation in case the Python parser misreads schema.
79+ run : |
80+ mvn -T 2C -f ./ddk-parent/pom.xml --batch-mode --fail-at-end \
81+ pmd:check pmd:cpd-check \
82+ checkstyle:check
83+ - name : Generate SpotBugs report
84+ run : |
85+ mvn -T 2C -f ./ddk-parent/pom.xml --batch-mode --fail-at-end \
86+ spotbugs:spotbugs
87+ - name : Annotate + count SpotBugs violations
88+ if : always()
89+ run : |
90+ python3 - <<'EOF'
91+ import os, sys
92+ from xml.etree import ElementTree as ET
93+ from pathlib import Path
94+
95+ root = Path(os.environ.get('GITHUB_WORKSPACE', '.'))
96+ count = 0
97+
98+ def annot(level, file, line, title, msg):
99+ global count
100+ count += 1
101+ msg = (msg or '').strip().replace('\n', ' ')[:1000]
102+ try:
103+ rel = Path(file).relative_to(root)
104+ except ValueError:
105+ rel = file
106+ print(f"::{level} file={rel},line={line},title={title}::{msg}")
107+
108+ for xml in root.rglob('target/spotbugsXml.xml'):
109+ for b in ET.parse(xml).getroot().findall('BugInstance'):
110+ sl = b.find('SourceLine')
111+ lm = b.find('LongMessage')
112+ if sl is not None and lm is not None:
113+ annot('warning', sl.attrib.get('sourcepath', '?'),
114+ sl.attrib.get('start', '1'),
115+ f"SpotBugs/{b.attrib.get('type','')}", lm.text)
116+
117+ print(f"SpotBugs violations: {count}")
118+ if count > 0:
119+ sys.exit(1)
120+ EOF
121+ - name : Enforce SpotBugs threshold (Maven safety-net)
122+ run : |
123+ mvn -T 2C -f ./ddk-parent/pom.xml --batch-mode --fail-at-end \
124+ spotbugs:check
31125 line-endings :
32126 runs-on : ubuntu-24.04
33127 steps :
@@ -64,10 +158,8 @@ jobs:
64158 with :
65159 path : /home/runner/.m2/repository
66160 key : ${{ runner.os }}-maven-0-${{ hashFiles('**/pom.xml') }}
67- - name : Build with Maven within a virtual X Server Environment
68- # Run pmd:pmd and pmd:cpd first to generate reports for all modules, then run pmd:check and pmd:cpd-check
69- # This ensures all violations are collected and reported before the build fails
70- run : xvfb-run mvn clean verify checkstyle:check pmd:pmd pmd:cpd pmd:check pmd:cpd-check spotbugs:check -f ./ddk-parent/pom.xml --batch-mode --fail-at-end
161+ - name : Build with Maven within a virtual X Server Environment
162+ run : xvfb-run mvn clean verify -f ./ddk-parent/pom.xml --batch-mode --fail-at-end
71163 - name : Fail on missing surefire reports
72164 # Tycho-Surefire writes no TEST-*.xml when discovery is empty — fail the job in that case.
73165 if : always()
0 commit comments