@kungfu-tech/buildchain 4.1.3-alpha.9 → 4.1.4-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/AGENTS.md +11 -13
- package/CONTRIBUTING.md +32 -9
- package/README.md +56 -140
- package/actions/release/promotion/ref/README.md +1 -1
- package/architecture/action-taxonomy.json +1 -1
- package/architecture/agent-change-map.md +32 -45
- package/architecture/build-orchestration.json +1 -1
- package/architecture/capability-state-machine-manifest.json +5 -5
- package/architecture/ci-lane-change-budget.json +92 -92
- package/architecture/code-layout.json +2 -12
- package/architecture/core-mechanisms.json +38 -39
- package/architecture/cross-platform-adopter-qualification.json +1 -1
- package/architecture/dev-delivery-orchestration.json +2 -2
- package/architecture/floating-consumer-policy.json +3 -3
- package/architecture/internal-capabilities.json +27 -28
- package/architecture/maintainability-debt.json +60 -94
- package/architecture/maintainability-policy.json +7 -13
- package/architecture/minimal-consumer-migration.json +43 -5014
- package/architecture/platform-stage-checkpoints.json +1 -1
- package/architecture/release-tail-contract.json +2 -2
- package/architecture/release-topology.json +33 -25
- package/architecture/stage-capsule-qualification.json +1 -1
- package/architecture/universal-workflow-bootstrap.json +60 -60
- package/architecture/universal-workflow-capability-policy.json +3 -3
- package/architecture/universal-workflow-fault-campaign.json +7 -7
- package/architecture/workflow-taxonomy.json +59 -60
- package/contracts/fixtures/v4-tail-reseal-v1/valid.json +1 -1
- package/dist/site/buildchain-contract.json +138 -66
- package/dist/site/buildchain-site.json +257 -331
- package/dist/site/capability-registry.json +4 -4
- package/dist/site/cli-registry.json +6 -142
- package/dist/site/controller-registry.json +19 -19
- package/dist/site/kfd-claims.json +481 -529
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +22 -22
- package/dist/site/node-api-registry.json +82 -339
- package/dist/site/page-registry.json +229 -304
- package/dist/site/public-surface-audit.json +544 -754
- package/dist/site/publication-authority-registry.json +316 -316
- package/dist/site/publication-registry.json +1 -1
- package/dist/site/site-manifest.json +23 -23
- package/dist/site/workflow-registry.json +1071 -1027
- package/docs/MAP.md +28 -20
- package/docs/auditable-demo.md +17 -49
- package/docs/bootstrap-recovery.md +46 -37
- package/docs/cli-reference.md +2 -46
- package/docs/cli.md +97 -186
- package/docs/code-organization.md +7 -5
- package/docs/dev-alpha-candidate-patrol.md +19 -42
- package/docs/dev-delivery-orchestration.md +15 -11
- package/docs/dev-delivery-qualification-landing-adr.md +10 -9
- package/docs/dev-delivery-warrant.md +17 -16
- package/docs/dev-qualification-patrol.md +25 -20
- package/docs/getting-started.md +80 -139
- package/docs/github-artifact-attestation.md +31 -81
- package/docs/install.md +66 -30
- package/docs/lifecycle-protocol.md +19 -57
- package/docs/migration-inventory.md +17 -45
- package/docs/next-development-transition.md +13 -13
- package/docs/node-api-reference.md +122 -138
- package/docs/oci-publication.md +13 -10
- package/docs/publication-artifacts.md +128 -486
- package/docs/publication-authority.md +15 -45
- package/docs/publish-transaction.md +13 -11
- package/docs/release-candidate.md +126 -355
- package/docs/release-discussions.md +36 -67
- package/docs/release-flow.md +80 -339
- package/docs/release-governance.md +114 -962
- package/docs/release-promotion-request.md +45 -43
- package/docs/release-propagation.md +13 -27
- package/docs/release-tail-provider-plane.md +38 -65
- package/docs/reusable-build-surface.md +78 -196
- package/docs/runtime-train-validation.md +8 -6
- package/docs/stable-candidate-patrol.md +13 -66
- package/docs/v4-adopter-delivery.md +15 -15
- package/docs/v4-declarative-release-tail-migration.md +19 -17
- package/docs/v4-production-release.md +11 -6
- package/docs/v4-publication-rehearsal.md +12 -27
- package/docs/v4-stage-capsule.md +14 -20
- package/docs/v4-tail-reseal.md +34 -20
- package/docs/web-surface-deployments.md +26 -264
- package/docs/workflow-catalog.md +31 -31
- package/docs/workflow-path-migration.md +10 -4
- package/package.json +5 -4
- package/packages/core/adoption/buildchain-kfd-claims.js +7 -7
- package/packages/core/adoption/cli/output.mjs +1 -9
- package/packages/core/adoption/cli/product-gate.mjs +1 -15
- package/packages/core/adoption/cli/project.mjs +9 -10
- package/packages/core/adoption/cli/standards.mjs +1 -14
- package/packages/core/adoption/cli/support.mjs +0 -2
- package/packages/core/adoption/cli/surface-register.mjs +0 -2
- package/packages/core/adoption/commands/init-repo.mjs +77 -485
- package/packages/core/adoption/consumer-init.js +279 -0
- package/packages/core/adoption/qualification/admission.js +1 -1
- package/packages/core/build/cli/cache.mjs +0 -2
- package/packages/core/build/cli/facts.mjs +0 -3
- package/packages/core/build/cli/homebrew.mjs +0 -4
- package/packages/core/build/cli/lifecycle.mjs +0 -3
- package/packages/core/build/github-artifact-attestation.js +2 -2
- package/packages/core/build/platform-stage-checkpoints.js +1 -1
- package/packages/core/build/signing/dispatch.js +1 -1
- package/packages/core/consumer/buildchain-config.js +9 -0
- package/packages/core/consumer/contract/inspection.js +351 -9
- package/packages/core/consumer/contract/javascript-syntax.js +439 -0
- package/packages/core/consumer/contract/javascript-values.js +61 -0
- package/packages/core/consumer/contract/javascript.js +555 -0
- package/packages/core/consumer/contract/local-validation.js +84 -0
- package/packages/core/contracts/buildchain-contract.js +39 -8
- package/packages/core/contracts/cli/introspection.mjs +1 -9
- package/packages/core/contracts/public-surface-cli.js +0 -1
- package/packages/core/dev-delivery/dev-delivery-contract-surface.js +2 -2
- package/packages/core/governance/buildchain-publication-authority.js +24 -24
- package/packages/core/governance/cli/doctor.mjs +58 -42
- package/packages/core/governance/commands/architecture.mjs +6 -1
- package/packages/core/governance/commands/audit-publication-control-plane.mjs +1 -1
- package/packages/core/governance/commands/workflow-friction-report.mjs +1 -1
- package/packages/core/governance/github-governance-authority.js +2 -2
- package/packages/core/governance/publication/collection.js +1 -1
- package/packages/core/index.js +1 -3
- package/packages/core/observability/cli/candidate.mjs +0 -2
- package/packages/core/observability/cli/context.mjs +0 -5
- package/packages/core/observability/cli/diagnostics.mjs +0 -7
- package/packages/core/observability/cli/events.mjs +2 -10
- package/packages/core/paper/commands/paper-work-fleet-cli.mjs +1 -1
- package/packages/core/paper/commands/paper.mjs +33 -422
- package/packages/core/paper/consumer-status.js +72 -0
- package/packages/core/paper/operations/identity.js +0 -3
- package/packages/core/paper/operations/migration.js +460 -0
- package/packages/core/paper/operations/preflight-checks.js +8 -68
- package/packages/core/paper/operations/scaffold.js +16 -326
- package/packages/core/paper/operations/status.js +27 -53
- package/packages/core/paper/paper-agent-entry.js +36 -147
- package/packages/core/paper/paper-fleet.js +24 -39
- package/packages/core/paper/paper-repository.js +16 -0
- package/packages/core/paper/paper-runtime-channels.js +1 -1
- package/packages/core/paper/paper-scaffold-content.js +153 -162
- package/packages/core/paper/paper-work.js +3 -10
- package/packages/core/paper/paper.js +43 -5
- package/packages/core/providers/github/artifact-attestation.js +1 -1
- package/packages/core/providers/github/pipeline-context-artifacts.js +172 -0
- package/packages/core/providers/github/pipeline-release-evidence.js +17 -98
- package/packages/core/providers/github/pipeline-stable-baseline.js +86 -0
- package/packages/core/providers/github/pipeline-stable-source.js +22 -4
- package/packages/core/providers/github/release-evidence-assets.js +97 -0
- package/packages/core/publication/authority/control-plane.js +2 -2
- package/packages/core/publication/authority/seal.js +1 -1
- package/packages/core/publication/cli/dispatch.mjs +1 -12
- package/packages/core/publication/pipeline/actions.js +16 -9
- package/packages/core/publication/pipeline/apply.js +17 -9
- package/packages/core/publication/pipeline/context.js +29 -0
- package/packages/core/publication/pipeline/journal.js +13 -1
- package/packages/core/publication/pipeline/prepare.js +15 -6
- package/packages/core/publication/pipeline/recovery-import.js +1 -1
- package/packages/core/publication/pipeline/recovery-materials.js +63 -1
- package/packages/core/publication/pipeline/recovery-prepare.js +21 -9
- package/packages/core/publication/pipeline/stable-entry.js +12 -3
- package/packages/core/publication/pipeline/stable-products.js +21 -19
- package/packages/core/publication/pipeline/version-actions.js +15 -6
- package/packages/core/publication/publication-rehearsal-projection.js +0 -9
- package/packages/core/release/cli/dispatch.mjs +1 -4
- package/packages/core/release/cli/inspection-handlers.mjs +1 -33
- package/packages/core/release/cli/release-handlers.mjs +2 -19
- package/packages/core/release/cli/verification-handlers.mjs +4 -25
- package/packages/core/release/next-development-projection.js +13 -13
- package/packages/core/release/passport/locations.js +13 -8
- package/packages/core/release/release-passport.js +70 -5
- package/packages/core/web/cli/badges.mjs +0 -4
- package/packages/core/web/publication-admission.js +1 -1
- package/packages/core/web/publication-capability.js +1 -1
- package/packages/core/web/readme-badges.js +1 -1
- package/packages/core/workflow/cli/main.mjs +1 -4
- package/packages/core/workflow/cli/process.mjs +1 -1
- package/packages/core/workflow/commands/buildchain-cli-help.mjs +2 -8
- package/packages/core/workflow/engine/conformance.js +1 -1
- package/packages/core/workflow/pipeline/build.js +21 -1
- package/packages/core/workflow/pipeline/delivery-observation.js +6 -2
- package/packages/core/workflow/workflow-taxonomy.mjs +61 -17
- package/scripts/check-code-layout.mjs +2 -0
- package/scripts/check-core-mechanism-inventory.mjs +29 -13
- package/scripts/check-floating-consumer-policy-contract.mjs +3 -3
- package/scripts/check-inventory.mjs +27 -27
- package/scripts/check-maintainability.mjs +28 -5
- package/scripts/check-public-dogfood-contract.mjs +3 -3
- package/scripts/check-release-topology.mjs +1 -1
- package/scripts/check-self-consumer-contract.mjs +7 -7
- package/scripts/check-universal-workflow-bootstrap.mjs +1 -1
- package/scripts/generate-channel-promotion-workflow.mjs +1 -1
- package/scripts/generate-minimal-consumer-contract.mjs +21 -1
- package/scripts/generate-site-bundle.mjs +2 -1
- package/scripts/generate-tail-reseal-fixture.mjs +3 -3
- package/scripts/inventory/promotion.mjs +1 -1
- package/scripts/next-development-self-dogfood-harness.mjs +1 -1
- package/scripts/next-development-self-dogfood.mjs +4 -4
- package/scripts/site-capability-metadata.mjs +2 -6
- package/scripts/source-metric-lineage.mjs +62 -7
- package/scripts/verify-golden-path.mjs +31 -35
- package/templates/native-dev-delivery.yml +1 -1
- package/templates/universal-buildchain-bootstrap.yml +1 -1
- package/packages/core/paper/operations/bootstrap.js +0 -75
- package/packages/core/paper/operations/plans.js +0 -213
- package/packages/core/paper/operations/provisioning.js +0 -113
- package/packages/core/paper/operations/scaffold-config.js +0 -77
- package/packages/core/paper/operations/scaffold-workflows.js +0 -116
- package/packages/core/paper/operations/workspace.js +0 -60
- package/packages/core/paper/paper-npm-bootstrap.js +0 -492
|
@@ -116,10 +116,10 @@ export function checkFloatingConsumerPolicyContract() {
|
|
|
116
116
|
assertOrdered("actions/publication/candidate/plan/action.yml", [
|
|
117
117
|
"Admit source checkout", "Enforce v4 floating consumer policy", "Resolve controller identities",
|
|
118
118
|
]);
|
|
119
|
-
const publication = YAML.parse(read(".github/workflows
|
|
119
|
+
const publication = YAML.parse(read(".github/workflows/.build-publication.yml"));
|
|
120
120
|
if (!Object.values(publication.jobs).some((job) => job.steps?.some((step) => step.uses?.endsWith("/actions/publication/candidate/plan"))))
|
|
121
121
|
fail("publication does not invoke its consumer policy node");
|
|
122
|
-
const stageCanary = read(".github/workflows
|
|
122
|
+
const stageCanary = read(".github/workflows/.build-stage-capsule-canary.yml");
|
|
123
123
|
if (
|
|
124
124
|
!stageCanary.includes("consumer-admission:") ||
|
|
125
125
|
!jobDependsOn(stageCanary, "qualify", "consumer-admission")
|
|
@@ -128,7 +128,7 @@ export function checkFloatingConsumerPolicyContract() {
|
|
|
128
128
|
"Stage Capsule qualification is not transitively gated by consumer admission",
|
|
129
129
|
);
|
|
130
130
|
}
|
|
131
|
-
const promotion = read(".github/workflows
|
|
131
|
+
const promotion = read(".github/workflows/.release-candidate-promote.yml");
|
|
132
132
|
if (
|
|
133
133
|
!promotion.includes("consumer-admission:") ||
|
|
134
134
|
!jobDependsOn(promotion, "invoke", "consumer-admission")
|
|
@@ -146,23 +146,23 @@ const requiredPaths = [
|
|
|
146
146
|
".buildchain/alpha-contract-lock.json",
|
|
147
147
|
".buildchain/release-impact.json",
|
|
148
148
|
".github/actionlint.yaml",
|
|
149
|
-
".github/workflows
|
|
150
|
-
".github/workflows
|
|
151
|
-
".github/workflows
|
|
152
|
-
".github/workflows
|
|
153
|
-
".github/workflows
|
|
154
|
-
".github/workflows
|
|
155
|
-
".github/workflows
|
|
156
|
-
".github/workflows
|
|
149
|
+
".github/workflows/.ops-release-governance.yml",
|
|
150
|
+
".github/workflows/.ops-dev-auto-merge.yml",
|
|
151
|
+
".github/workflows/.ops-patrol.yml",
|
|
152
|
+
".github/workflows/.ops-patrol-daily.yml",
|
|
153
|
+
".github/workflows/.ops-patrol-weekly.yml",
|
|
154
|
+
".github/workflows/.ops-patrol-monthly.yml",
|
|
155
|
+
".github/workflows/.ops-observed-evidence.yml",
|
|
156
|
+
".github/workflows/.release-candidate-promote.yml",
|
|
157
157
|
".github/workflows/.release-promote.yml",
|
|
158
|
-
".github/workflows
|
|
159
|
-
".github/workflows
|
|
158
|
+
".github/workflows/.release-propagation.yml",
|
|
159
|
+
".github/workflows/.release-paper.yml",
|
|
160
160
|
".github/workflows/.release-binary-assets.yml",
|
|
161
161
|
".github/workflows/.build.yml",
|
|
162
162
|
".github/workflows/.build-gate-profile.yml",
|
|
163
163
|
".github/workflows/.build-demo-adapter.yml",
|
|
164
|
-
".github/workflows
|
|
165
|
-
".github/workflows
|
|
164
|
+
".github/workflows/.build-demo.yml",
|
|
165
|
+
".github/workflows/.build-candidate.yml",
|
|
166
166
|
"fixtures/libnode-shaped/buildchain.toml",
|
|
167
167
|
"fixtures/libnode-shaped/.github/workflows/build.yml",
|
|
168
168
|
"fixtures/libnode-shaped/package.json",
|
|
@@ -281,7 +281,7 @@ for (const requiredSnippet of [
|
|
|
281
281
|
}
|
|
282
282
|
}
|
|
283
283
|
const channelBuildWorkflow = fs.readFileSync(
|
|
284
|
-
path.join(root, ".github/workflows
|
|
284
|
+
path.join(root, ".github/workflows/.build-candidate.yml"),
|
|
285
285
|
"utf8",
|
|
286
286
|
);
|
|
287
287
|
const advancedPromotionWorkflow = fs.readFileSync(
|
|
@@ -289,7 +289,7 @@ const advancedPromotionWorkflow = fs.readFileSync(
|
|
|
289
289
|
"utf8",
|
|
290
290
|
);
|
|
291
291
|
const channelPromotionWorkflow = fs.readFileSync(
|
|
292
|
-
path.join(root, ".github/workflows
|
|
292
|
+
path.join(root, ".github/workflows/.release-candidate-promote.yml"),
|
|
293
293
|
"utf8",
|
|
294
294
|
);
|
|
295
295
|
assertPromotionInventory(root);
|
|
@@ -306,7 +306,7 @@ const actionlintConfig = fs.readFileSync(
|
|
|
306
306
|
"utf8",
|
|
307
307
|
);
|
|
308
308
|
for (const requiredSnippet of [
|
|
309
|
-
".github/workflows
|
|
309
|
+
".github/workflows/.build-candidate.yml:",
|
|
310
310
|
".github/workflows/.build.yml:",
|
|
311
311
|
".github/workflows/.build-gate-profile.yml:",
|
|
312
312
|
'property "workflow_ref" is not defined in object type',
|
|
@@ -859,25 +859,25 @@ for (const requiredSnippet of [
|
|
|
859
859
|
}
|
|
860
860
|
const reusableBuildSurfaceDoc = fs.readFileSync(path.join(root, "docs/reusable-build-surface.md"), "utf8");
|
|
861
861
|
for (const requiredSnippet of [
|
|
862
|
-
"
|
|
863
|
-
"
|
|
864
|
-
"
|
|
865
|
-
"
|
|
866
|
-
"
|
|
867
|
-
"
|
|
868
|
-
"
|
|
869
|
-
"
|
|
870
|
-
"
|
|
871
|
-
"
|
|
862
|
+
".buildchain/buildchain.toml",
|
|
863
|
+
"schema = 2",
|
|
864
|
+
"[[products]]",
|
|
865
|
+
"public-ops-pipeline.yml@v4",
|
|
866
|
+
"public-ops-recover.yml@v4",
|
|
867
|
+
"Without a lock",
|
|
868
|
+
"exact Git commit, tree and TOML blob",
|
|
869
|
+
"without provider credentials",
|
|
870
|
+
"original attempt",
|
|
871
|
+
"Consumers do not call",
|
|
872
872
|
]) {
|
|
873
873
|
if (!reusableBuildSurfaceDoc.includes(requiredSnippet)) {
|
|
874
|
-
throw new Error(`
|
|
874
|
+
throw new Error(`consumer build surface doc missing schema-2 contract snippet: ${requiredSnippet}`);
|
|
875
875
|
}
|
|
876
876
|
}
|
|
877
877
|
for (const [docName, docSource] of Object.entries({ "docs/cli.md": cliDoc, "docs/install.md": installDoc })) {
|
|
878
878
|
for (const requiredSnippet of [
|
|
879
879
|
"minimumReleaseAgeExclude",
|
|
880
|
-
"@kungfu-tech/buildchain@4.
|
|
880
|
+
"@kungfu-tech/buildchain@4.1.3",
|
|
881
881
|
"package/version-specific",
|
|
882
882
|
]) {
|
|
883
883
|
if (!docSource.includes(requiredSnippet)) {
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import fs from "node:fs";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
projectRenamedMetrics,
|
|
6
|
+
projectWorkflowMetrics,
|
|
7
|
+
} from "./source-metric-lineage.mjs";
|
|
8
|
+
import {
|
|
9
|
+
workflowPath,
|
|
10
|
+
TAXONOMY_PATH,
|
|
11
|
+
} from "../packages/core/workflow/workflow-taxonomy.mjs";
|
|
5
12
|
import path from "node:path";
|
|
6
13
|
import { execFileSync } from "node:child_process";
|
|
7
14
|
import { pathToFileURL } from "node:url";
|
|
@@ -417,10 +424,25 @@ function checkMaintainability({ root = process.cwd() } = {}) {
|
|
|
417
424
|
if (file.endsWith(".rs")) baselineFiles[file] = metrics;
|
|
418
425
|
}
|
|
419
426
|
const baselineTests = testMetricsAtRevision(root, extendedCoverageRevision);
|
|
420
|
-
const
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
427
|
+
const taxonomyCoordinates = (policy) =>
|
|
428
|
+
policy.entries.map((entry) => ({
|
|
429
|
+
id: entry.id,
|
|
430
|
+
path: workflowPath(entry),
|
|
431
|
+
}));
|
|
432
|
+
const workflowLineage = projectWorkflowMetrics({
|
|
433
|
+
before: taxonomyCoordinates(
|
|
434
|
+
JSON.parse(
|
|
435
|
+
gitOutput(root, [
|
|
436
|
+
"show",
|
|
437
|
+
`${extendedCoverageRevision}:${TAXONOMY_PATH}`,
|
|
438
|
+
]),
|
|
439
|
+
),
|
|
440
|
+
),
|
|
441
|
+
after: taxonomyCoordinates(readJson(root, TAXONOMY_PATH)),
|
|
442
|
+
metrics: workflowMetricsAtRevision(root, extendedCoverageRevision),
|
|
443
|
+
currentPaths: new Set(Object.keys(current.workflows)),
|
|
444
|
+
});
|
|
445
|
+
const baselineWorkflows = workflowLineage.metrics;
|
|
424
446
|
const issues = evaluateExceptionGovernance({ policy });
|
|
425
447
|
issues.push(...evaluateExceptionBudget({ policy }));
|
|
426
448
|
const hotspots = collectHotspots(root, current, 20, debt.hotspots || []);
|
|
@@ -469,6 +491,7 @@ function checkMaintainability({ root = process.cwd() } = {}) {
|
|
|
469
491
|
trackedFiles: current.repository.trackedFiles,
|
|
470
492
|
sourceFiles: current.repository.handMaintainedSourceFiles,
|
|
471
493
|
measurementRenames: lineage.renames,
|
|
494
|
+
workflowMeasurementRenames: workflowLineage.renames,
|
|
472
495
|
publicSurface: current.publicSurface,
|
|
473
496
|
hotspots: current.hotspots,
|
|
474
497
|
governedDebtSurfaces: Object.values(debt.surfaces).reduce(
|
|
@@ -11,7 +11,7 @@ const DEFAULT_ROOT = path.resolve(
|
|
|
11
11
|
"..",
|
|
12
12
|
);
|
|
13
13
|
const CALLER_PATH = ".github/workflows/self-build-public-consumer-dogfood.yml";
|
|
14
|
-
const REUSABLE_PATH = ".github/workflows
|
|
14
|
+
const REUSABLE_PATH = ".github/workflows/.build-stage-capsule-canary.yml";
|
|
15
15
|
export const PUBLIC_DOGFOOD_ENTRY_REF = "v4";
|
|
16
16
|
const PRIVATE_CONSUMER = ["buildchain", "self", "dogfood"].join("-");
|
|
17
17
|
const PRIVATE_SHADOW = ["kungfu", "shadow"].join("-");
|
|
@@ -201,7 +201,7 @@ function assertWorkflowInventory(root) {
|
|
|
201
201
|
fail(`${relative} invokes the private qualification script directly`);
|
|
202
202
|
if (
|
|
203
203
|
relative !== CALLER_PATH &&
|
|
204
|
-
text.includes(".github/workflows
|
|
204
|
+
text.includes(".github/workflows/.build-stage-capsule-canary.yml@")
|
|
205
205
|
)
|
|
206
206
|
fail(`${relative} creates a second v4 dogfood caller`);
|
|
207
207
|
if (relative !== REUSABLE_PATH && relative !== CALLER_PATH)
|
|
@@ -275,7 +275,7 @@ function assertArchitecture(root) {
|
|
|
275
275
|
!dogfood ||
|
|
276
276
|
dogfood.callerWorkflow !== CALLER_PATH ||
|
|
277
277
|
dogfood.reusableWorkflow !==
|
|
278
|
-
"kungfu-systems/buildchain/.github/workflows
|
|
278
|
+
"kungfu-systems/buildchain/.github/workflows/.build-stage-capsule-canary.yml" ||
|
|
279
279
|
dogfood.runtimeBinding !== "entry-selected-runtime" ||
|
|
280
280
|
dogfood.consumerSourceBinding !== "github.sha" ||
|
|
281
281
|
JSON.stringify(dogfood.executableStages) !==
|
|
@@ -532,7 +532,7 @@ export function checkReleaseTopology() {
|
|
|
532
532
|
assertPipelinePublicationTopology(ledger, discoverReleaseTopology, root);
|
|
533
533
|
const preview = ledger.postPublicationScope;
|
|
534
534
|
assert.deepEqual(preview.workflowPaths, [
|
|
535
|
-
".github/workflows
|
|
535
|
+
".github/workflows/.release-oci-compose-preview.yml",
|
|
536
536
|
]);
|
|
537
537
|
const previewTopology = discoverReleaseTopology(
|
|
538
538
|
preview.workflowPaths,
|
|
@@ -2,12 +2,11 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { parse as yaml } from "yaml";
|
|
5
|
-
import
|
|
5
|
+
import * as consumerPlan from "../packages/core/consumer/contract/plan.js";
|
|
6
6
|
import { consumerWorkflows } from "../packages/core/consumer/contract/entries.js";
|
|
7
7
|
import { workflowPath } from "../packages/core/workflow/workflow-taxonomy.mjs";
|
|
8
8
|
|
|
9
|
-
export const SELF_ENTRY_CHANNEL = "v4
|
|
10
|
-
export const SELF_CONFIG_PATH = ".buildchain/minimal-consumer.toml";
|
|
9
|
+
export const SELF_ENTRY_CHANNEL = "v4";
|
|
11
10
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
12
11
|
const PLATFORMS = ["linux-x64", "macos-arm64", "windows-x64"];
|
|
13
12
|
|
|
@@ -19,10 +18,11 @@ export function checkSelfConsumerContract(root = ROOT) {
|
|
|
19
18
|
const fail = (message) => {
|
|
20
19
|
throw new Error(`self-consumer-contract: ${message}`);
|
|
21
20
|
};
|
|
22
|
-
const plan = compileConsumerPlan(read(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
const plan = consumerPlan.compileConsumerPlan(read(consumerPlan.CONFIG_PATH));
|
|
22
|
+
const retired = path.join(root, ".buildchain/minimal-consumer.toml");
|
|
23
|
+
if (fs.lstatSync(retired, { throwIfNoEntry: false }))
|
|
24
|
+
fail("retired transition config must not remain in the self consumer tree");
|
|
25
|
+
const callers = consumerWorkflows();
|
|
26
26
|
for (const [file, bytes] of Object.entries(callers))
|
|
27
27
|
if (read(file) !== bytes) fail(`${file}: generated caller drift`);
|
|
28
28
|
const taxonomy = JSON.parse(read("architecture/workflow-taxonomy.json"));
|
|
@@ -41,7 +41,7 @@ assert.equal(executor.with["mutation-token"], "${{ inputs.secrets-buildchain-pro
|
|
|
41
41
|
assert.equal(executor.with.token, "${{ github.token }}");
|
|
42
42
|
assert.doesNotMatch(read(contract.bootstrap.publicWorkflow), /admission-policy-json:/u);
|
|
43
43
|
const template = parse(contract.bootstrap.consumerTemplate);
|
|
44
|
-
assert.equal(template.jobs.bootstrap.uses, "kungfu-systems/buildchain/.github/workflows
|
|
44
|
+
assert.equal(template.jobs.bootstrap.uses, "kungfu-systems/buildchain/.github/workflows/.ops-bootstrap.yml@v4");
|
|
45
45
|
assert.equal(template.jobs.bootstrap.with["runtime-ref"], "${{ inputs.runtime-ref }}");
|
|
46
46
|
assert.equal(contract.bootstrap.selfDogfoodActive, false);
|
|
47
47
|
assert.equal(fs.existsSync(path.join(root, contract.bootstrap.selfDogfoodWorkflow)), false,
|
|
@@ -41,4 +41,4 @@ export function generateChannelPromotionWorkflow(source) {
|
|
|
41
41
|
}, { lineWidth: 0, aliasDuplicateObjects: false });
|
|
42
42
|
}
|
|
43
43
|
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url))
|
|
44
|
-
writeWorkflowSource(root, ".github/workflows
|
|
44
|
+
writeWorkflowSource(root, ".github/workflows/.release-candidate-promote.yml", generateChannelPromotionWorkflow(fs.readFileSync(path.join(root, ".github/workflows/.release-promote.yml"), "utf8")));
|
|
@@ -5,6 +5,7 @@ import { parse as yaml } from "yaml";
|
|
|
5
5
|
import { format } from "prettier";
|
|
6
6
|
import { standardConsumerExample } from "../packages/core/consumer/contract/examples.js";
|
|
7
7
|
import { inspectConsumerContract } from "../packages/core/consumer/contract/inspection.js";
|
|
8
|
+
import { validateConsumerWiring } from "../packages/core/consumer/contract/local-validation.js";
|
|
8
9
|
import { workflowPath } from "../packages/core/workflow/workflow-taxonomy.mjs";
|
|
9
10
|
|
|
10
11
|
const root = process.cwd(),
|
|
@@ -13,6 +14,25 @@ const tracked = execFileSync("git", ["ls-files", "-z"], { encoding: "utf8" })
|
|
|
13
14
|
.split("\0")
|
|
14
15
|
.filter(Boolean);
|
|
15
16
|
|
|
17
|
+
if (check) {
|
|
18
|
+
const files = Object.create(null);
|
|
19
|
+
for (const file of tracked)
|
|
20
|
+
Object.defineProperty(files, file, {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: () => fs.readFileSync(path.join(root, file), "utf8"),
|
|
23
|
+
});
|
|
24
|
+
const { channel } = validateConsumerWiring(root);
|
|
25
|
+
const inspection = inspectConsumerContract(files, { channel });
|
|
26
|
+
if (inspection.controlIssues.length)
|
|
27
|
+
throw new Error(inspection.controlIssues.join("\n"));
|
|
28
|
+
const unresolved = inspection.commandClosures.filter(
|
|
29
|
+
(closure) => !closure.commandEdgesResolved,
|
|
30
|
+
).length;
|
|
31
|
+
console.log(
|
|
32
|
+
`Self control wiring verified; ${unresolved} product graphs remain unresolved and require read-only runtime execution.`,
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
16
36
|
function output(file, value) {
|
|
17
37
|
const target = path.join(root, file);
|
|
18
38
|
if (check) {
|
|
@@ -143,7 +163,7 @@ output(
|
|
|
143
163
|
await format(
|
|
144
164
|
JSON.stringify({
|
|
145
165
|
schema: "buildchain.consumer-migration/v1",
|
|
146
|
-
stage: "self-
|
|
166
|
+
stage: "self-default-entry; final-release-qualification-pending",
|
|
147
167
|
workflows: workflowInventory(),
|
|
148
168
|
consumerSources: consumerSourceInventory(),
|
|
149
169
|
}),
|
|
@@ -887,8 +887,9 @@ function buildSiteBundle() {
|
|
|
887
887
|
["self-hosted-runner-smoke", "compatibility-fixture"],
|
|
888
888
|
]);
|
|
889
889
|
const engineeringHousekeeper = semanticId.startsWith("engineering-housekeeper");
|
|
890
|
+
if (classification?.role === "component") statusById.set(semanticId, "repository-internal");
|
|
890
891
|
return {
|
|
891
|
-
...entry,
|
|
892
|
+
...entry, apiRole: classification?.role === "public" ? "public" : "implementation",
|
|
892
893
|
...(classification ? { taxonomy: { id: classification.id, role: classification.role, category: classification.category, purpose: classification.purpose, status: classification.status, canonicalPath: workflowPath(classification), ...(classification.role === "self" && classification.migration ? { contractPath: classification.migration.previousPath } : {}), compatibilityAlias: entry.path !== workflowPath(classification) } } : {}),
|
|
893
894
|
surface: surfaceById.get(semanticId) || (entry.path.includes("/.") ? "reusable-workflow" : "repository-workflow"),
|
|
894
895
|
capabilityGroup: workflowCapabilityGroup({
|
|
@@ -19,8 +19,8 @@ export function tailResealFixturePolicyReceipt(fixture, policy) {
|
|
|
19
19
|
try {
|
|
20
20
|
fs.mkdirSync(path.join(root, ".github/workflows"), { recursive: true });
|
|
21
21
|
fs.writeFileSync(
|
|
22
|
-
path.join(root, ".github/workflows
|
|
23
|
-
"jobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows
|
|
22
|
+
path.join(root, ".github/workflows/.build-candidate.yml"),
|
|
23
|
+
"jobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build-stage-capsule-canary.yml@v4-alpha\n",
|
|
24
24
|
);
|
|
25
25
|
fs.mkdirSync(path.join(root, ".buildchain"), { recursive: true });
|
|
26
26
|
for (const [file, ref, resolvedSha] of [
|
|
@@ -51,7 +51,7 @@ export function tailResealFixturePolicyReceipt(fixture, policy) {
|
|
|
51
51
|
root,
|
|
52
52
|
repository: fixture.repository,
|
|
53
53
|
sourceSha: fixture.source.sha,
|
|
54
|
-
invokedWorkflow: "
|
|
54
|
+
invokedWorkflow: ".build-stage-capsule-canary.yml",
|
|
55
55
|
expectedInvocationChannel: "alpha",
|
|
56
56
|
resolvedRuntimeSha: fixture.runtime.sha,
|
|
57
57
|
policy,
|
|
@@ -8,7 +8,7 @@ import { generateChannelPromotionWorkflow } from "../generate-channel-promotion-
|
|
|
8
8
|
|
|
9
9
|
export function assertPromotionInventory(root) {
|
|
10
10
|
const read = (file) => fs.readFileSync(path.join(root, file), "utf8");
|
|
11
|
-
const publicPath = ".github/workflows
|
|
11
|
+
const publicPath = ".github/workflows/.release-candidate-promote.yml";
|
|
12
12
|
const api = YAML.parse(read(publicPath));
|
|
13
13
|
assert.equal(
|
|
14
14
|
read(publicPath),
|
|
@@ -164,7 +164,7 @@ export function validateSelfDogfoodRoute(route) {
|
|
|
164
164
|
targetRepository !== "kungfu-systems/buildchain" ||
|
|
165
165
|
route.runtimeRef !== "v4-alpha" ||
|
|
166
166
|
route.publicWorkflow !==
|
|
167
|
-
`${targetRepository}/.github/workflows
|
|
167
|
+
`${targetRepository}/.github/workflows/.build-candidate.yml@v4-alpha` ||
|
|
168
168
|
route.protectedDevBranch !== PROTECTED_DEV_BRANCH ||
|
|
169
169
|
JSON.stringify(route.hostedReadbackPaths) !==
|
|
170
170
|
JSON.stringify(HOSTED_READBACK_PATHS)
|
|
@@ -66,7 +66,7 @@ export function validateSelfDogfoodCheckpoint(checkpoint) {
|
|
|
66
66
|
if (
|
|
67
67
|
checkpoint.route.runtimeRef !== "v4-alpha" ||
|
|
68
68
|
checkpoint.route.publicWorkflow !==
|
|
69
|
-
`${targetRepository}/.github/workflows
|
|
69
|
+
`${targetRepository}/.github/workflows/.build-candidate.yml@v4-alpha` ||
|
|
70
70
|
targetRepository !== "kungfu-systems/buildchain"
|
|
71
71
|
) {
|
|
72
72
|
throw new Error("checkpoint requires the public owner/repo v4-alpha route");
|
|
@@ -122,7 +122,7 @@ export async function createSelfDogfoodCheckpoint({
|
|
|
122
122
|
const routeRepository = repository(targetRepository);
|
|
123
123
|
const route = {
|
|
124
124
|
repository: routeRepository,
|
|
125
|
-
publicWorkflow: `${routeRepository}/.github/workflows
|
|
125
|
+
publicWorkflow: `${routeRepository}/.github/workflows/.build-candidate.yml@v4-alpha`,
|
|
126
126
|
runtimeRef: required(runtimeRef, "runtimeRef"),
|
|
127
127
|
runtimeSha: exactSha(runtimeSha, "runtimeSha"),
|
|
128
128
|
contractRoot: exactRoot(contractRoot, "contractRoot"),
|
|
@@ -239,7 +239,7 @@ export function validateSelfDogfoodEvidence(evidence) {
|
|
|
239
239
|
validateAdapterEvidence(evidence.adapter, semver, anchored);
|
|
240
240
|
if (
|
|
241
241
|
evidence.adoption?.coordinate !==
|
|
242
|
-
"kungfu-systems/buildchain/.github/workflows
|
|
242
|
+
"kungfu-systems/buildchain/.github/workflows/.build-candidate.yml@v4" ||
|
|
243
243
|
evidence.adoption?.exactShaProductionPin !== false
|
|
244
244
|
) {
|
|
245
245
|
throw new Error("Kungfu adoption must use the floating v4 coordinate");
|
|
@@ -367,7 +367,7 @@ export async function resumeSelfDogfoodCheckpoint(
|
|
|
367
367
|
},
|
|
368
368
|
},
|
|
369
369
|
adoption: {
|
|
370
|
-
coordinate: "kungfu-systems/buildchain/.github/workflows
|
|
370
|
+
coordinate: "kungfu-systems/buildchain/.github/workflows/.build-candidate.yml@v4",
|
|
371
371
|
runtimeRef: "v4",
|
|
372
372
|
exactShaProductionPin: false,
|
|
373
373
|
},
|
|
@@ -134,14 +134,10 @@ export function cliCommandMeta(id) {
|
|
|
134
134
|
"npm-dry-run": { group: "release-passport-trust", purpose: "Verify npm publish shape before a release transaction." },
|
|
135
135
|
paper: { group: "reusable-build", purpose: "Inspect the unified paper repository and publication command families." },
|
|
136
136
|
"paper-agent": { group: "getting-started", purpose: "Verify the mandatory managed Paper agent entry contract on an existing work branch." },
|
|
137
|
-
"paper-
|
|
138
|
-
"paper-bootstrap-npm": { group: "release-passport-trust", purpose: "Dry-run or explicitly bootstrap the public npm package and bind GitHub Trusted Publishing." },
|
|
139
|
-
"paper-build": { group: "reusable-build", purpose: "Plan or execute the existing two-clean-build reproducibility gate for a paper." },
|
|
140
|
-
"paper-fleet-audit": { group: "governance-versioning", purpose: "Discover Paper repositories and emit one deterministic v3 dependency, control-surface, and governance audit." },
|
|
137
|
+
"paper-fleet-audit": { group: "governance-versioning", purpose: "Discover Paper repositories and audit current consumer configuration, dependencies, and governance." },
|
|
141
138
|
"paper-fleet-update": { group: "governance-versioning", purpose: "Plan or write a bounded v3 migration across isolated Paper work branches." },
|
|
142
139
|
"paper-migrate": { group: "getting-started", purpose: "Plan or write the bounded Buildchain-owned control-file migration for an existing paper repository." },
|
|
143
|
-
"paper-preflight": { group: "reusable-build", purpose: "
|
|
144
|
-
"paper-resume": { group: "release-passport-trust", purpose: "Plan or dispatch recovery of the exact existing sealed paper release transaction." },
|
|
140
|
+
"paper-preflight": { group: "reusable-build", purpose: "Validate the schema-2 consumer configuration and inspect retained legacy evidence without inferring hosted publication." },
|
|
145
141
|
"paper-scaffold": { group: "getting-started", purpose: "Plan or write an idempotent, no-overwrite, release-ready paper repository scaffold." },
|
|
146
142
|
"paper-status": { group: "reusable-build", purpose: "Report explicit evidence for every paper lifecycle state without unsupported inference." },
|
|
147
143
|
"paper-work-start": { group: "getting-started", purpose: "Create a safe Paper work branch from the exact canonical remote development SHA." },
|
|
@@ -1,17 +1,72 @@
|
|
|
1
|
-
import { execFileSync } from
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
2
|
|
|
3
3
|
// Measurement identity follows Git's observed renames. This does not resolve a
|
|
4
4
|
// runtime path or keep a removed entrypoint callable.
|
|
5
|
-
export function projectRenamedMetrics({
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
export function projectRenamedMetrics({
|
|
6
|
+
root,
|
|
7
|
+
revision,
|
|
8
|
+
metrics,
|
|
9
|
+
currentPaths,
|
|
10
|
+
}) {
|
|
11
|
+
const records = execFileSync(
|
|
12
|
+
"git",
|
|
13
|
+
[
|
|
14
|
+
"diff",
|
|
15
|
+
"--name-status",
|
|
16
|
+
"-z",
|
|
17
|
+
"--find-renames=50%",
|
|
18
|
+
"--diff-filter=R",
|
|
19
|
+
revision,
|
|
20
|
+
],
|
|
21
|
+
{ cwd: root, encoding: "utf8", maxBuffer: 16 * 1024 * 1024 },
|
|
22
|
+
).split("\0");
|
|
23
|
+
const projected = { ...metrics },
|
|
24
|
+
renames = [];
|
|
9
25
|
for (let index = 0; index < records.length && records[index]; index += 3) {
|
|
10
26
|
const [status, source, target] = records.slice(index, index + 3);
|
|
11
|
-
if (!/^R\d+$/.test(status) || !source || !target)
|
|
12
|
-
|
|
27
|
+
if (!/^R\d+$/.test(status) || !source || !target)
|
|
28
|
+
throw Error("Invalid Git metric lineage");
|
|
29
|
+
if (!metrics[source] || metrics[target] || !currentPaths.has(target))
|
|
30
|
+
continue;
|
|
13
31
|
projected[target] = { ...metrics[source], file: target };
|
|
14
32
|
renames.push({ source, target, similarity: Number(status.slice(1)) });
|
|
15
33
|
}
|
|
16
34
|
return { metrics: projected, renames };
|
|
17
35
|
}
|
|
36
|
+
|
|
37
|
+
// Workflow taxonomy IDs survive role/path changes and are available at both
|
|
38
|
+
// exact cuts even in a shallow checkout. Preserve their original measured budget.
|
|
39
|
+
export function projectWorkflowMetrics({
|
|
40
|
+
metrics,
|
|
41
|
+
before,
|
|
42
|
+
after,
|
|
43
|
+
currentPaths,
|
|
44
|
+
}) {
|
|
45
|
+
for (const entries of [before, after])
|
|
46
|
+
for (const key of ["id", "path"])
|
|
47
|
+
if (
|
|
48
|
+
new Set(entries.map((entry) => entry[key])).size !== entries.length ||
|
|
49
|
+
entries.some((entry) => typeof entry[key] !== "string" || !entry[key])
|
|
50
|
+
)
|
|
51
|
+
throw Error(
|
|
52
|
+
"Workflow measurement identities must be unique and explicit",
|
|
53
|
+
);
|
|
54
|
+
const originals = new Map(before.map((entry) => [entry.id, entry.path]));
|
|
55
|
+
const projected = { ...metrics },
|
|
56
|
+
renames = [];
|
|
57
|
+
for (const { id, path: target } of after) {
|
|
58
|
+
const source = originals.get(id);
|
|
59
|
+
if (
|
|
60
|
+
!source ||
|
|
61
|
+
source === target ||
|
|
62
|
+
!metrics[source] ||
|
|
63
|
+
metrics[target] ||
|
|
64
|
+
!currentPaths.has(target) ||
|
|
65
|
+
currentPaths.has(source)
|
|
66
|
+
)
|
|
67
|
+
continue;
|
|
68
|
+
projected[target] = { ...metrics[source], file: target };
|
|
69
|
+
renames.push({ id, source, target });
|
|
70
|
+
}
|
|
71
|
+
return { metrics: projected, renames };
|
|
72
|
+
}
|
|
@@ -56,7 +56,12 @@ export function verifyGoldenPath() {
|
|
|
56
56
|
name: "buildchain-golden-path-consumer",
|
|
57
57
|
version: "0.1.0",
|
|
58
58
|
private: true,
|
|
59
|
-
scripts: {
|
|
59
|
+
scripts: {
|
|
60
|
+
build:
|
|
61
|
+
"node -e \"require('fs').mkdirSync('dist',{recursive:true});require('fs').writeFileSync('dist/index.js','export const value = 1;')\"",
|
|
62
|
+
check:
|
|
63
|
+
"node -e \"require('assert').ok(require('fs').statSync('dist/index.js').size > 0)\"",
|
|
64
|
+
},
|
|
60
65
|
},
|
|
61
66
|
null,
|
|
62
67
|
2,
|
|
@@ -88,34 +93,19 @@ export function verifyGoldenPath() {
|
|
|
88
93
|
{ cwd: consumer, json: true },
|
|
89
94
|
);
|
|
90
95
|
const workflow = fs.readFileSync(
|
|
91
|
-
path.join(consumer, ".github", "workflows", "
|
|
96
|
+
path.join(consumer, ".github", "workflows", "buildchain.yml"),
|
|
92
97
|
"utf8",
|
|
93
98
|
);
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
);
|
|
105
|
-
fs.mkdirSync(path.dirname(passportPath), { recursive: true });
|
|
106
|
-
run(
|
|
107
|
-
process.execPath,
|
|
108
|
-
[
|
|
109
|
-
"--input-type=module",
|
|
110
|
-
"--eval",
|
|
111
|
-
`import fs from "node:fs"; import { createReleasePassport } from "@kungfu-tech/buildchain"; const value=createReleasePassport({repository:"example/consumer",tag:"v0.1.0-alpha.0",sourceSha:"a".repeat(40),assets:[{name:"consumer.tgz",sha256:"b".repeat(64)}]}); fs.writeFileSync(${JSON.stringify(passportPath)}, JSON.stringify(value,null,2)+"\\n");`,
|
|
112
|
-
],
|
|
113
|
-
{ cwd: consumer },
|
|
114
|
-
);
|
|
115
|
-
const inspection = run(
|
|
116
|
-
buildchain,
|
|
117
|
-
["inspect", "release", "--passport", passportPath, "--json"],
|
|
118
|
-
{ cwd: consumer, json: true },
|
|
99
|
+
run("git", ["init", "-q"], { cwd: consumer });
|
|
100
|
+
const doctor = run(buildchain, ["doctor", "--json"], {
|
|
101
|
+
cwd: consumer,
|
|
102
|
+
json: true,
|
|
103
|
+
});
|
|
104
|
+
run("npm", ["run", "build"], { cwd: consumer });
|
|
105
|
+
run("npm", ["run", "check"], { cwd: consumer });
|
|
106
|
+
const recovery = fs.readFileSync(
|
|
107
|
+
path.join(consumer, ".github/workflows/buildchain-recover.yml"),
|
|
108
|
+
"utf8",
|
|
119
109
|
);
|
|
120
110
|
|
|
121
111
|
assert(
|
|
@@ -133,7 +123,7 @@ export function verifyGoldenPath() {
|
|
|
133
123
|
"Golden Path validation did not retain the required lifecycle stages",
|
|
134
124
|
);
|
|
135
125
|
assert(
|
|
136
|
-
/uses:\s+kungfu-systems\/buildchain\/\.github\/workflows\/
|
|
126
|
+
/uses:\s+kungfu-systems\/buildchain\/\.github\/workflows\/public-ops-pipeline\.yml@v4/.test(
|
|
137
127
|
workflow,
|
|
138
128
|
),
|
|
139
129
|
"Golden Path workflow is not a thin v4 reusable-workflow caller",
|
|
@@ -142,13 +132,18 @@ export function verifyGoldenPath() {
|
|
|
142
132
|
!/\n\s+(?:inputs|with|steps):/.test(workflow),
|
|
143
133
|
"Golden Path ordinary caller must have zero inputs and delegate its steps",
|
|
144
134
|
);
|
|
135
|
+
assert(doctor.ok, "Golden Path doctor rejected the initialized consumer");
|
|
136
|
+
assert(
|
|
137
|
+
validation.config.schema === 2 && validation.products[0].type === "npm",
|
|
138
|
+
"Golden Path did not validate the schema-2 product",
|
|
139
|
+
);
|
|
145
140
|
assert(
|
|
146
|
-
|
|
147
|
-
"Golden Path
|
|
141
|
+
/public-ops-recover\.yml@v4/.test(recovery),
|
|
142
|
+
"Golden Path recovery entry is not the shared caller",
|
|
148
143
|
);
|
|
149
144
|
assert(
|
|
150
|
-
|
|
151
|
-
"Golden Path
|
|
145
|
+
Object.keys(validation.consumer || {}).length > 0,
|
|
146
|
+
"Golden Path validation did not inspect caller wiring",
|
|
152
147
|
);
|
|
153
148
|
return {
|
|
154
149
|
contract: "kungfu-buildchain-golden-path-verification/v1",
|
|
@@ -156,9 +151,10 @@ export function verifyGoldenPath() {
|
|
|
156
151
|
version,
|
|
157
152
|
projectType: initialized.type,
|
|
158
153
|
validationPath: validation.config?.path,
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
154
|
+
reusableWorkflows: validation.consumer.workflows,
|
|
155
|
+
productBuildAndVerification: true,
|
|
156
|
+
doctor: doctor.ok,
|
|
157
|
+
providerEffects: false,
|
|
162
158
|
};
|
|
163
159
|
} finally {
|
|
164
160
|
fs.rmSync(temporary, { recursive: true, force: true });
|
|
@@ -93,7 +93,7 @@ permissions:
|
|
|
93
93
|
statuses: write
|
|
94
94
|
jobs:
|
|
95
95
|
deliver:
|
|
96
|
-
uses: kungfu-systems/buildchain/.github/workflows
|
|
96
|
+
uses: kungfu-systems/buildchain/.github/workflows/.ops-dev-auto-merge.yml@v4-alpha
|
|
97
97
|
with:
|
|
98
98
|
runtime-ref: ${{ inputs.runtime-ref || '' }}
|
|
99
99
|
target-branch: ${{ github.event.client_payload.candidate.targetBranch || inputs.target-branch }}
|
|
@@ -30,7 +30,7 @@ permissions:
|
|
|
30
30
|
|
|
31
31
|
jobs:
|
|
32
32
|
bootstrap:
|
|
33
|
-
uses: kungfu-systems/buildchain/.github/workflows
|
|
33
|
+
uses: kungfu-systems/buildchain/.github/workflows/.ops-bootstrap.yml@v4
|
|
34
34
|
with:
|
|
35
35
|
request-json: ${{ inputs.request-json }}
|
|
36
36
|
runtime-ref: ${{ inputs.runtime-ref }}
|