Public Access
generated from Philipp/template-git
CI Tests / JS Unit Tests (pull_request) Successful in 46s
Philipp/Global-Workflows: Pre-commit Lint (Scoped) / pre-commit (pull_request) Successful in 1m54s
CI Tests / cross-check-mixed-sbom (sbom=false) (pull_request) Failing after 3m22s
CI Tests / cross-check-mixed-sbom (sbom=true) (pull_request) Failing after 2m38s
CI Tests / with-inbuild-sbom (sbom=false) (pull_request) Failing after 4m21s
CI Tests / without-inbuild-sbom (sbom=true) (pull_request) Failing after 5m36s
CI Tests / without-inbuild-sbom (sbom=false) (pull_request) Failing after 6m47s
CI Tests / with-inbuild-sbom (sbom=true) (pull_request) Failing after 2m59s
Extract ~450 lines of complex bash from action.yaml into modular, unit-tested Node.js scripts in lib/. All logic is covered by 26 native node:test unit tests (node --test, no external dependencies). Modules added: - lib/platforms.js - platform parsing and OCI manifest auto-discovery - lib/distro.js - SPDX PURL distro detection (os_name/os_version) - lib/verifier.js - Trivy arch mapping and SHA256 verification - lib/diagnostics.js - CI terminal diagnostic formatters - lib/install-trivy.js - Trivy install/verify entrypoint (replaces bash step) - lib/extract-sboms.js - SBOM extraction entrypoint (replaces bash step) - lib/scan-sboms.js - SBOM scan + diff entrypoint (replaces bash step) Tests added (all pass, auto-discovered by ode --test): - test/platforms.test.js - test/distro.test.js - test/verifier.test.js - test/diagnostics.test.js - test/orchestration.test.js action.yaml shrinks from 554 to 107 lines. Inputs are bridged to Node scripts via INPUT_* env vars so modules are fully decoupled from the Actions runner and testable in isolation.
107 lines
2.8 KiB
JavaScript
107 lines
2.8 KiB
JavaScript
/**
|
|
* Diagnostic formatting and reporting utilities.
|
|
*/
|
|
|
|
function formatSbomOverview({
|
|
headImage,
|
|
targetImage,
|
|
headFiles = [],
|
|
targetFiles = [],
|
|
headError = null,
|
|
targetError = null,
|
|
}) {
|
|
const lines = [
|
|
'',
|
|
'================================================================================',
|
|
' SBOM EXTRACTION DIAGNOSTIC OVERVIEW ',
|
|
'================================================================================',
|
|
];
|
|
|
|
if (headError) {
|
|
lines.push(`HEAD Image (${headImage}): ❌ FAILED - ${headError}`);
|
|
} else {
|
|
lines.push(`HEAD Image (${headImage}): ✅ SUCCESS`);
|
|
for (const f of headFiles) {
|
|
lines.push(` - ${f.name} (${f.size} bytes)`);
|
|
}
|
|
}
|
|
|
|
if (targetError) {
|
|
lines.push(`TARGET Baseline Image (${targetImage}): ❌ FAILED - ${targetError}`);
|
|
} else {
|
|
lines.push(`TARGET Baseline Image (${targetImage}): ✅ SUCCESS`);
|
|
for (const f of targetFiles) {
|
|
lines.push(` - ${f.name} (${f.size} bytes)`);
|
|
}
|
|
}
|
|
|
|
lines.push('================================================================================');
|
|
lines.push('');
|
|
return lines.join('\n');
|
|
}
|
|
|
|
function formatScanOverview({
|
|
headImage,
|
|
targetImage,
|
|
targetBranch = 'main',
|
|
strategy = null,
|
|
headSummary = [],
|
|
targetSummary = [],
|
|
}) {
|
|
const lines = [
|
|
'',
|
|
'================================================================================',
|
|
' CVE VULNERABILITY SCAN DIAGNOSTIC OVERVIEW ',
|
|
'================================================================================',
|
|
];
|
|
|
|
if (strategy) {
|
|
lines.push(`Scan Strategy: ${strategy}`);
|
|
lines.push('--------------------------------------------------------------------------------');
|
|
}
|
|
|
|
lines.push(`HEAD Image: ${headImage}`);
|
|
for (const line of headSummary) {
|
|
lines.push(line);
|
|
}
|
|
|
|
lines.push('');
|
|
lines.push(`TARGET Baseline Image: ${targetImage} (branch: '${targetBranch}')`);
|
|
for (const line of targetSummary) {
|
|
lines.push(line);
|
|
}
|
|
|
|
lines.push('================================================================================');
|
|
lines.push('');
|
|
return lines.join('\n');
|
|
}
|
|
|
|
function countVulnerabilities(report) {
|
|
if (!report) return 0;
|
|
let data = report;
|
|
if (typeof report === 'string' || Buffer.isBuffer(report)) {
|
|
try {
|
|
data = JSON.parse(report.toString('utf8'));
|
|
} catch {
|
|
return 0;
|
|
}
|
|
}
|
|
if (!data || typeof data !== 'object') return 0;
|
|
|
|
let count = 0;
|
|
if (Array.isArray(data.Results)) {
|
|
for (const res of data.Results) {
|
|
if (res && Array.isArray(res.Vulnerabilities)) {
|
|
count += res.Vulnerabilities.length;
|
|
}
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
module.exports = {
|
|
formatSbomOverview,
|
|
formatScanOverview,
|
|
countVulnerabilities,
|
|
};
|