@kungfu-tech/buildchain 3.0.9-alpha.8 → 4.0.0-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 +39 -0
- package/README.md +17 -13
- package/actions/promote-buildchain-ref/README.md +0 -10
- package/actions/release-tail/README.md +6 -10
- package/architecture/internal-capabilities.json +502 -0
- package/architecture/maintainability-baseline.json +59 -0
- package/architecture/maintainability-policy.json +1384 -0
- package/architecture/release-tail-contract-inventory.json +587 -0
- package/architecture/v3-core-mechanism-inventory.json +1043 -0
- package/architecture/v3-core-mechanism-inventory.md +67 -0
- package/architecture/v4-adopter-delivery-parity.json +47 -0
- package/architecture/v4-architecture-constitution.md +210 -0
- package/architecture/v4-bootstrap-authority.json +56 -0
- package/architecture/v4-canonical-contract-fixtures.json +105 -0
- package/architecture/v4-capability-state-machine-manifest.json +480 -0
- package/architecture/v4-capability-state-machine-manifest.schema.json +202 -0
- package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.json +830 -0
- package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.md +223 -0
- package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.schema.json +318 -0
- package/architecture/v4-delivery-warrant-shadow-fixtures.json +227 -0
- package/architecture/v4-delivery-warrant-shadow-fixtures.schema.json +67 -0
- package/architecture/v4-exception-ledger.json +5 -0
- package/architecture/v4-exception-ledger.schema.json +56 -0
- package/architecture/v4-partial-mutation-recovery-qualification.json +65 -0
- package/architecture/v4-platform-stage-checkpoints.json +97 -0
- package/architecture/v4-provider-operation-journal-contract.json +113 -0
- package/architecture/v4-release-activation-shadow-domain.json +61 -0
- package/architecture/v4-release-train-parity.json +68 -0
- package/architecture/v4-rust-libnode-bridge-evaluation.json +107 -0
- package/architecture/v4-rust-libnode-bridge-spike.md +85 -0
- package/architecture/v4-stable-publication-fence.json +66 -0
- package/architecture/v4-stage-capsule-contract.json +90 -0
- package/architecture/v4-stage-capsule-qualification.json +99 -0
- package/architecture/v4-stage-capsule-resume-planner.json +52 -0
- package/architecture/v4-stage-capsule-store-contract.json +72 -0
- package/bin/buildchain.mjs +15 -6
- package/contracts/auditable-demo-scenario-v1.schema.json +1 -1
- package/contracts/buildchain-v2-residuals-v1.json +2 -2
- package/contracts/fixtures/v4-delivery-warrant-trace-v1/golden.json +158 -0
- package/contracts/fixtures/v4-delivery-warrant-trace-v1/property.json +380 -0
- package/contracts/fixtures/v4-delivery-warrant-trace-v1/replay.json +163 -0
- package/contracts/fixtures/v4-partial-mutation-recovery-v1/shared.json +155 -0
- package/contracts/fixtures/v4-provider-operation-journal-v1/shared.json +457 -0
- package/contracts/fixtures/v4-provider-readback-idempotency-v1/shared.json +682 -0
- package/contracts/fixtures/v4-release-activation-shadow-v1/shared.json +53 -0
- package/contracts/fixtures/v4-stable-publication-fence-v1/shared.json +56 -0
- package/contracts/fixtures/v4-stage-capsule-resume-v1/late-platform-failure.json +176 -0
- package/contracts/fixtures/v4-stage-capsule-store-v1/shared.json +132 -0
- package/contracts/fixtures/v4-stage-capsule-v1/shared.json +111 -0
- package/contracts/v4-canonical-contracts-v1.schema.json +182 -0
- package/contracts/v4-delivery-warrant-semantic-diff-report-v1.schema.json +284 -0
- package/contracts/v4-delivery-warrant-trace-v1.schema.json +215 -0
- package/contracts/v4-host-contract-v1.schema.json +135 -0
- package/contracts/v4-partial-mutation-recovery-v1.schema.json +168 -0
- package/contracts/v4-provider-operation-journal-v1.schema.json +381 -0
- package/contracts/v4-release-activation-shadow-v1.schema.json +186 -0
- package/contracts/v4-stable-publication-fence-v1.schema.json +125 -0
- package/contracts/v4-stage-capsule-resume-v1.schema.json +225 -0
- package/contracts/v4-stage-capsule-store-v1.schema.json +154 -0
- package/contracts/v4-stage-capsule-v1.schema.json +178 -0
- package/crates/buildchain-v4-bridge/Cargo.lock +213 -0
- package/crates/buildchain-v4-bridge/Cargo.toml +12 -0
- package/crates/buildchain-v4-bridge/src/main.rs +495 -0
- package/dist/site/agent-index.json +0 -3
- package/dist/site/artifact-schemas.json +0 -6
- package/dist/site/buildchain-contract.json +103 -397
- package/dist/site/buildchain-site.json +302 -270
- package/dist/site/capability-registry.json +9 -11
- package/dist/site/cli-registry.json +8 -30
- package/dist/site/controller-registry.json +48 -8
- package/dist/site/kfd-claims.json +129 -142
- package/dist/site/kfd-upstream-aggregate.json +9 -9
- package/dist/site/manual-registry.json +18 -49
- package/dist/site/node-api-registry.json +1882 -4118
- package/dist/site/page-registry.json +278 -230
- package/dist/site/public-surface-audit.json +87 -185
- package/dist/site/publication-authority-registry.json +11 -1
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +3 -7
- package/dist/site/schemas/kfd-support-projection-v1.schema.json +106 -0
- package/dist/site/site-manifest.json +22 -38
- package/dist/site/workflow-registry.json +80 -35
- package/docs/MAP.md +8 -4
- package/docs/auditable-demo.md +2 -2
- package/docs/aws-us-elastic-runner-burst-plane.md +7 -59
- package/docs/cli-reference.md +15 -92
- package/docs/cli.md +14 -14
- package/docs/dev-alpha-candidate-patrol.md +3 -11
- package/docs/dev-delivery-warrant.md +28 -100
- package/docs/engineering-housekeeper.md +12 -4
- package/docs/getting-started.md +1 -1
- package/docs/install.md +5 -5
- package/docs/kfd-support.md +2 -7
- package/docs/lifecycle-protocol.md +2 -4
- package/docs/node-api-reference.md +414 -523
- package/docs/release-flow.md +31 -31
- package/docs/release-governance.md +16 -28
- package/docs/release-passport.md +2 -15
- package/docs/release-tail-contract.md +13 -6
- package/docs/release-tail-provider-plane.md +13 -19
- package/docs/release-train.md +4 -4
- package/docs/reusable-build-surface.md +14 -27
- package/docs/site-bundle-contract.md +1 -5
- package/docs/stable-candidate-patrol.md +7 -7
- package/docs/v4-canonical-contracts.md +92 -0
- package/docs/v4-delivery-warrant-read-candidate.md +73 -0
- package/docs/v4-delivery-warrant-semantic-diff.md +75 -0
- package/docs/v4-production-release.md +63 -0
- package/docs/v4-stage-capsule.md +193 -0
- package/docs/versioning.md +3 -3
- package/package.json +19 -17
- package/packages/core/adopter-delivery-gate.js +576 -0
- package/packages/core/adopter-delivery-json.js +66 -0
- package/packages/core/artifact-signing.js +0 -61
- package/packages/core/artifact-verification-envelope.js +5 -5
- package/packages/core/build-facts.js +12 -4
- package/packages/core/buildchain-agent-manuals.js +0 -2
- package/packages/core/buildchain-config.js +4 -69
- package/packages/core/buildchain-contract.js +232 -46
- package/packages/core/buildchain-kfd-claims.js +1 -1
- package/packages/core/channel-candidate.js +0 -8
- package/packages/core/channel-promotion-baseline.js +0 -52
- package/packages/core/controller-evidence.js +3 -4
- package/packages/core/dev-alpha-candidate-selection.js +2 -10
- package/packages/core/dev-delivery-warrant-cancellation.js +0 -1
- package/packages/core/dev-delivery-warrant-settlement.js +1 -5
- package/packages/core/dev-delivery-warrant.js +12 -52
- package/packages/core/diagnostics.js +3 -8
- package/packages/core/github-governance-authority.js +3 -1
- package/packages/core/kfd-adopter-category-driver.js +167 -0
- package/packages/core/kfd-adopter-manifest.js +47 -46
- package/packages/core/kfd-gate.js +15 -45
- package/packages/core/paper-agent-entry.js +7 -16
- package/packages/core/paper-fleet.js +2 -2
- package/packages/core/paper-repository.js +2 -3
- package/packages/core/paper-scaffold-content.js +2 -23
- package/packages/core/paper.js +11 -43
- package/packages/core/publication-reproducibility.js +4 -4
- package/packages/core/release-line-bootstrap.js +21 -8
- package/packages/core/release-passport-contract.js +5 -5
- package/packages/core/release-passport.js +20 -131
- package/packages/core/self-dogfood-version.js +48 -35
- package/packages/core/spawn-command.js +232 -8
- package/packages/core/v4-adopter-delivery-parity.js +219 -0
- package/packages/core/v4-canonical-contracts.js +284 -0
- package/packages/core/v4-delivery-warrant-fixture-runner.js +371 -0
- package/packages/core/v4-delivery-warrant-read-candidate.js +279 -0
- package/packages/core/v4-delivery-warrant-semantic-diff-gate.js +352 -0
- package/packages/core/v4-delivery-warrant-shadow-adapter.js +447 -0
- package/packages/core/v4-partial-mutation-recovery-qualification.js +395 -0
- package/packages/core/v4-platform-stage-checkpoints.js +471 -0
- package/packages/core/v4-provider-operation-journal.js +531 -0
- package/packages/core/v4-provider-readback-idempotency.js +394 -0
- package/packages/core/v4-release-activation-shadow.js +519 -0
- package/packages/core/v4-stable-publication-fence.js +357 -0
- package/packages/core/v4-stage-capsule-local-store.js +426 -0
- package/packages/core/v4-stage-capsule-qualification-campaign.js +512 -0
- package/packages/core/v4-stage-capsule-qualification.js +456 -0
- package/packages/core/v4-stage-capsule-resume-planner.js +397 -0
- package/packages/core/v4-stage-capsule-store.js +401 -0
- package/packages/core/v4-stage-capsule.js +319 -0
- package/scripts/assemble-self-publication-admission.mjs +1 -1
- package/scripts/audit-publication-control-plane.mjs +5 -5
- package/scripts/auditable-demo-bundle-verification.mjs +3 -2
- package/scripts/auditable-demo-platform.mjs +2 -2
- package/scripts/auditable-demo-renditions.mjs +1 -1
- package/scripts/auditable-demo.mjs +2 -2
- package/scripts/aws-macos-jit-controller-core.mjs +13 -346
- package/scripts/aws-macos-jit-controller-runtime.mjs +2 -210
- package/scripts/aws-macos-jit-controller.mjs +37 -275
- package/scripts/aws-macos-jit-core.mjs +3 -41
- package/scripts/aws-macos-jit.mjs +0 -12
- package/scripts/aws-windows-jit-campaign.mjs +2 -2
- package/scripts/aws-windows-jit-controller-core.mjs +1 -1
- package/scripts/aws-windows-jit-controller.mjs +3 -3
- package/scripts/build-contract-core.mjs +3 -8
- package/scripts/build-standalone-binary.mjs +3 -14
- package/scripts/buildchain-channel-router.mjs +4 -0
- package/scripts/buildchain-cli-help.mjs +7 -13
- package/scripts/buildchain-contract-lock.mjs +0 -6
- package/scripts/check-action-bundles.mjs +3 -4
- package/scripts/check-internal-architecture.mjs +7 -6
- package/scripts/check-inventory.mjs +30 -25
- package/scripts/check-v4-public-dogfood-contract.mjs +270 -0
- package/scripts/create-release-bundle.mjs +8 -4
- package/scripts/dev-alpha-candidate-patrol.mjs +1 -22
- package/scripts/dev-delivery-proof.mjs +2 -54
- package/scripts/dev-delivery-warrant.mjs +59 -77
- package/scripts/dev-pr-auto-merge.mjs +4 -30
- package/scripts/dev-pr-delivery-warrant.mjs +0 -55
- package/scripts/dispatch-artifact-signing-authority.mjs +7 -4
- package/scripts/generate-buildchain-kfd-witnesses.mjs +94 -88
- package/scripts/generate-channel-build-workflow.mjs +54 -24
- package/scripts/generate-channel-promotion-workflow.mjs +15 -6
- package/scripts/generate-site-bundle.mjs +5 -21
- package/scripts/git-fetch-process-tree.mjs +34 -1
- package/scripts/init-repo.mjs +64 -159
- package/scripts/inspect-artifact-signing-requests.mjs +0 -6
- package/scripts/locked-source-checkout.mjs +3 -4
- package/scripts/maintainability-metrics.mjs +8 -2
- package/scripts/npm-publish-dry-run.mjs +2 -2
- package/scripts/npm-publish-transaction.mjs +2 -2
- package/scripts/publication-commit-evidence.mjs +23 -69
- package/scripts/release-candidate-resolver.mjs +11 -17
- package/scripts/release-tail.mjs +3 -49
- package/scripts/resume-from-candidate-run.mjs +9 -123
- package/scripts/run-lifecycle-core.mjs +12 -13
- package/scripts/seal-artifact-signing-requests.mjs +17 -21
- package/scripts/site-capability-metadata.mjs +2 -7
- package/scripts/stable-candidate-qualification.mjs +10 -10
- package/scripts/v4-architecture.mjs +12 -2
- package/scripts/v4-bridge-bootstrap.mjs +141 -0
- package/scripts/v4-bridge-evidence.mjs +141 -0
- package/scripts/v4-host-adapter.mjs +182 -0
- package/scripts/v4-platform-stage-checkpoint-rehearsal.mjs +207 -0
- package/scripts/v4-stage-capsule-qualification.mjs +528 -0
- package/scripts/v4-stage-capsule-resume-rehearsal.mjs +57 -0
- package/scripts/v4-warrant-shadow-plan.mjs +601 -0
- package/scripts/verify-golden-path.mjs +5 -5
- package/scripts/web-surface-cloudfront-rewrite.mjs +15 -15
- package/scripts/web-surface-core.mjs +2 -8
- package/scripts/workflow-call-contract.mjs +5 -184
- package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-perspective.json +0 -16
- package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-replay.json +0 -57
- package/contracts/fixtures/next-development-transition-v1/anchored-manual-waiting.json +0 -47
- package/contracts/fixtures/next-development-transition-v1/semver-auto-planned.json +0 -47
- package/contracts/fixtures/next-development-transition-v1/version-model-cases.json +0 -40
- package/contracts/next-development-request-v1.schema.json +0 -66
- package/contracts/next-development-transition-v1.schema.json +0 -292
- package/contracts/publication-rehearsal-capsule-v1.schema.json +0 -173
- package/dist/site/schemas/publication-rehearsal-capsule-v1.schema.json +0 -269
- package/dist/site/schemas/release-tail-capabilities-v1.schema.json +0 -353
- package/dist/site/schemas/release-tail-provider-bindings-v1.schema.json +0 -94
- package/docs/next-development-transition.md +0 -119
- package/docs/publication-rehearsal.md +0 -94
- package/packages/core/buildchain-compatibility-proof.js +0 -631
- package/packages/core/dev-delivery-native-proof.js +0 -333
- package/packages/core/dev-delivery-warrant-shadow.js +0 -502
- package/packages/core/next-development-candidate-reservation.js +0 -186
- package/packages/core/next-development-controller.js +0 -726
- package/packages/core/next-development-projection.js +0 -288
- package/packages/core/next-development-transition.js +0 -738
- package/packages/core/publication-rehearsal-projection.js +0 -173
- package/packages/core/publication-rehearsal-runtime.js +0 -921
- package/scripts/aws-macos-jit-instance-rehydrate.mjs +0 -260
- package/scripts/aws-macos-jit-source-rebind.mjs +0 -724
- package/scripts/dev-delivery-native-run.mjs +0 -187
- package/scripts/dev-delivery-two-phase.mjs +0 -598
- package/scripts/generate-next-development-guidance.mjs +0 -49
- package/scripts/materialize-self-release-candidate-version.mjs +0 -137
- package/scripts/next-development-self-dogfood-harness.mjs +0 -409
- package/scripts/next-development-self-dogfood.mjs +0 -532
- package/scripts/next-development-transition.mjs +0 -47
- package/scripts/release-candidate-tail-reseal.mjs +0 -426
- package/templates/native-dev-delivery.yml +0 -82
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { classifyDevDeliveryDelta, createIntegrationDeliveryProof,
|
|
4
|
+
import { classifyDevDeliveryDelta, createIntegrationDeliveryProof, createProjectCutReplayPlan, createProjectCutReplayProof, createSourceQualificationProof, verifyIntegrationDeliveryProof, verifyProjectCutReplayProof, verifySourceQualificationProof } from "../packages/core/dev-delivery-warrant.js";
|
|
5
5
|
|
|
6
6
|
function flag(args, name, fallback = "") {
|
|
7
7
|
const index = args.indexOf(`--${name}`);
|
|
@@ -52,7 +52,6 @@ export function devDeliveryProofCliOptions(args = [], environment = process.env)
|
|
|
52
52
|
affectedPaths: flag(rest, "affected-paths-json", environment.BUILDCHAIN_DEV_DELIVERY_AFFECTED_PATHS || "[]"),
|
|
53
53
|
shardEvidenceRoots: flag(rest, "shard-evidence-roots-json", environment.BUILDCHAIN_DEV_DELIVERY_SHARD_EVIDENCE_ROOTS || "[]"),
|
|
54
54
|
qualifiedAt: flag(rest, "qualified-at", environment.BUILDCHAIN_DEV_DELIVERY_QUALIFIED_AT),
|
|
55
|
-
qualifiedBase: flag(rest, "qualified-base", environment.BUILDCHAIN_DEV_DELIVERY_QUALIFIED_BASE),
|
|
56
55
|
sourceProofPath: flag(rest, "source-proof", environment.BUILDCHAIN_DEV_DELIVERY_SOURCE_PROOF),
|
|
57
56
|
sourceProofRoot: flag(rest, "source-proof-root", environment.BUILDCHAIN_DEV_DELIVERY_SOURCE_PROOF_ROOT),
|
|
58
57
|
warrantResultPath: flag(rest, "warrant-result", environment.BUILDCHAIN_DEV_DELIVERY_WARRANT_RESULT),
|
|
@@ -118,57 +117,6 @@ export function runDevDeliveryProofCommand(options) {
|
|
|
118
117
|
},
|
|
119
118
|
});
|
|
120
119
|
}
|
|
121
|
-
if (options.command === "native") {
|
|
122
|
-
return createNativeQualificationProof({
|
|
123
|
-
repository: options.repository,
|
|
124
|
-
protectedBase: options.protectedBase,
|
|
125
|
-
sourceIdentityRoot: options.sourceIdentityRoot,
|
|
126
|
-
sourcePatchRoot: options.sourcePatchRoot,
|
|
127
|
-
planRoot: options.planRoot,
|
|
128
|
-
closureRoot: options.closureRoot,
|
|
129
|
-
dependencyRoot: options.dependencyRoot,
|
|
130
|
-
toolchainRoot: options.toolchainRoot,
|
|
131
|
-
qualifiedBase: options.qualifiedBase,
|
|
132
|
-
affectedPaths: jsonList(options.affectedPaths, "affected paths"),
|
|
133
|
-
shardEvidenceRoots: jsonList(options.shardEvidenceRoots, "shard evidence roots", { required: true }),
|
|
134
|
-
qualifiedAt: options.qualifiedAt,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
if (options.command === "verify-native") {
|
|
138
|
-
return verifyNativeQualificationProof(jsonFile(options.sourceProofPath, "native proof"));
|
|
139
|
-
}
|
|
140
|
-
if (options.command === "classify-native") {
|
|
141
|
-
return createNativeProofReuseDecision({
|
|
142
|
-
proof: jsonFile(options.sourceProofPath, "native proof"),
|
|
143
|
-
current: {
|
|
144
|
-
sourceIdentityRoot: options.sourceIdentityRoot,
|
|
145
|
-
sourcePatchRoot: options.sourcePatchRoot,
|
|
146
|
-
planRoot: options.planRoot,
|
|
147
|
-
closureRoot: options.closureRoot,
|
|
148
|
-
dependencyRoot: options.dependencyRoot,
|
|
149
|
-
toolchainRoot: options.toolchainRoot,
|
|
150
|
-
currentBase: options.currentBase,
|
|
151
|
-
graphKnown: options.graphKnown,
|
|
152
|
-
changedPaths: jsonList(options.changedPaths, "changed paths"),
|
|
153
|
-
},
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
if (options.command === "verify-native-reuse") {
|
|
157
|
-
return verifyNativeProofReuseDecision(jsonFile(options.qualificationReceiptPath, "native reuse decision"), {
|
|
158
|
-
proof: jsonFile(options.sourceProofPath, "native proof"),
|
|
159
|
-
current: {
|
|
160
|
-
sourceIdentityRoot: options.sourceIdentityRoot,
|
|
161
|
-
sourcePatchRoot: options.sourcePatchRoot,
|
|
162
|
-
planRoot: options.planRoot,
|
|
163
|
-
closureRoot: options.closureRoot,
|
|
164
|
-
dependencyRoot: options.dependencyRoot,
|
|
165
|
-
toolchainRoot: options.toolchainRoot,
|
|
166
|
-
currentBase: options.currentBase,
|
|
167
|
-
graphKnown: options.graphKnown,
|
|
168
|
-
changedPaths: jsonList(options.changedPaths, "changed paths"),
|
|
169
|
-
},
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
120
|
if (options.command === "replay") {
|
|
173
121
|
return createProjectCutReplayPlan({
|
|
174
122
|
repository: options.repository,
|
|
@@ -220,7 +168,7 @@ export function runDevDeliveryProofCommand(options) {
|
|
|
220
168
|
}
|
|
221
169
|
|
|
222
170
|
function usage() {
|
|
223
|
-
return "Usage:\n buildchain dev proof <source|verify-source|classify|
|
|
171
|
+
return "Usage:\n buildchain dev proof <source|verify-source|classify|replay|replay-proof|verify-replay|integration|verify-integration> [options] [--output FILE] [--json]\n";
|
|
224
172
|
}
|
|
225
173
|
|
|
226
174
|
async function main() {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { cancelQueuedDevDeliveryCandidate, closeDevDeliveryWarrant, createDevDeliveryQueue, heartbeatDevDeliveryWarrant, observeDevDeliveryQueue,
|
|
5
|
-
import {
|
|
4
|
+
import { cancelQueuedDevDeliveryCandidate, closeDevDeliveryWarrant, createDevDeliveryQueue, heartbeatDevDeliveryWarrant, observeDevDeliveryQueue, recoverExpiredDevDeliveryWarrant, selectDevDeliveryWarrant, settleDevDeliveryTerminalEvent, submitDevDeliveryCandidate } from "../packages/core/dev-delivery-warrant.js";
|
|
5
|
+
import { runV4DeliveryWarrantReadCandidate } from "../packages/core/v4-delivery-warrant-read-candidate.js";
|
|
6
6
|
|
|
7
7
|
const STATE_PATH = "queue.json";
|
|
8
8
|
const STATE_REF_PREFIX = "buildchain/dev-delivery-warrant/";
|
|
@@ -174,22 +174,6 @@ function warrantIdentity(queue, options) {
|
|
|
174
174
|
return { candidateId: active.candidateId, fencingToken, generation };
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
function jsonFile(file, label) {
|
|
178
|
-
if (!file) throw new Error(`${label} is required`);
|
|
179
|
-
return JSON.parse(fs.readFileSync(file, "utf8"));
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
function jsonList(value, label) {
|
|
183
|
-
let parsed;
|
|
184
|
-
try {
|
|
185
|
-
parsed = JSON.parse(value || "[]");
|
|
186
|
-
} catch (cause) {
|
|
187
|
-
throw new Error(`${label} must be a JSON array: ${cause.message}`);
|
|
188
|
-
}
|
|
189
|
-
if (!Array.isArray(parsed)) throw new Error(`${label} must be a JSON array`);
|
|
190
|
-
return parsed;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
177
|
function transitionFor(command, queue, options) {
|
|
194
178
|
if (command === "submit") {
|
|
195
179
|
return submitDevDeliveryCandidate(
|
|
@@ -206,8 +190,6 @@ function transitionFor(command, queue, options) {
|
|
|
206
190
|
closureRoot: exactRoot(options.closureRoot, "closureRoot"),
|
|
207
191
|
dependencyRoot: exactRoot(options.dependencyRoot, "dependencyRoot"),
|
|
208
192
|
toolchainRoot: exactRoot(options.toolchainRoot, "toolchainRoot"),
|
|
209
|
-
affectedPaths: jsonList(options.affectedPaths, "affected paths"),
|
|
210
|
-
sourceWorkflowRunId: options.sourceWorkflowRunId ? positiveInteger(options.sourceWorkflowRunId, "sourceWorkflowRunId") : 0,
|
|
211
193
|
deliveryClass: options.deliveryClass,
|
|
212
194
|
priority: options.priority || "ordinary",
|
|
213
195
|
},
|
|
@@ -226,18 +208,6 @@ function transitionFor(command, queue, options) {
|
|
|
226
208
|
leaseSeconds: options.leaseSeconds,
|
|
227
209
|
});
|
|
228
210
|
}
|
|
229
|
-
if (command === "qualify") {
|
|
230
|
-
return qualifyDevDeliveryWarrant(queue, warrantIdentity(queue, options), {
|
|
231
|
-
nativeProof: jsonFile(options.nativeProofPath, "native proof"),
|
|
232
|
-
reuseDecision: jsonFile(options.nativeReuseDecisionPath, "native reuse decision"),
|
|
233
|
-
current: {
|
|
234
|
-
currentBase: options.currentBase,
|
|
235
|
-
graphKnown: options.graphKnown,
|
|
236
|
-
changedPaths: jsonList(options.changedPaths, "changed paths"),
|
|
237
|
-
},
|
|
238
|
-
now: options.now,
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
211
|
if (command === "recover") return recoverExpiredDevDeliveryWarrant(queue, { now: options.now });
|
|
242
212
|
if (command === "close") {
|
|
243
213
|
return closeDevDeliveryWarrant(queue, warrantIdentity(queue, options), {
|
|
@@ -282,6 +252,50 @@ function transitionFor(command, queue, options) {
|
|
|
282
252
|
throw new Error(`unsupported dev delivery command ${command || "<empty>"}`);
|
|
283
253
|
}
|
|
284
254
|
|
|
255
|
+
async function observeQueue(loaded, options) {
|
|
256
|
+
const readMode = text(options.readMode || "v3").toLowerCase();
|
|
257
|
+
if (!["v3", "v4"].includes(readMode)) throw new Error("readMode must be v3 or v4");
|
|
258
|
+
let observation = observeDevDeliveryQueue(loaded.queue, { now: options.now });
|
|
259
|
+
let readCandidate;
|
|
260
|
+
if (readMode === "v4") {
|
|
261
|
+
const qualification = options.readQualification || JSON.parse(fs.readFileSync(options.readQualificationPath, "utf8"));
|
|
262
|
+
const retain =
|
|
263
|
+
options.retainReadEvidence ||
|
|
264
|
+
(async (evidence) => {
|
|
265
|
+
if (!options.readEvidenceOutput) throw new Error("readEvidenceOutput is required");
|
|
266
|
+
fs.mkdirSync(path.dirname(options.readEvidenceOutput), { recursive: true });
|
|
267
|
+
fs.writeFileSync(options.readEvidenceOutput, `${JSON.stringify(evidence, null, 2)}\n`);
|
|
268
|
+
return { receiptRoot: evidence.evidenceRoot };
|
|
269
|
+
});
|
|
270
|
+
readCandidate = await runV4DeliveryWarrantReadCandidate(loaded.queue, {
|
|
271
|
+
qualification,
|
|
272
|
+
expectedQualificationRoot: options.readQualificationRoot,
|
|
273
|
+
expectedSources: {
|
|
274
|
+
typescriptRevision: options.readTypescriptRevision,
|
|
275
|
+
rustRevision: options.readRustRevision,
|
|
276
|
+
validatorVersion: options.readValidatorVersion,
|
|
277
|
+
},
|
|
278
|
+
observedAt: options.now,
|
|
279
|
+
timeoutMs: positiveInteger(options.readTimeoutMs, "readTimeoutMs", 5_000),
|
|
280
|
+
signal: options.readSignal,
|
|
281
|
+
invokeRust: options.invokeV4ReadHost,
|
|
282
|
+
host: options.readHost,
|
|
283
|
+
retain,
|
|
284
|
+
});
|
|
285
|
+
observation = readCandidate.observation;
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
schema: "kungfu.buildchain.dev-delivery-command-result/v1",
|
|
289
|
+
ok: true,
|
|
290
|
+
mode: "observe",
|
|
291
|
+
readMode,
|
|
292
|
+
stateRef: options.stateRef,
|
|
293
|
+
stateCommit: loaded.commitSha,
|
|
294
|
+
observation,
|
|
295
|
+
...(readCandidate ? { readCandidate } : {}),
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
285
299
|
export async function runDevDeliveryCommand(optionsInput = {}, clientInput) {
|
|
286
300
|
const options = {
|
|
287
301
|
...optionsInput,
|
|
@@ -306,16 +320,7 @@ export async function runDevDeliveryCommand(optionsInput = {}, clientInput) {
|
|
|
306
320
|
if (options.expectedOldStateRoot && loaded.queue.stateRoot !== options.expectedOldStateRoot) {
|
|
307
321
|
throw new Error(`expected-old state drift: ${loaded.queue.stateRoot} != ${options.expectedOldStateRoot}`);
|
|
308
322
|
}
|
|
309
|
-
if (options.command === "observe")
|
|
310
|
-
return {
|
|
311
|
-
schema: "kungfu.buildchain.dev-delivery-command-result/v1",
|
|
312
|
-
ok: true,
|
|
313
|
-
mode: "observe",
|
|
314
|
-
stateRef: options.stateRef,
|
|
315
|
-
stateCommit: loaded.commitSha,
|
|
316
|
-
observation: observeDevDeliveryQueue(loaded.queue, { now: options.now }),
|
|
317
|
-
};
|
|
318
|
-
}
|
|
323
|
+
if (options.command === "observe") return observeQueue(loaded, options);
|
|
319
324
|
const initialLoaded = loaded;
|
|
320
325
|
let changed = transitionFor(options.command, loaded.queue, options);
|
|
321
326
|
let mutates = changed.queue.stateRoot !== loaded.queue.stateRoot;
|
|
@@ -376,23 +381,6 @@ export async function runDevDeliveryCommand(optionsInput = {}, clientInput) {
|
|
|
376
381
|
};
|
|
377
382
|
}
|
|
378
383
|
|
|
379
|
-
export function runDevDeliveryShadowCommand(options = {}) {
|
|
380
|
-
if (bool(options.execute, false)) {
|
|
381
|
-
throw new Error("shadow qualification is effect-disabled and rejects --execute");
|
|
382
|
-
}
|
|
383
|
-
if (!options.inputPath) throw new Error("shadow qualification requires --input FILE");
|
|
384
|
-
const input = JSON.parse(fs.readFileSync(options.inputPath, "utf8"));
|
|
385
|
-
if (options.command === "shadow-plan") {
|
|
386
|
-
return planDevDeliveryWarrantShadow(input, {
|
|
387
|
-
maxConcurrency: positiveInteger(options.maxConcurrency, "maxConcurrency", 2),
|
|
388
|
-
});
|
|
389
|
-
}
|
|
390
|
-
if (options.command === "shadow-qualify") {
|
|
391
|
-
return qualifyDevDeliveryWarrantShadow(input);
|
|
392
|
-
}
|
|
393
|
-
throw new Error(`unsupported shadow command ${options.command || "<empty>"}`);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
384
|
function flag(args, name, fallback = "") {
|
|
397
385
|
const index = args.indexOf(`--${name}`);
|
|
398
386
|
return index === -1 ? fallback : args[index + 1] || "";
|
|
@@ -420,12 +408,6 @@ export function devDeliveryCliOptions(args = [], environment = process.env) {
|
|
|
420
408
|
sourceIdentityRoot: flag(rest, "source-identity-root", environment.BUILDCHAIN_DEV_DELIVERY_SOURCE_IDENTITY_ROOT),
|
|
421
409
|
sourcePatchRoot: flag(rest, "source-patch-root", environment.BUILDCHAIN_DEV_DELIVERY_SOURCE_PATCH_ROOT),
|
|
422
410
|
sourceProofRoot: flag(rest, "source-proof-root", environment.BUILDCHAIN_DEV_DELIVERY_SOURCE_PROOF_ROOT),
|
|
423
|
-
affectedPaths: flag(rest, "affected-paths-json", environment.BUILDCHAIN_DEV_DELIVERY_AFFECTED_PATHS || "[]"),
|
|
424
|
-
nativeProofPath: flag(rest, "native-proof", environment.BUILDCHAIN_DEV_DELIVERY_NATIVE_PROOF),
|
|
425
|
-
nativeReuseDecisionPath: flag(rest, "native-reuse-decision", environment.BUILDCHAIN_DEV_DELIVERY_NATIVE_REUSE_DECISION),
|
|
426
|
-
currentBase: flag(rest, "current-base", environment.BUILDCHAIN_DEV_DELIVERY_CURRENT_BASE),
|
|
427
|
-
changedPaths: flag(rest, "changed-paths-json", environment.BUILDCHAIN_DEV_DELIVERY_CHANGED_PATHS || "[]"),
|
|
428
|
-
graphKnown: ["1", "true", "yes", "on"].includes(flag(rest, "graph-known", environment.BUILDCHAIN_DEV_DELIVERY_GRAPH_KNOWN).trim().toLowerCase()),
|
|
429
411
|
planRoot: flag(rest, "plan-root", environment.BUILDCHAIN_DEV_DELIVERY_PLAN_ROOT),
|
|
430
412
|
closureRoot: flag(rest, "closure-root", environment.BUILDCHAIN_DEV_DELIVERY_CLOSURE_ROOT),
|
|
431
413
|
dependencyRoot: flag(rest, "dependency-root", environment.BUILDCHAIN_DEV_DELIVERY_DEPENDENCY_ROOT),
|
|
@@ -439,9 +421,15 @@ export function devDeliveryCliOptions(args = [], environment = process.env) {
|
|
|
439
421
|
eventAction: flag(rest, "event-action", environment.BUILDCHAIN_DEV_DELIVERY_EVENT_ACTION),
|
|
440
422
|
evidenceRoot: flag(rest, "evidence-root", environment.BUILDCHAIN_DEV_DELIVERY_EVIDENCE_ROOT),
|
|
441
423
|
reason: flag(rest, "reason", environment.BUILDCHAIN_DEV_DELIVERY_REASON),
|
|
424
|
+
readMode: flag(rest, "read-mode", environment.BUILDCHAIN_V4_WARRANT_READ_MODE || "v3"),
|
|
425
|
+
readQualificationPath: flag(rest, "read-qualification", environment.BUILDCHAIN_V4_WARRANT_READ_QUALIFICATION),
|
|
426
|
+
readQualificationRoot: flag(rest, "read-qualification-root", environment.BUILDCHAIN_V4_WARRANT_READ_QUALIFICATION_ROOT),
|
|
427
|
+
readTypescriptRevision: flag(rest, "read-typescript-revision", environment.BUILDCHAIN_V4_WARRANT_TYPESCRIPT_REVISION),
|
|
428
|
+
readRustRevision: flag(rest, "read-rust-revision", environment.BUILDCHAIN_V4_WARRANT_RUST_REVISION),
|
|
429
|
+
readValidatorVersion: flag(rest, "read-validator-version", environment.BUILDCHAIN_V4_WARRANT_VALIDATOR_VERSION),
|
|
430
|
+
readTimeoutMs: flag(rest, "read-timeout-ms", environment.BUILDCHAIN_V4_WARRANT_READ_TIMEOUT_MS || "5000"),
|
|
431
|
+
readEvidenceOutput: flag(rest, "read-evidence-output", environment.BUILDCHAIN_V4_WARRANT_READ_EVIDENCE || ".buildchain/dev-delivery/v4-read-evidence.json"),
|
|
442
432
|
now: flag(rest, "now", environment.BUILDCHAIN_DEV_DELIVERY_NOW),
|
|
443
|
-
inputPath: flag(rest, "input", environment.BUILDCHAIN_DEV_DELIVERY_SHADOW_INPUT),
|
|
444
|
-
maxConcurrency: flag(rest, "max-concurrency", environment.BUILDCHAIN_DEV_DELIVERY_SHADOW_MAX_CONCURRENCY || "2"),
|
|
445
433
|
outputPath: flag(rest, "output", environment.BUILDCHAIN_DEV_DELIVERY_OUTPUT || ".buildchain/dev-delivery/result.json"),
|
|
446
434
|
execute: hasFlag(rest, "execute"),
|
|
447
435
|
json: hasFlag(rest, "json"),
|
|
@@ -449,7 +437,7 @@ export function devDeliveryCliOptions(args = [], environment = process.env) {
|
|
|
449
437
|
}
|
|
450
438
|
|
|
451
439
|
function usage() {
|
|
452
|
-
return "Usage:\n buildchain dev warrant <submit|select|heartbeat|
|
|
440
|
+
return "Usage:\n buildchain dev warrant <submit|select|heartbeat|recover|close|settle|cancel-queued|observe> --repository owner/repo --branch dev/vN/vN.M [--execute] [--output FILE] [--json]\n\nRead candidate:\n observe --read-mode v4 --read-qualification FILE --read-qualification-root sha256:... --read-typescript-revision SHA --read-rust-revision SHA --read-validator-version TOKEN [--read-evidence-output FILE]\n";
|
|
453
441
|
}
|
|
454
442
|
|
|
455
443
|
async function main() {
|
|
@@ -459,22 +447,16 @@ async function main() {
|
|
|
459
447
|
return;
|
|
460
448
|
}
|
|
461
449
|
const options = devDeliveryCliOptions(args);
|
|
462
|
-
if (!["submit", "select", "heartbeat", "
|
|
450
|
+
if (!["submit", "select", "heartbeat", "recover", "close", "settle", "cancel-queued", "observe"].includes(options.command)) {
|
|
463
451
|
throw new Error(usage().trim());
|
|
464
452
|
}
|
|
465
|
-
const
|
|
466
|
-
const result = shadow ? runDevDeliveryShadowCommand(options) : await runDevDeliveryCommand(options);
|
|
453
|
+
const result = await runDevDeliveryCommand(options);
|
|
467
454
|
fs.mkdirSync(path.dirname(options.outputPath), { recursive: true });
|
|
468
455
|
fs.writeFileSync(options.outputPath, `${JSON.stringify(result, null, 2)}\n`);
|
|
469
456
|
if (options.json) process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
470
457
|
else {
|
|
471
458
|
process.stdout.write(`Buildchain dev delivery ${options.command}: ${result.receipt?.reason || result.mode}\n`);
|
|
472
|
-
|
|
473
|
-
process.stdout.write(`Decision: ${result.decision}\n`);
|
|
474
|
-
process.stdout.write(`Evidence root: ${result.planRoot || result.qualificationRoot}\n`);
|
|
475
|
-
} else {
|
|
476
|
-
process.stdout.write(`State root: ${result.after?.stateRoot || result.observation.stateRoot}\n`);
|
|
477
|
-
}
|
|
459
|
+
process.stdout.write(`State root: ${result.after?.stateRoot || result.observation.stateRoot}\n`);
|
|
478
460
|
if (result.receiptRoot) process.stdout.write(`Receipt root: ${result.receiptRoot}\n`);
|
|
479
461
|
process.stdout.write(`Result: ${options.outputPath}\n`);
|
|
480
462
|
}
|
|
@@ -4,7 +4,7 @@ import { spawnSync } from "node:child_process";
|
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { verifyProjectCutReplayProof } from "../packages/core/dev-delivery-warrant.js";
|
|
7
|
-
import { admitExistingQueueEntry, createDevPrAdmissionReceipt,
|
|
7
|
+
import { admitExistingQueueEntry, createDevPrAdmissionReceipt, readDeliveryWarrantResult, runSourceQualification, runTargetedQueueAdmission } from "./dev-pr-delivery-warrant.mjs";
|
|
8
8
|
const DEFAULT_BLOCK_LABELS = ["blocked", "do-not-merge", "work-in-progress"];
|
|
9
9
|
const DEFAULT_ALLOWED_HEAD_PREFIXES = ["feature/", "fix/", "chore/", "docs/", "ci/", "refactor/"];
|
|
10
10
|
const DEFAULT_REQUIRED_CHECKS = ["check"];
|
|
@@ -70,7 +70,6 @@ function normalizeOptions(options = {}) {
|
|
|
70
70
|
allowedHeadPrefixes: splitList(options.allowedHeadPrefixes, DEFAULT_ALLOWED_HEAD_PREFIXES),
|
|
71
71
|
requiredChecks: splitList(options.requiredChecks, DEFAULT_REQUIRED_CHECKS),
|
|
72
72
|
queueAdmissionContext: String(options.queueAdmissionContext || "").trim(),
|
|
73
|
-
activeLeaseContext: String(options.activeLeaseContext || "").trim(),
|
|
74
73
|
requireApproval: boolOption(options.requireApproval, true),
|
|
75
74
|
sameRepositoryOnly: boolOption(options.sameRepositoryOnly, true),
|
|
76
75
|
maxMerges: intOption(options.maxMerges, 1),
|
|
@@ -219,20 +218,6 @@ async function setQueueAdmissionStatus(client, repository, sha, context, state)
|
|
|
219
218
|
return { context, state, sha };
|
|
220
219
|
}
|
|
221
220
|
|
|
222
|
-
async function setActiveLeaseStatus(client, repository, sha, context, state) {
|
|
223
|
-
if (!context) return null;
|
|
224
|
-
await client.request("POST", `/repos/${repository.owner}/${repository.repo}/statuses/${sha}`, {
|
|
225
|
-
body: {
|
|
226
|
-
state,
|
|
227
|
-
context,
|
|
228
|
-
description: state === "pending"
|
|
229
|
-
? "Buildchain reactivated this exact lease for merge-group qualification"
|
|
230
|
-
: "Buildchain released this exact lease after queue admission failed",
|
|
231
|
-
},
|
|
232
|
-
});
|
|
233
|
-
return { context, state, sha };
|
|
234
|
-
}
|
|
235
|
-
|
|
236
221
|
function skip(reason, details = {}) {
|
|
237
222
|
return { action: "skip", reason, ...details };
|
|
238
223
|
}
|
|
@@ -868,15 +853,11 @@ export async function runDevPrAdmission(optionsInput = {}, clientInput) {
|
|
|
868
853
|
let warrant = null;
|
|
869
854
|
try {
|
|
870
855
|
warrant = readDeliveryWarrantResult(options, pr);
|
|
871
|
-
await verifyCurrentDeliveryWarrant(client, options, pr, warrant);
|
|
872
856
|
} catch (error) {
|
|
873
857
|
return reject("blocked", error.code || "invalid-delivery-warrant");
|
|
874
858
|
}
|
|
875
859
|
const matchingEntry = initialQueue.entries.find((entry) =>
|
|
876
860
|
entry.pullRequestNumber === pr.number && entry.pullRequestHeadSha === options.expectedHeadSha);
|
|
877
|
-
if (matchingEntry && !options.dryRun) {
|
|
878
|
-
await setActiveLeaseStatus(client, options.repository, options.expectedHeadSha, options.activeLeaseContext, "pending");
|
|
879
|
-
}
|
|
880
861
|
const existing = await admitExistingQueueEntry({
|
|
881
862
|
options, pullRequest: pr, readiness, client, entry: matchingEntry, warrant,
|
|
882
863
|
createReceipt: createAdmissionReceipt,
|
|
@@ -912,7 +893,6 @@ async function reconcileEnqueueError({ client, options, pr, expectedHeadSha, ent
|
|
|
912
893
|
const exactEntry = queueReadback?.entries?.find((candidate) =>
|
|
913
894
|
candidate.pullRequestNumber === pr.number && candidate.pullRequestHeadSha === expectedHeadSha);
|
|
914
895
|
if (exactEntry) {
|
|
915
|
-
entry.activeLeaseStatus = await setActiveLeaseStatus(client, options.repository, expectedHeadSha, options.activeLeaseContext, "pending");
|
|
916
896
|
entry.action = "enqueued";
|
|
917
897
|
entry.reason = "already-enqueued-exact-head";
|
|
918
898
|
entry.queueEntry = exactEntry;
|
|
@@ -922,7 +902,6 @@ async function reconcileEnqueueError({ client, options, pr, expectedHeadSha, ent
|
|
|
922
902
|
return;
|
|
923
903
|
}
|
|
924
904
|
entry.queueAdmissionStatus = await setQueueAdmissionStatus(client, options.repository, expectedHeadSha, options.queueAdmissionContext, "failure");
|
|
925
|
-
entry.activeLeaseStatus = await setActiveLeaseStatus(client, options.repository, expectedHeadSha, options.activeLeaseContext, "failure");
|
|
926
905
|
entry.action = "skip";
|
|
927
906
|
entry.reason = "enqueue-rejected";
|
|
928
907
|
entry.enqueueError = {
|
|
@@ -1088,14 +1067,10 @@ export async function runDevPrAutoMerge(optionsInput = {}, clientInput) {
|
|
|
1088
1067
|
result.skipped.push(entry);
|
|
1089
1068
|
} else {
|
|
1090
1069
|
try {
|
|
1091
|
-
entry.activeLeaseStatus = await setActiveLeaseStatus(client, options.repository, expectedHeadSha, options.activeLeaseContext, "pending");
|
|
1092
1070
|
entry.queueAdmissionStatus = await setQueueAdmissionStatus(client, options.repository, expectedHeadSha, options.queueAdmissionContext, "success");
|
|
1093
|
-
const queueEntry = await
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
attempts: options.pollMergeableAttempts,
|
|
1097
|
-
delayMs: options.pollMergeableDelayMs,
|
|
1098
|
-
sleep: delay,
|
|
1071
|
+
const queueEntry = await client.enqueuePullRequest({
|
|
1072
|
+
pullRequestId: decision.pullRequestId,
|
|
1073
|
+
expectedHeadOid: expectedHeadSha,
|
|
1099
1074
|
});
|
|
1100
1075
|
entry.action = "enqueued";
|
|
1101
1076
|
entry.reason = "enqueued-with-expected-head";
|
|
@@ -1180,7 +1155,6 @@ export function cliOptions(args = [], environment = process.env) {
|
|
|
1180
1155
|
allowedHeadPrefixes: cliValue(args, "allowed-head-prefixes", environment.BUILDCHAIN_DEV_PR_ALLOWED_HEAD_PREFIXES),
|
|
1181
1156
|
requiredChecks: cliValue(args, "required-checks", environment.BUILDCHAIN_DEV_PR_REQUIRED_CHECKS),
|
|
1182
1157
|
queueAdmissionContext: cliValue(args, "queue-admission-context", environment.BUILDCHAIN_DEV_PR_QUEUE_ADMISSION_CONTEXT),
|
|
1183
|
-
activeLeaseContext: cliValue(args, "active-lease-context", environment.BUILDCHAIN_DEV_PR_ACTIVE_LEASE_CONTEXT),
|
|
1184
1158
|
diagnosticContext: cliValue(args, "diagnostic-context", environment.BUILDCHAIN_DEV_PR_DIAGNOSTIC_CONTEXT),
|
|
1185
1159
|
warrantMode: cliValue(args, "warrant-mode", environment.BUILDCHAIN_DEV_PR_WARRANT_MODE),
|
|
1186
1160
|
warrantResultPath: cliValue(args, "warrant-result", environment.BUILDCHAIN_DEV_PR_WARRANT_RESULT_PATH),
|
|
@@ -34,11 +34,6 @@ function exactActiveReadback(result) {
|
|
|
34
34
|
const warrant = result.observation.activeWarrant;
|
|
35
35
|
const candidate = result.observation.activeCandidate;
|
|
36
36
|
requireMatch(warrant?.schema === "kungfu.buildchain.dev-delivery-warrant/v1", "delivery-warrant-missing");
|
|
37
|
-
requireMatch((warrant.phase || "qualified") === "qualified", "delivery-warrant-not-qualified");
|
|
38
|
-
if (warrant.phase === "qualified") {
|
|
39
|
-
requireMatch(ROOT_PATTERN.test(String(warrant.nativeProofRoot || "")), "delivery-warrant-native-proof-missing");
|
|
40
|
-
requireMatch(ROOT_PATTERN.test(String(warrant.nativeProofReuseRoot || "")), "delivery-warrant-native-reuse-missing");
|
|
41
|
-
}
|
|
42
37
|
requireMatch(candidate?.candidateId === warrant.candidateId, "delivery-warrant-candidate-readback-missing");
|
|
43
38
|
requireMatch(!result.warrant || JSON.stringify(result.warrant) === JSON.stringify(warrant), "delivery-warrant-readback-mismatch");
|
|
44
39
|
return { warrant, candidate };
|
|
@@ -121,56 +116,6 @@ export function readDeliveryWarrantResult(options, pullRequest) {
|
|
|
121
116
|
};
|
|
122
117
|
}
|
|
123
118
|
|
|
124
|
-
export async function readCurrentDeliveryQueueState(client, repository, targetBranch) {
|
|
125
|
-
if (typeof client.getDevDeliveryQueueState === "function") {
|
|
126
|
-
return client.getDevDeliveryQueueState(targetBranch);
|
|
127
|
-
}
|
|
128
|
-
const stateRef = `buildchain/dev-delivery-warrant/${targetBranch.replaceAll("/", "-")}`;
|
|
129
|
-
const query = new URLSearchParams({ ref: stateRef });
|
|
130
|
-
const { data } = await client.request(
|
|
131
|
-
"GET",
|
|
132
|
-
`/repos/${repository.owner}/${repository.repo}/contents/queue.json?${query}`,
|
|
133
|
-
);
|
|
134
|
-
if (data?.type !== "file" || data?.encoding !== "base64" || !data?.content) {
|
|
135
|
-
mismatch("delivery-warrant-current-readback-invalid");
|
|
136
|
-
}
|
|
137
|
-
return JSON.parse(Buffer.from(String(data.content).replace(/\s+/g, ""), "base64").toString("utf8"));
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export async function verifyCurrentDeliveryWarrant(client, options, pullRequest, warrant) {
|
|
141
|
-
if (!warrant) return;
|
|
142
|
-
let queue;
|
|
143
|
-
try {
|
|
144
|
-
queue = await readCurrentDeliveryQueueState(client, options.repository, options.targetBranch);
|
|
145
|
-
} catch {
|
|
146
|
-
mismatch("delivery-warrant-current-readback-failed");
|
|
147
|
-
}
|
|
148
|
-
const active = queue?.activeWarrant;
|
|
149
|
-
const candidate = queue?.candidates?.find((entry) => entry.candidateId === active?.candidateId);
|
|
150
|
-
requireMatch(active?.candidateId === warrant.candidateId, "delivery-warrant-no-longer-active");
|
|
151
|
-
requireMatch(active?.fencingToken === warrant.fencingToken, "delivery-warrant-current-fencing-mismatch");
|
|
152
|
-
requireMatch(Number(active?.generation) === Number(warrant.generation), "delivery-warrant-current-generation-mismatch");
|
|
153
|
-
requireMatch(Number(active?.pullRequestNumber) === Number(pullRequest.number), "delivery-warrant-current-pr-mismatch");
|
|
154
|
-
requireMatch(String(active?.sourceHead || "").toLowerCase() === options.expectedHeadSha, "delivery-warrant-current-head-mismatch");
|
|
155
|
-
requireMatch(["selected", "proving", "waiting", "blocked", "qualified"].includes(candidate?.status), "delivery-warrant-current-candidate-not-selected");
|
|
156
|
-
requireMatch(candidate?.sourceHead === active.sourceHead, "delivery-warrant-current-candidate-head-mismatch");
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
export async function enqueueAfterStatusPropagation({ enqueue, input, attempts, delayMs, sleep }) {
|
|
160
|
-
let lastError;
|
|
161
|
-
for (let attempt = 1; attempt <= attempts; attempt += 1) {
|
|
162
|
-
try {
|
|
163
|
-
return await enqueue(input);
|
|
164
|
-
} catch (error) {
|
|
165
|
-
lastError = error;
|
|
166
|
-
const propagation = /required status(?:es| check).*failing|failing required status|cannot change this locked branch/i.test(String(error?.message || ""));
|
|
167
|
-
if (!propagation || attempt === attempts) throw error;
|
|
168
|
-
await sleep(delayMs);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
throw lastError;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
119
|
export async function runSourceQualification({ options, pullRequest, readiness, client, evaluate, admissionState, createReceipt, root, publishDiagnostic, reject }) {
|
|
175
120
|
const decision = await evaluate(pullRequest, { ...options, landingMode: options.landingMode, dryRun: true }, client);
|
|
176
121
|
if (decision.observedHeadSha && String(decision.observedHeadSha).toLowerCase() !== options.expectedHeadSha) {
|
|
@@ -39,15 +39,18 @@ export async function resolveArtifactSigningAuthorityRuntime({
|
|
|
39
39
|
const ref = resolveAuthorityDispatchRef(authorityRef);
|
|
40
40
|
const encodedRef = ref.split("/").map(encodeURIComponent).join("/");
|
|
41
41
|
const response = await requestImpl(
|
|
42
|
-
`/repos/${authorityRepo}/
|
|
42
|
+
`/repos/${authorityRepo}/git/ref/heads/${encodedRef}`,
|
|
43
43
|
{ token: required(token, "Buildchain authority dispatch token") },
|
|
44
44
|
);
|
|
45
|
-
|
|
46
|
-
if (!/^[0-9a-f]{40}$/u.test(sha)) {
|
|
45
|
+
if (response?.object?.type !== "commit") {
|
|
47
46
|
throw new Error(
|
|
48
|
-
"Buildchain signing authority ref
|
|
47
|
+
"Buildchain signing authority ref does not resolve to a commit",
|
|
49
48
|
);
|
|
50
49
|
}
|
|
50
|
+
const sha = String(response.object.sha || "");
|
|
51
|
+
if (!/^[0-9a-f]{40}$/u.test(sha)) {
|
|
52
|
+
throw new Error("Buildchain signing authority runtime SHA must be exact");
|
|
53
|
+
}
|
|
51
54
|
return { ref, sha };
|
|
52
55
|
}
|
|
53
56
|
|