From f8ca673630fc4a649db6e479067cc1dbb37cac98 Mon Sep 17 00:00:00 2001 From: wbsong111 Date: Wed, 8 Jul 2026 14:14:27 +0900 Subject: [PATCH] fix(sbom-ci): summary shows only scanned severities (drop always-zero MED/LOW) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SEVERITY 로 스캔한 심각도만 요약표 컬럼으로 동적 출력. 기본(HIGH,CRITICAL)에서 항상 0이던 MED/LOW 컬럼 제거. SEVERITY 에 MEDIUM/LOW 추가 시에만 해당 컬럼 표시. TSV 는 CRITICAL 을 첫 카운트 열로 유지(게이트 호환). Co-Authored-By: Claude Opus 4.8 (1M context) --- doc/scripts/scan-sbom.sh | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/doc/scripts/scan-sbom.sh b/doc/scripts/scan-sbom.sh index 4eed972..c17be66 100755 --- a/doc/scripts/scan-sbom.sh +++ b/doc/scripts/scan-sbom.sh @@ -139,6 +139,10 @@ python3 - "$RESULTS" "$CHARTMAP" "$SEVERITY" "$TOTAL" "$(ts)" "$SUMMARY_TSV" <<' import sys results, chartmap, sev, total, tstamp, tsv_out = sys.argv[1:7] total=int(total) +# 표시 심각도 = 실제 스캔한 SEVERITY 만 (순위 내림차순). MED/LOW 는 스캔 안 하면 항상 0이므로 제외. +RANK=["CRITICAL","HIGH","MEDIUM","LOW"]; IDX={"CRITICAL":1,"HIGH":2,"MEDIUM":3,"LOW":4} +scanned=[s.strip().upper() for s in sev.split(",") if s.strip()] +shown=[s for s in RANK if s in scanned] or ["CRITICAL","HIGH"] cm={} try: for l in open(chartmap): @@ -152,29 +156,31 @@ for l in open(results): img=p[0] if p[5]=="OK" or img not in best or best[img][5]!="OK": best[img]=p rows=list(best.values()) -def key(r): - try: return (-int(r[1]),-int(r[2])) - except: return (1,0) -rows.sort(key=key) +def cnt(r,s): + try: return int(r[IDX[s]]) + except: return 0 +rows.sort(key=lambda r: tuple(-cnt(r,s) for s in shown)) ok=[r for r in rows if r[5]=="OK"]; err=[r for r in rows if r[5]!="OK"] -tc=sum(int(r[1]) for r in ok); th=sum(int(r[2]) for r in ok) +totals={s:sum(cnt(r,s) for r in ok) for s in shown} secs=[int(r[6]) for r in rows if len(r)>=7 and r[6].isdigit()] +# TSV: chart, image, , status, sec (CRITICAL 은 첫 카운트 열 = col3) with open(tsv_out,"w") as f: for r in rows: - f.write(f"{cm.get(r[0],'')}\t{r[0]}\t{r[1]}\t{r[2]}\t{r[3]}\t{r[4]}\t{r[5]}\t{r[6] if len(r)>=7 else ''}\n") + cols=[cm.get(r[0],""), r[0]] + [str(cnt(r,s)) for s in shown] + [r[5], r[6] if len(r)>=7 else ""] + f.write("\t".join(cols)+"\n") print("# Trivy SBOM 취약점 요약\n") print(f"- 생성: {tstamp}") print(f"- 총 소요: **{total//60}분 {total%60}초** (SBOM {len(rows)}개)") print(f"- 성공/실패: **{len(ok)} / {len(err)}**") print(f"- 집계 심각도: `{sev}`") -print(f"- 취약점 합계: **CRITICAL {tc}**, **HIGH {th}**") +print("- 취약점 합계: " + ", ".join(f"**{s} {totals[s]}**" for s in shown)) if secs: print(f"- SBOM당 스캔시간: 최소 {min(secs)}s / 최대 {max(secs)}s / 평균 {sum(secs)//len(secs)}s") print() -print("| Chart | Image | CRIT | HIGH | MED | LOW | Status | Sec |") -print("|---|---|---:|---:|---:|---:|---|---:|") +print("| Chart | Image | " + " | ".join(shown) + " | Status | Sec |") +print("|---|---|" + "---:|"*len(shown) + "---|---:|") for r in rows: - sec=r[6] if len(r)>=7 else "-" - print(f"| {cm.get(r[0],'')} | `{r[0]}` | {r[1]} | {r[2]} | {r[3]} | {r[4]} | {r[5]} | {sec} |") + cells=" | ".join(str(cnt(r,s)) for s in shown) + print(f"| {cm.get(r[0],'')} | `{r[0]}` | {cells} | {r[5]} | {r[6] if len(r)>=7 else '-'} |") PY {