Publish Clusterflux 45bbc21
This commit is contained in:
parent
eb1077f380
commit
3f88254c70
28 changed files with 896 additions and 167 deletions
|
|
@ -537,7 +537,9 @@ function stageEvidenceAsset(
|
|||
sourceDigest,
|
||||
publicTreeIdentity,
|
||||
binaryDigests,
|
||||
candidateBinding
|
||||
candidateBinding,
|
||||
candidateConfigurationIdentity,
|
||||
candidateProxyConfigurationIdentity
|
||||
) {
|
||||
const stage = path.join(stagingDir, "evidence");
|
||||
fs.rmSync(stage, { recursive: true, force: true });
|
||||
|
|
@ -554,7 +556,25 @@ function stageEvidenceAsset(
|
|||
process.env.CLUSTERFLUX_FINAL_RESULT_PATH ||
|
||||
path.join(evidenceRoot, "cli-happy-path-live.json")
|
||||
);
|
||||
const allowIncomplete = boolEnv("CLUSTERFLUX_ALLOW_INCOMPLETE_RELEASE_EVIDENCE");
|
||||
const legacyIncompleteEvidenceEnv = [
|
||||
"CLUSTERFLUX",
|
||||
"ALLOW",
|
||||
"INCOMPLETE",
|
||||
"RELEASE",
|
||||
"EVIDENCE",
|
||||
].join("_");
|
||||
if (process.env[legacyIncompleteEvidenceEnv]) {
|
||||
throw new Error(
|
||||
"the legacy incomplete-evidence environment switch is unsupported; use CLUSTERFLUX_RELEASE_STAGE=candidate or final"
|
||||
);
|
||||
}
|
||||
const releaseStage =
|
||||
process.env.CLUSTERFLUX_RELEASE_STAGE ||
|
||||
(candidateManifestPath ? "final" : "candidate");
|
||||
if (!new Set(["candidate", "final"]).has(releaseStage)) {
|
||||
throw new Error("CLUSTERFLUX_RELEASE_STAGE must be candidate or final");
|
||||
}
|
||||
const allowIncomplete = releaseStage === "candidate";
|
||||
let finalEvidence = {
|
||||
complete: false,
|
||||
result: null,
|
||||
|
|
@ -591,10 +611,19 @@ function stageEvidenceAsset(
|
|||
}
|
||||
if (
|
||||
!Array.isArray(liveResult.named_scenarios) ||
|
||||
liveResult.named_scenarios.length !== 16 ||
|
||||
liveResult.named_scenarios.length !== 25 ||
|
||||
liveResult.named_scenarios.some((scenario) => scenario.status !== "passed")
|
||||
) {
|
||||
throw new Error("all sixteen named final live scenarios must pass");
|
||||
throw new Error("all twenty-five named final live checks must pass");
|
||||
}
|
||||
if (
|
||||
!liveResult.release_binding?.deployment ||
|
||||
!liveResult.release_binding?.configuration ||
|
||||
!liveResult.release_binding?.proxy_configuration
|
||||
) {
|
||||
throw new Error(
|
||||
"final live evidence must bind deployment, runtime configuration, and proxy configuration identities"
|
||||
);
|
||||
}
|
||||
if (
|
||||
!Array.isArray(liveResult.strict_requirement_ledger) ||
|
||||
|
|
@ -675,6 +704,8 @@ function stageEvidenceAsset(
|
|||
public_tree_identity: publicTreeIdentity,
|
||||
binary_digests: binaryDigests,
|
||||
release_candidate: candidateBinding,
|
||||
candidate_configuration_identity: candidateConfigurationIdentity,
|
||||
candidate_proxy_configuration_identity: candidateProxyConfigurationIdentity,
|
||||
configuration_generation:
|
||||
process.env.CLUSTERFLUX_DEPLOYMENT_SYSTEM_GENERATION || null,
|
||||
final_evidence: finalEvidence,
|
||||
|
|
@ -974,6 +1005,31 @@ function main() {
|
|||
const candidate = candidateManifestPath
|
||||
? JSON.parse(fs.readFileSync(candidateManifestPath, "utf8"))
|
||||
: null;
|
||||
if (candidate) {
|
||||
for (const asset of candidate.assets ?? []) {
|
||||
asset.file = path.isAbsolute(asset.file)
|
||||
? asset.file
|
||||
: path.resolve(path.dirname(candidateManifestPath), asset.file);
|
||||
}
|
||||
}
|
||||
const releaseStage =
|
||||
process.env.CLUSTERFLUX_RELEASE_STAGE ||
|
||||
(candidateManifestPath ? "final" : "candidate");
|
||||
if (releaseStage === "final" && !candidate) {
|
||||
throw new Error("final release stage requires CLUSTERFLUX_RELEASE_CANDIDATE_MANIFEST");
|
||||
}
|
||||
if (releaseStage === "candidate" && candidate) {
|
||||
throw new Error("candidate release stage cannot consume a prior candidate manifest");
|
||||
}
|
||||
if (
|
||||
releaseStage === "candidate" &&
|
||||
(!process.env.CLUSTERFLUX_CANDIDATE_CONFIGURATION_IDENTITY ||
|
||||
!process.env.CLUSTERFLUX_CANDIDATE_PROXY_CONFIGURATION_IDENTITY)
|
||||
) {
|
||||
throw new Error(
|
||||
"candidate release stage requires configuration and proxy configuration identities"
|
||||
);
|
||||
}
|
||||
if (candidate) {
|
||||
assertCandidateManifest(candidate);
|
||||
if (path.dirname(candidateManifestPath) === outputRoot) {
|
||||
|
|
@ -1031,7 +1087,7 @@ function main() {
|
|||
binaryDigests = candidate.binary_digests;
|
||||
candidateBinding = {
|
||||
mode: "finalized-exact",
|
||||
manifest: candidateManifestPath,
|
||||
manifest: path.relative(outputRoot, candidateManifestPath).split(path.sep).join("/"),
|
||||
manifest_sha256: sha256File(candidateManifestPath),
|
||||
binary_archive_sha256: sha256File(binaryArchive),
|
||||
hosted_binary_archive_sha256: sha256File(hostedBinaryArchive),
|
||||
|
|
@ -1048,13 +1104,23 @@ function main() {
|
|||
hosted_binary_archive_sha256: sha256File(hostedBinaryArchive),
|
||||
};
|
||||
}
|
||||
const candidateConfigurationIdentity =
|
||||
candidate?.candidate_configuration_identity ||
|
||||
process.env.CLUSTERFLUX_CANDIDATE_CONFIGURATION_IDENTITY ||
|
||||
null;
|
||||
const candidateProxyConfigurationIdentity =
|
||||
candidate?.candidate_proxy_configuration_identity ||
|
||||
process.env.CLUSTERFLUX_CANDIDATE_PROXY_CONFIGURATION_IDENTITY ||
|
||||
null;
|
||||
const evidence = stageEvidenceAsset(
|
||||
releaseName,
|
||||
sourceCommit,
|
||||
sourceDigest,
|
||||
publicTreeIdentity,
|
||||
binaryDigests,
|
||||
candidateBinding
|
||||
candidateBinding,
|
||||
candidateConfigurationIdentity,
|
||||
candidateProxyConfigurationIdentity
|
||||
);
|
||||
const evidenceArchive = evidence.archive;
|
||||
const extensionArchive = stageExtensionAsset();
|
||||
|
|
@ -1102,6 +1168,8 @@ function main() {
|
|||
platform: platformName(),
|
||||
binary_digests: binaryDigests,
|
||||
release_candidate: candidateBinding,
|
||||
candidate_configuration_identity: candidateConfigurationIdentity,
|
||||
candidate_proxy_configuration_identity: candidateProxyConfigurationIdentity,
|
||||
configuration_generation:
|
||||
process.env.CLUSTERFLUX_DEPLOYMENT_SYSTEM_GENERATION || null,
|
||||
final_evidence: evidence.finalEvidence,
|
||||
|
|
@ -1126,7 +1194,7 @@ function main() {
|
|||
]),
|
||||
],
|
||||
assets: [...assets, sha256Sums].map((asset) => ({
|
||||
file: asset,
|
||||
file: path.relative(outputRoot, asset).split(path.sep).join("/"),
|
||||
name: path.basename(asset),
|
||||
sha256: sha256File(asset),
|
||||
})),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue