Skip to content

Commit 0ec7cec

Browse files
committed
Scan summary table for GH comment logic
1 parent f92d2d6 commit 0ec7cec

File tree

1 file changed

+106
-9
lines changed

1 file changed

+106
-9
lines changed

.github/workflows/aquasec_repo_scan.yml

Lines changed: 106 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ concurrency:
1616
cancel-in-progress: true
1717

1818
jobs:
19-
aquasec:
19+
aquasec-scanning:
2020
name: AquaSec Full Repository Scan
2121
runs-on: ubuntu-latest
2222
steps:
@@ -62,7 +62,7 @@ jobs:
6262
echo "=== Receiving AquaSec Scan Results ==="
6363
6464
SCAN_RESULTS_ENDPOINT="https://eu-1.codesec.aquasec.com/api/v1/scans/results"
65-
ALL_DATA="[]"
65+
FINDINGS_JSON="[]"
6666
PAGE_NUM=1
6767
PAGE_SIZE=100
6868
TOTAL_EXPECTED=0
@@ -90,22 +90,22 @@ jobs:
9090
PAGE_COUNT=$(echo "$PAGE_DATA" | jq 'length')
9191
echo "Retrieved $PAGE_COUNT findings on page $PAGE_NUM"
9292
93-
ALL_DATA=$(echo "$ALL_DATA" "$PAGE_DATA" | jq -s 'add')
93+
FINDINGS_JSON=$(echo "FINDINGS_JSON" "$PAGE_DATA" | jq -s 'add')
9494
95-
TOTAL_RETRIEVED=$(echo "$ALL_DATA" | jq 'length')
95+
FINDINGS_COUNT=$(echo "FINDINGS_JSON" | jq 'length')
9696
97-
if [ "$TOTAL_RETRIEVED" -ge "$TOTAL_EXPECTED" ] || [ "$PAGE_COUNT" -eq 0 ]; then
97+
if [ "FINDINGS_COUNT" -ge "$TOTAL_EXPECTED" ] || [ "$PAGE_COUNT" -eq 0 ]; then
9898
break
9999
fi
100100
101101
PAGE_NUM=$((PAGE_NUM + 1))
102102
sleep 2
103103
done
104104
105-
TOTAL_RETRIEVED=$(echo "$ALL_DATA" | jq 'length')
106-
echo "Total findings retrieved: $TOTAL_RETRIEVED"
105+
FINDINGS_COUNT=$(echo "FINDINGS_JSON" | jq 'length')
106+
echo "Total findings retrieved: FINDINGS_COUNT"
107107
108-
jq -n --argjson total "$TOTAL_RETRIEVED" --argjson data "$ALL_DATA" \
108+
jq -n --argjson total "FINDINGS_COUNT" --argjson data "FINDINGS_JSON" \
109109
'{"total": $total, "size": $total, "page": 1, "data": $data}' > aquasec_scan_results.json
110110
111111
echo "Full repository scan retrieved successfully"
@@ -224,7 +224,7 @@ jobs:
224224
}
225225
226226
with open("aquasec_scan.sarif", "w") as f:
227-
json.dump(sarif_output, f)
227+
json.dump(sarif_output, f, indent=2)
228228
229229
print(f"Converted {len(sarif_findings)} findings to SARIF 2.1.0 format")
230230
@@ -233,3 +233,100 @@ jobs:
233233
with:
234234
sarif_file: aquasec_scan.sarif
235235
category: aquasec
236+
237+
- name: Create Scan Summary Table
238+
id: scan_summary_table
239+
shell: python
240+
run: |
241+
import os
242+
import json
243+
import sys
244+
from collections import Counter
245+
246+
SARIF_PATH = "aquasec_scan.sarif"
247+
SEVERITIES = ["CRITICAL", "HIGH", "MEDIUM", "LOW"]
248+
CATEGORIES = ["sast", "vulnerabilities", "iacMisconfigurations", "secrets", "pipelineMisconfigurations", "license"]
249+
250+
print("=== Generating Scan Summary Table ===")
251+
try:
252+
with open(SARIF_PATH, "r", encoding="utf-8") as f:
253+
sarif = json.load(f)
254+
255+
if "runs" not in sarif or not sarif["runs"]:
256+
raise ValueError("SARIF file contains no runs")
257+
258+
run = sarif["runs"][0]
259+
rules = run.get("tool", {}).get("driver", {}).get("rules", [])
260+
results = run.get("results", [])
261+
262+
except (IOError, json.JSONDecodeError, ValueError) as e:
263+
print(f"Error processing SARIF file: {e}", file=sys.stderr)
264+
sys.exit(1)
265+
266+
# Initialize counters for each category
267+
category_severity_counts = {cat: Counter() for cat in CATEGORIES}
268+
269+
# Count results by category and severity
270+
for result in results:
271+
rule_idx = result.get("ruleIndex")
272+
if rule_idx is None or rule_idx >= len(rules):
273+
continue
274+
275+
rule = rules[rule_idx]
276+
category = rule.get("name", "")
277+
tags = rule.get("properties", {}).get("tags", [])
278+
severity = next((s for s in SEVERITIES if s in tags), None)
279+
280+
if category in CATEGORIES and severity:
281+
category_severity_counts[category][severity] += 1
282+
283+
# Build Markdown summary table
284+
headers = ["AQUASEC"] + SEVERITIES + ["TOTAL"]
285+
summary_table = "| " + " | ".join(headers) + " |\n"
286+
summary_table += "|---|---|---|---|---|---|\n"
287+
288+
total_severity = Counter()
289+
total_all = 0
290+
for category in CATEGORIES:
291+
row = [category]
292+
category_total = 0
293+
for severity in SEVERITIES:
294+
count = category_severity_counts[category][severity]
295+
row.append(str(count))
296+
total_severity[severity] += count
297+
category_total += count
298+
row.append(f"**{category_total}**")
299+
total_all += category_total
300+
summary_table += "| " + " | ".join(row) + " |\n"
301+
302+
total_row = ["**➡️ Total**"] + [f"**{total_severity[sev]}**" for sev in SEVERITIES] + [f"**{total_all}**"]
303+
summary_table += "| " + " | ".join(total_row) + " |"
304+
305+
try:
306+
if "GITHUB_OUTPUT" in os.environ:
307+
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as f:
308+
f.write("table<<EOF\n")
309+
f.write(summary_table + "\n")
310+
f.write("EOF\n")
311+
else:
312+
print("Warning: GITHUB_OUTPUT not set", file=sys.stderr)
313+
except IOError as e:
314+
print(f"Error writing output: {e}", file=sys.stderr)
315+
sys.exit(1)
316+
317+
- name: GitHub scan summary comment
318+
if: github.event_name == 'pull_request'
319+
uses: actions/github-script@v8
320+
with:
321+
github-token: ${{ secrets.GITHUB_TOKEN }}
322+
script: |
323+
const link = `https://github.com/${context.repo.owner}/${context.repo.repo}/security/code-scanning?query=pr%3A${context.issue.number}+is%3Aopen`;
324+
const sentence = `AquaSec has completed a full security repository scan ✅ You can find the analysis results for this PR branch on [this overview](${link}).\n Below is the summary of the findings:`;
325+
const summaryTable = `${{ steps.scan_summary_table.outputs.table }}`;
326+
const body = `${sentence}\n\n${summaryTable}`;
327+
github.rest.issues.createComment({
328+
issue_number: context.issue.number,
329+
owner: context.repo.owner,
330+
repo: context.repo.repo,
331+
body
332+
});

0 commit comments

Comments
 (0)