diff --git a/action.yml b/action.yml index d024632..c881336 100644 --- a/action.yml +++ b/action.yml @@ -165,6 +165,41 @@ runs: comment += `| 🟡 Medium | ${mediumSla} | ${mediumSlaNoFix} | ${slaMediumWithFix} / ${slaMediumNoFix} days | ${mediumSlaStatus} |\n`; comment += `| đŸ”ĩ Low | ${lowSla} | ${lowSlaNoFix} | ${slaLowWithFix} / ${slaLowNoFix} days | ${lowSlaStatus} |\n\n`; + if (totalSlaBreaches > 0) { + function addVulnerabilityDetails(severityName, icon, details, threshold) { + if (!details || details.trim() === '') return; + + const vulns = details.split(';;').filter(v => v.trim()); + if (vulns.length === 0) return; + + comment += `### ${icon} ${severityName} Severity - SLA Breached Issues (with fixes)\n\n`; + comment += `Showing ${vulns.length} issue(s) that have exceeded the ${threshold}-day SLA threshold:\n\n`; + + vulns.forEach((vuln, idx) => { + const parts = vuln.split('|'); + if (parts.length >= 6) { + const [id, title, pkg, daysAgo, cvssScore, cve] = parts; + comment += `${idx + 1}. **${title}**\n`; + comment += ` - ID: \`${id}\`\n`; + comment += ` - Package: \`${pkg}\`\n`; + comment += ` - Published: ${daysAgo} days ago (SLA: ${threshold} days)\n`; + if (cvssScore && cvssScore !== '0') { + comment += ` - CVSS Score: ${cvssScore}\n`; + } + if (cve && cve !== 'N/A') { + comment += ` - CVE: ${cve}\n`; + } + comment += '\n'; + } + }); + } + + addVulnerabilityDetails('Critical', '🔴', process.env.critical_sla_details || '', slaCriticalWithFix); + addVulnerabilityDetails('High', '🟠', process.env.high_sla_details || '', slaHighWithFix); + addVulnerabilityDetails('Medium', '🟡', process.env.medium_sla_details || '', slaMediumWithFix); + addVulnerabilityDetails('Low', 'đŸ”ĩ', process.env.low_sla_details || '', slaLowWithFix); + } + if (parseInt(criticalNoFix) > 0 || parseInt(highNoFix) > 0 || parseInt(mediumNoFix) > 0 || parseInt(lowNoFix) > 0) { comment += '### â„šī¸ Vulnerabilities Without Available Fixes (Informational Only)\n\n'; comment += 'The following vulnerabilities were detected but **do not have fixes available** (no upgrade or patch). These are excluded from failure thresholds:\n\n'; diff --git a/snyk-parser.sh b/snyk-parser.sh index 31c176f..f3c3657 100755 --- a/snyk-parser.sh +++ b/snyk-parser.sh @@ -99,6 +99,38 @@ high_sla_breaches_no_fix=$(count_sla_breaches "high" "false" "$SLA_HIGH_NO_FIX") medium_sla_breaches_no_fix=$(count_sla_breaches "medium" "false" "$SLA_MEDIUM_NO_FIX") low_sla_breaches_no_fix=$(count_sla_breaches "low" "false" "$SLA_LOW_NO_FIX") +echo "Generating detailed SLA breach lists..." + +get_breached_details() { + local severity=$1 + local threshold=$2 + + echo "$SNYK_DATA" | jq --arg current "$current_time" --arg threshold "$threshold" --arg sev "$severity" -r ' + [.vulnerabilities[]? | + select(.severity == $sev and (.isUpgradable == true or .isPatchable == true)) | + select(.publicationTime != null) | + .publicationTime |= (. | sub("\\.[0-9]+Z$"; "Z")) | + select(($current | tonumber) - (.publicationTime | fromdateiso8601) > ($threshold | tonumber * 86400)) | + { + id: .id, + title: (.title // .id), + package: ((.packageName // .name) + "@" + .version), + daysAgo: ((($current | tonumber) - (.publicationTime | fromdateiso8601)) / 86400 | floor), + cvssScore: (.cvssScore // 0), + cve: (.identifiers.CVE[0] // "N/A") + }] | + sort_by(-.daysAgo) | + .[:20] | + map("\(.id)|\(.title)|\(.package)|\(.daysAgo)|\(.cvssScore)|\(.cve)") | + join(";;") + ' 2>/dev/null || echo "" +} + +critical_sla_details=$(get_breached_details "critical" "$SLA_CRITICAL_WITH_FIX") +high_sla_details=$(get_breached_details "high" "$SLA_HIGH_WITH_FIX") +medium_sla_details=$(get_breached_details "medium" "$SLA_MEDIUM_WITH_FIX") +low_sla_details=$(get_breached_details "low" "$SLA_LOW_WITH_FIX") + echo "Exporting SLA counts to GITHUB_ENV..." echo "critical_sla_breaches=$critical_sla_breaches" >> "$GITHUB_ENV" @@ -118,6 +150,21 @@ echo "SLA_HIGH_NO_FIX=$SLA_HIGH_NO_FIX" >> "$GITHUB_ENV" echo "SLA_MEDIUM_NO_FIX=$SLA_MEDIUM_NO_FIX" >> "$GITHUB_ENV" echo "SLA_LOW_NO_FIX=$SLA_LOW_NO_FIX" >> "$GITHUB_ENV" +{ + echo "critical_sla_details<> "$GITHUB_ENV" + echo "Generating summary and checking thresholds..." fail_build=false warn_build=false