generated from karsten.jeppesen/KAJE-Template
All checks were successful
DMA-CSD-CICD/noah.pretzer/pipeline/head This commit looks good
106 lines
3.3 KiB
Bash
106 lines
3.3 KiB
Bash
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
IN_JSON="${1:-scan_results.json}"
|
|
OUT_MD="${2:-report.md}"
|
|
|
|
if [[ ! -s "$IN_JSON" ]]; then
|
|
echo "# Security Scan Report" > "$OUT_MD"
|
|
echo "_No results available (empty input)._" >> "$OUT_MD"
|
|
exit 0
|
|
fi
|
|
|
|
BRANCH="${BRANCH_NAME:-${GIT_BRANCH:-unknown}}"
|
|
SHA="${GIT_COMMIT:-unknown}"
|
|
SHORT_SHA="${SHA:0:7}"
|
|
|
|
TOTAL_FILES=$(jq 'length' "$IN_JSON")
|
|
TOTAL_FINDINGS=$(jq '[.[].findings] | flatten | length' "$IN_JSON")
|
|
LOW=$(jq '[.[].findings] | flatten | map(select(.severity=="LOW")) | length' "$IN_JSON")
|
|
MED=$(jq '[.[].findings] | flatten | map(select(.severity=="MEDIUM")) | length' "$IN_JSON")
|
|
HIGH=$(jq '[.[].findings] | flatten | map(select(.severity=="HIGH")) | length' "$IN_JSON")
|
|
CRIT=$(jq '[.[].findings] | flatten | map(select(.severity=="CRITICAL")) | length' "$IN_JSON")
|
|
|
|
{
|
|
echo "# Security Scan Report (Ollama)"
|
|
echo ""
|
|
echo "- **Branch**: \`${BRANCH}\`"
|
|
echo "- **Commit**: \`${SHORT_SHA}\`"
|
|
echo "- **Files analyzed**: ${TOTAL_FILES}"
|
|
echo "- **Total findings**: ${TOTAL_FINDINGS}"
|
|
echo ""
|
|
echo "### Severity Summary"
|
|
echo ""
|
|
echo "| Severity | Count |"
|
|
echo "|-----------|------:|"
|
|
echo "| CRITICAL | ${CRIT} |"
|
|
echo "| HIGH | ${HIGH} |"
|
|
echo "| MEDIUM | ${MED} |"
|
|
echo "| LOW | ${LOW} |"
|
|
echo ""
|
|
echo "---"
|
|
echo "## Per-File Findings"
|
|
echo ""
|
|
} > "$OUT_MD"
|
|
|
|
file_count=$(jq 'length' "$IN_JSON")
|
|
if [[ "$file_count" -eq 0 ]]; then
|
|
echo "_No files were scanned._" >> "$OUT_MD"
|
|
exit 0
|
|
fi
|
|
|
|
# Helper: safe cell formatter via jq (strip newlines and excessive whitespace)
|
|
# We do not export a function; we let jq do formatting inline per row.
|
|
|
|
for i in $(seq 0 $((file_count-1))); do
|
|
file_path=$(jq -r ".[$i].file" "$IN_JSON")
|
|
findings_len=$(jq -r ".[$i].findings | length" "$IN_JSON")
|
|
|
|
echo "### \`$file_path\`" >> "$OUT_MD"
|
|
echo "" >> "$OUT_MD"
|
|
|
|
if [[ "$findings_len" -eq 0 ]]; then
|
|
echo "_No issues found._" >> "$OUT_MD"
|
|
echo "" >> "$OUT_MD"
|
|
continue
|
|
fi
|
|
|
|
echo "| Severity | Line | Rule ID | Description | Recommendation |" >> "$OUT_MD"
|
|
echo "|----------|-----:|---------|-------------|----------------|" >> "$OUT_MD"
|
|
|
|
# Notes:
|
|
# - Replace CRLF and LF with spaces via gsub("\r?\n"; " ")
|
|
# - Collapse all whitespace via gsub("[[:space:]]+"; " ")
|
|
# - Trim leading/trailing spaces using sub and gsub
|
|
jq -r ".[$i].findings[] |
|
|
[
|
|
(.severity // \"\"),
|
|
(if (.line|type==\"number\") then (.line|tostring) else \"\" end),
|
|
(.rule_id // \"\"),
|
|
((.description // \"\")
|
|
| gsub(\"\\r?\\n\"; \" \")
|
|
| gsub(\"[[:space:]]+\"; \" \")
|
|
| sub(\"^ \"; \"\")
|
|
| sub(\" $\"; \"\")),
|
|
((.recommendation // \"\")
|
|
| gsub(\"\\r?\\n\"; \" \")
|
|
| gsub(\"[[:space:]]+\"; \" \")
|
|
| sub(\"^ \"; \"\")
|
|
| sub(\" $\"; \"\"))
|
|
]
|
|
| \"| \" + (.[0]) + \" | \" + (.[1]) + \" | \" + (.[2]) + \" | \" + (.[3]) + \" | \" + (.[4]) + \" |\"
|
|
" "$IN_JSON" >> "$OUT_MD"
|
|
|
|
# References (if present)
|
|
refs_count=$(jq ".[$i].findings | map(select(.references != null and (.references|length>0))) | length" "$IN_JSON")
|
|
if [[ "$refs_count" -gt 0 ]]; then
|
|
echo "" >> "$OUT_MD"
|
|
echo "**References**:" >> "$OUT_MD"
|
|
jq -r ".[$i].findings[] | select(.references != null) | .references[]? | \"- \" + tostring" "$IN_JSON" >> "$OUT_MD"
|
|
fi
|
|
|
|
echo "" >> "$OUT_MD"
|
|
done
|
|
|
|
echo "[INFO] Markdown report generated: $OUT_MD"
|
|
`` |