From f46228b94df729b38346da3c4f421793e83e3038 Mon Sep 17 00:00:00 2001 From: william brady Date: Sun, 11 Jan 2026 21:38:41 -0500 Subject: [PATCH 1/2] feat: Add detailed findings output to GitHub Actions logs Previously, the GitHub Actions logs only showed summary counts and top 10 findings in the step summary. This made it difficult to see which scanner detected each issue and the exact file/line locations. Changes: - Add "Detailed Findings" section that outputs all findings to console - Each finding shows: [tool] rule_id, title, file:line location - Findings grouped by severity (CRITICAL -> LOW) - Include resource name for IaC findings - Include truncated description and remediation guidance --- entrypoint.sh | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/entrypoint.sh b/entrypoint.sh index 3a80aac..cf792a1 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -290,6 +290,73 @@ for i, finding in enumerate(findings[:10]): fi fi +# ============================================================================= +# Output detailed findings to logs (for visibility in GitHub Actions logs) +# ============================================================================= + +log_info "Detailed Findings" + +if [[ -f "$JSON_REPORT" && "$TOTAL" -gt 0 ]]; then + echo "" + echo "==============================================" + echo "SECURITY FINDINGS DETAILS" + echo "==============================================" + echo "" + + python3 -c " +import json + +with open('$JSON_REPORT', 'r') as f: + data = json.load(f) + +findings = data.get('findings', []) +severity_order = {'CRITICAL': 0, 'HIGH': 1, 'MEDIUM': 2, 'LOW': 3, 'INFO': 4} +findings.sort(key=lambda x: severity_order.get(x.get('severity', 'INFO'), 5)) + +# Group by severity for cleaner output +current_severity = None +for finding in findings: + severity = finding.get('severity', 'UNKNOWN') + tool = finding.get('tool', 'unknown') + rule_id = finding.get('rule_id', 'N/A') + title = finding.get('title', finding.get('rule_id', 'Unknown')) + file_path = finding.get('file_path', 'N/A') + line = finding.get('line_number', '') + resource = finding.get('resource', '') + description = finding.get('description', '') + remediation = finding.get('remediation', '') + + location = f'{file_path}:{line}' if line else file_path + + # Print severity header if changed + if severity != current_severity: + current_severity = severity + print(f'\\n--- {severity} ---\\n') + + print(f'[{tool}] {rule_id}: {title}') + print(f' Location: {location}') + if resource: + print(f' Resource: {resource}') + if description and description != 'FAILED': + # Truncate long descriptions + desc = description[:200] + '...' if len(description) > 200 else description + print(f' Description: {desc}') + if remediation: + # Truncate long remediation text + rem = remediation[:150] + '...' if len(remediation) > 150 else remediation + print(f' Remediation: {rem}') + print() +" + + echo "==============================================" + echo "END OF FINDINGS DETAILS" + echo "==============================================" +else + echo "No findings to display." +fi + +log_end_group + add_step_summary "" add_step_summary "---" add_step_summary "*Generated by [SDLC Code Scanner](https://github.com/crofton-cloud/sdlc-code-scanner)*" From dae4139119dd8ca61d7cb15ad382d2b283602350 Mon Sep 17 00:00:00 2001 From: william brady Date: Sun, 11 Jan 2026 21:44:47 -0500 Subject: [PATCH 2/2] fix: Address review comments for consistency - Use 'INFO' as default severity (matches sort order) instead of 'UNKNOWN' - Check `line is not None` instead of truthy check to handle line 0 --- entrypoint.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/entrypoint.sh b/entrypoint.sh index cf792a1..5c20d76 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -316,17 +316,17 @@ findings.sort(key=lambda x: severity_order.get(x.get('severity', 'INFO'), 5)) # Group by severity for cleaner output current_severity = None for finding in findings: - severity = finding.get('severity', 'UNKNOWN') + severity = finding.get('severity', 'INFO') tool = finding.get('tool', 'unknown') rule_id = finding.get('rule_id', 'N/A') title = finding.get('title', finding.get('rule_id', 'Unknown')) file_path = finding.get('file_path', 'N/A') - line = finding.get('line_number', '') + line = finding.get('line_number') resource = finding.get('resource', '') description = finding.get('description', '') remediation = finding.get('remediation', '') - location = f'{file_path}:{line}' if line else file_path + location = f'{file_path}:{line}' if line is not None else file_path # Print severity header if changed if severity != current_severity: