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.
76 lines
2.7 KiB
JavaScript
76 lines
2.7 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Installs and verifies Trivy binary against checksums lockfile.
|
|
*/
|
|
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const os = require('node:os');
|
|
const cp = require('node:child_process');
|
|
const { mapArch, parseChecksums, verifyFileSha256 } = require('./verifier.js');
|
|
|
|
function main() {
|
|
const version = process.env.TRIVY_VERSION || '0.74.0';
|
|
const homeDir = os.homedir();
|
|
const binDir = path.join(homeDir, '.local', 'bin');
|
|
const cacheDir = path.join(homeDir, '.cache', 'trivy-bin');
|
|
|
|
fs.mkdirSync(binDir, { recursive: true });
|
|
fs.mkdirSync(cacheDir, { recursive: true });
|
|
|
|
// Expose bin directory to GITHUB_PATH if running in Actions runner
|
|
if (process.env.GITHUB_PATH) {
|
|
fs.appendFileSync(process.env.GITHUB_PATH, `${binDir}\n`);
|
|
}
|
|
|
|
const unameArch = os.arch() === 'x64' ? 'x86_64' : (os.arch() === 'arm64' ? 'ARM64' : os.arch());
|
|
const tArch = mapArch(unameArch);
|
|
const tarball = `trivy_${version}_Linux-${tArch}.tar.gz`;
|
|
const tarballPath = path.join(cacheDir, tarball);
|
|
|
|
const checksumsFile = path.resolve(__dirname, '..', 'checksums.txt');
|
|
if (!fs.existsSync(checksumsFile)) {
|
|
console.error(`::error::Checksums lockfile not found at ${checksumsFile}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
const checksums = parseChecksums(fs.readFileSync(checksumsFile, 'utf8'));
|
|
const expectedHash = checksums.get(tarball);
|
|
if (!expectedHash) {
|
|
console.error(`::error::Tarball ${tarball} not found in checksums.txt`);
|
|
process.exit(1);
|
|
}
|
|
|
|
if (fs.existsSync(tarballPath) && verifyFileSha256(tarballPath, expectedHash)) {
|
|
console.log('Cached Trivy archive verified against lockfile.');
|
|
} else {
|
|
console.log('Archive missing or checksum mismatch; downloading...');
|
|
const downloadUrl = `https://github.com/aquasecurity/trivy/releases/download/v${version}/${tarball}`;
|
|
cp.execFileSync('curl', ['-sfLO', downloadUrl, '--output-dir', cacheDir], { stdio: 'inherit' });
|
|
|
|
if (!verifyFileSha256(tarballPath, expectedHash)) {
|
|
console.error(`::error::Downloaded archive ${tarball} failed SHA256 checksum verification!`);
|
|
process.exit(1);
|
|
}
|
|
console.log('Downloaded Trivy archive verified successfully.');
|
|
}
|
|
|
|
// Extract binary
|
|
cp.execFileSync('tar', ['-xzf', tarballPath, '-C', binDir, 'trivy'], { stdio: 'inherit' });
|
|
const trivyBin = path.join(binDir, 'trivy');
|
|
if (fs.existsSync(trivyBin)) {
|
|
fs.chmodSync(trivyBin, 0o755);
|
|
console.log(`Trivy ${version} installed and verified successfully at ${trivyBin}`);
|
|
} else {
|
|
console.error('::error::Failed to extract trivy binary from tarball.');
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
if (require.main === module) {
|
|
main();
|
|
}
|
|
|
|
module.exports = { main };
|