xpeditis2.0/scripts/ci/summarize-security.py
David 5c59ef044b
Some checks failed
Dev CI / Backend — Lint (push) Successful in 1m4s
Dev CI / Security gate (push) Failing after 1m36s
Dev CI / Backend — Unit Tests (push) Successful in 1m7s
Dev CI / Frontend — Lint & Type-check (push) Successful in 1m51s
Dev CI / Frontend — Unit Tests (push) Successful in 1m22s
Dev CI / Notify Failure (push) Has been skipped
fix
2026-09-23 22:56:46 +02:00

46 lines
1.8 KiB
Python

"""Print audit counts without exposing secret matches or source snippets."""
import json
import os
from pathlib import Path
def summarize(reports):
incomplete = False
def read(name):
nonlocal incomplete
try:
report = json.loads((reports / name).read_text())
if not isinstance(report, dict) or report.get('error'):
raise ValueError('Invalid audit report')
return report
except (OSError, ValueError):
print(f'{name}: report missing, invalid or scanner error; inspect the audit step.')
incomplete = True
return {}
for project in ('root', 'backend', 'frontend', 'log-exporter'):
report = read(f'npm-audit-{project}.json')
counts = report.get('metadata', {}).get('vulnerabilities', {})
if 'high' not in counts or 'critical' not in counts:
print(f'{project}: dependency audit unavailable.')
incomplete = True
continue
print(f'{project}: {counts["high"]} high, {counts["critical"]} critical vulnerabilities.')
report = read('source-security.json')
if 'Results' not in report:
print('Source audit unavailable.')
incomplete = True
else:
results = report['Results'] or []
secrets = sum(len(result.get('Secrets') or []) for result in results)
misconfigs = sum(len(result.get('Misconfigurations') or []) for result in results)
print(f'Source: {secrets} secret findings, {misconfigs} infrastructure findings.')
print('Download the security-reports artifact for details. The audit step determines pass/fail.')
return int(incomplete)
if __name__ == '__main__':
raise SystemExit(summarize(Path(os.environ['RUNNER_TEMP']) / 'security-reports'))