@kungfu-tech/buildchain 2.9.0 → 2.9.1
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/bin/buildchain.mjs +47 -0
- package/dist/site/agent-index.json +1 -0
- package/dist/site/artifact-schemas.json +1 -0
- package/dist/site/buildchain-contract.json +5 -5
- package/dist/site/buildchain-site.json +29 -22
- package/dist/site/cli-registry.json +239 -42
- package/dist/site/kfd-claims.json +2181 -1
- package/dist/site/manual-registry.json +6 -6
- package/dist/site/node-api-registry.json +17 -5
- package/dist/site/page-registry.json +17 -12
- package/dist/site/public-surface-audit.json +1969 -0
- package/dist/site/release-provenance.json +3 -0
- package/dist/site/site-manifest.json +11 -10
- package/dist/site/workflow-registry.json +741 -18
- package/docs/MAP.md +1 -0
- package/docs/cli.md +47 -0
- package/docs/release-flow.md +31 -0
- package/docs/release-passport.md +10 -0
- package/docs/site-bundle-contract.md +7 -0
- package/docs/web-surface-deployments.md +10 -0
- package/package.json +4 -1
- package/packages/core/buildchain-kfd-claims.js +118 -7
- package/packages/core/index.js +16 -0
- package/packages/core/public-surface-audit.js +298 -0
- package/packages/core/release-line-bootstrap.js +242 -0
- package/scripts/check-inventory.mjs +32 -1
- package/scripts/generate-site-bundle.mjs +95 -32
- package/scripts/web-surface-core.mjs +79 -6
|
@@ -11,6 +11,12 @@ import {
|
|
|
11
11
|
import {
|
|
12
12
|
createReadmeBadgeEndpointRegistry,
|
|
13
13
|
} from "../packages/core/readme-badges.js";
|
|
14
|
+
import {
|
|
15
|
+
collectPublicSurfaceReverseAudit,
|
|
16
|
+
enumerateActionInputs,
|
|
17
|
+
enumerateCliCommandsFromBin,
|
|
18
|
+
enumerateWorkflowInputs,
|
|
19
|
+
} from "../packages/core/public-surface-audit.js";
|
|
14
20
|
import { createSurfaceTimestampPolicy } from "../packages/core/surface-manifest.js";
|
|
15
21
|
|
|
16
22
|
const SITE_BUNDLE_CONTRACT = "kungfu-buildchain-site-bundle";
|
|
@@ -276,29 +282,53 @@ function buildSiteBundle() {
|
|
|
276
282
|
artifactDigestScope: "npm package dist/site JSON files",
|
|
277
283
|
});
|
|
278
284
|
|
|
285
|
+
const cliPurposeById = new Map([
|
|
286
|
+
["version", "Print the package or embedded binary version."],
|
|
287
|
+
["help", "Print Buildchain CLI help."],
|
|
288
|
+
["init", "Bootstrap a repository with Buildchain configuration and caller workflow files."],
|
|
289
|
+
["validate", "Validate buildchain.toml and declared lifecycle surfaces."],
|
|
290
|
+
["doctor", "Report local integration readiness."],
|
|
291
|
+
["lifecycle", "Run configured lifecycle commands and write deterministic artifact manifests."],
|
|
292
|
+
["release-dry-run", "Explain what a channel merge would publish before the PR is merged."],
|
|
293
|
+
["release-line-open", "Plan or write the initial version-state commit for a new minor release line."],
|
|
294
|
+
["release-transaction", "Inspect, recover, finalize, or abort durable release transactions."],
|
|
295
|
+
["transaction-inspect", "Inspect durable release transaction state."],
|
|
296
|
+
["collect-github-release", "Collect release assets into a release passport."],
|
|
297
|
+
["verify-release-passport", "Fail closed unless a release passport and its evidence are complete."],
|
|
298
|
+
["verify-artifact", "Verify artifact subjects against release passport evidence."],
|
|
299
|
+
["verify-infra-contract-evidence-bundle", "Fail closed unless an infra-contract lifecycle evidence bundle is complete, hash-bound, and validation-consistent."],
|
|
300
|
+
["verify-observability-log", "Verify Buildchain observability log events."],
|
|
301
|
+
["explain-release", "Explain a release passport for humans or agents."],
|
|
302
|
+
["explain-artifact", "Explain artifact evidence for humans or agents."],
|
|
303
|
+
["inspect-release", "Inspect release passport evidence."],
|
|
304
|
+
["inspect-artifact", "Inspect artifact evidence."],
|
|
305
|
+
["release-propagation", "Plan channel-preserving downstream release PRs and write exact upstream release locks."],
|
|
306
|
+
["logging", "Emit timestamped build events, summarize logs, and enforce required phases."],
|
|
307
|
+
["mark", "Emit a single Buildchain log event."],
|
|
308
|
+
["span", "Run a command inside a Buildchain log span."],
|
|
309
|
+
["diagnostics-summary", "Summarize diagnostics artifacts into JSON and cross-platform lifecycle timing tables."],
|
|
310
|
+
["build-facts", "Collect and verify Git source, version, module output, product artifact, and legacy Kungfu buildinfo facts."],
|
|
311
|
+
["sample-process-tree", "Sample process-tree diagnostics for a wrapped command."],
|
|
312
|
+
["npm-dry-run", "Verify npm publish shape before a release transaction."],
|
|
313
|
+
["infra-contract", "Validate and publish provider-neutral infrastructure contract evidence."],
|
|
314
|
+
["web-surface", "Plan, verify, and apply Buildchain web-surface deployments."],
|
|
315
|
+
["badges-readme", "Generate or verify managed README badge blocks."],
|
|
316
|
+
["badges-bundle", "Generate or verify the combined KFD and Release Passport badge bundle."],
|
|
317
|
+
["homebrew-update-formula", "Generate Homebrew Formula metadata from upstream release passport evidence."],
|
|
318
|
+
["homebrew-check", "Verify Homebrew tap metadata against upstream release passport evidence."],
|
|
319
|
+
["publish-source", "Create, inspect, or verify publish-gate source-lock refs."],
|
|
320
|
+
["build-contract", "Resolve Buildchain runtime contract metadata."],
|
|
321
|
+
]);
|
|
279
322
|
const cliRegistry = {
|
|
280
323
|
schemaVersion: 1,
|
|
281
324
|
contract: "kungfu-buildchain-cli-registry",
|
|
282
325
|
binary: "buildchain",
|
|
283
326
|
npmPackage: packageJson.name,
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
{ id: "lifecycle", usage: "buildchain lifecycle run <stage>", purpose: "Run configured lifecycle commands and write deterministic artifact manifests." },
|
|
290
|
-
{ id: "release-dry-run", usage: "buildchain release --dry-run --target-ref <ref>", purpose: "Explain what a channel merge would publish before the PR is merged." },
|
|
291
|
-
{ id: "collect-github-release", usage: "buildchain collect github-release --tag <tag>", purpose: "Collect release assets into a release passport." },
|
|
292
|
-
{ id: "verify-release-passport", usage: "buildchain verify release-passport <file-or-url>", purpose: "Fail closed unless a release passport and its evidence are complete." },
|
|
293
|
-
{ id: "release-propagation", usage: "buildchain release-propagation <plan|write-lock>", purpose: "Plan channel-preserving downstream release PRs and write exact upstream release locks." },
|
|
294
|
-
{ id: "verify-infra-contract-evidence-bundle", usage: "buildchain verify infra-contract-evidence-bundle <file>", purpose: "Fail closed unless an infra-contract lifecycle evidence bundle is complete, hash-bound, and validation-consistent." },
|
|
295
|
-
{ id: "logging", usage: "buildchain log|mark|span|verify observability-log", purpose: "Emit timestamped build events, summarize logs, and enforce required phases." },
|
|
296
|
-
{ id: "diagnostics-summary", usage: "buildchain diagnostics summary <diagnostics.json>...", purpose: "Summarize small diagnostics artifacts into JSON and a cross-platform lifecycle timing table." },
|
|
297
|
-
{ id: "build-facts", usage: "buildchain facts module|aggregate|verify", purpose: "Collect and verify Git source, version, module output, product artifact, and legacy Kungfu buildinfo facts." },
|
|
298
|
-
{ id: "npm-dry-run", usage: "buildchain npm dry-run --json", purpose: "Verify npm publish shape before a release transaction." },
|
|
299
|
-
{ id: "infra-contract", usage: "buildchain infra-contract --mode validate|ci|plan|contract|propagation-plan|propagation-apply|apply|evidence-bundle", purpose: "Validate and publish provider-neutral infrastructure contract evidence with a mutation-free CI evidence chain, provider command plans, configured provider command execution, saved-plan apply gates, dry-run-first propagation, and lifecycle evidence bundles." },
|
|
300
|
-
{ id: "homebrew", usage: "buildchain homebrew update-formula|check", purpose: "Generate and verify Homebrew tap Formula metadata as a distribution-index projection of upstream release passport evidence." },
|
|
301
|
-
],
|
|
327
|
+
commandSource: "bin/buildchain.mjs reverse enumeration",
|
|
328
|
+
commands: enumerateCliCommandsFromBin({ root }).map((entry) => ({
|
|
329
|
+
...entry,
|
|
330
|
+
purpose: cliPurposeById.get(entry.id) || "Public Buildchain CLI surface. Add a specific purpose in scripts/generate-site-bundle.mjs when this command graduates.",
|
|
331
|
+
})),
|
|
302
332
|
};
|
|
303
333
|
|
|
304
334
|
const manualRegistry = {
|
|
@@ -374,21 +404,49 @@ function buildSiteBundle() {
|
|
|
374
404
|
const workflowRegistry = {
|
|
375
405
|
schemaVersion: 1,
|
|
376
406
|
contract: "kungfu-buildchain-workflow-registry",
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
407
|
+
workflowSource: ".github/workflows reverse input enumeration",
|
|
408
|
+
workflows: enumerateWorkflowInputs({ root }).map((entry) => {
|
|
409
|
+
const surfaceById = new Map([
|
|
410
|
+
["build", "reusable-build"],
|
|
411
|
+
["web-surface", "site-app-deployment"],
|
|
412
|
+
["buildchain-ref-promotion", "release-governance"],
|
|
413
|
+
["release-line-bootstrap", "release-governance"],
|
|
414
|
+
["release-candidate-promote", "release-governance"],
|
|
415
|
+
["release-propagation", "release-propagation"],
|
|
416
|
+
["dev-pr-auto-merge", "dev-governance"],
|
|
417
|
+
["binary-distribution", "release-passport"],
|
|
418
|
+
["buildchain-patrol", "repository-patrol"],
|
|
419
|
+
["buildchain-patrol-daily", "repository-patrol"],
|
|
420
|
+
["buildchain-patrol-weekly", "repository-patrol"],
|
|
421
|
+
["buildchain-patrol-monthly", "repository-patrol"],
|
|
422
|
+
["patrol-daily", "repository-patrol"],
|
|
423
|
+
["patrol-weekly", "repository-patrol"],
|
|
424
|
+
["patrol-monthly", "repository-patrol"],
|
|
425
|
+
]);
|
|
426
|
+
const statusById = new Map([
|
|
427
|
+
["release-propagation", "preview"],
|
|
428
|
+
["candidate-lab", "repository-internal"],
|
|
429
|
+
["build-surface-fixture", "repository-internal"],
|
|
430
|
+
["self-hosted-runner-smoke", "compatibility-fixture"],
|
|
431
|
+
]);
|
|
432
|
+
return {
|
|
433
|
+
...entry,
|
|
434
|
+
surface: surfaceById.get(entry.id) || (entry.path.includes("/.") ? "reusable-workflow" : "repository-workflow"),
|
|
435
|
+
status: statusById.get(entry.id) || "active",
|
|
436
|
+
};
|
|
437
|
+
}),
|
|
438
|
+
actionSource: "actions/*/action.yml reverse input enumeration",
|
|
439
|
+
actions: enumerateActionInputs({ root }).map((entry) => ({
|
|
440
|
+
...entry,
|
|
441
|
+
status: "active",
|
|
442
|
+
})),
|
|
391
443
|
};
|
|
444
|
+
const publicSurfaceAudit = collectPublicSurfaceReverseAudit({
|
|
445
|
+
root,
|
|
446
|
+
cliRegistry,
|
|
447
|
+
workflowRegistry,
|
|
448
|
+
pageRegistry,
|
|
449
|
+
});
|
|
392
450
|
|
|
393
451
|
const releaseModel = {
|
|
394
452
|
schemaVersion: 1,
|
|
@@ -460,6 +518,7 @@ function buildSiteBundle() {
|
|
|
460
518
|
"manual-registry.json",
|
|
461
519
|
"node-api-registry.json",
|
|
462
520
|
"workflow-registry.json",
|
|
521
|
+
"public-surface-audit.json",
|
|
463
522
|
"release-model.json",
|
|
464
523
|
"artifact-schemas.json",
|
|
465
524
|
"buildchain-contract.json",
|
|
@@ -538,6 +597,7 @@ function buildSiteBundle() {
|
|
|
538
597
|
"manual-registry.json",
|
|
539
598
|
"node-api-registry.json",
|
|
540
599
|
"workflow-registry.json",
|
|
600
|
+
"public-surface-audit.json",
|
|
541
601
|
"release-model.json",
|
|
542
602
|
"artifact-schemas.json",
|
|
543
603
|
"badge-endpoint-registry.json",
|
|
@@ -560,6 +620,7 @@ function buildSiteBundle() {
|
|
|
560
620
|
"manual-registry.json",
|
|
561
621
|
"node-api-registry.json",
|
|
562
622
|
"workflow-registry.json",
|
|
623
|
+
"public-surface-audit.json",
|
|
563
624
|
"artifact-schemas.json",
|
|
564
625
|
"buildchain-contract.json",
|
|
565
626
|
"kfd-claims.json",
|
|
@@ -690,6 +751,7 @@ function buildSiteBundle() {
|
|
|
690
751
|
"release model facts",
|
|
691
752
|
"workflow and action registries",
|
|
692
753
|
"CLI command registry",
|
|
754
|
+
"public surface reverse audit",
|
|
693
755
|
"manual and Node API registries",
|
|
694
756
|
"KFD claim registry",
|
|
695
757
|
"release-passport evidence vocabulary",
|
|
@@ -715,6 +777,7 @@ function buildSiteBundle() {
|
|
|
715
777
|
"manual-registry.json": manualRegistry,
|
|
716
778
|
"node-api-registry.json": nodeApiRegistry,
|
|
717
779
|
"workflow-registry.json": workflowRegistry,
|
|
780
|
+
"public-surface-audit.json": publicSurfaceAudit,
|
|
718
781
|
"release-model.json": releaseModel,
|
|
719
782
|
"artifact-schemas.json": artifactSchemas,
|
|
720
783
|
"badge-endpoint-registry.json": badgeEndpointRegistry,
|
|
@@ -324,6 +324,70 @@ function directoryIndexAliasOperations({ surfaceArtifactRoot, bucket, binding })
|
|
|
324
324
|
});
|
|
325
325
|
}
|
|
326
326
|
|
|
327
|
+
function cloudfrontDefaultRootObjectOperation({ distributionId, directoryIndex = "index.html" }) {
|
|
328
|
+
const normalizedDistribution = String(distributionId || "").trim();
|
|
329
|
+
const normalizedDirectoryIndex = normalizeS3Key(directoryIndex || "index.html");
|
|
330
|
+
if (!normalizedDistribution || !normalizedDirectoryIndex || normalizedDirectoryIndex.includes("/")) {
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
return {
|
|
334
|
+
action: "ensure-cloudfront-default-root-object",
|
|
335
|
+
surface: "__distribution__",
|
|
336
|
+
command: "bash",
|
|
337
|
+
args: [
|
|
338
|
+
"-euo",
|
|
339
|
+
"pipefail",
|
|
340
|
+
"-c",
|
|
341
|
+
[
|
|
342
|
+
'distribution_id="$1"',
|
|
343
|
+
'root_object="$2"',
|
|
344
|
+
'tmp_dir="$(mktemp -d)"',
|
|
345
|
+
'trap \'rm -rf "$tmp_dir"\' EXIT',
|
|
346
|
+
'aws cloudfront get-distribution-config --id "$distribution_id" > "$tmp_dir/distribution.json"',
|
|
347
|
+
'etag="$(jq -r \'.ETag\' "$tmp_dir/distribution.json")"',
|
|
348
|
+
'current="$(jq -r \'.DistributionConfig.DefaultRootObject // ""\' "$tmp_dir/distribution.json")"',
|
|
349
|
+
'if [ "$current" = "$root_object" ]; then',
|
|
350
|
+
' echo "cloudfront default root object already $root_object for $distribution_id"',
|
|
351
|
+
' exit 0',
|
|
352
|
+
'fi',
|
|
353
|
+
'jq --arg root "$root_object" \'.DistributionConfig | .DefaultRootObject = $root\' "$tmp_dir/distribution.json" > "$tmp_dir/distribution-config.json"',
|
|
354
|
+
'aws cloudfront update-distribution --id "$distribution_id" --if-match "$etag" --distribution-config "file://$tmp_dir/distribution-config.json" >/dev/null',
|
|
355
|
+
'aws cloudfront wait distribution-deployed --id "$distribution_id"',
|
|
356
|
+
'echo "cloudfront default root object set to $root_object for $distribution_id"',
|
|
357
|
+
].join("\n"),
|
|
358
|
+
"buildchain-cloudfront-default-root-object",
|
|
359
|
+
normalizedDistribution,
|
|
360
|
+
normalizedDirectoryIndex,
|
|
361
|
+
],
|
|
362
|
+
routing: {
|
|
363
|
+
contract: "kungfu-buildchain-web-surface-cloudfront-default-root-object",
|
|
364
|
+
distributionId: normalizedDistribution,
|
|
365
|
+
defaultRootObject: normalizedDirectoryIndex,
|
|
366
|
+
reason: "Surface host root requests must resolve to index.html before host/path prefix rewrite reaches the S3 origin.",
|
|
367
|
+
},
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function cloudfrontDefaultRootObjectOperations({ bindings }) {
|
|
372
|
+
const seen = new Set();
|
|
373
|
+
return (bindings || []).flatMap((binding) => {
|
|
374
|
+
if (binding.directoryIndexResolution === false || !binding.distributionId) {
|
|
375
|
+
return [];
|
|
376
|
+
}
|
|
377
|
+
const directoryIndex = binding.directoryIndex || "index.html";
|
|
378
|
+
const key = `${binding.distributionId}:${directoryIndex}`;
|
|
379
|
+
if (seen.has(key)) {
|
|
380
|
+
return [];
|
|
381
|
+
}
|
|
382
|
+
seen.add(key);
|
|
383
|
+
const operation = cloudfrontDefaultRootObjectOperation({
|
|
384
|
+
distributionId: binding.distributionId,
|
|
385
|
+
directoryIndex,
|
|
386
|
+
});
|
|
387
|
+
return operation ? [operation] : [];
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
|
|
327
391
|
function defaultCommandRunner({ command, args, stdin = "" }) {
|
|
328
392
|
const result = spawnSync(command, args, {
|
|
329
393
|
encoding: "utf8",
|
|
@@ -941,12 +1005,15 @@ export function applyWebSurfaceDeploy({
|
|
|
941
1005
|
});
|
|
942
1006
|
}
|
|
943
1007
|
}
|
|
944
|
-
const operations =
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
1008
|
+
const operations = [
|
|
1009
|
+
...cloudfrontDefaultRootObjectOperations({ bindings }),
|
|
1010
|
+
...bindings.flatMap((binding) => deployBindingOperations({
|
|
1011
|
+
artifactRoot,
|
|
1012
|
+
deployConfig,
|
|
1013
|
+
manifest: resolvedPlan.manifest,
|
|
1014
|
+
binding,
|
|
1015
|
+
})),
|
|
1016
|
+
];
|
|
950
1017
|
const primaryBinding = bindings[0] || {};
|
|
951
1018
|
const objectPrefix = primaryBinding.objectPrefix || objectPrefixFor(deployConfig, resolvedPlan.manifest.alias || resolvedPlan.manifest.channel);
|
|
952
1019
|
const manifestKey = primaryBinding.manifestKey || deployManifestKey(deployConfig, resolvedPlan.manifest);
|
|
@@ -1428,6 +1495,12 @@ function deployBindingOperations({ artifactRoot, deployConfig, manifest, binding
|
|
|
1428
1495
|
function planAdapterSteps(adapter, deployConfig, manifest) {
|
|
1429
1496
|
if (adapter === "aws-s3-cloudfront") {
|
|
1430
1497
|
return [
|
|
1498
|
+
...cloudfrontDefaultRootObjectOperations({ bindings: manifest.surfaceBindings }).map((operation) => ({
|
|
1499
|
+
action: operation.action,
|
|
1500
|
+
surface: operation.surface,
|
|
1501
|
+
distribution: operation.routing.distributionId,
|
|
1502
|
+
defaultRootObject: operation.routing.defaultRootObject,
|
|
1503
|
+
})),
|
|
1431
1504
|
...manifest.surfaceBindings.flatMap((binding) => [
|
|
1432
1505
|
{
|
|
1433
1506
|
action: "sync-static-artifact",
|