@kungfu-tech/buildchain 4.0.9-alpha.0 → 4.0.9-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/architecture/ci-lane-change-budget.json +17 -0
- package/architecture/maintainability-debt.json +18 -18
- package/architecture/release-topology.json +6 -5
- package/architecture/workflow-taxonomy.json +14 -1
- package/dist/site/buildchain-contract.json +4 -4
- package/dist/site/buildchain-site.json +24 -19
- package/dist/site/capability-registry.json +1 -1
- package/dist/site/kfd-claims.json +19 -5
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +3 -3
- package/dist/site/node-api-registry.json +4 -4
- package/dist/site/page-registry.json +17 -12
- package/dist/site/public-surface-audit.json +14 -3
- package/dist/site/publication-authority-registry.json +22 -1
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/site-manifest.json +7 -7
- package/dist/site/workflow-registry.json +35 -5
- package/docs/node-api-reference.md +6 -6
- package/docs/release-governance.md +19 -18
- package/docs/reusable-build-surface.md +1 -0
- package/docs/v4-production-release.md +10 -0
- package/docs/workflow-catalog.md +1 -0
- package/package.json +1 -1
- package/packages/core/build-configuration.js +1 -1
- package/packages/core/buildchain-publication-authority.js +1 -0
- package/scripts/check-inventory.mjs +9 -22
- package/scripts/check-maintainability.mjs +23 -8
- package/scripts/resolve-build-configuration.mjs +2 -2
- package/scripts/stable-candidate-qualification.mjs +59 -34
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
2
3
|
|
|
3
4
|
const DEFAULTS = {
|
|
4
5
|
buildWorkflowFile: "self-build-fixture.yml",
|
|
@@ -41,27 +42,49 @@ function optionalSha(value, label) {
|
|
|
41
42
|
return normalized;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
export function
|
|
45
|
-
if (
|
|
46
|
-
|
|
45
|
+
export function validatePublicBuildRun(run, workflow, repositoryName) {
|
|
46
|
+
if (run?.repository?.full_name !== repositoryName || run?.head_repository?.full_name !== repositoryName
|
|
47
|
+
|| run?.workflow_id !== workflow?.id || workflow?.path !== ".github/workflows/self-build-alpha-dogfood.yml"
|
|
48
|
+
|| run?.name !== "Buildchain Alpha Self-Dogfood" || !successful(run) || !optionalSha(run?.head_sha, "source SHA")) {
|
|
49
|
+
throw new Error("qualification requires the exact successful repository-owned public build run");
|
|
47
50
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|| evidence?.
|
|
55
|
-
|| evidence?.
|
|
56
|
-
|
|
57
|
-
|
|
51
|
+
return run;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function resolveStableCandidateQualificationCandidate({ sourceRun, buildSummary, repositoryName } = {}) {
|
|
55
|
+
const evidence = buildSummary, runtime = evidence?.runtime;
|
|
56
|
+
if (!successful(sourceRun) || sourceRun?.repository?.full_name !== repositoryName
|
|
57
|
+
|| evidence?.artifactName !== "buildchain" || evidence?.contract !== "kungfu-buildchain-build-summary" || evidence?.git?.repository !== repositoryName
|
|
58
|
+
|| evidence?.git?.sha !== sourceRun?.head_sha || String(evidence?.git?.runId) !== String(sourceRun?.id)
|
|
59
|
+
|| String(evidence?.git?.runAttempt) !== String(sourceRun?.run_attempt)
|
|
60
|
+
|| runtime?.ref !== "v4-alpha" || runtime?.workflowShellRef !== "v4-alpha" || runtime?.class !== "alpha"
|
|
61
|
+
|| runtime?.override !== false || runtime?.trustDecision !== "workflow-identity") {
|
|
62
|
+
throw new Error("public build summary does not bind the exact source run and alpha workflow identity");
|
|
58
63
|
}
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
if (
|
|
62
|
-
|
|
64
|
+
const platforms = evidence.platforms || [];
|
|
65
|
+
const ids = platforms.map((entry) => entry.platform?.id).sort();
|
|
66
|
+
if (evidence.platformCount !== 3 || JSON.stringify(ids) !== JSON.stringify(["linux-x64", "macos", "windows-x64"])
|
|
67
|
+
|| platforms.some((entry) => entry.expectedArtifacts?.ok !== true || !/^[a-f0-9]{64}$/u.test(entry.summary?.digest || "")
|
|
68
|
+
|| ["install", "build", "verify"].some((stage) => !(entry.observability?.lifecycle?.stages?.[stage]?.eventCount > 0)))) {
|
|
69
|
+
throw new Error("public build summary requires verified artifacts for all three platforms");
|
|
63
70
|
}
|
|
64
|
-
|
|
71
|
+
const sha = optionalSha(runtime.sha, "observed alpha SHA");
|
|
72
|
+
if (!sha) throw new Error("public build summary is missing its runtime SHA");
|
|
73
|
+
return sha;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export async function qualifyPublicBuild({ repositoryName, sourceRun, buildSummary }, client) {
|
|
77
|
+
const sha = resolveStableCandidateQualificationCandidate({ repositoryName, sourceRun, buildSummary });
|
|
78
|
+
const candidate = await client.resolveExactAlpha(repositoryName, sha);
|
|
79
|
+
if (!candidate || candidate.sha !== sha) throw new Error("observed runtime must be an exact published alpha, never an ancestor");
|
|
80
|
+
const context = "buildchain-canary/buildchain-zero-input";
|
|
81
|
+
const status = await client.createCommitStatus({ repository: repositoryName, sha, context,
|
|
82
|
+
targetUrl: sourceRun.html_url, description: "Zero-input public build passed on all three platforms" });
|
|
83
|
+
if (status.state !== "success") throw new Error("public build qualification status readback failed");
|
|
84
|
+
return { contract: "kungfu-buildchain-public-build-qualification/v1", candidate, sourceSha: sourceRun.head_sha,
|
|
85
|
+
runId: sourceRun.id, runAttempt: sourceRun.run_attempt, context, status: status.state,
|
|
86
|
+
summaryRoot: `sha256:${createHash("sha256").update(JSON.stringify(buildSummary)).digest("hex")}`,
|
|
87
|
+
artifacts: buildSummary.platforms.map((entry) => ({ platform: entry.platform.id, digest: entry.summary.digest })) };
|
|
65
88
|
}
|
|
66
89
|
|
|
67
90
|
function optionalRef(value, label) {
|
|
@@ -253,6 +276,12 @@ export function createGitHubQualificationClient({
|
|
|
253
276
|
.sort((left, right) => String(right.created_at).localeCompare(String(left.created_at)))[0];
|
|
254
277
|
}
|
|
255
278
|
return {
|
|
279
|
+
async readPublicBuildRun(repositoryName, runId) {
|
|
280
|
+
if (!/^[1-9][0-9]*$/u.test(String(runId))) throw new Error("source run ID must be a positive integer");
|
|
281
|
+
const run = await api(`/repos/${repositoryName}/actions/runs/${runId}`);
|
|
282
|
+
const workflow = await api(`/repos/${repositoryName}/actions/workflows/self-build-alpha-dogfood.yml`);
|
|
283
|
+
return validatePublicBuildRun(run, workflow, repositoryName);
|
|
284
|
+
},
|
|
256
285
|
async resolveExactAlpha(repositoryName, candidateSha) {
|
|
257
286
|
const releases = (await api(`/repos/${repositoryName}/releases?per_page=100`)).sort((left, right) => right.tag_name.localeCompare(left.tag_name, "en", { numeric: true }));
|
|
258
287
|
for (const release of releases) {
|
|
@@ -297,22 +326,18 @@ export function createGitHubQualificationClient({
|
|
|
297
326
|
}
|
|
298
327
|
|
|
299
328
|
async function main() {
|
|
300
|
-
if (
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
process.stdout.write(`${sha}\n`);
|
|
313
|
-
if (process.env.GITHUB_OUTPUT) {
|
|
314
|
-
const fs = await import("node:fs");
|
|
315
|
-
fs.appendFileSync(process.env.GITHUB_OUTPUT, `sha=${sha}\n`);
|
|
329
|
+
if (["resolve-public-build", "qualify-public-build"].includes(process.argv[2])) {
|
|
330
|
+
const fs = await import("node:fs");
|
|
331
|
+
const repositoryName = repository(process.env.GITHUB_REPOSITORY);
|
|
332
|
+
const client = createGitHubQualificationClient({ token: process.env.GITHUB_TOKEN });
|
|
333
|
+
const sourceRun = await client.readPublicBuildRun(repositoryName, process.env.BUILDCHAIN_QUALIFICATION_RUN_ID);
|
|
334
|
+
if (process.argv[2] === "resolve-public-build") {
|
|
335
|
+
fs.appendFileSync(process.env.GITHUB_OUTPUT, `artifact-name=buildchain-summary-${sourceRun.head_sha}\n`);
|
|
336
|
+
} else {
|
|
337
|
+
const buildSummary = JSON.parse(fs.readFileSync(".buildchain/qualification/source/build-summary.json", "utf8"));
|
|
338
|
+
const result = await qualifyPublicBuild({ repositoryName, sourceRun, buildSummary }, client);
|
|
339
|
+
fs.writeFileSync(".buildchain/qualification/result.json", JSON.stringify(result, null, 2) + "\n");
|
|
340
|
+
process.stdout.write(JSON.stringify(result) + "\n");
|
|
316
341
|
}
|
|
317
342
|
return;
|
|
318
343
|
}
|