From 77f3cf68e4c2197cdad0963abad16c0a1f6839e2 Mon Sep 17 00:00:00 2001 From: Philipp Horstenkamp Date: Sun, 13 Sep 2026 20:02:35 +0200 Subject: [PATCH] feat: warn when an image has 0 reported CVEs and display warning banner --- action.yaml | 14 ++++++++++++-- cve-diff.js | 47 ++++++++++++++++++++++++++++++----------------- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/action.yaml b/action.yaml index 5404d7a..5407c55 100644 --- a/action.yaml +++ b/action.yaml @@ -235,7 +235,12 @@ runs: if trivy sbom --skip-version-check --format json --output "$out_json" "$f" 2>"$err_log"; then if [ -s "$out_json" ]; then vuln_cnt=$(grep -o '"VulnerabilityID"' "$out_json" 2>/dev/null | wc -l || echo 0) - head_summary+=(" - ${arch}: ✅ OK (${vuln_cnt} vulnerability findings)") + if [ "$vuln_cnt" -eq 0 ]; then + echo "::warning::Head image architecture '${arch}' has 0 CVE findings. Verify that OS/packages were recognized." + head_summary+=(" - ${arch}: ⚠️ WARNING (0 vulnerability findings detected)") + else + head_summary+=(" - ${arch}: ✅ OK (${vuln_cnt} vulnerability findings)") + fi head_report_count=$((head_report_count + 1)) else head_ok=false @@ -264,7 +269,12 @@ runs: if trivy sbom --skip-version-check --format json --output "$out_json" "$f" 2>"$err_log"; then if [ -s "$out_json" ]; then vuln_cnt=$(grep -o '"VulnerabilityID"' "$out_json" 2>/dev/null | wc -l || echo 0) - target_summary+=(" - ${arch}: ✅ OK (${vuln_cnt} vulnerability findings)") + if [ "$vuln_cnt" -eq 0 ]; then + echo "::warning::Target baseline image architecture '${arch}' has 0 CVE findings. Verify that OS/packages were recognized." + target_summary+=(" - ${arch}: ⚠️ WARNING (0 vulnerability findings detected)") + else + target_summary+=(" - ${arch}: ✅ OK (${vuln_cnt} vulnerability findings)") + fi target_report_count=$((target_report_count + 1)) else target_ok=false diff --git a/cve-diff.js b/cve-diff.js index 00ae61a..127157f 100755 --- a/cve-diff.js +++ b/cve-diff.js @@ -149,19 +149,17 @@ function formatVulnRow(v) { * @returns {string} */ function renderMarkdownDiff(baseCves, branchCves, baseName = 'main') { - if (baseCves.size === 0) { - return [ - `### 🔄 Vulnerability Delta (vs \`${baseName}\`)`, - '', - '> [!NOTE]', - `> No baseline scan from \`${baseName}\` was available to compare against.`, - '', - ].join('\n'); - } - const baseKeys = new Set(baseCves.keys()); const branchKeys = new Set(branchCves.keys()); + if (branchCves.size === 0) { + console.error('::warning::Head image contains 0 reported vulnerabilities. Verify that packages and dependencies were recognized.'); + } + + if (baseCves.size === 0) { + console.error(`::warning::Baseline target (${baseName}) contains 0 reported vulnerabilities.`); + } + const newKeys = []; let unchangedCount = 0; for (const key of branchKeys) { @@ -196,15 +194,30 @@ function renderMarkdownDiff(baseCves, branchCves, baseName = 'main') { const lines = [ `### 🔄 Vulnerability Delta (vs \`${baseName}\`)`, '', - '| Metric | Count |', - '| :--- | :--- |', - `| 🚨 **New Vulnerabilities** | ${newVulns.length > 0 ? `🚨 **${newVulns.length}**` : '0'} |`, - `| ✅ **Resolved Vulnerabilities** | ${resolvedVulns.length > 0 ? `✅ **${resolvedVulns.length}**` : '0'} |`, - `| ⚪ **Unchanged Vulnerabilities** | ${unchangedCount} |`, - '', - `#### 🚨 New Vulnerabilities Introduced (${newVulns.length})`, ]; + if (branchCves.size === 0 && baseCves.size === 0) { + lines.push('> [!WARNING]'); + lines.push('> Both the head image and baseline target have **0 reported vulnerabilities**.'); + lines.push(''); + } else if (branchCves.size === 0) { + lines.push('> [!WARNING]'); + lines.push('> The head image has **0 reported vulnerabilities**. Verify that OS packages and language dependencies were properly indexed in the SBOM.'); + lines.push(''); + } else if (baseCves.size === 0) { + lines.push('> [!WARNING]'); + lines.push(`> The baseline image (\`${baseName}\`) has **0 reported vulnerabilities**.`); + lines.push(''); + } + + lines.push('| Metric | Count |'); + lines.push('| :--- | :--- |'); + lines.push(`| 🚨 **New Vulnerabilities** | ${newVulns.length > 0 ? `🚨 **${newVulns.length}**` : '0'} |`); + lines.push(`| ✅ **Resolved Vulnerabilities** | ${resolvedVulns.length > 0 ? `✅ **${resolvedVulns.length}**` : '0'} |`); + lines.push(`| ⚪ **Unchanged Vulnerabilities** | ${unchangedCount} |`); + lines.push(''); + lines.push(`#### 🚨 New Vulnerabilities Introduced (${newVulns.length})`); + if (newVulns.length > 0) { lines.push('| Severity | CVE | Package | Arch | Installed | Fixed In | Title |'); lines.push('| :--- | :--- | :--- | :--- | :--- | :--- | :--- |');