@kungfu-tech/buildchain 3.0.1 → 3.0.2-alpha.0
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/README.md +5 -3
- package/actions/promote-buildchain-ref/README.md +7 -0
- package/bin/buildchain.mjs +173 -513
- package/bin/internal/cli-options.mjs +79 -0
- package/bin/internal/trust-release-cli.mjs +469 -0
- package/dist/site/agent-index.json +2 -0
- package/dist/site/artifact-schemas.json +5 -0
- package/dist/site/badge-endpoint-registry.json +18 -18
- package/dist/site/badges/v1/kfd-12/aligned.json +1 -1
- package/dist/site/badges/v1/kfd-12/declared.json +1 -1
- package/dist/site/badges/v1/kfd-12/downgraded.json +1 -1
- package/dist/site/badges/v1/kfd-12/draft.json +1 -1
- package/dist/site/badges/v1/kfd-12/failed.json +1 -1
- package/dist/site/badges/v1/kfd-12/missing.json +1 -1
- package/dist/site/badges/v1/kfd-12/passed.json +1 -1
- package/dist/site/badges/v1/kfd-12/planned.json +1 -1
- package/dist/site/badges/v1/kfd-13/aligned.json +1 -1
- package/dist/site/badges/v1/kfd-13/declared.json +1 -1
- package/dist/site/badges/v1/kfd-13/downgraded.json +1 -1
- package/dist/site/badges/v1/kfd-13/draft.json +1 -1
- package/dist/site/badges/v1/kfd-13/failed.json +1 -1
- package/dist/site/badges/v1/kfd-13/missing.json +1 -1
- package/dist/site/badges/v1/kfd-13/passed.json +1 -1
- package/dist/site/badges/v1/kfd-13/planned.json +1 -1
- package/dist/site/buildchain-contract.json +32 -22
- package/dist/site/buildchain-site.json +28 -18
- package/dist/site/capability-registry.json +2 -2
- package/dist/site/cli-registry.json +108 -0
- package/dist/site/controller-registry.json +10 -2
- package/dist/site/kfd-claims.json +136 -10
- package/dist/site/kfd-upstream-aggregate.json +20 -11
- package/dist/site/manual-registry.json +3 -3
- package/dist/site/node-api-registry.json +21 -8
- package/dist/site/page-registry.json +20 -10
- package/dist/site/public-surface-audit.json +114 -8
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-passport-check-manifest.json +11 -0
- package/dist/site/release-provenance.json +3 -0
- package/dist/site/schemas/kfd-product-gate-input-v1.schema.json +164 -0
- package/dist/site/schemas/kfd-support-projection-v1.schema.json +106 -0
- package/dist/site/schemas/release-passport-v1.schema.json +3 -0
- package/dist/site/site-manifest.json +7 -7
- package/dist/site/workflow-registry.json +9 -3
- package/docs/cli.md +9 -2
- package/docs/kfd-support.md +43 -7
- package/docs/release-passport.md +15 -0
- package/package.json +6 -3
- package/packages/core/index.js +17 -0
- package/packages/core/kfd-product-gates.js +865 -0
- package/packages/core/kfd.js +16 -7
- package/packages/core/kfd3-surface-register.js +105 -1
- package/packages/core/public-surface-audit.js +6 -1
- package/packages/core/release-passport-contract.js +13 -0
- package/packages/core/release-passport.js +87 -3
- package/scripts/check-internal-architecture.mjs +171 -0
- package/scripts/check-inventory.mjs +4 -0
- package/scripts/generate-site-bundle.mjs +23 -0
- package/scripts/promotion-routing-evidence.mjs +73 -0
package/bin/buildchain.mjs
CHANGED
|
@@ -7,7 +7,6 @@ import { fileURLToPath } from "node:url";
|
|
|
7
7
|
import { initBuildchainRepo } from "../scripts/init-repo.mjs";
|
|
8
8
|
import { npmPublishDryRun } from "../scripts/npm-publish-dry-run.mjs";
|
|
9
9
|
import { runLifecycle } from "../scripts/run-lifecycle-core.mjs";
|
|
10
|
-
import { verifyInfraContractEvidenceBundle } from "../scripts/infra-contract-core.mjs";
|
|
11
10
|
import { runReleasePropagationCli } from "../scripts/release-propagation.mjs";
|
|
12
11
|
import { runReleaseGovernanceCli } from "../scripts/reconcile-release-governance.mjs";
|
|
13
12
|
import { runPublicationArtifactCli } from "../scripts/publication-artifact.mjs";
|
|
@@ -18,40 +17,13 @@ import {
|
|
|
18
17
|
createBuildchainLogger,
|
|
19
18
|
defaultBuildchainLogPath,
|
|
20
19
|
summarizeBuildchainLogEvents,
|
|
21
|
-
verifyBuildchainLogEvents,
|
|
22
20
|
} from "../packages/core/logging.js";
|
|
23
|
-
import {
|
|
24
|
-
explainReleaseLineDryRun,
|
|
25
|
-
formatReleaseLineDryRun,
|
|
26
|
-
} from "../packages/core/release-line-dry-run.js";
|
|
27
|
-
import {
|
|
28
|
-
planReleaseLineBootstrap,
|
|
29
|
-
writeReleaseLineBootstrapVersionState,
|
|
30
|
-
} from "../packages/core/release-line-bootstrap.js";
|
|
31
|
-
import {
|
|
32
|
-
collectGitHubReleasePassport,
|
|
33
|
-
explainReleasePassport,
|
|
34
|
-
verifyReleasePassport,
|
|
35
|
-
} from "../packages/core/release-passport.js";
|
|
36
21
|
import {
|
|
37
22
|
explainKfdAgentHub,
|
|
38
23
|
initKfdAgentHub,
|
|
39
24
|
inspectKfdAgentHub,
|
|
40
25
|
testKfdAgentHub,
|
|
41
26
|
} from "../packages/core/kfd-agent-hub.js";
|
|
42
|
-
import {
|
|
43
|
-
createPublicationAdmission,
|
|
44
|
-
createRunnerProvenance,
|
|
45
|
-
verifyPublicationAdmission,
|
|
46
|
-
} from "../packages/core/publication-authority.js";
|
|
47
|
-
import {
|
|
48
|
-
explainArtifactPassport,
|
|
49
|
-
verifyArtifactPassport,
|
|
50
|
-
} from "../packages/core/artifact-passport.js";
|
|
51
|
-
import {
|
|
52
|
-
projectArtifactVerificationEnvelopeToKfx,
|
|
53
|
-
verifyArtifactVerificationEnvelope,
|
|
54
|
-
} from "../packages/core/artifact-verification-envelope.js";
|
|
55
27
|
import {
|
|
56
28
|
checkBadgeBundleBlock,
|
|
57
29
|
checkReadmeBadgeBlock,
|
|
@@ -102,12 +74,31 @@ import {
|
|
|
102
74
|
queryKfd3Capabilities,
|
|
103
75
|
registerKfd3Surfaces,
|
|
104
76
|
} from "../packages/core/kfd3-surface-register.js";
|
|
77
|
+
import {
|
|
78
|
+
createKfdSupportProjection,
|
|
79
|
+
evaluateKfdProductGate,
|
|
80
|
+
validateKfdProductGateResult,
|
|
81
|
+
validateKfdSupportProjection,
|
|
82
|
+
} from "../packages/core/kfd-product-gates.js";
|
|
105
83
|
import { createBuildchainLayoutDiscovery } from "../packages/core/buildchain-layout.js";
|
|
106
84
|
import { createPortableDevCachePlan, createPortableDevCacheReceipt } from "../packages/core/portable-dev-cache.js";
|
|
107
85
|
import {
|
|
108
86
|
createCandidateTimeline,
|
|
109
87
|
formatCandidateTimelineReport,
|
|
110
88
|
} from "../packages/core/candidate-timeline.js";
|
|
89
|
+
import {
|
|
90
|
+
printJson,
|
|
91
|
+
readBooleanFlag,
|
|
92
|
+
readFlag,
|
|
93
|
+
readJsonInput,
|
|
94
|
+
readRepeatedFlag,
|
|
95
|
+
readRepeatedJsonInputs,
|
|
96
|
+
writeJsonFile,
|
|
97
|
+
} from "./internal/cli-options.mjs";
|
|
98
|
+
import {
|
|
99
|
+
TRUST_RELEASE_COMMANDS,
|
|
100
|
+
dispatchTrustReleaseCommand,
|
|
101
|
+
} from "./internal/trust-release-cli.mjs";
|
|
111
102
|
|
|
112
103
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
113
104
|
const embeddedPackageVersion = process.env.BUILDCHAIN_EMBEDDED_PACKAGE_VERSION || "";
|
|
@@ -169,6 +160,8 @@ function usage() {
|
|
|
169
160
|
[--kfd-3-prebuild-witness-json <json-or-path>]...
|
|
170
161
|
[--kfd-3-artifact-witness-json <json-or-path>]...
|
|
171
162
|
[--kfd-3-artifact-verify-cmd <command>]
|
|
163
|
+
[--kfd-support-matrix-json <json-or-path>]
|
|
164
|
+
[--kfd-product-gate-json <json-or-path>]...
|
|
172
165
|
[--invariant-passport-json <json-or-path>]...
|
|
173
166
|
[--invariant-passport-cmd <command>]
|
|
174
167
|
[--kfd-agent-hub-evidence-json <json-or-path>]
|
|
@@ -268,6 +261,19 @@ function usage() {
|
|
|
268
261
|
buildchain kfd 3 query [<product>] [--cwd <dir>] [--registry <path>]
|
|
269
262
|
[--passport <file-or-url>] [--artifact <path>] [--json]
|
|
270
263
|
buildchain kfd 4 schema [--schema <name>] [--json]
|
|
264
|
+
buildchain kfd 4 gate --input-json <file-or-json> [--cwd <dir>] [--output <file>] [--json]
|
|
265
|
+
buildchain kfd 4 verify --gate-json <file-or-json> [--expected-source-sha <sha>] [--json]
|
|
266
|
+
buildchain kfd 5 schema [--schema <name>] [--json]
|
|
267
|
+
buildchain kfd 5 gate --input-json <file-or-json> [--cwd <dir>] [--output <file>] [--json]
|
|
268
|
+
buildchain kfd 5 verify --gate-json <file-or-json> [--expected-source-sha <sha>] [--json]
|
|
269
|
+
buildchain kfd 7 schema [--schema <name>] [--json]
|
|
270
|
+
buildchain kfd 7 gate --input-json <file-or-json> [--cwd <dir>] [--output <file>] [--json]
|
|
271
|
+
buildchain kfd 7 verify --gate-json <file-or-json> [--expected-source-sha <sha>] [--json]
|
|
272
|
+
buildchain kfd support project --matrix-json <file-or-json> --gate-json <file-or-json>...
|
|
273
|
+
[--expected-source-sha <sha>] [--checked-at <date-time>]
|
|
274
|
+
[--output <file>] [--json]
|
|
275
|
+
buildchain kfd support verify --projection-json <file-or-json>
|
|
276
|
+
[--expected-source-sha <sha>] [--checked-at <date-time>] [--json]
|
|
271
277
|
buildchain sample process-tree [--interval-ms <n>] [--label <name>]
|
|
272
278
|
[--output <jsonl>] [--summary-output <json>]
|
|
273
279
|
[--requested-parallelism <n>] [--json]
|
|
@@ -330,40 +336,6 @@ Examples:
|
|
|
330
336
|
`;
|
|
331
337
|
}
|
|
332
338
|
|
|
333
|
-
function readFlag(args, name, fallback = "") {
|
|
334
|
-
const index = args.indexOf(`--${name}`);
|
|
335
|
-
if (index === -1) {
|
|
336
|
-
return fallback;
|
|
337
|
-
}
|
|
338
|
-
return args[index + 1] || "";
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
function readBooleanFlag(args, name) {
|
|
342
|
-
return args.includes(`--${name}`);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
function readRepeatedFlag(args, name) {
|
|
346
|
-
const values = [];
|
|
347
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
348
|
-
if (args[index] === `--${name}` && args[index + 1]) {
|
|
349
|
-
values.push(args[index + 1]);
|
|
350
|
-
index += 1;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
return values;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
function artifactEnvelopeOptions(args) {
|
|
357
|
-
const assessmentTime = readFlag(args, "assessment-time", "");
|
|
358
|
-
return {
|
|
359
|
-
...(assessmentTime ? { assessmentTime: Number(assessmentTime) } : {}),
|
|
360
|
-
expectedEnvelopeRoot: readFlag(args, "expected-root", ""),
|
|
361
|
-
expectedIssuer: readFlag(args, "expected-issuer", ""),
|
|
362
|
-
expectedPublisher: readFlag(args, "expected-publisher", ""),
|
|
363
|
-
expectedContractVersion: readFlag(args, "expected-contract", ""),
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
|
|
367
339
|
function readAttributes(args) {
|
|
368
340
|
const attributes = {};
|
|
369
341
|
for (const value of readRepeatedFlag(args, "attribute")) {
|
|
@@ -464,38 +436,6 @@ function runScript(scriptName, args) {
|
|
|
464
436
|
process.exitCode = result.status ?? 1;
|
|
465
437
|
}
|
|
466
438
|
|
|
467
|
-
function printJson(value) {
|
|
468
|
-
process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
function writeJsonFile(filePath, value) {
|
|
472
|
-
if (!filePath) {
|
|
473
|
-
return "";
|
|
474
|
-
}
|
|
475
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
476
|
-
fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`);
|
|
477
|
-
return filePath;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
function readJsonInput(value, { cwd = process.cwd(), label = "json" } = {}) {
|
|
481
|
-
const input = String(value || "").trim();
|
|
482
|
-
if (!input) {
|
|
483
|
-
throw new Error(`${label} is required`);
|
|
484
|
-
}
|
|
485
|
-
const filePath = path.isAbsolute(input) ? input : path.join(cwd, input);
|
|
486
|
-
if (fs.existsSync(filePath)) {
|
|
487
|
-
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
488
|
-
}
|
|
489
|
-
return JSON.parse(input);
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
function readRepeatedJsonInputs(args, name, { cwd = process.cwd(), label = name } = {}) {
|
|
493
|
-
return readRepeatedFlag(args, name).map((value, index) => readJsonInput(value, {
|
|
494
|
-
cwd,
|
|
495
|
-
label: `${label}[${index}]`,
|
|
496
|
-
}));
|
|
497
|
-
}
|
|
498
|
-
|
|
499
439
|
async function runReadmeBadgesCli(args = []) {
|
|
500
440
|
const [subcommand = "", surface = "", ...badgeArgs] = args;
|
|
501
441
|
if (!["readme", "bundle"].includes(subcommand) || (surface && surface.startsWith("--") === false)) {
|
|
@@ -946,10 +886,136 @@ function runKfd2Cli(args = []) {
|
|
|
946
886
|
throw new Error("usage: buildchain kfd 2 <schema|taxonomy|claims|product-claims|trust-claims|trust-assessment> ...");
|
|
947
887
|
}
|
|
948
888
|
|
|
889
|
+
async function runKfdProductGateCli(standard, args = []) {
|
|
890
|
+
const [rawAction = "schema", ...rest] = args;
|
|
891
|
+
const action = rawAction || "schema";
|
|
892
|
+
const cwd = path.resolve(readFlag(rest, "cwd", process.cwd()));
|
|
893
|
+
const json = readBooleanFlag(rest, "json");
|
|
894
|
+
if (action === "schema") {
|
|
895
|
+
printKfdSchemaOrJson({
|
|
896
|
+
result: readKfdSchema({ standard, schema: readFlag(rest, "schema", "") }),
|
|
897
|
+
json,
|
|
898
|
+
});
|
|
899
|
+
return;
|
|
900
|
+
}
|
|
901
|
+
if (action === "gate") {
|
|
902
|
+
const inputValue = readFlag(rest, "input-json", "");
|
|
903
|
+
if (!inputValue) {
|
|
904
|
+
throw new Error(`buildchain kfd ${standard.slice(4)} gate requires --input-json <file-or-json>`);
|
|
905
|
+
}
|
|
906
|
+
const result = await evaluateKfdProductGate({
|
|
907
|
+
cwd,
|
|
908
|
+
input: readJsonInput(inputValue, { cwd, label: `${standard} product gate input` }),
|
|
909
|
+
expectedSourceSha: readFlag(rest, "expected-source-sha", ""),
|
|
910
|
+
checkedAt: readFlag(rest, "checked-at", "") || new Date().toISOString(),
|
|
911
|
+
});
|
|
912
|
+
const output = readFlag(rest, "output", "");
|
|
913
|
+
if (output) writeJsonFile(path.resolve(cwd, output), result);
|
|
914
|
+
if (json || !output) {
|
|
915
|
+
printJson(result);
|
|
916
|
+
} else {
|
|
917
|
+
process.stdout.write(`${standard} product gate: ${result.status} -> ${output}\n`);
|
|
918
|
+
for (const entry of result.issues) {
|
|
919
|
+
process.stdout.write(`- ${entry.code}: ${entry.path}: ${entry.message}\n`);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
if (result.status !== "passed") process.exitCode = 1;
|
|
923
|
+
return;
|
|
924
|
+
}
|
|
925
|
+
if (action === "verify") {
|
|
926
|
+
const gateValue = readFlag(rest, "gate-json", "");
|
|
927
|
+
if (!gateValue) {
|
|
928
|
+
throw new Error(`buildchain kfd ${standard.slice(4)} verify requires --gate-json <file-or-json>`);
|
|
929
|
+
}
|
|
930
|
+
const gate = readJsonInput(gateValue, { cwd, label: `${standard} product gate result` });
|
|
931
|
+
const validation = validateKfdProductGateResult(gate, {
|
|
932
|
+
expectedSourceSha: readFlag(rest, "expected-source-sha", ""),
|
|
933
|
+
checkedAt: readFlag(rest, "checked-at", "") || new Date().toISOString(),
|
|
934
|
+
});
|
|
935
|
+
const result = {
|
|
936
|
+
schemaVersion: 1,
|
|
937
|
+
contract: "kungfu-buildchain-kfd-product-gate-verification",
|
|
938
|
+
valid: validation.valid,
|
|
939
|
+
passed: validation.valid && gate.status === "passed",
|
|
940
|
+
standard: gate.standard || standard,
|
|
941
|
+
gateRoot: gate.gateRoot || "",
|
|
942
|
+
issues: validation.issues,
|
|
943
|
+
};
|
|
944
|
+
if (json) printJson(result);
|
|
945
|
+
else process.stdout.write(`${standard} product gate verify: ${result.passed ? "passed" : "failed"}\n`);
|
|
946
|
+
if (!result.passed) process.exitCode = 1;
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
throw new Error(`usage: buildchain kfd ${standard.slice(4)} <schema|gate|verify> ...`);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
function runKfdSupportCli(args = []) {
|
|
953
|
+
const [action = "", ...rest] = args;
|
|
954
|
+
const cwd = path.resolve(readFlag(rest, "cwd", process.cwd()));
|
|
955
|
+
const json = readBooleanFlag(rest, "json");
|
|
956
|
+
const checkedAt = readFlag(rest, "checked-at", "") || new Date().toISOString();
|
|
957
|
+
const expectedSourceSha = readFlag(rest, "expected-source-sha", "");
|
|
958
|
+
if (action === "project") {
|
|
959
|
+
const matrixInput = readFlag(rest, "matrix-json", "");
|
|
960
|
+
if (!matrixInput) {
|
|
961
|
+
throw new Error("buildchain kfd support project requires --matrix-json <file-or-json>");
|
|
962
|
+
}
|
|
963
|
+
const matrix = readJsonInput(matrixInput, { cwd, label: "KFD support matrix" });
|
|
964
|
+
const matrixPath = path.resolve(cwd, matrixInput);
|
|
965
|
+
const matrixRoot = fs.existsSync(matrixPath)
|
|
966
|
+
? `sha256:${crypto.createHash("sha256").update(fs.readFileSync(matrixPath)).digest("hex")}`
|
|
967
|
+
: "";
|
|
968
|
+
const gateResults = readRepeatedJsonInputs(rest, "gate-json", {
|
|
969
|
+
cwd,
|
|
970
|
+
label: "KFD product gate result",
|
|
971
|
+
});
|
|
972
|
+
const result = createKfdSupportProjection({
|
|
973
|
+
matrix,
|
|
974
|
+
matrixRoot,
|
|
975
|
+
gateResults,
|
|
976
|
+
expectedSourceSha,
|
|
977
|
+
checkedAt,
|
|
978
|
+
});
|
|
979
|
+
const output = readFlag(rest, "output", "");
|
|
980
|
+
if (output) writeJsonFile(path.resolve(cwd, output), result);
|
|
981
|
+
if (json || !output) {
|
|
982
|
+
printJson(result);
|
|
983
|
+
} else {
|
|
984
|
+
process.stdout.write(`KFD support projection: ${result.status} -> ${output}\n`);
|
|
985
|
+
for (const entry of result.issues) {
|
|
986
|
+
process.stdout.write(`- ${entry.code}: ${entry.path}: ${entry.message}\n`);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
if (result.status !== "passed") process.exitCode = 1;
|
|
990
|
+
return;
|
|
991
|
+
}
|
|
992
|
+
if (action === "verify") {
|
|
993
|
+
const projectionInput = readFlag(rest, "projection-json", "");
|
|
994
|
+
if (!projectionInput) {
|
|
995
|
+
throw new Error("buildchain kfd support verify requires --projection-json <file-or-json>");
|
|
996
|
+
}
|
|
997
|
+
const result = validateKfdSupportProjection(
|
|
998
|
+
readJsonInput(projectionInput, { cwd, label: "KFD support projection" }),
|
|
999
|
+
{ expectedSourceSha, checkedAt },
|
|
1000
|
+
);
|
|
1001
|
+
const report = {
|
|
1002
|
+
schemaVersion: 1,
|
|
1003
|
+
contract: "kungfu-buildchain-kfd-support-projection-verification",
|
|
1004
|
+
ok: result.valid,
|
|
1005
|
+
issues: result.issues,
|
|
1006
|
+
};
|
|
1007
|
+
if (json) printJson(report);
|
|
1008
|
+
else process.stdout.write(`KFD support projection verify: ${report.ok ? "passed" : "failed"}\n`);
|
|
1009
|
+
if (!report.ok) process.exitCode = 1;
|
|
1010
|
+
return;
|
|
1011
|
+
}
|
|
1012
|
+
throw new Error("usage: buildchain kfd support <project|verify> ...");
|
|
1013
|
+
}
|
|
1014
|
+
|
|
949
1015
|
async function runKfdCli(args = []) {
|
|
950
1016
|
const [subcommand = "", maybeStandardOrAction = "", ...rest] = args;
|
|
951
1017
|
if (!subcommand) {
|
|
952
|
-
throw new Error("usage: buildchain kfd <status|migrate-layout|schema|upstream|aggregate|hub|1|2|3|4> ...");
|
|
1018
|
+
throw new Error("usage: buildchain kfd <status|migrate-layout|schema|upstream|aggregate|hub|support|1|2|3|4|5|7> ...");
|
|
953
1019
|
}
|
|
954
1020
|
|
|
955
1021
|
if (subcommand === "hub") {
|
|
@@ -1038,7 +1104,7 @@ async function runKfdCli(args = []) {
|
|
|
1038
1104
|
if (schemaCommand === "show") {
|
|
1039
1105
|
const standard = maybeStandard && !maybeStandard.startsWith("--") ? maybeStandard : readFlag(effectiveArgs, "standard", "");
|
|
1040
1106
|
if (!standard) {
|
|
1041
|
-
throw new Error("usage: buildchain kfd schema show <kfd-1
|
|
1107
|
+
throw new Error("usage: buildchain kfd schema show <kfd-1..kfd-13> [--schema <name>]");
|
|
1042
1108
|
}
|
|
1043
1109
|
const result = readKfdSchema({ standard, schema: readFlag(effectiveArgs, "schema", "") });
|
|
1044
1110
|
if (json) {
|
|
@@ -1117,6 +1183,11 @@ async function runKfdCli(args = []) {
|
|
|
1117
1183
|
return;
|
|
1118
1184
|
}
|
|
1119
1185
|
|
|
1186
|
+
if (subcommand === "support") {
|
|
1187
|
+
runKfdSupportCli([maybeStandardOrAction, ...rest]);
|
|
1188
|
+
return;
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1120
1191
|
const standard = normalizeKfdStandardId(subcommand);
|
|
1121
1192
|
if (standard === "kfd-1") {
|
|
1122
1193
|
runKfd1Cli([maybeStandardOrAction, ...rest]);
|
|
@@ -1130,17 +1201,11 @@ async function runKfdCli(args = []) {
|
|
|
1130
1201
|
await runKfd3Cli([maybeStandardOrAction, ...rest]);
|
|
1131
1202
|
return;
|
|
1132
1203
|
}
|
|
1133
|
-
if (
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
const schemaArgs = rest;
|
|
1137
|
-
const json = readBooleanFlag(schemaArgs, "json");
|
|
1138
|
-
printKfdSchemaOrJson({ result: readKfdSchema({ standard, schema: readFlag(schemaArgs, "schema", "") }), json });
|
|
1139
|
-
return;
|
|
1140
|
-
}
|
|
1141
|
-
throw new Error("KFD-4 is currently schema-only in Buildchain; use: buildchain kfd 4 schema");
|
|
1204
|
+
if (["kfd-4", "kfd-5", "kfd-7"].includes(standard)) {
|
|
1205
|
+
await runKfdProductGateCli(standard, [maybeStandardOrAction, ...rest]);
|
|
1206
|
+
return;
|
|
1142
1207
|
}
|
|
1143
|
-
throw new Error("usage: buildchain kfd <status|migrate-layout|schema|upstream|aggregate|hub|1|2|3|4> ...");
|
|
1208
|
+
throw new Error("usage: buildchain kfd <status|migrate-layout|schema|upstream|aggregate|hub|support|1|2|3|4|5|7> ...");
|
|
1144
1209
|
}
|
|
1145
1210
|
|
|
1146
1211
|
async function runBuildFactsCli(args = []) {
|
|
@@ -1724,413 +1789,8 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
1724
1789
|
return;
|
|
1725
1790
|
}
|
|
1726
1791
|
|
|
1727
|
-
if (command
|
|
1728
|
-
|
|
1729
|
-
const lineArgs = args.slice(2);
|
|
1730
|
-
const options = {
|
|
1731
|
-
cwd: readFlag(lineArgs, "cwd", process.cwd()),
|
|
1732
|
-
major: readFlag(lineArgs, "major", ""),
|
|
1733
|
-
minor: readFlag(lineArgs, "minor", ""),
|
|
1734
|
-
sourceRef: readFlag(lineArgs, "source-ref", ""),
|
|
1735
|
-
initialVersion: readFlag(lineArgs, "initial-version", ""),
|
|
1736
|
-
};
|
|
1737
|
-
const result = readBooleanFlag(lineArgs, "write")
|
|
1738
|
-
? writeReleaseLineBootstrapVersionState({
|
|
1739
|
-
...options,
|
|
1740
|
-
runVersionStateLifecycle: !readBooleanFlag(lineArgs, "skip-version-state-lifecycle"),
|
|
1741
|
-
generatedAt: readFlag(lineArgs, "generated-at", ""),
|
|
1742
|
-
})
|
|
1743
|
-
: planReleaseLineBootstrap({
|
|
1744
|
-
...options,
|
|
1745
|
-
requiredStatusCheck: readFlag(lineArgs, "required-status-check", "check"),
|
|
1746
|
-
setDefault: !readBooleanFlag(lineArgs, "no-set-default"),
|
|
1747
|
-
createAlphaPr: !readBooleanFlag(lineArgs, "no-alpha-pr"),
|
|
1748
|
-
approvalCount: Number(readFlag(lineArgs, "approval-count", "1")),
|
|
1749
|
-
bootstrapBranch: readFlag(lineArgs, "bootstrap-branch", ""),
|
|
1750
|
-
});
|
|
1751
|
-
if (readBooleanFlag(lineArgs, "json")) {
|
|
1752
|
-
printJson(result);
|
|
1753
|
-
} else {
|
|
1754
|
-
process.stdout.write(`Buildchain release line bootstrap ${result.line}\n`);
|
|
1755
|
-
process.stdout.write(`- source: ${result.source.ref}${result.source.sha ? ` (${result.source.sha})` : ""}\n`);
|
|
1756
|
-
process.stdout.write(`- initial version: ${result.initialVersion}\n`);
|
|
1757
|
-
process.stdout.write(`- dev: ${result.refs.dev}\n`);
|
|
1758
|
-
process.stdout.write(`- alpha: ${result.refs.alpha}\n`);
|
|
1759
|
-
process.stdout.write(`- release: ${result.refs.release}\n`);
|
|
1760
|
-
process.stdout.write(`- version files: ${result.versionState.files.join(", ") || "none"}\n`);
|
|
1761
|
-
if (result.changedFiles) {
|
|
1762
|
-
process.stdout.write(`- changed files: ${result.changedFiles.join(", ") || "none"}\n`);
|
|
1763
|
-
}
|
|
1764
|
-
process.stdout.write(result.dryRun ? "No refs, branches, PRs, or files were modified.\n" : "Version-state files were updated in the working tree.\n");
|
|
1765
|
-
}
|
|
1766
|
-
return;
|
|
1767
|
-
}
|
|
1768
|
-
const explainMode = args[0] === "dry-run" || args[0] === "explain";
|
|
1769
|
-
const releaseArgs = explainMode ? args.slice(1) : args;
|
|
1770
|
-
if (explainMode || readBooleanFlag(args, "dry-run")) {
|
|
1771
|
-
const plan = explainReleaseLineDryRun({
|
|
1772
|
-
cwd: readFlag(releaseArgs, "cwd", process.cwd()),
|
|
1773
|
-
targetRef: readFlag(releaseArgs, "target-ref", ""),
|
|
1774
|
-
sourceRef: readFlag(releaseArgs, "source-ref", ""),
|
|
1775
|
-
sha: readFlag(releaseArgs, "sha", ""),
|
|
1776
|
-
tags: readFlag(releaseArgs, "tags", ""),
|
|
1777
|
-
publishTransaction: readBooleanFlag(releaseArgs, "publish-transaction"),
|
|
1778
|
-
publishCommand: readFlag(releaseArgs, "publish-command", ""),
|
|
1779
|
-
});
|
|
1780
|
-
if (readBooleanFlag(releaseArgs, "json")) {
|
|
1781
|
-
printJson(plan);
|
|
1782
|
-
} else {
|
|
1783
|
-
process.stdout.write(formatReleaseLineDryRun(plan));
|
|
1784
|
-
}
|
|
1785
|
-
return;
|
|
1786
|
-
}
|
|
1787
|
-
runScript("release-transaction.mjs", args);
|
|
1788
|
-
return;
|
|
1789
|
-
}
|
|
1790
|
-
|
|
1791
|
-
if (command === "transaction") {
|
|
1792
|
-
const [subcommand = "inspect", ...transactionArgs] = args;
|
|
1793
|
-
if (subcommand !== "inspect") {
|
|
1794
|
-
throw new Error("usage: buildchain transaction inspect ...");
|
|
1795
|
-
}
|
|
1796
|
-
runScript("release-transaction.mjs", ["inspect", ...transactionArgs]);
|
|
1797
|
-
return;
|
|
1798
|
-
}
|
|
1799
|
-
|
|
1800
|
-
if (command === "create") {
|
|
1801
|
-
const [subcommand = "", ...createArgs] = args;
|
|
1802
|
-
const inputValue = readFlag(createArgs, "input-json", "");
|
|
1803
|
-
if (!inputValue || !["publication-admission", "runner-provenance"].includes(subcommand)) {
|
|
1804
|
-
throw new Error("usage: buildchain create <publication-admission|runner-provenance> --input-json <file-or-json> [--output <file>]");
|
|
1805
|
-
}
|
|
1806
|
-
const input = readJsonInput(inputValue, { label: "input-json" });
|
|
1807
|
-
const value = subcommand === "publication-admission"
|
|
1808
|
-
? createPublicationAdmission(input)
|
|
1809
|
-
: createRunnerProvenance(input);
|
|
1810
|
-
const output = readFlag(createArgs, "output", "");
|
|
1811
|
-
if (output) writeJsonFile(path.resolve(output), value);
|
|
1812
|
-
if (!output || readBooleanFlag(createArgs, "json")) printJson(value);
|
|
1813
|
-
else process.stdout.write(`${subcommand}: ${output}\n`);
|
|
1814
|
-
return;
|
|
1815
|
-
}
|
|
1816
|
-
|
|
1817
|
-
if (command === "collect") {
|
|
1818
|
-
const [subcommand = "", ...collectArgs] = args;
|
|
1819
|
-
if (subcommand !== "github-release") {
|
|
1820
|
-
throw new Error("usage: buildchain collect github-release --tag <tag>");
|
|
1821
|
-
}
|
|
1822
|
-
const workflow = {
|
|
1823
|
-
name: process.env.GITHUB_WORKFLOW || "",
|
|
1824
|
-
runId: process.env.GITHUB_RUN_ID || "",
|
|
1825
|
-
runAttempt: process.env.GITHUB_RUN_ATTEMPT || "",
|
|
1826
|
-
url: process.env.GITHUB_SERVER_URL && process.env.GITHUB_REPOSITORY && process.env.GITHUB_RUN_ID
|
|
1827
|
-
? `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`
|
|
1828
|
-
: "",
|
|
1829
|
-
runnerKind: process.env.BUILDCHAIN_RUNNER_KIND || "github-hosted",
|
|
1830
|
-
runnerOs: process.env.RUNNER_OS || process.platform,
|
|
1831
|
-
runnerArch: process.env.RUNNER_ARCH || process.arch,
|
|
1832
|
-
runnerImage: process.env.ImageOS || "",
|
|
1833
|
-
};
|
|
1834
|
-
const result = collectGitHubReleasePassport({
|
|
1835
|
-
cwd: readFlag(collectArgs, "cwd", process.cwd()),
|
|
1836
|
-
tag: readFlag(collectArgs, "tag", ""),
|
|
1837
|
-
repository: readFlag(collectArgs, "repository", process.env.GITHUB_REPOSITORY || ""),
|
|
1838
|
-
sourceSha: readFlag(collectArgs, "source-sha", process.env.GITHUB_SHA || ""),
|
|
1839
|
-
line: readFlag(collectArgs, "line", ""),
|
|
1840
|
-
outputDir: readFlag(collectArgs, "output-dir", ".buildchain/release-passport"),
|
|
1841
|
-
assetsDir: readFlag(collectArgs, "assets-dir", ""),
|
|
1842
|
-
assetsJson: readFlag(collectArgs, "assets-json", ""),
|
|
1843
|
-
releaseJson: readFlag(collectArgs, "release-json", ""),
|
|
1844
|
-
productName: readFlag(collectArgs, "product-name", "Buildchain"),
|
|
1845
|
-
packageName: readFlag(collectArgs, "package-name", "@kungfu-tech/buildchain"),
|
|
1846
|
-
packageVersion: readFlag(collectArgs, "package-version", packageVersion()),
|
|
1847
|
-
packageSetJson: readFlag(collectArgs, "package-set-json", ""),
|
|
1848
|
-
publishEvidenceJson: readFlag(collectArgs, "publish-evidence-json", ""),
|
|
1849
|
-
trustedPublishingJson: readFlag(collectArgs, "trusted-publishing-json", ""),
|
|
1850
|
-
transactionJson: readFlag(collectArgs, "transaction-json", ""),
|
|
1851
|
-
anchorManifestJson: readFlag(collectArgs, "anchor-manifest-json", ""),
|
|
1852
|
-
impactJson: readFlag(collectArgs, "impact-json", ""),
|
|
1853
|
-
buildSummaryJson: readFlag(collectArgs, "build-summary-json", ""),
|
|
1854
|
-
buildFactsJsons: readRepeatedFlag(collectArgs, "build-facts-json"),
|
|
1855
|
-
platformManifestJsons: readRepeatedFlag(collectArgs, "platform-manifest-json"),
|
|
1856
|
-
distTagEvidenceJson: readFlag(collectArgs, "dist-tag-evidence-json", ""),
|
|
1857
|
-
kfd1WitnessJsons: readRepeatedFlag(collectArgs, "kfd-1-witness-json"),
|
|
1858
|
-
kfd2ClaimJsons: readRepeatedFlag(collectArgs, "kfd-2-claim-json"),
|
|
1859
|
-
kfd3PrebuildWitnessJsons: readRepeatedFlag(collectArgs, "kfd-3-prebuild-witness-json"),
|
|
1860
|
-
kfd3ArtifactWitnessJsons: readRepeatedFlag(collectArgs, "kfd-3-artifact-witness-json"),
|
|
1861
|
-
kfd3ArtifactVerifyCommand: readFlag(collectArgs, "kfd-3-artifact-verify-cmd", ""),
|
|
1862
|
-
invariantPassportJsons: readRepeatedFlag(collectArgs, "invariant-passport-json"),
|
|
1863
|
-
invariantPassportCommand: readFlag(collectArgs, "invariant-passport-cmd", ""),
|
|
1864
|
-
kfdAgentHubEvidenceJson: readFlag(collectArgs, "kfd-agent-hub-evidence-json", ""),
|
|
1865
|
-
basePassportJson: readFlag(collectArgs, "base-passport-json", ""),
|
|
1866
|
-
requireBaseKfd: readBooleanFlag(collectArgs, "require-base-kfd"),
|
|
1867
|
-
releaseJsonExtra: readFlag(collectArgs, "release-extra-json", ""),
|
|
1868
|
-
publishJson: readFlag(collectArgs, "publish-json", ""),
|
|
1869
|
-
workflow,
|
|
1870
|
-
});
|
|
1871
|
-
if (readBooleanFlag(collectArgs, "json")) {
|
|
1872
|
-
printJson(result);
|
|
1873
|
-
} else {
|
|
1874
|
-
process.stdout.write(`release passport collected: ${path.relative(process.cwd(), result.outputDir)}\n`);
|
|
1875
|
-
process.stdout.write(`artifacts: ${result.artifactEvidence.artifacts.length}\n`);
|
|
1876
|
-
}
|
|
1877
|
-
return;
|
|
1878
|
-
}
|
|
1879
|
-
|
|
1880
|
-
if (command === "project") {
|
|
1881
|
-
const [subcommand = "", location = "", ...projectArgs] = args;
|
|
1882
|
-
if (subcommand !== "kfx-admission" || !location) {
|
|
1883
|
-
throw new Error("usage: buildchain project kfx-admission <file-or-json>");
|
|
1884
|
-
}
|
|
1885
|
-
const projection = projectArtifactVerificationEnvelopeToKfx({
|
|
1886
|
-
envelope: readJsonInput(location, { label: "artifact verification envelope" }),
|
|
1887
|
-
...artifactEnvelopeOptions(projectArgs),
|
|
1888
|
-
});
|
|
1889
|
-
if (readBooleanFlag(projectArgs, "json")) {
|
|
1890
|
-
printJson(projection);
|
|
1891
|
-
} else {
|
|
1892
|
-
process.stdout.write(`KFX admission envelope: ${projection.envelopeRoot}\n`);
|
|
1893
|
-
}
|
|
1894
|
-
return;
|
|
1895
|
-
}
|
|
1896
|
-
|
|
1897
|
-
if (command === "verify") {
|
|
1898
|
-
const [subcommand = "", location = "", ...verifyArgs] = args;
|
|
1899
|
-
if (subcommand === "publication-admission") {
|
|
1900
|
-
if (!location) {
|
|
1901
|
-
throw new Error("usage: buildchain verify publication-admission <file-or-json> --registry-json <file-or-json> --runner-json <file-or-json> --control-plane-audit-json <file-or-json> --publication-evidence-json <file-or-json>");
|
|
1902
|
-
}
|
|
1903
|
-
const requiredInput = (name) => {
|
|
1904
|
-
const value = readFlag(verifyArgs, name, "");
|
|
1905
|
-
if (!value) throw new Error(`buildchain verify publication-admission requires --${name} <file-or-json>`);
|
|
1906
|
-
return readJsonInput(value, { label: name });
|
|
1907
|
-
};
|
|
1908
|
-
const expectedInput = readFlag(verifyArgs, "expected-json", "");
|
|
1909
|
-
const capability = verifyPublicationAdmission({
|
|
1910
|
-
admission: readJsonInput(location, { label: "publication admission" }),
|
|
1911
|
-
registry: requiredInput("registry-json"),
|
|
1912
|
-
runnerProvenance: requiredInput("runner-json"),
|
|
1913
|
-
controlPlaneAudit: requiredInput("control-plane-audit-json"),
|
|
1914
|
-
publicationEvidence: requiredInput("publication-evidence-json"),
|
|
1915
|
-
expected: expectedInput ? readJsonInput(expectedInput, { label: "expected-json" }) : {},
|
|
1916
|
-
usedNonces: readRepeatedFlag(verifyArgs, "used-nonce"),
|
|
1917
|
-
});
|
|
1918
|
-
if (readBooleanFlag(verifyArgs, "json")) {
|
|
1919
|
-
printJson(capability);
|
|
1920
|
-
} else {
|
|
1921
|
-
process.stdout.write(`publication admission: ${capability.decision}\n`);
|
|
1922
|
-
process.stdout.write(`capability digest: ${capability.capabilityDigest}\n`);
|
|
1923
|
-
process.stdout.write(`expires at: ${capability.expiresAt}\n`);
|
|
1924
|
-
}
|
|
1925
|
-
return;
|
|
1926
|
-
}
|
|
1927
|
-
if (subcommand === "artifact") {
|
|
1928
|
-
if (!location) {
|
|
1929
|
-
throw new Error("usage: buildchain verify artifact <subject>");
|
|
1930
|
-
}
|
|
1931
|
-
const report = await verifyArtifactPassport({
|
|
1932
|
-
subject: location,
|
|
1933
|
-
cwd: process.cwd(),
|
|
1934
|
-
passportLocation: readFlag(verifyArgs, "passport", ""),
|
|
1935
|
-
locatorConfig: readFlag(verifyArgs, "locator-config", ""),
|
|
1936
|
-
repository: readFlag(verifyArgs, "repository", ""),
|
|
1937
|
-
tag: readFlag(verifyArgs, "tag", ""),
|
|
1938
|
-
githubReleaseBaseUrl: readFlag(verifyArgs, "github-release-base-url", ""),
|
|
1939
|
-
subjectDigest: readFlag(verifyArgs, "subject-digest", ""),
|
|
1940
|
-
subjectKind: readFlag(verifyArgs, "subject-kind", ""),
|
|
1941
|
-
npmRegistryBaseUrl: readFlag(verifyArgs, "npm-registry", ""),
|
|
1942
|
-
});
|
|
1943
|
-
if (readBooleanFlag(verifyArgs, "json")) {
|
|
1944
|
-
printJson(report);
|
|
1945
|
-
} else {
|
|
1946
|
-
process.stdout.write(`artifact: ${report.outcome}\n`);
|
|
1947
|
-
process.stdout.write(`subject: ${report.subject?.name || location}\n`);
|
|
1948
|
-
process.stdout.write(`passport: ${report.passport?.location || report.discovery?.passportLocation || "unresolved"}\n`);
|
|
1949
|
-
for (const entry of report.issues) {
|
|
1950
|
-
process.stdout.write(`- ${entry.level}: ${entry.code}: ${entry.message}\n`);
|
|
1951
|
-
}
|
|
1952
|
-
}
|
|
1953
|
-
process.exitCode = report.ok ? 0 : 1;
|
|
1954
|
-
return;
|
|
1955
|
-
}
|
|
1956
|
-
if (subcommand === "artifact-envelope") {
|
|
1957
|
-
if (!location) {
|
|
1958
|
-
throw new Error("usage: buildchain verify artifact-envelope <file-or-json>");
|
|
1959
|
-
}
|
|
1960
|
-
const report = verifyArtifactVerificationEnvelope({
|
|
1961
|
-
envelope: readJsonInput(location, { label: "artifact verification envelope" }),
|
|
1962
|
-
...artifactEnvelopeOptions(verifyArgs),
|
|
1963
|
-
});
|
|
1964
|
-
if (readBooleanFlag(verifyArgs, "json")) {
|
|
1965
|
-
printJson(report);
|
|
1966
|
-
} else {
|
|
1967
|
-
process.stdout.write(`artifact verification envelope: ${report.outcome}\n`);
|
|
1968
|
-
process.stdout.write(`root: ${report.envelopeRoot || "unresolved"}\n`);
|
|
1969
|
-
for (const entry of report.issues) {
|
|
1970
|
-
process.stdout.write(`- ${entry.level}: ${entry.code}: ${entry.message}\n`);
|
|
1971
|
-
}
|
|
1972
|
-
}
|
|
1973
|
-
process.exitCode = report.ok ? 0 : 1;
|
|
1974
|
-
return;
|
|
1975
|
-
}
|
|
1976
|
-
if (subcommand === "observability-log") {
|
|
1977
|
-
if (!location) {
|
|
1978
|
-
throw new Error("usage: buildchain verify observability-log <jsonl>");
|
|
1979
|
-
}
|
|
1980
|
-
const report = verifyBuildchainLogEvents({
|
|
1981
|
-
path: location,
|
|
1982
|
-
minEvents: Number(readFlag(verifyArgs, "min-events", "1")),
|
|
1983
|
-
allowErrors: readBooleanFlag(verifyArgs, "allow-errors"),
|
|
1984
|
-
requirePhases: readRepeatedFlag(verifyArgs, "require-phase"),
|
|
1985
|
-
requireComponents: readRepeatedFlag(verifyArgs, "require-component"),
|
|
1986
|
-
requireEvents: readRepeatedFlag(verifyArgs, "require-event"),
|
|
1987
|
-
});
|
|
1988
|
-
if (readBooleanFlag(verifyArgs, "json")) {
|
|
1989
|
-
printJson(report);
|
|
1990
|
-
} else {
|
|
1991
|
-
process.stdout.write(`observability log: ${report.ok ? "ok" : "failed"}\n`);
|
|
1992
|
-
process.stdout.write(`events: ${report.summary.eventCount}\n`);
|
|
1993
|
-
for (const entry of report.issues) {
|
|
1994
|
-
process.stdout.write(`- ${entry.level}: ${entry.code}: ${entry.message}\n`);
|
|
1995
|
-
}
|
|
1996
|
-
}
|
|
1997
|
-
process.exitCode = report.ok ? 0 : 1;
|
|
1998
|
-
return;
|
|
1999
|
-
}
|
|
2000
|
-
if (subcommand === "infra-contract-evidence-bundle") {
|
|
2001
|
-
if (!location) {
|
|
2002
|
-
throw new Error("usage: buildchain verify infra-contract-evidence-bundle <file>");
|
|
2003
|
-
}
|
|
2004
|
-
const bundle = JSON.parse(fs.readFileSync(path.resolve(location), "utf8"));
|
|
2005
|
-
const report = verifyInfraContractEvidenceBundle(bundle);
|
|
2006
|
-
if (readBooleanFlag(verifyArgs, "json")) {
|
|
2007
|
-
printJson(report);
|
|
2008
|
-
} else {
|
|
2009
|
-
process.stdout.write(`infra contract evidence bundle: ${report.ok ? "ok" : "failed"}\n`);
|
|
2010
|
-
process.stdout.write(`artifact: ${report.artifactHash || "unknown"}\n`);
|
|
2011
|
-
for (const entry of report.issues) {
|
|
2012
|
-
process.stdout.write(`- ${entry.level}: ${entry.code}: ${entry.message}\n`);
|
|
2013
|
-
}
|
|
2014
|
-
}
|
|
2015
|
-
process.exitCode = report.ok ? 0 : 1;
|
|
2016
|
-
return;
|
|
2017
|
-
}
|
|
2018
|
-
if (subcommand !== "release-passport" || !location) {
|
|
2019
|
-
throw new Error("usage: buildchain verify release-passport <file-or-url>");
|
|
2020
|
-
}
|
|
2021
|
-
const report = await verifyReleasePassport({ passportLocation: location });
|
|
2022
|
-
if (readBooleanFlag(verifyArgs, "json")) {
|
|
2023
|
-
printJson(report);
|
|
2024
|
-
} else {
|
|
2025
|
-
process.stdout.write(`release passport: ${report.ok ? "ok" : "failed"}\n`);
|
|
2026
|
-
process.stdout.write(`artifacts: ${report.completeness.artifactCount}\n`);
|
|
2027
|
-
for (const entry of report.issues) {
|
|
2028
|
-
process.stdout.write(`- ${entry.level}: ${entry.code}: ${entry.message}\n`);
|
|
2029
|
-
}
|
|
2030
|
-
}
|
|
2031
|
-
process.exitCode = report.ok ? 0 : 1;
|
|
2032
|
-
return;
|
|
2033
|
-
}
|
|
2034
|
-
|
|
2035
|
-
if (command === "audit") {
|
|
2036
|
-
const [subcommand = "", ...auditArgs] = args;
|
|
2037
|
-
if (subcommand === "publication-control-plane") {
|
|
2038
|
-
runScript("audit-publication-control-plane.mjs", auditArgs);
|
|
2039
|
-
return;
|
|
2040
|
-
}
|
|
2041
|
-
if (subcommand === "github-governance") {
|
|
2042
|
-
runScript("audit-github-governance.mjs", auditArgs);
|
|
2043
|
-
return;
|
|
2044
|
-
}
|
|
2045
|
-
throw new Error("usage: buildchain audit <publication-control-plane|github-governance> ...");
|
|
2046
|
-
}
|
|
2047
|
-
|
|
2048
|
-
if (command === "explain") {
|
|
2049
|
-
const [subcommand = "", ...explainArgs] = args;
|
|
2050
|
-
if (subcommand === "artifact") {
|
|
2051
|
-
const subject = explainArgs[0] || "";
|
|
2052
|
-
if (!subject) {
|
|
2053
|
-
throw new Error("usage: buildchain explain artifact <subject>");
|
|
2054
|
-
}
|
|
2055
|
-
const explanation = await explainArtifactPassport({
|
|
2056
|
-
subject,
|
|
2057
|
-
cwd: process.cwd(),
|
|
2058
|
-
passportLocation: readFlag(explainArgs, "passport", ""),
|
|
2059
|
-
locatorConfig: readFlag(explainArgs, "locator-config", ""),
|
|
2060
|
-
repository: readFlag(explainArgs, "repository", ""),
|
|
2061
|
-
tag: readFlag(explainArgs, "tag", ""),
|
|
2062
|
-
githubReleaseBaseUrl: readFlag(explainArgs, "github-release-base-url", ""),
|
|
2063
|
-
subjectDigest: readFlag(explainArgs, "subject-digest", ""),
|
|
2064
|
-
subjectKind: readFlag(explainArgs, "subject-kind", ""),
|
|
2065
|
-
npmRegistryBaseUrl: readFlag(explainArgs, "npm-registry", ""),
|
|
2066
|
-
forAudience: readFlag(explainArgs, "for", "human"),
|
|
2067
|
-
});
|
|
2068
|
-
if (readBooleanFlag(explainArgs, "json")) {
|
|
2069
|
-
printJson(explanation);
|
|
2070
|
-
} else {
|
|
2071
|
-
process.stdout.write(`artifact: ${explanation.subject?.name || subject}\n`);
|
|
2072
|
-
process.stdout.write(`trust: ${explanation.trust}\n`);
|
|
2073
|
-
process.stdout.write(`next action: ${explanation.nextAction}\n`);
|
|
2074
|
-
}
|
|
2075
|
-
process.exitCode = explanation.trust === "pass" ? 0 : 1;
|
|
2076
|
-
return;
|
|
2077
|
-
}
|
|
2078
|
-
if (subcommand !== "release") {
|
|
2079
|
-
throw new Error("usage: buildchain explain release --passport <file-or-url>");
|
|
2080
|
-
}
|
|
2081
|
-
const passport = readFlag(explainArgs, "passport", "");
|
|
2082
|
-
if (!passport) {
|
|
2083
|
-
throw new Error("buildchain explain release requires --passport <file-or-url>");
|
|
2084
|
-
}
|
|
2085
|
-
const explanation = await explainReleasePassport({
|
|
2086
|
-
passportLocation: passport,
|
|
2087
|
-
forAudience: readFlag(explainArgs, "for", "human"),
|
|
2088
|
-
});
|
|
2089
|
-
if (readBooleanFlag(explainArgs, "json")) {
|
|
2090
|
-
printJson(explanation);
|
|
2091
|
-
} else {
|
|
2092
|
-
process.stdout.write(`release: ${explanation.release?.tag || "unknown"}\n`);
|
|
2093
|
-
process.stdout.write(`trust: ${explanation.trust}\n`);
|
|
2094
|
-
process.stdout.write(`next action: ${explanation.nextAction}\n`);
|
|
2095
|
-
}
|
|
2096
|
-
return;
|
|
2097
|
-
}
|
|
2098
|
-
|
|
2099
|
-
if (command === "inspect") {
|
|
2100
|
-
const [subcommand = "", ...inspectArgs] = args;
|
|
2101
|
-
if (subcommand === "artifact") {
|
|
2102
|
-
const subject = inspectArgs[0] || "";
|
|
2103
|
-
if (!subject) {
|
|
2104
|
-
throw new Error("usage: buildchain inspect artifact <subject>");
|
|
2105
|
-
}
|
|
2106
|
-
const report = await verifyArtifactPassport({
|
|
2107
|
-
subject,
|
|
2108
|
-
cwd: process.cwd(),
|
|
2109
|
-
passportLocation: readFlag(inspectArgs, "passport", ""),
|
|
2110
|
-
locatorConfig: readFlag(inspectArgs, "locator-config", ""),
|
|
2111
|
-
repository: readFlag(inspectArgs, "repository", ""),
|
|
2112
|
-
tag: readFlag(inspectArgs, "tag", ""),
|
|
2113
|
-
githubReleaseBaseUrl: readFlag(inspectArgs, "github-release-base-url", ""),
|
|
2114
|
-
subjectDigest: readFlag(inspectArgs, "subject-digest", ""),
|
|
2115
|
-
subjectKind: readFlag(inspectArgs, "subject-kind", ""),
|
|
2116
|
-
npmRegistryBaseUrl: readFlag(inspectArgs, "npm-registry", ""),
|
|
2117
|
-
});
|
|
2118
|
-
printJson(report);
|
|
2119
|
-
process.exitCode = report.ok ? 0 : 1;
|
|
2120
|
-
return;
|
|
2121
|
-
}
|
|
2122
|
-
if (subcommand !== "release") {
|
|
2123
|
-
throw new Error("usage: buildchain inspect release --passport <file-or-url>");
|
|
2124
|
-
}
|
|
2125
|
-
const passport = readFlag(inspectArgs, "passport", "");
|
|
2126
|
-
if (!passport) {
|
|
2127
|
-
throw new Error("buildchain inspect release requires --passport <file-or-url>");
|
|
2128
|
-
}
|
|
2129
|
-
const explanation = await explainReleasePassport({
|
|
2130
|
-
passportLocation: passport,
|
|
2131
|
-
forAudience: readFlag(inspectArgs, "for", "human"),
|
|
2132
|
-
});
|
|
2133
|
-
printJson(explanation);
|
|
1792
|
+
if (TRUST_RELEASE_COMMANDS.has(command)) {
|
|
1793
|
+
await dispatchTrustReleaseCommand({ command, args, runScript, packageVersion });
|
|
2134
1794
|
return;
|
|
2135
1795
|
}
|
|
2136
1796
|
|