@intentius/chant 0.124.27 → 0.124.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/__golden__/wave-loop/fan-out-gated.json +8 -0
- package/dist/__golden__/wave-loop/fan-out-no-members.json +4 -0
- package/dist/__golden__/wave-loop/fan-out-only.json +6 -0
- package/dist/__golden__/wave-loop/op-by-apply-hold.json +2 -0
- package/dist/__golden__/wave-loop/op-cost-member.json +3 -0
- package/dist/__golden__/wave-loop/op-held-on-before-apply.json +1 -0
- package/dist/__golden__/wave-loop/op-held-on.json +2 -0
- package/dist/__golden__/wave-loop/op-hooks-held.json +2 -0
- package/dist/__golden__/wave-loop/op-hooks-hold-before-apply.json +2 -0
- package/dist/__golden__/wave-loop/op-hooks-refused-at-base.json +3 -0
- package/dist/__golden__/wave-loop/op-hooks-share.json +3 -0
- package/dist/__golden__/wave-loop/op-per-run.json +7 -0
- package/dist/__golden__/wave-loop/op-pr-review.json +7 -0
- package/dist/__golden__/wave-loop/op-sealed.json +3 -0
- package/dist/__golden__/wave-loop/op-spend.json +3 -0
- package/dist/__golden__/wave-loop/op-wave-commands.json +7 -0
- package/dist/__golden__/wave-loop/op-wide-waiting.json +4 -0
- package/dist/change-set-graph.d.ts +56 -0
- package/dist/change-set-graph.d.ts.map +1 -0
- package/dist/change-set-graph.js +128 -0
- package/dist/change-set.d.ts +52 -3
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +35 -4
- package/dist/chant-version.d.ts +9 -0
- package/dist/chant-version.d.ts.map +1 -0
- package/dist/chant-version.js +16 -0
- package/dist/cli/commands/build.d.ts +8 -0
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +9 -8
- package/dist/cli/commands/check-lexicon-docs.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon-docs.js +30 -2
- package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon.js +13 -2
- package/dist/cli/commands/init-lexicon/templates/docs.d.ts +4 -1
- package/dist/cli/commands/init-lexicon/templates/docs.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon/templates/docs.js +6 -6
- package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon.js +17 -8
- package/dist/cli/handlers/approve.d.ts.map +1 -1
- package/dist/cli/handlers/approve.js +19 -4
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.js +28 -0
- package/dist/cli/handlers/change-set.d.ts +10 -0
- package/dist/cli/handlers/change-set.d.ts.map +1 -1
- package/dist/cli/handlers/change-set.js +51 -1
- package/dist/cli/handlers/fan-out.d.ts +1 -1
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.js +14 -3
- package/dist/cli/handlers/pr.d.ts +8 -2
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +148 -24
- package/dist/cli/handlers/promote.d.ts.map +1 -1
- package/dist/cli/handlers/promote.js +256 -21
- package/dist/cli/handlers/release.d.ts +34 -0
- package/dist/cli/handlers/release.d.ts.map +1 -0
- package/dist/cli/handlers/release.js +203 -0
- package/dist/cli/handlers/run.d.ts +28 -2
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/handlers/run.js +170 -13
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +88 -13
- package/dist/cli/mcp/workspace-tools.js +1 -1
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +49 -3
- package/dist/cli/registry.d.ts +29 -3
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/cli/run-events.d.ts +29 -0
- package/dist/cli/run-events.d.ts.map +1 -0
- package/dist/cli/run-events.js +47 -0
- package/dist/cli/version.d.ts +3 -5
- package/dist/cli/version.d.ts.map +1 -1
- package/dist/cli/version.js +3 -13
- package/dist/codegen/docs-in-site.d.ts +71 -0
- package/dist/codegen/docs-in-site.d.ts.map +1 -0
- package/dist/codegen/docs-in-site.js +177 -0
- package/dist/codegen/docs-types.d.ts +14 -1
- package/dist/codegen/docs-types.d.ts.map +1 -1
- package/dist/codegen/docs.d.ts +18 -1
- package/dist/codegen/docs.d.ts.map +1 -1
- package/dist/codegen/docs.js +40 -7
- package/dist/codegen/rehype-base-url.mjs +15 -9
- package/dist/components/auto-release.d.ts +4 -1
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/auto-release.js +2 -0
- package/dist/components/cli-support.d.ts +6 -0
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/cli-support.js +10 -9
- package/dist/components/driver.d.ts +42 -9
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/driver.js +81 -54
- package/dist/components/fan-out-run.d.ts +7 -0
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-run.js +35 -26
- package/dist/components/pr-run.d.ts +11 -0
- package/dist/components/pr-run.d.ts.map +1 -1
- package/dist/components/pr-run.js +20 -1
- package/dist/components/promote-order.d.ts +38 -0
- package/dist/components/promote-order.d.ts.map +1 -0
- package/dist/components/promote-order.js +62 -0
- package/dist/components/promote.d.ts +15 -2
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/promote.js +17 -0
- package/dist/components/release-compile.d.ts +133 -0
- package/dist/components/release-compile.d.ts.map +1 -0
- package/dist/components/release-compile.js +376 -0
- package/dist/components/release-gate.d.ts +125 -0
- package/dist/components/release-gate.d.ts.map +1 -0
- package/dist/components/release-gate.js +282 -0
- package/dist/components/release-promote.d.ts +96 -0
- package/dist/components/release-promote.d.ts.map +1 -0
- package/dist/components/release-promote.js +204 -0
- package/dist/components/run-progress.d.ts +7 -0
- package/dist/components/run-progress.d.ts.map +1 -1
- package/dist/components/wave-plan.d.ts +3 -1
- package/dist/components/wave-plan.d.ts.map +1 -1
- package/dist/components/wave-plan.js +1 -1
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/lifecycle/change-set-store.d.ts +67 -0
- package/dist/lifecycle/change-set-store.d.ts.map +1 -0
- package/dist/lifecycle/change-set-store.js +96 -0
- package/dist/lifecycle/commit-sha.d.ts +13 -0
- package/dist/lifecycle/commit-sha.d.ts.map +1 -0
- package/dist/lifecycle/commit-sha.js +21 -0
- package/dist/lifecycle/gate-change-set.d.ts +69 -0
- package/dist/lifecycle/gate-change-set.d.ts.map +1 -0
- package/dist/lifecycle/gate-change-set.js +106 -0
- package/dist/lifecycle/gate-ledger.d.ts +49 -1
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.js +18 -0
- package/dist/lifecycle/release-cut.d.ts +107 -0
- package/dist/lifecycle/release-cut.d.ts.map +1 -0
- package/dist/lifecycle/release-cut.js +273 -0
- package/dist/lifecycle/release-ledger.d.ts +54 -0
- package/dist/lifecycle/release-ledger.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.js +53 -20
- package/dist/lifecycle/release-store.d.ts +190 -0
- package/dist/lifecycle/release-store.d.ts.map +1 -0
- package/dist/lifecycle/release-store.js +318 -0
- package/dist/lifecycle/run-ledger.d.ts +4 -0
- package/dist/lifecycle/run-ledger.d.ts.map +1 -1
- package/dist/lifecycle/run-ledger.js +2 -0
- package/dist/op/activities/change-coverage.d.ts.map +1 -1
- package/dist/op/activities/change-coverage.js +4 -2
- package/dist/op/activities/source-release.d.ts.map +1 -1
- package/dist/op/activities/source-release.js +7 -3
- package/dist/op/activities/source-rollback.d.ts.map +1 -1
- package/dist/op/activities/source-rollback.js +7 -3
- package/dist/op/gate-name.d.ts +11 -2
- package/dist/op/gate-name.d.ts.map +1 -1
- package/dist/op/gate-name.js +12 -3
- package/dist/op/gate-run-locator.d.ts +22 -0
- package/dist/op/gate-run-locator.d.ts.map +1 -1
- package/dist/op/gate-run-locator.js +31 -0
- package/dist/op/gate.d.ts +27 -3
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/gate.js +57 -3
- package/dist/op/local-executor.d.ts +36 -1
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-executor.js +158 -52
- package/dist/op/op-waves-run.d.ts.map +1 -1
- package/dist/op/op-waves-run.js +4 -0
- package/dist/op/run-live.d.ts +2 -0
- package/dist/op/run-live.d.ts.map +1 -1
- package/dist/op/run-live.js +1 -1
- package/dist/op/runtime.d.ts +46 -0
- package/dist/op/runtime.d.ts.map +1 -1
- package/dist/op/runtimes/local.d.ts.map +1 -1
- package/dist/op/runtimes/local.js +8 -0
- package/dist/point-decision.d.ts +2 -0
- package/dist/point-decision.d.ts.map +1 -1
- package/dist/point-decision.js +9 -2
- package/dist/run-event-store.d.ts +77 -0
- package/dist/run-event-store.d.ts.map +1 -0
- package/dist/run-event-store.js +204 -0
- package/dist/run-event-stream.d.ts +132 -0
- package/dist/run-event-stream.d.ts.map +1 -0
- package/dist/run-event-stream.js +238 -0
- package/dist/run-event.d.ts +267 -0
- package/dist/run-event.d.ts.map +1 -0
- package/dist/run-event.js +207 -0
- package/dist/wave-runtime.mjs +204 -199
- package/dist/workspace/__fixtures__/run-event-check.d.ts +19 -0
- package/dist/workspace/__fixtures__/run-event-check.d.ts.map +1 -0
- package/dist/workspace/__fixtures__/run-event-check.js +59 -0
- package/dist/workspace/change-set-show.d.ts +56 -0
- package/dist/workspace/change-set-show.d.ts.map +1 -0
- package/dist/workspace/change-set-show.js +54 -0
- package/dist/workspace/change-set-show.schema.json +102 -0
- package/dist/workspace/change-set.schema.json +28 -1
- package/dist/workspace/changes-cli.d.ts.map +1 -1
- package/dist/workspace/changes-cli.js +10 -1
- package/dist/workspace/changes.d.ts +37 -0
- package/dist/workspace/changes.d.ts.map +1 -1
- package/dist/workspace/changes.js +49 -2
- package/dist/workspace/changes.schema.json +135 -0
- package/dist/workspace/ci-green-cli.d.ts +19 -4
- package/dist/workspace/ci-green-cli.d.ts.map +1 -1
- package/dist/workspace/ci-green-cli.js +75 -12
- package/dist/workspace/ci-green-forge.d.ts +20 -3
- package/dist/workspace/ci-green-forge.d.ts.map +1 -1
- package/dist/workspace/ci-green-forge.js +6 -4
- package/dist/workspace/ci-green-workflow.d.ts +11 -0
- package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
- package/dist/workspace/ci-green-workflow.js +6 -0
- package/dist/workspace/ci-green.d.ts +273 -13
- package/dist/workspace/ci-green.d.ts.map +1 -1
- package/dist/workspace/ci-green.js +449 -38
- package/dist/workspace/ci-last-green.schema.json +32 -2
- package/dist/workspace/ci-list.schema.json +525 -0
- package/dist/workspace/commit-links.d.ts +85 -0
- package/dist/workspace/commit-links.d.ts.map +1 -0
- package/dist/workspace/commit-links.js +163 -0
- package/dist/workspace/declaration.d.ts +19 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.js +1 -1
- package/dist/workspace/declaration.schema.json +12 -0
- package/dist/workspace/identity-gate-rule.d.ts +37 -0
- package/dist/workspace/identity-gate-rule.d.ts.map +1 -1
- package/dist/workspace/identity-gate-rule.js +72 -7
- package/dist/workspace/identity.d.ts +12 -0
- package/dist/workspace/identity.d.ts.map +1 -1
- package/dist/workspace/identity.js +13 -1
- package/dist/workspace/intent.d.ts +6 -1
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/intent.js +51 -1
- package/dist/workspace/ls.d.ts +4 -0
- package/dist/workspace/ls.d.ts.map +1 -1
- package/dist/workspace/ls.js +2 -0
- package/dist/workspace/ls.schema.json +3 -1
- package/dist/workspace/member-pipeline.d.ts +6 -0
- package/dist/workspace/member-pipeline.d.ts.map +1 -1
- package/dist/workspace/member-pipeline.js +6 -0
- package/dist/workspace/promotion-order.d.ts +41 -0
- package/dist/workspace/promotion-order.d.ts.map +1 -0
- package/dist/workspace/promotion-order.js +95 -0
- package/dist/workspace/reason-codes.d.ts +2 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +4 -1
- package/dist/workspace/releases.d.ts +72 -0
- package/dist/workspace/releases.d.ts.map +1 -0
- package/dist/workspace/releases.js +94 -0
- package/dist/workspace/releases.schema.json +391 -0
- package/dist/workspace/run-event.schema.json +288 -0
- package/dist/workspace/status-gates.d.ts +26 -1
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status-gates.js +31 -2
- package/dist/workspace/status-stewards.d.ts +4 -0
- package/dist/workspace/status-stewards.d.ts.map +1 -1
- package/dist/workspace/status-stewards.js +2 -0
- package/dist/workspace/status.d.ts +39 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/status.js +48 -1
- package/dist/workspace/status.schema.json +70 -1
- package/dist/workspace/trust/ci-tag-statement.d.ts +102 -0
- package/dist/workspace/trust/ci-tag-statement.d.ts.map +1 -0
- package/dist/workspace/trust/ci-tag-statement.js +123 -0
- package/dist/workspace/trust/op-run-statement.d.ts +91 -0
- package/dist/workspace/trust/op-run-statement.d.ts.map +1 -0
- package/dist/workspace/trust/op-run-statement.js +143 -0
- package/dist/workspace/trust/rotation.d.ts +18 -2
- package/dist/workspace/trust/rotation.d.ts.map +1 -1
- package/dist/workspace/trust/rotation.js +65 -16
- package/dist/workspace/trust/seal.d.ts +11 -0
- package/dist/workspace/trust/seal.d.ts.map +1 -1
- package/dist/workspace/trust/seal.js +9 -0
- package/dist/workspace/trust/ssh-commit.d.ts.map +1 -1
- package/dist/workspace/trust/ssh-commit.js +10 -10
- package/package.json +1 -1
- package/src/__golden__/wave-loop/fan-out-gated.json +8 -0
- package/src/__golden__/wave-loop/fan-out-no-members.json +4 -0
- package/src/__golden__/wave-loop/fan-out-only.json +6 -0
- package/src/__golden__/wave-loop/op-by-apply-hold.json +2 -0
- package/src/__golden__/wave-loop/op-cost-member.json +3 -0
- package/src/__golden__/wave-loop/op-held-on-before-apply.json +1 -0
- package/src/__golden__/wave-loop/op-held-on.json +2 -0
- package/src/__golden__/wave-loop/op-hooks-held.json +2 -0
- package/src/__golden__/wave-loop/op-hooks-hold-before-apply.json +2 -0
- package/src/__golden__/wave-loop/op-hooks-refused-at-base.json +3 -0
- package/src/__golden__/wave-loop/op-hooks-share.json +3 -0
- package/src/__golden__/wave-loop/op-per-run.json +7 -0
- package/src/__golden__/wave-loop/op-pr-review.json +7 -0
- package/src/__golden__/wave-loop/op-sealed.json +3 -0
- package/src/__golden__/wave-loop/op-spend.json +3 -0
- package/src/__golden__/wave-loop/op-wave-commands.json +7 -0
- package/src/__golden__/wave-loop/op-wide-waiting.json +4 -0
- package/src/change-set-graph.test.ts +72 -0
- package/src/change-set-graph.ts +133 -0
- package/src/change-set.ts +76 -6
- package/src/chant-version.ts +16 -0
- package/src/cli/commands/build.ts +19 -8
- package/src/cli/commands/check-lexicon-docs.test.ts +51 -0
- package/src/cli/commands/check-lexicon-docs.ts +39 -2
- package/src/cli/commands/check-lexicon.ts +14 -2
- package/src/cli/commands/init-lexicon/templates/docs.ts +7 -6
- package/src/cli/commands/init-lexicon.test.ts +25 -0
- package/src/cli/commands/init-lexicon.ts +18 -8
- package/src/cli/handlers/approve-release.test.ts +80 -0
- package/src/cli/handlers/approve.ts +18 -2
- package/src/cli/handlers/build.test.ts +52 -0
- package/src/cli/handlers/build.ts +29 -0
- package/src/cli/handlers/change-set.ts +49 -1
- package/src/cli/handlers/fan-out.test.ts +48 -0
- package/src/cli/handlers/fan-out.ts +15 -3
- package/src/cli/handlers/operator.test.ts +37 -0
- package/src/cli/handlers/pr.test.ts +194 -0
- package/src/cli/handlers/pr.ts +168 -34
- package/src/cli/handlers/promote.test.ts +389 -5
- package/src/cli/handlers/promote.ts +279 -20
- package/src/cli/handlers/release-implicit.e2e.test.ts +153 -0
- package/src/cli/handlers/release.e2e.test.ts +85 -0
- package/src/cli/handlers/release.ts +206 -0
- package/src/cli/handlers/run-auto-release.test.ts +71 -0
- package/src/cli/handlers/run-events-cmd.test.ts +92 -0
- package/src/cli/handlers/run.test.ts +30 -0
- package/src/cli/handlers/run.ts +176 -15
- package/src/cli/main.test.ts +7 -0
- package/src/cli/main.ts +88 -13
- package/src/cli/mcp/never-over-mcp.test.ts +2 -0
- package/src/cli/mcp/workspace-tools.ts +1 -1
- package/src/cli/parse-args.ts +37 -3
- package/src/cli/registry.ts +29 -3
- package/src/cli/run-events.ts +54 -0
- package/src/cli/version.ts +3 -13
- package/src/codegen/docs-in-site.test.ts +166 -0
- package/src/codegen/docs-in-site.ts +182 -0
- package/src/codegen/docs-site/AgentPrompt.astro +26 -1
- package/src/codegen/docs-types.ts +14 -1
- package/src/codegen/docs.ts +60 -7
- package/src/codegen/rehype-base-url.d.mts +3 -1
- package/src/codegen/rehype-base-url.mjs +15 -9
- package/src/codegen/rehype-base-url.test.ts +34 -0
- package/src/components/auto-release.test.ts +21 -0
- package/src/components/auto-release.ts +6 -1
- package/src/components/cli-support.test.ts +82 -0
- package/src/components/cli-support.ts +16 -9
- package/src/components/driver.ts +129 -56
- package/src/components/fan-out-run.ts +56 -35
- package/src/components/pr-run.ts +30 -1
- package/src/components/promote-order.test.ts +90 -0
- package/src/components/promote-order.ts +75 -0
- package/src/components/promote.test.ts +10 -1
- package/src/components/promote.ts +26 -1
- package/src/components/release-compile.test.ts +147 -0
- package/src/components/release-compile.ts +445 -0
- package/src/components/release-gate.test.ts +215 -0
- package/src/components/release-gate.ts +341 -0
- package/src/components/release-promote.test.ts +159 -0
- package/src/components/release-promote.ts +232 -0
- package/src/components/run-progress.ts +7 -0
- package/src/components/wave-plan.ts +1 -1
- package/src/config.ts +7 -1
- package/src/index.ts +2 -0
- package/src/lifecycle/change-set-store.test.ts +217 -0
- package/src/lifecycle/change-set-store.ts +112 -0
- package/src/lifecycle/commit-sha.ts +23 -0
- package/src/lifecycle/gate-change-set.e2e.test.ts +122 -0
- package/src/lifecycle/gate-change-set.ts +133 -0
- package/src/lifecycle/gate-ledger.test.ts +33 -0
- package/src/lifecycle/gate-ledger.ts +66 -1
- package/src/lifecycle/release-cut-signed.test.ts +180 -0
- package/src/lifecycle/release-cut.test.ts +411 -0
- package/src/lifecycle/release-cut.ts +367 -0
- package/src/lifecycle/release-ledger.test.ts +14 -0
- package/src/lifecycle/release-ledger.ts +85 -17
- package/src/lifecycle/release-store.ts +423 -0
- package/src/lifecycle/run-ledger.test.ts +10 -0
- package/src/lifecycle/run-ledger.ts +6 -0
- package/src/op/activities/change-coverage.ts +4 -1
- package/src/op/activities/source-release.ts +8 -3
- package/src/op/activities/source-rollback.ts +8 -4
- package/src/op/commit-run-gate-deploy-join.test.ts +117 -0
- package/src/op/gate-name.ts +13 -3
- package/src/op/gate-release.test.ts +126 -0
- package/src/op/gate-run-locator.test.ts +110 -0
- package/src/op/gate-run-locator.ts +35 -0
- package/src/op/gate.ts +88 -6
- package/src/op/local-executor.ts +207 -52
- package/src/op/op-waves-run.ts +4 -0
- package/src/op/run-events.test.ts +166 -0
- package/src/op/run-live.ts +1 -1
- package/src/op/runtime.ts +39 -0
- package/src/op/runtimes/local.test.ts +16 -0
- package/src/op/runtimes/local.ts +9 -0
- package/src/point-decision.ts +12 -2
- package/src/run-event-store.test.ts +144 -0
- package/src/run-event-store.ts +213 -0
- package/src/run-event-stream.test.ts +175 -0
- package/src/run-event-stream.ts +306 -0
- package/src/run-event.test.ts +277 -0
- package/src/run-event.ts +451 -0
- package/src/wave-loop-golden.test.ts +9 -0
- package/src/workspace/__fixtures__/run-event-check.ts +58 -0
- package/src/workspace/ancestry-index.test.ts +93 -0
- package/src/workspace/change-set-show.schema.json +102 -0
- package/src/workspace/change-set-show.ts +72 -0
- package/src/workspace/change-set.schema.json +28 -1
- package/src/workspace/changes-cli.ts +10 -1
- package/src/workspace/changes.schema.json +135 -0
- package/src/workspace/changes.test.ts +1 -1
- package/src/workspace/changes.ts +84 -2
- package/src/workspace/ci-green-cli.ts +75 -13
- package/src/workspace/ci-green-forge.ts +24 -4
- package/src/workspace/ci-green-runs.test.ts +242 -0
- package/src/workspace/ci-green-signed.test.ts +302 -0
- package/src/workspace/ci-green-workflow.test.ts +16 -0
- package/src/workspace/ci-green-workflow.ts +12 -0
- package/src/workspace/ci-green.test.ts +131 -2
- package/src/workspace/ci-green.ts +624 -42
- package/src/workspace/ci-last-green.schema.json +32 -2
- package/src/workspace/ci-list.schema.json +525 -0
- package/src/workspace/commit-links.test.ts +279 -0
- package/src/workspace/commit-links.ts +183 -0
- package/src/workspace/declaration.schema.json +12 -0
- package/src/workspace/declaration.ts +22 -2
- package/src/workspace/identity-gate-rule.ts +91 -7
- package/src/workspace/identity.ts +14 -1
- package/src/workspace/intent.ts +48 -1
- package/src/workspace/ls.schema.json +3 -1
- package/src/workspace/ls.ts +6 -0
- package/src/workspace/member-pipeline.test.ts +17 -0
- package/src/workspace/member-pipeline.ts +9 -0
- package/src/workspace/promotion-order.ts +97 -0
- package/src/workspace/read-contract.e2e.test.ts +4 -1
- package/src/workspace/reason-codes.test.ts +2 -1
- package/src/workspace/reason-codes.ts +4 -1
- package/src/workspace/releases.schema.json +391 -0
- package/src/workspace/releases.test.ts +108 -0
- package/src/workspace/releases.ts +122 -0
- package/src/workspace/run-event.schema.json +288 -0
- package/src/workspace/status-contract.test.ts +52 -1
- package/src/workspace/status-gates.ts +56 -1
- package/src/workspace/status-stewards.ts +6 -0
- package/src/workspace/status.schema.json +70 -1
- package/src/workspace/status.ts +80 -1
- package/src/workspace/trust/ci-tag-statement.ts +151 -0
- package/src/workspace/trust/op-run-statement.ts +148 -0
- package/src/workspace/trust/rotation.ts +61 -14
- package/src/workspace/trust/seal.ts +10 -0
- package/src/workspace/trust/ssh-commit.ts +10 -9
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/astro.config.mjs +0 -14
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/package.json +0 -16
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/src/content/docs/index.mdx +0 -8
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/src/content.config.ts +0 -15
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/tsconfig.json +0 -10
|
@@ -52,6 +52,7 @@ import { gateName } from "../op/gate-name.js";
|
|
|
52
52
|
import { GateNotRecordableError } from "../lifecycle/no-record.js";
|
|
53
53
|
import { componentPlanDigest } from "./gate-plan.js";
|
|
54
54
|
import { isPromotedArtifact } from "./auto-release.js";
|
|
55
|
+
import { gateEventsOf, joinRunEventSinks, progressSinkOf } from "../run-event-stream.js";
|
|
55
56
|
function isGateStep(step) {
|
|
56
57
|
return step.kind === "gate";
|
|
57
58
|
}
|
|
@@ -210,7 +211,7 @@ class GateStop extends Error {
|
|
|
210
211
|
this.name = "GateStop";
|
|
211
212
|
}
|
|
212
213
|
}
|
|
213
|
-
/** A result status as the
|
|
214
|
+
/** A result status as the event stream spells it — the only difference is `fail` vs `failed`, which the two vocabularies have always disagreed on. */
|
|
214
215
|
function progressStatus(status) {
|
|
215
216
|
return status === "fail" ? "failed" : status;
|
|
216
217
|
}
|
|
@@ -261,30 +262,44 @@ async function runCapabilityStep(step, phaseName, ctx, registry, phaseOutputs, c
|
|
|
261
262
|
* gate is a read of the ledger rather than work, and starting activities a
|
|
262
263
|
* pending gate is about to strand defeats the point of stopping at it.
|
|
263
264
|
*
|
|
264
|
-
* `
|
|
265
|
-
* step runs, a `step`
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
265
|
+
* `emit`, when supplied, gets the phase's run events (#4041): `phase-start`
|
|
266
|
+
* before any step runs, a `step-start` and a `step-settle` around each gate
|
|
267
|
+
* and each capability invocation, the gate's `gate-resolved` or
|
|
268
|
+
* `gate-waiting`, a `skipped` settle with `skip: "not-run"` for each step a
|
|
269
|
+
* failure or a gate stopped, and `phase-settle` once the phase settles. It
|
|
270
|
+
* is observation only, never consulted for control flow. Recursion into a
|
|
271
|
+
* nested fan-out phase passes the same sink through, so a nested phase's
|
|
272
|
+
* events use its own name. `--progress-json` reads the same events through
|
|
273
|
+
* `progressOfRunEvent` (../run-event-stream.ts), which keeps the older
|
|
274
|
+
* stream's shape.
|
|
272
275
|
*/
|
|
273
|
-
async function runPhase(phaseDef, ctx, registry, phaseOutputs, componentOutputs, gates,
|
|
276
|
+
async function runPhase(phaseDef, ctx, registry, phaseOutputs, componentOutputs, gates, emit) {
|
|
277
|
+
/** Where a step of this phase sits, for its events. */
|
|
278
|
+
const stepAt = (entry, step) => ({
|
|
279
|
+
component: ctx.component,
|
|
280
|
+
phase: phaseDef.phase,
|
|
281
|
+
step,
|
|
282
|
+
index: phaseDef.steps.indexOf(entry),
|
|
283
|
+
});
|
|
274
284
|
/** Decide this phase's gates against the ledger, in authored order, before any of its work starts. Throws `GateStop` at the first one nobody has approved. */
|
|
275
285
|
const decideGates = async () => {
|
|
276
286
|
const gateRecords = [];
|
|
277
287
|
for (const gate of phaseDef.steps.filter(isGateStep)) {
|
|
278
288
|
const start = Date.now();
|
|
279
289
|
const base = { component: ctx.component, phase: phaseDef.phase, kind: `gate:${gateName(gate)}` };
|
|
290
|
+
const at = stepAt(gate, base.kind);
|
|
291
|
+
emit?.({ type: "step-start", ...at });
|
|
280
292
|
let check;
|
|
281
293
|
try {
|
|
282
294
|
check = await evaluateGate(gates.port, {
|
|
283
|
-
op: ctx.component,
|
|
295
|
+
op: gates.releaseGate?.op ?? ctx.component,
|
|
284
296
|
gate: gateName(gate),
|
|
285
297
|
// #2574: an approval counts only for this environment and this plan.
|
|
286
298
|
environment: ctx.env,
|
|
287
299
|
...(gates.planDigest !== undefined ? { planDigest: gates.planDigest } : {}),
|
|
300
|
+
// #4045: and under a release, only for that release.
|
|
301
|
+
...(gates.releaseGate ? { releaseDigest: gates.releaseGate.releaseDigest } : {}),
|
|
302
|
+
...(gates.releaseGate?.verifyEmpty ? { verifyEmpty: gates.releaseGate.verifyEmpty } : {}),
|
|
288
303
|
...(gate.description ? { description: gate.description } : {}),
|
|
289
304
|
...(gate.timeout ? { timeout: gate.timeout } : {}),
|
|
290
305
|
...(gates.now ? { now: gates.now } : {}),
|
|
@@ -296,11 +311,18 @@ async function runPhase(phaseDef, ctx, registry, phaseOutputs, componentOutputs,
|
|
|
296
311
|
if (!(err instanceof GateNotRecordableError))
|
|
297
312
|
throw err;
|
|
298
313
|
gateRecords.push({ ...base, status: "fail", durationMs: Date.now() - start, error: err.message });
|
|
314
|
+
emit?.({ type: "step-settle", ...at, status: "failed", durationMs: Date.now() - start, error: err.message });
|
|
299
315
|
for (const skipped of phaseDef.steps.filter((s) => !isGateStep(s))) {
|
|
300
316
|
gateRecords.push(skippedRecord(skipped));
|
|
301
317
|
}
|
|
302
318
|
throw new StepFailure(gateRecords, []);
|
|
303
319
|
}
|
|
320
|
+
for (const body of gateEventsOf(check, { ...at, op: gates.releaseGate?.op ?? ctx.component, gate: gateName(gate) }, {
|
|
321
|
+
durationMs: Date.now() - start,
|
|
322
|
+
...(!check.satisfied && check.mismatch ? { message: "an approval stands for this gate, but for another environment or plan" } : {}),
|
|
323
|
+
})) {
|
|
324
|
+
emit?.(body);
|
|
325
|
+
}
|
|
304
326
|
if (!check.satisfied) {
|
|
305
327
|
gateRecords.push({ ...base, status: "skipped", durationMs: Date.now() - start });
|
|
306
328
|
for (const skipped of phaseDef.steps.filter((s) => !isGateStep(s))) {
|
|
@@ -317,6 +339,8 @@ async function runPhase(phaseDef, ctx, registry, phaseOutputs, componentOutputs,
|
|
|
317
339
|
resolvedBy: check.resolution.resolvedBy,
|
|
318
340
|
timestamp: check.resolution.timestamp,
|
|
319
341
|
...(check.resolution.url ? { url: check.resolution.url } : {}),
|
|
342
|
+
...(gates.releaseGate ? { op: gates.releaseGate.op } : {}),
|
|
343
|
+
...(check.via === "empty" ? { empty: true } : {}),
|
|
320
344
|
},
|
|
321
345
|
});
|
|
322
346
|
}
|
|
@@ -326,7 +350,7 @@ async function runPhase(phaseDef, ctx, registry, phaseOutputs, componentOutputs,
|
|
|
326
350
|
const runEntry = async (entry) => {
|
|
327
351
|
if (isPhaseStep(entry)) {
|
|
328
352
|
try {
|
|
329
|
-
const nested = await runPhase(entry, ctx, registry, phaseOutputs, componentOutputs, gates,
|
|
353
|
+
const nested = await runPhase(entry, ctx, registry, phaseOutputs, componentOutputs, gates, emit);
|
|
330
354
|
return { ...nested, failed: false };
|
|
331
355
|
}
|
|
332
356
|
catch (err) {
|
|
@@ -348,14 +372,14 @@ async function runPhase(phaseDef, ctx, registry, phaseOutputs, componentOutputs,
|
|
|
348
372
|
throw err;
|
|
349
373
|
}
|
|
350
374
|
}
|
|
351
|
-
|
|
375
|
+
const at = stepAt(entry, entry.kind);
|
|
376
|
+
emit?.({ type: "step-start", ...at });
|
|
352
377
|
const { record, resolvedInput, output } = await runCapabilityStep(entry, phaseDef.phase, ctx, registry, phaseOutputs, componentOutputs);
|
|
353
|
-
|
|
354
|
-
type: "step",
|
|
355
|
-
|
|
356
|
-
phase: phaseDef.phase,
|
|
357
|
-
step: entry.kind,
|
|
378
|
+
emit?.({
|
|
379
|
+
type: "step-settle",
|
|
380
|
+
...at,
|
|
358
381
|
status: record.status === "ok" ? "ok" : "failed",
|
|
382
|
+
durationMs: record.durationMs,
|
|
359
383
|
...(record.error !== undefined ? { error: record.error } : {}),
|
|
360
384
|
});
|
|
361
385
|
if (record.status === "ok") {
|
|
@@ -372,13 +396,12 @@ async function runPhase(phaseDef, ctx, registry, phaseOutputs, componentOutputs,
|
|
|
372
396
|
failed: record.status === "fail",
|
|
373
397
|
};
|
|
374
398
|
};
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
phase:
|
|
378
|
-
|
|
379
|
-
status: "skipped",
|
|
380
|
-
|
|
381
|
-
});
|
|
399
|
+
/** A step a failure or a gate stopped before it started: recorded, and settled `skipped` with `skip: "not-run"`. */
|
|
400
|
+
const skippedRecord = (entry) => {
|
|
401
|
+
const kind = isPhaseStep(entry) ? entry.phase : entry.kind;
|
|
402
|
+
emit?.({ type: "step-settle", ...stepAt(entry, kind), status: "skipped", skip: "not-run", durationMs: null });
|
|
403
|
+
return { component: ctx.component, phase: phaseDef.phase, kind, status: "skipped", durationMs: 0 };
|
|
404
|
+
};
|
|
382
405
|
const runEntries = async () => {
|
|
383
406
|
const gateRecords = await decideGates();
|
|
384
407
|
if (phaseDef.parallel) {
|
|
@@ -412,18 +435,18 @@ async function runPhase(phaseDef, ctx, registry, phaseOutputs, componentOutputs,
|
|
|
412
435
|
}
|
|
413
436
|
return { records, executed };
|
|
414
437
|
};
|
|
415
|
-
|
|
438
|
+
emit?.({ type: "phase-start", component: ctx.component, phase: phaseDef.phase });
|
|
416
439
|
try {
|
|
417
440
|
const result = await runEntries();
|
|
418
|
-
|
|
441
|
+
emit?.({ type: "phase-settle", component: ctx.component, phase: phaseDef.phase, status: "ok" });
|
|
419
442
|
return result;
|
|
420
443
|
}
|
|
421
444
|
catch (err) {
|
|
422
445
|
if (err instanceof GateStop) {
|
|
423
|
-
|
|
446
|
+
emit?.({ type: "phase-settle", component: ctx.component, phase: phaseDef.phase, status: "gated" });
|
|
424
447
|
}
|
|
425
448
|
else if (err instanceof StepFailure) {
|
|
426
|
-
|
|
449
|
+
emit?.({ type: "phase-settle", component: ctx.component, phase: phaseDef.phase, status: "failed" });
|
|
427
450
|
}
|
|
428
451
|
throw err;
|
|
429
452
|
}
|
|
@@ -492,16 +515,17 @@ async function rollbackExecuted(executed, ctx, registry) {
|
|
|
492
515
|
* any) are recorded into `componentOutputs` under its own name so downstream
|
|
493
516
|
* components can reference `@<name>.publish.*`.
|
|
494
517
|
*
|
|
495
|
-
* `onProgress
|
|
496
|
-
*
|
|
497
|
-
* `
|
|
498
|
-
* `
|
|
499
|
-
* unwind step-by-step compensation
|
|
500
|
-
*
|
|
501
|
-
*
|
|
502
|
-
*
|
|
518
|
+
* `onProgress` (the older `RunProgressEvent` stream) and `onRunEvent` (run
|
|
519
|
+
* events, #4041), when supplied, are forwarded to every `runPhase` call (both
|
|
520
|
+
* the forward `deploy` phases and, on failure, the component's own authored
|
|
521
|
+
* `rollback` phases), so a consumer sees the phase and step events of
|
|
522
|
+
* whichever phases actually ran. The saga unwind step-by-step compensation
|
|
523
|
+
* (`rollbackExecuted` below) stays silent: it isn't a `deploy` phase, and
|
|
524
|
+
* its record statuses (`rolled-back`/`rollback-opted-out`) are not step
|
|
525
|
+
* statuses either stream has.
|
|
503
526
|
*/
|
|
504
|
-
export async function runComponentDeploy(component, ctx, registry, componentOutputs, onProgress, gateContext = { port: gitGateLedgerPort() }) {
|
|
527
|
+
export async function runComponentDeploy(component, ctx, registry, componentOutputs, onProgress, gateContext = { port: gitGateLedgerPort() }, onRunEvent) {
|
|
528
|
+
const emit = joinRunEventSinks(onRunEvent, progressSinkOf(onProgress));
|
|
505
529
|
// Each component tracks its own release: a digest one component promoted never stamps another's deploy.
|
|
506
530
|
if (ctx.release)
|
|
507
531
|
ctx = { ...ctx, release: { ...ctx.release } };
|
|
@@ -515,18 +539,20 @@ export async function runComponentDeploy(component, ctx, registry, componentOutp
|
|
|
515
539
|
ctx.release.version = release;
|
|
516
540
|
const gates = {
|
|
517
541
|
...gateContext,
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
542
|
+
// #4045: a release gate binds the release's change set, not this composition.
|
|
543
|
+
planDigest: gateContext.releaseGate?.planDigest ??
|
|
544
|
+
componentPlanDigest({
|
|
545
|
+
environment: ctx.env,
|
|
546
|
+
component,
|
|
547
|
+
...(ctx.vars ? { vars: ctx.vars } : {}),
|
|
548
|
+
...(release !== undefined ? { release } : {}),
|
|
549
|
+
}),
|
|
524
550
|
};
|
|
525
551
|
const records = [];
|
|
526
552
|
const allExecuted = [];
|
|
527
553
|
try {
|
|
528
554
|
for (const phaseDef of component.deploy) {
|
|
529
|
-
const result = await runPhase(phaseDef, ctx, registry, phaseOutputs, componentOutputs, gates,
|
|
555
|
+
const result = await runPhase(phaseDef, ctx, registry, phaseOutputs, componentOutputs, gates, emit);
|
|
530
556
|
records.push(...result.records);
|
|
531
557
|
allExecuted.push(...result.executed);
|
|
532
558
|
}
|
|
@@ -559,7 +585,7 @@ export async function runComponentDeploy(component, ctx, registry, componentOutp
|
|
|
559
585
|
records.push(...(await rollbackExecuted(allExecuted, ctx, registry)));
|
|
560
586
|
for (const phaseDef of [...(component.rollback ?? [])].reverse()) {
|
|
561
587
|
try {
|
|
562
|
-
const result = await runPhase(phaseDef, ctx, registry, phaseOutputs, componentOutputs, gates,
|
|
588
|
+
const result = await runPhase(phaseDef, ctx, registry, phaseOutputs, componentOutputs, gates, emit);
|
|
563
589
|
records.push(...result.records);
|
|
564
590
|
}
|
|
565
591
|
catch (compErr) {
|
|
@@ -688,29 +714,30 @@ export async function runInterpretDriver(components, registry, options) {
|
|
|
688
714
|
const { order, waves } = resolveComponentGraph(components);
|
|
689
715
|
const byName = new Map(components.map((c) => [c.name, c]));
|
|
690
716
|
const componentOutputs = { ...(options.componentOutputs ?? {}) };
|
|
691
|
-
const
|
|
717
|
+
const emit = joinRunEventSinks(options.onRunEvent, progressSinkOf(options.onProgress));
|
|
692
718
|
const gates = {
|
|
693
719
|
port: options.gates ?? gitGateLedgerPort(),
|
|
694
720
|
...(options.now ? { now: options.now } : {}),
|
|
695
721
|
...(options.releases ? { releases: options.releases } : {}),
|
|
722
|
+
...(options.releaseGate ? { releaseGate: options.releaseGate } : {}),
|
|
696
723
|
};
|
|
697
|
-
|
|
724
|
+
emit?.({ type: "run-start", waves });
|
|
698
725
|
const results = [];
|
|
699
726
|
let failedComponent;
|
|
700
727
|
let gated;
|
|
701
728
|
waveLoop: for (const [waveIndex, wave] of waves.entries()) {
|
|
702
729
|
const waveNum = waveIndex + 1;
|
|
703
|
-
|
|
730
|
+
emit?.({ type: "wave-start", wave: waveNum, components: wave });
|
|
704
731
|
const waveComponents = wave.map((name) => byName.get(name));
|
|
705
732
|
const waveResults = await Promise.all(waveComponents.map(async (component) => {
|
|
706
|
-
|
|
707
|
-
const result = await runComponentDeploy(component, deployContext(options, component.name), registry, componentOutputs,
|
|
708
|
-
|
|
733
|
+
emit?.({ type: "component-start", wave: waveNum, component: component.name });
|
|
734
|
+
const result = await runComponentDeploy(component, deployContext(options, component.name), registry, componentOutputs, undefined, gates, emit);
|
|
735
|
+
emit?.({ type: "component-settle", wave: waveNum, component: component.name, status: progressStatus(result.status) });
|
|
709
736
|
return result;
|
|
710
737
|
}));
|
|
711
738
|
results.push(...waveResults);
|
|
712
739
|
const stopped = waveResults.find((r) => r.status !== "ok");
|
|
713
|
-
|
|
740
|
+
emit?.({ type: "wave-settle", wave: waveNum, status: progressStatus(stopped?.status ?? "ok") });
|
|
714
741
|
if (stopped) {
|
|
715
742
|
// A failure in the same wave outranks a gate: something is actually
|
|
716
743
|
// broken, and reporting the run as "waiting on a human" would hide it.
|
|
@@ -724,7 +751,7 @@ export async function runInterpretDriver(components, registry, options) {
|
|
|
724
751
|
}
|
|
725
752
|
const status = failedComponent ? "fail" : gated ? "gated" : "ok";
|
|
726
753
|
const ok = status === "ok";
|
|
727
|
-
|
|
754
|
+
emit?.({ type: "run-settle", status: progressStatus(status), durationMs: null });
|
|
728
755
|
const result = {
|
|
729
756
|
order, waves, results, ok, status, failedComponent, componentOutputs,
|
|
730
757
|
...(gated
|
|
@@ -42,6 +42,7 @@ import type { ReleaseIdentity } from "../telemetry-attribution.js";
|
|
|
42
42
|
import { type FanOutPlan, type FanOutProgress, type FanOutSkip } from "./fan-out.js";
|
|
43
43
|
import { type GateLedgerPort } from "../op/gate.js";
|
|
44
44
|
import type { RunProgressEvent } from "./run-progress.js";
|
|
45
|
+
import { type RunEventSink } from "../run-event-stream.js";
|
|
45
46
|
import type { CapabilityRegistry } from "./capability.js";
|
|
46
47
|
import type { PendingGateRecord } from "../lifecycle/gate-ledger.js";
|
|
47
48
|
import type { DeployContext } from "./capability.js";
|
|
@@ -93,6 +94,12 @@ export interface FanOutRunOptions {
|
|
|
93
94
|
/** Outputs of components this run is not running: the ones the plan lists in `seeds`. */
|
|
94
95
|
componentOutputs?: Record<string, Record<string, unknown>>;
|
|
95
96
|
onProgress?: (event: RunProgressEvent) => void;
|
|
97
|
+
/**
|
|
98
|
+
* Where the run's events go (#4041, `--events-json`). A gate over the set
|
|
99
|
+
* or over a wave is a `gate:<name>` step of a `gate` phase with no
|
|
100
|
+
* component, settled before the components it lets through start.
|
|
101
|
+
*/
|
|
102
|
+
onRunEvent?: RunEventSink;
|
|
96
103
|
gates?: GateLedgerPort;
|
|
97
104
|
now?: string;
|
|
98
105
|
/** One approval over the ordered set, bound to `plan.digest`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fan-out-run.d.ts","sourceRoot":"","sources":["../../src/components/fan-out-run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAE3B,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAqC,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AACrH,OAAO,EAAmD,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAClG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAqB,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAA6E,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"fan-out-run.d.ts","sourceRoot":"","sources":["../../src/components/fan-out-run.ts"],"names":[],"mappings":"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"}
|
|
@@ -40,8 +40,13 @@
|
|
|
40
40
|
import { deployContext, runComponentDeploy, } from "./driver.js";
|
|
41
41
|
import { downstreamWithin, remainingFanOut } from "./fan-out.js";
|
|
42
42
|
import { evaluateGate, gitGateLedgerPort } from "../op/gate.js";
|
|
43
|
+
import { emitGateStep, joinRunEventSinks, progressSinkOf } from "../run-event-stream.js";
|
|
43
44
|
import { planWaveComponent } from "./wave-plan.js";
|
|
44
45
|
import { decideWaveGate, runWaveLoop, waveGateName, waveSetDigest } from "../wave-engine.js";
|
|
46
|
+
/** The sink a fan-out emits to: run events, and the older stream through them. */
|
|
47
|
+
function fanOutSink(options) {
|
|
48
|
+
return joinRunEventSinks(options.onRunEvent, progressSinkOf(options.onProgress));
|
|
49
|
+
}
|
|
45
50
|
/** Thrown when `FanOutWaveGate.only` names a wave whose predecessors have not all applied. */
|
|
46
51
|
export class EarlierWaveNotAppliedError extends Error {
|
|
47
52
|
constructor(wave, earlier, components) {
|
|
@@ -78,18 +83,22 @@ export async function runFanOut(plan, components, registry, options) {
|
|
|
78
83
|
if (options.waveGate) {
|
|
79
84
|
return runGatedWaves(plan, active, components, registry, options, options.waveGate, gates, componentOutputs);
|
|
80
85
|
}
|
|
86
|
+
const emit = fanOutSink(options);
|
|
87
|
+
emit?.({ type: "run-start", waves: active.waves });
|
|
81
88
|
if (options.gate) {
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
89
|
+
const gate = options.gate;
|
|
90
|
+
const check = await emitGateStep(emit, gate, () => evaluateGate(gates.port, {
|
|
91
|
+
op: gate.op,
|
|
92
|
+
gate: gate.gate,
|
|
85
93
|
planDigest: active.digest,
|
|
86
|
-
...(
|
|
87
|
-
...(
|
|
94
|
+
...(gate.description ? { description: gate.description } : {}),
|
|
95
|
+
...(gate.timeout ? { timeout: gate.timeout } : {}),
|
|
88
96
|
...(options.now ? { now: options.now } : {}),
|
|
89
|
-
});
|
|
97
|
+
}));
|
|
90
98
|
if (!check.satisfied) {
|
|
91
99
|
// Nothing ran, so nothing is half-applied and there is nothing to
|
|
92
100
|
// compensate. A gate is a fact, not a failure.
|
|
101
|
+
emit?.({ type: "run-settle", status: "gated", durationMs: null });
|
|
93
102
|
return {
|
|
94
103
|
plan: active,
|
|
95
104
|
status: "gated",
|
|
@@ -116,20 +125,19 @@ export async function runFanOut(plan, components, registry, options) {
|
|
|
116
125
|
blockedBy.set(component, by);
|
|
117
126
|
}
|
|
118
127
|
};
|
|
119
|
-
options.onProgress?.({ type: "run-start", waves: active.waves });
|
|
120
128
|
for (const [waveIndex, wave] of active.waves.entries()) {
|
|
121
129
|
const waveNum = waveIndex + 1;
|
|
122
130
|
// A component whose upstream failed in an earlier wave is not dispatched.
|
|
123
131
|
const runnable = wave.filter((name) => inPlan.has(name) && !blockedBy.has(name));
|
|
124
132
|
if (runnable.length === 0)
|
|
125
133
|
continue;
|
|
126
|
-
|
|
134
|
+
emit?.({ type: "wave-start", wave: waveNum, components: runnable });
|
|
127
135
|
const waveResults = await Promise.all(runnable.map(async (name) => {
|
|
128
|
-
|
|
136
|
+
emit?.({ type: "component-start", wave: waveNum, component: name });
|
|
129
137
|
const planned = options.plans?.[name];
|
|
130
|
-
const result = await runComponentDeploy(byName.get(name), { ...fanOutContext(options, name), ...(planned && Object.keys(planned).length > 0 ? { plans: planned } : {}) }, registry, componentOutputs,
|
|
131
|
-
|
|
132
|
-
type: "component-
|
|
138
|
+
const result = await runComponentDeploy(byName.get(name), { ...fanOutContext(options, name), ...(planned && Object.keys(planned).length > 0 ? { plans: planned } : {}) }, registry, componentOutputs, undefined, gates, emit);
|
|
139
|
+
emit?.({
|
|
140
|
+
type: "component-settle",
|
|
133
141
|
wave: waveNum,
|
|
134
142
|
component: name,
|
|
135
143
|
status: result.status === "fail" ? "failed" : result.status,
|
|
@@ -155,8 +163,8 @@ export async function runFanOut(plan, components, registry, options) {
|
|
|
155
163
|
markBlocked(result.component);
|
|
156
164
|
}
|
|
157
165
|
const waveFailed = waveResults.some((r) => r.status === "fail");
|
|
158
|
-
|
|
159
|
-
type: "wave-
|
|
166
|
+
emit?.({
|
|
167
|
+
type: "wave-settle",
|
|
160
168
|
wave: waveNum,
|
|
161
169
|
status: waveFailed ? "failed" : waveResults.some((r) => r.status === "gated") ? "gated" : "ok",
|
|
162
170
|
});
|
|
@@ -167,7 +175,7 @@ export async function runFanOut(plan, components, registry, options) {
|
|
|
167
175
|
// A failure outranks a gate: something is actually broken, and reporting the
|
|
168
176
|
// run as "waiting on a human" would hide it. Same precedence the driver uses.
|
|
169
177
|
const status = failed.length > 0 ? "fail" : gatedFact ? "gated" : "ok";
|
|
170
|
-
|
|
178
|
+
emit?.({ type: "run-settle", status: status === "fail" ? "failed" : status, durationMs: null });
|
|
171
179
|
return {
|
|
172
180
|
plan: active,
|
|
173
181
|
status,
|
|
@@ -230,7 +238,8 @@ async function runGatedWaves(plan, active, components, registry, options, waveGa
|
|
|
230
238
|
blockedBy.set(component, by);
|
|
231
239
|
}
|
|
232
240
|
};
|
|
233
|
-
|
|
241
|
+
const emit = fanOutSink(options);
|
|
242
|
+
emit?.({ type: "run-start", waves: plan.waves });
|
|
234
243
|
await runWaveLoop({
|
|
235
244
|
first: 1,
|
|
236
245
|
onward: (_k, outcome) => outcome === "next",
|
|
@@ -300,14 +309,14 @@ async function runGatedWaves(plan, active, components, registry, options, waveGa
|
|
|
300
309
|
options.onWaveSettled?.(record);
|
|
301
310
|
return { end: "next" };
|
|
302
311
|
}
|
|
303
|
-
const check = await decideWaveGate(gates.port, {
|
|
312
|
+
const check = await emitGateStep(emit, { op: waveGate.op, gate: gateName }, () => decideWaveGate(gates.port, {
|
|
304
313
|
op: waveGate.op,
|
|
305
314
|
gate: gateName,
|
|
306
315
|
digest,
|
|
307
316
|
description: waveGate.description ?? `wave ${waveNum} of ${plan.waves.length}: ${toRun.join(", ")}`,
|
|
308
317
|
...(waveGate.timeout ? { timeout: waveGate.timeout } : {}),
|
|
309
318
|
...(options.now ? { now: options.now } : {}),
|
|
310
|
-
});
|
|
319
|
+
}));
|
|
311
320
|
if (!check.satisfied) {
|
|
312
321
|
// Nothing in this wave ran, and no later wave is planned: its plan
|
|
313
322
|
// would read outputs this wave has not written.
|
|
@@ -324,14 +333,14 @@ async function runGatedWaves(plan, active, components, registry, options, waveGa
|
|
|
324
333
|
return { go: { check, record, toRun } };
|
|
325
334
|
},
|
|
326
335
|
async apply({ k: waveNum }, { contexts, plansFor, waveFailures }, { check, record, toRun }) {
|
|
327
|
-
|
|
336
|
+
emit?.({ type: "wave-start", wave: waveNum, components: toRun });
|
|
328
337
|
const waveResults = await Promise.all(toRun.map(async (name) => {
|
|
329
|
-
|
|
338
|
+
emit?.({ type: "component-start", wave: waveNum, component: name });
|
|
330
339
|
const plans = plansFor.get(name);
|
|
331
340
|
const ctx = { ...contexts.get(name), ...(Object.keys(plans).length > 0 ? { plans } : {}) };
|
|
332
|
-
const result = await runComponentDeploy(byName.get(name), ctx, registry, componentOutputs,
|
|
333
|
-
|
|
334
|
-
type: "component-
|
|
341
|
+
const result = await runComponentDeploy(byName.get(name), ctx, registry, componentOutputs, undefined, gates, emit);
|
|
342
|
+
emit?.({
|
|
343
|
+
type: "component-settle",
|
|
335
344
|
wave: waveNum,
|
|
336
345
|
component: name,
|
|
337
346
|
status: result.status === "fail" ? "failed" : result.status,
|
|
@@ -362,8 +371,8 @@ async function runGatedWaves(plan, active, components, registry, options, waveGa
|
|
|
362
371
|
};
|
|
363
372
|
waves.push(settled);
|
|
364
373
|
options.onWaveSettled?.(settled);
|
|
365
|
-
|
|
366
|
-
type: "wave-
|
|
374
|
+
emit?.({
|
|
375
|
+
type: "wave-settle",
|
|
367
376
|
wave: waveNum,
|
|
368
377
|
status: waveFailures.length > 0 ? "failed" : waveResults.some((r) => r.status === "gated") ? "gated" : "ok",
|
|
369
378
|
});
|
|
@@ -374,7 +383,7 @@ async function runGatedWaves(plan, active, components, registry, options, waveGa
|
|
|
374
383
|
.sort(([a], [b]) => a.localeCompare(b))
|
|
375
384
|
.map(([component, by]) => ({ component, reason: "blocked", blockedBy: by }));
|
|
376
385
|
const status = failed.length > 0 ? "fail" : gatedFact ? "gated" : "ok";
|
|
377
|
-
|
|
386
|
+
emit?.({ type: "run-settle", status: status === "fail" ? "failed" : status, durationMs: null });
|
|
378
387
|
return {
|
|
379
388
|
// The derivation's waves, not the narrowed re-layering: their numbers name the gates.
|
|
380
389
|
plan: { ...active, waves: plan.waves },
|
|
@@ -41,6 +41,7 @@ import { type ComponentChangeSignal, type FanOutPlan } from "./fan-out.js";
|
|
|
41
41
|
import type { PrApplyRecord } from "./fan-out-record.js";
|
|
42
42
|
import type { CapabilityRegistry } from "./capability.js";
|
|
43
43
|
import type { RunProgressEvent } from "./run-progress.js";
|
|
44
|
+
import type { RunEventSink } from "../run-event-stream.js";
|
|
44
45
|
export interface PrPlanSetOptions {
|
|
45
46
|
/** Every component in the project. */
|
|
46
47
|
components: DriverComponent[];
|
|
@@ -51,7 +52,15 @@ export interface PrPlanSetOptions {
|
|
|
51
52
|
vars?: Record<string, unknown>;
|
|
52
53
|
/** Outputs supplied by the caller (`--seed-outputs`). They win over outputs read here. */
|
|
53
54
|
seededOutputs?: Record<string, Record<string, unknown>>;
|
|
55
|
+
/**
|
|
56
|
+
* Where the planning's events go (#4041): a `plan` phase with no
|
|
57
|
+
* component, and in it one `plan` step per component, started as its wave
|
|
58
|
+
* is planned and settled `ok` or `failed`.
|
|
59
|
+
*/
|
|
60
|
+
onRunEvent?: RunEventSink;
|
|
54
61
|
}
|
|
62
|
+
/** The phase a pull request's planning is, in its run's events. */
|
|
63
|
+
export declare const PR_PLAN_PHASE = "plan";
|
|
55
64
|
/** Every member of a pull request, planned. */
|
|
56
65
|
export interface PrPlanSet {
|
|
57
66
|
/** The change-set document over every member. Its digest is what the gate binds. */
|
|
@@ -101,6 +110,8 @@ export interface PrApplyOptions {
|
|
|
101
110
|
/** The set {@link planPrSet} planned and the gate approved, or {@link resumePrSet}'s set. */
|
|
102
111
|
set: PrPlanSet;
|
|
103
112
|
onProgress?: (event: RunProgressEvent) => void;
|
|
113
|
+
/** Where the apply's events go (#4041): the fan-out's run events. */
|
|
114
|
+
onRunEvent?: RunEventSink;
|
|
104
115
|
/**
|
|
105
116
|
* What an earlier attempt at this approved set applied (#3464): its
|
|
106
117
|
* components, which are reported applied and not run again, and the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pr-run.d.ts","sourceRoot":"","sources":["../../src/components/pr-run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAA2C,KAAK,iBAAiB,EAA2C,MAAM,eAAe,CAAC;AACzI,OAAO,EAAgB,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,QAAQ,EACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAiB,KAAK,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAE3F,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAmB,KAAK,qBAAqB,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AACzF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"pr-run.d.ts","sourceRoot":"","sources":["../../src/components/pr-run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAA2C,KAAK,iBAAiB,EAA2C,MAAM,eAAe,CAAC;AACzI,OAAO,EAAgB,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,QAAQ,EACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAiB,KAAK,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAE3F,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAmB,KAAK,qBAAqB,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AACzF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,MAAM,WAAW,gBAAgB;IAC/B,sCAAsC;IACtC,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,qFAAqF;IACrF,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,0FAA0F;IAC1F,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD;;;;OAIG;IACH,UAAU,CAAC,EAAE,YAAY,CAAC;CAC3B;AAED,mEAAmE;AACnE,eAAO,MAAM,aAAa,SAAS,CAAC;AAEpC,+CAA+C;AAC/C,MAAM,WAAW,SAAS;IACxB,oFAAoF;IACpF,GAAG,EAAE,iBAAiB,CAAC;IACvB,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,qFAAqF;IACrF,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/C,0FAA0F;IAC1F,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACjD,4CAA4C;IAC5C,MAAM,EAAE,OAAO,CAAC;CACjB;AAWD;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC,CAoE7E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,cAAc,CAQnE;AAED,wDAAwD;AACxD,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,CAOvD;AAED,uDAAuD;AACvD,wBAAsB,YAAY,CAChC,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtF,OAAO,CAAC,SAAS,CAAC,CAQpB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAI5G;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,6FAA6F;IAC7F,GAAG,EAAE,SAAS,CAAC;IACf,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC/C,qEAAqE;IACrE,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B;;;;OAIG;IACH,OAAO,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;KAAE,CAAC;IACpF,4FAA4F;IAC5F,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,KAAK,IAAI,CAAC;CAC5G;AAID;;;GAGG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAAC,GAAG,EAAE,eAAe,CAAA;CAAE,CAAC,CA0C9I;AAID;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,iBAAiB,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAqDvH;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,yGAAyG;IACzG,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,iDAAiD;IACjD,MAAM,EAAE,aAAa,CAAC;IACtB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,MAAM,QAAQ,GAChB;IACE,EAAE,EAAE,IAAI,CAAC;IACT,+CAA+C;IAC/C,IAAI,EAAE,UAAU,CAAC;IACjB,mGAAmG;IACnG,GAAG,EAAE,SAAS,CAAC;IACf,wDAAwD;IACxD,KAAK,EAAE,SAAS,CAAC;CAClB,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,6EAA6E;IAC7E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEN;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,CA8B7E;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,GAAG,EAAE,SAAS,CAAC;IACf,QAAQ,EAAE,UAAU,CAAC;IACrB,MAAM,EAAE,QAAQ,CAAC;IACjB,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,iCAAiC;AACjC,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,QAAQ,CA6BvD"}
|
|
@@ -40,6 +40,8 @@ import { deployUnits } from "./deploy-units.js";
|
|
|
40
40
|
import { runFanOut } from "./fan-out-run.js";
|
|
41
41
|
import { remainingFanOut } from "./fan-out.js";
|
|
42
42
|
import { planWaveComponent, readComponentOutputs } from "./wave-plan.js";
|
|
43
|
+
/** The phase a pull request's planning is, in its run's events. */
|
|
44
|
+
export const PR_PLAN_PHASE = "plan";
|
|
43
45
|
/** A failed component's members: the units its steps target, else the component itself. */
|
|
44
46
|
function failedParts(component, error) {
|
|
45
47
|
const units = deployUnits(component.deploy).map((u) => u.unit);
|
|
@@ -61,6 +63,8 @@ export async function planPrSet(options) {
|
|
|
61
63
|
const componentOf = new Map();
|
|
62
64
|
const plans = {};
|
|
63
65
|
let failed = false;
|
|
66
|
+
const emit = options.onRunEvent;
|
|
67
|
+
emit?.({ type: "phase-start", component: null, phase: PR_PLAN_PHASE });
|
|
64
68
|
for (const wave of options.plan.waves) {
|
|
65
69
|
// The dependencies' outputs first, each read once. A dependency that
|
|
66
70
|
// cannot say leaves its references unresolved, which its dependent's
|
|
@@ -75,7 +79,20 @@ export async function planPrSet(options) {
|
|
|
75
79
|
outputs[dep] = found;
|
|
76
80
|
}
|
|
77
81
|
}
|
|
78
|
-
const planned = await Promise.all(wave.map((name) =>
|
|
82
|
+
const planned = await Promise.all(wave.map(async (name) => {
|
|
83
|
+
const at = { component: name, phase: PR_PLAN_PHASE, step: "plan" };
|
|
84
|
+
emit?.({ type: "step-start", ...at });
|
|
85
|
+
const start = Date.now();
|
|
86
|
+
const p = await planWaveComponent(byName.get(name), options.registry, deployContext(options, name), outputs);
|
|
87
|
+
emit?.({
|
|
88
|
+
type: "step-settle",
|
|
89
|
+
...at,
|
|
90
|
+
status: "error" in p ? "failed" : "ok",
|
|
91
|
+
durationMs: Date.now() - start,
|
|
92
|
+
...("error" in p ? { error: p.error } : {}),
|
|
93
|
+
});
|
|
94
|
+
return p;
|
|
95
|
+
}));
|
|
79
96
|
for (const p of planned) {
|
|
80
97
|
const component = byName.get(p.component);
|
|
81
98
|
if ("error" in p) {
|
|
@@ -93,6 +110,7 @@ export async function planPrSet(options) {
|
|
|
93
110
|
}
|
|
94
111
|
}
|
|
95
112
|
}
|
|
113
|
+
emit?.({ type: "phase-settle", component: null, phase: PR_PLAN_PHASE, status: failed ? "failed" : "ok" });
|
|
96
114
|
const doc = composeChangeSet(parts);
|
|
97
115
|
const members = doc.members.map((m) => ({
|
|
98
116
|
member: m.member,
|
|
@@ -161,6 +179,7 @@ export async function applyPrSet(options) {
|
|
|
161
179
|
plans: options.set.plans,
|
|
162
180
|
componentOutputs: { ...before },
|
|
163
181
|
...(options.onProgress ? { onProgress: options.onProgress } : {}),
|
|
182
|
+
...(options.onRunEvent ? { onRunEvent: options.onRunEvent } : {}),
|
|
164
183
|
...(options.onComponentSettled ? { onComponentSettled: options.onComponentSettled } : {}),
|
|
165
184
|
});
|
|
166
185
|
const completed = new Set(run.completed);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The environment `chant components promote` reads from, given the member's
|
|
3
|
+
* promotion order (#4030, see `../workspace/promotion-order.ts`). These
|
|
4
|
+
* refusals are promote's own and are not codes of the workspace read contract.
|
|
5
|
+
*/
|
|
6
|
+
import type { PromotionStep } from "../workspace/promotion-order.js";
|
|
7
|
+
/** The refusals `components promote` gives for the declared order. Stable: scripts may match on them. */
|
|
8
|
+
export declare const PROMOTE_ORDER_CODES: readonly [
|
|
9
|
+
/** `--from` is more than one step behind `--to` in the declared order, and `--allow-skip` was not given. */
|
|
10
|
+
"promote-skips-environment",
|
|
11
|
+
/** `--to` is the first step of the declared order, so no environment comes before it to default `--from` to. */
|
|
12
|
+
"promote-no-previous-environment",
|
|
13
|
+
/** `--from` was left out and `--to` is not a step of the declared order, so there is nothing to default it from. */
|
|
14
|
+
"promote-to-not-in-order"];
|
|
15
|
+
export type PromoteOrderCode = (typeof PROMOTE_ORDER_CODES)[number];
|
|
16
|
+
export interface PromotionRefusal {
|
|
17
|
+
error: {
|
|
18
|
+
code: PromoteOrderCode;
|
|
19
|
+
message: string;
|
|
20
|
+
fix: string;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The environment a promote reads from. With an order declared, `--from`
|
|
25
|
+
* defaults to the step before `to`, and a `--from` that skips a step is
|
|
26
|
+
* refused unless `allowSkip`. Without an order, or when `to` or `from` is not
|
|
27
|
+
* a step of it, the order has nothing to say and `from` is returned as given
|
|
28
|
+
* (`undefined` is the caller's to refuse, as before).
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolvePromotionSource(opts: {
|
|
31
|
+
order: readonly PromotionStep[];
|
|
32
|
+
to: string;
|
|
33
|
+
from?: string;
|
|
34
|
+
allowSkip?: boolean;
|
|
35
|
+
}): {
|
|
36
|
+
from: string | undefined;
|
|
37
|
+
} | PromotionRefusal;
|
|
38
|
+
//# sourceMappingURL=promote-order.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promote-order.d.ts","sourceRoot":"","sources":["../../src/components/promote-order.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,yGAAyG;AACzG,eAAO,MAAM,mBAAmB;AAC9B,4GAA4G;AAC5G,2BAA2B;AAC3B,gHAAgH;AAChH,iCAAiC;AACjC,oHAAoH;AACpH,yBAAyB,CACjB,CAAC;AACX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE;QAAE,IAAI,EAAE,gBAAgB,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACjE;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GAAG;IAAE,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAAG,gBAAgB,CAuClD"}
|