refactor: validate generated evidence artifacts
This commit is contained in:
@@ -10,6 +10,16 @@ import {
|
||||
} from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
import {
|
||||
bundlePerformanceArtifactSchema,
|
||||
dependencyDiffArtifactSchema,
|
||||
dependencyInventoryArtifactSchema,
|
||||
licenseReportArtifactSchema,
|
||||
provenanceArtifactSchema,
|
||||
sbomArtifactSchema,
|
||||
supplyChainVerificationArtifactSchema,
|
||||
vulnerabilityReportArtifactSchema,
|
||||
} from "./contracts/release-artifacts.ts";
|
||||
import {
|
||||
diffDependencyInventories,
|
||||
flattenPnpmDependencyTree,
|
||||
@@ -22,6 +32,7 @@ import {
|
||||
verifySupplyChainCoherence,
|
||||
type DependencyInventoryDiff,
|
||||
} from "./lib/supply-chain.ts";
|
||||
import { writeValidatedJsonArtifact } from "./lib/validated-json-artifact.ts";
|
||||
|
||||
type Document = Record<string, unknown>;
|
||||
|
||||
@@ -428,81 +439,80 @@ const verification = {
|
||||
: "FAIL_UNVERIFIED",
|
||||
failures: localFailures,
|
||||
};
|
||||
const bundleReport = {
|
||||
schemaVersion: 1,
|
||||
generatedAt: new Date().toISOString(),
|
||||
context: {
|
||||
nodeVersion: process.version,
|
||||
packageManager: String(packageJson.packageManager ?? ""),
|
||||
runnerImage:
|
||||
process.env.CI_RUNNER_IMAGE ?? `${process.platform}-${process.arch}`,
|
||||
},
|
||||
outputs,
|
||||
};
|
||||
const dependencyDiffReport = {
|
||||
schemaVersion: 2,
|
||||
baselineDigest: baseline ? supplyChainDigest(baseline) : null,
|
||||
currentDigest: supplyChainDigest(inventory),
|
||||
...dependencyDiff,
|
||||
highRisk: reviewResult.highRisk,
|
||||
reviewFailures: reviewResult.failures,
|
||||
};
|
||||
const licenseReport = {
|
||||
schemaVersion: 1,
|
||||
status: licenseResult.passed ? "PASS" : "FAIL",
|
||||
dependencyCount: inventory.dependencyCount,
|
||||
results: licenseResult.results,
|
||||
failures: licenseResult.failures,
|
||||
};
|
||||
|
||||
await mkdir("artifacts/performance", { recursive: true });
|
||||
await mkdir("artifacts/release", { recursive: true });
|
||||
await mkdir("artifacts/security", { recursive: true });
|
||||
await writeFile(
|
||||
"artifacts/performance/bundle.json",
|
||||
`${JSON.stringify(
|
||||
{
|
||||
schemaVersion: 1,
|
||||
generatedAt: new Date().toISOString(),
|
||||
context: {
|
||||
nodeVersion: process.version,
|
||||
packageManager: String(packageJson.packageManager ?? ""),
|
||||
runnerImage:
|
||||
process.env.CI_RUNNER_IMAGE ?? `${process.platform}-${process.arch}`,
|
||||
},
|
||||
outputs,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
)}\n`,
|
||||
);
|
||||
await writeFile(
|
||||
"artifacts/release/dependency-inventory.json",
|
||||
`${JSON.stringify(inventory, null, 2)}\n`,
|
||||
);
|
||||
await writeFile(
|
||||
"artifacts/release/sbom.cdx.json",
|
||||
`${JSON.stringify(sbom, null, 2)}\n`,
|
||||
);
|
||||
await writeFile(
|
||||
"artifacts/release/provenance.json",
|
||||
`${JSON.stringify(provenance, null, 2)}\n`,
|
||||
);
|
||||
await writeValidatedJsonArtifact({
|
||||
path: "artifacts/performance/bundle.json",
|
||||
schema: bundlePerformanceArtifactSchema,
|
||||
value: bundleReport,
|
||||
});
|
||||
await writeValidatedJsonArtifact({
|
||||
path: "artifacts/release/dependency-inventory.json",
|
||||
schema: dependencyInventoryArtifactSchema,
|
||||
value: inventory,
|
||||
});
|
||||
await writeValidatedJsonArtifact({
|
||||
path: "artifacts/release/sbom.cdx.json",
|
||||
schema: sbomArtifactSchema,
|
||||
value: sbom,
|
||||
});
|
||||
await writeValidatedJsonArtifact({
|
||||
path: "artifacts/release/provenance.json",
|
||||
schema: provenanceArtifactSchema,
|
||||
value: provenance,
|
||||
});
|
||||
await writeFile(
|
||||
"artifacts/release/checksums.txt",
|
||||
`${outputs.map((output) => `${output.sha256} ${output.path}`).join("\n")}\n`,
|
||||
);
|
||||
await writeFile(
|
||||
"artifacts/security/dependency-diff.json",
|
||||
`${JSON.stringify(
|
||||
{
|
||||
schemaVersion: 2,
|
||||
baselineDigest: baseline ? supplyChainDigest(baseline) : null,
|
||||
currentDigest: supplyChainDigest(inventory),
|
||||
...dependencyDiff,
|
||||
highRisk: reviewResult.highRisk,
|
||||
reviewFailures: reviewResult.failures,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
)}\n`,
|
||||
);
|
||||
await writeFile(
|
||||
"artifacts/security/license-report.json",
|
||||
`${JSON.stringify(
|
||||
{
|
||||
schemaVersion: 1,
|
||||
status: licenseResult.passed ? "PASS" : "FAIL",
|
||||
dependencyCount: inventory.dependencyCount,
|
||||
results: licenseResult.results,
|
||||
failures: licenseResult.failures,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
)}\n`,
|
||||
);
|
||||
await writeFile(
|
||||
"artifacts/security/vulnerability-report.json",
|
||||
`${JSON.stringify(vulnerabilityReport, null, 2)}\n`,
|
||||
);
|
||||
await writeFile(
|
||||
"artifacts/security/supply-chain-verification.json",
|
||||
`${JSON.stringify(verification, null, 2)}\n`,
|
||||
);
|
||||
await writeValidatedJsonArtifact({
|
||||
path: "artifacts/security/dependency-diff.json",
|
||||
schema: dependencyDiffArtifactSchema,
|
||||
value: dependencyDiffReport,
|
||||
});
|
||||
await writeValidatedJsonArtifact({
|
||||
path: "artifacts/security/license-report.json",
|
||||
schema: licenseReportArtifactSchema,
|
||||
value: licenseReport,
|
||||
});
|
||||
await writeValidatedJsonArtifact({
|
||||
path: "artifacts/security/vulnerability-report.json",
|
||||
schema: vulnerabilityReportArtifactSchema,
|
||||
value: vulnerabilityReport,
|
||||
});
|
||||
await writeValidatedJsonArtifact({
|
||||
path: "artifacts/security/supply-chain-verification.json",
|
||||
schema: supplyChainVerificationArtifactSchema,
|
||||
value: verification,
|
||||
});
|
||||
|
||||
if (!localPassed) {
|
||||
process.stderr.write(
|
||||
|
||||
Reference in New Issue
Block a user