@@ -16,7 +16,7 @@ concurrency:
1616 cancel-in-progress : true
1717
1818jobs :
19- aquasec :
19+ aquasec-scanning :
2020 name : AquaSec Full Repository Scan
2121 runs-on : ubuntu-latest
2222 steps :
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