Skip to content

Commit b35c33b

Browse files
committed
ci: coding guidelines: add per-file violation table to SARIF summary
Extend sarif_summary.py to also report the number of violations broken down by file. parse_sarif now collects a file_counts Counter by walking each result's locations[].physicalLocation.artifactLocation.uri field. The new write_file_summary helper renders a second Markdown table sorted by descending violation count, with a header showing the total number of distinct files affected. The table is appended to the step summary immediately after the existing per-rule table. Assisted-by: GitHub Copilot:claude-sonnet-4.6 Signed-off-by: Anas Nashif <anas.nashif@intel.com>
1 parent a5645fb commit b35c33b

2 files changed

Lines changed: 38 additions & 12 deletions

File tree

.github/workflows/coding_guidelines_full.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ jobs:
164164
- name: Summarize SARIF results
165165
if: always()
166166
run: |
167-
python3 scripts/ci/sarif_summary.py results.sarif
167+
python3 scripts/ci/sarif_summary.py results_${GITHUB_SHA}.sarif
168168
169169
# disabled for now
170170
# - name: Upload Analysis Results

scripts/ci/sarif_summary.py

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,18 @@ def _tag_order(tag):
2424

2525

2626
def parse_sarif(path):
27-
"""Return (counts, rule_meta) from *path*.
27+
"""Return (counts, rule_meta, file_counts) from *path*.
2828
29-
counts -- Counter mapping ruleId -> total violation count
30-
rule_meta -- dict mapping ruleId -> {desc, tag}
29+
counts -- Counter mapping ruleId -> total violation count
30+
rule_meta -- dict mapping ruleId -> {desc, tag}
31+
file_counts -- Counter mapping file URI -> total violation count
3132
"""
3233
with open(path, encoding="utf-8") as fh:
3334
sarif = json.load(fh)
3435

3536
counts = collections.Counter()
3637
rule_meta = {}
38+
file_counts = collections.Counter()
3739

3840
for run in sarif.get("runs", []):
3941
for rule in run.get("tool", {}).get("driver", {}).get("rules", []):
@@ -53,11 +55,32 @@ def parse_sarif(path):
5355
for result in run.get("results", []):
5456
rid = result.get("ruleId", "unknown")
5557
counts[rid] += 1
56-
57-
return counts, rule_meta
58-
59-
60-
def write_summary(counts, rule_meta, out):
58+
for loc in result.get("locations", []):
59+
uri = (
60+
loc.get("physicalLocation", {})
61+
.get("artifactLocation", {})
62+
.get("uri", "")
63+
)
64+
if uri:
65+
file_counts[uri] += 1
66+
67+
return counts, rule_meta, file_counts
68+
69+
70+
def write_file_summary(file_counts, out):
71+
"""Write a Markdown table of violation counts per file."""
72+
n_files = len(file_counts)
73+
out.write(f"## :file_folder: Violations by File\n\n")
74+
out.write(f"> **Files with violations:** {n_files:,}\n\n")
75+
out.write("| # | File | Violations |\n")
76+
out.write("|--:|------|----------:|\n")
77+
for idx, (uri, cnt) in enumerate(
78+
sorted(file_counts.items(), key=lambda kv: -kv[1]), 1
79+
):
80+
out.write(f"| {idx} | `{uri}` | {cnt:,} |\n")
81+
82+
83+
def write_summary(counts, rule_meta, file_counts, out):
6184
total = sum(counts.values())
6285
n_rules = len(counts)
6386

@@ -81,6 +104,9 @@ def write_summary(counts, rule_meta, out):
81104
desc = m.get("desc", "")
82105
out.write(f"| {idx} | `{rid}` | {tag} | {cnt:,} | {desc} |\n")
83106

107+
out.write("\n")
108+
write_file_summary(file_counts, out)
109+
84110

85111
def emit_annotations(counts, rule_meta):
86112
"""Emit one ``::notice::`` annotation per rule for the Actions log."""
@@ -110,14 +136,14 @@ def main():
110136
)
111137
args = ap.parse_args()
112138

113-
counts, rule_meta = parse_sarif(args.sarif)
139+
counts, rule_meta, file_counts = parse_sarif(args.sarif)
114140

115141
summary_file = os.environ.get("GITHUB_STEP_SUMMARY")
116142
if summary_file:
117143
with open(summary_file, "a", encoding="utf-8") as fh:
118-
write_summary(counts, rule_meta, fh)
144+
write_summary(counts, rule_meta, file_counts, fh)
119145
else:
120-
write_summary(counts, rule_meta, sys.stdout)
146+
write_summary(counts, rule_meta, file_counts, sys.stdout)
121147

122148
if not args.no_annotations:
123149
emit_annotations(counts, rule_meta)

0 commit comments

Comments
 (0)