@intentius/chant 0.124.51 → 0.124.54
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/dist/audit/discover.d.ts.map +1 -1
- package/dist/audit/discover.js +3 -1
- package/dist/behaviour.d.ts +1 -1
- package/dist/behaviour.d.ts.map +1 -1
- package/dist/capabilities/templates.d.ts +65 -0
- package/dist/capabilities/templates.d.ts.map +1 -0
- package/dist/capabilities/templates.js +193 -0
- package/dist/capabilities/templates.json +145 -0
- package/dist/change-set-graph.d.ts +35 -3
- package/dist/change-set-graph.d.ts.map +1 -1
- package/dist/change-set-graph.js +60 -9
- package/dist/change-set.d.ts +65 -7
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +23 -12
- package/dist/ci-identity.d.ts +7 -2
- package/dist/ci-identity.d.ts.map +1 -1
- package/dist/ci-identity.js +4 -1
- package/dist/cli/commands/import-index.d.ts +52 -0
- package/dist/cli/commands/import-index.d.ts.map +1 -0
- package/dist/cli/commands/import-index.js +226 -0
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/lint.js +4 -2
- package/dist/cli/handlers/components.d.ts.map +1 -1
- package/dist/cli/handlers/components.js +11 -2
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.js +16 -3
- package/dist/cli/handlers/graph.d.ts.map +1 -1
- package/dist/cli/handlers/graph.js +22 -4
- package/dist/cli/handlers/index-cloud.d.ts +14 -0
- package/dist/cli/handlers/index-cloud.d.ts.map +1 -0
- package/dist/cli/handlers/index-cloud.js +22 -0
- package/dist/cli/handlers/index-diff.d.ts +18 -0
- package/dist/cli/handlers/index-diff.d.ts.map +1 -0
- package/dist/cli/handlers/index-diff.js +142 -0
- package/dist/cli/handlers/lifecycle-drift.d.ts +25 -0
- package/dist/cli/handlers/lifecycle-drift.d.ts.map +1 -0
- package/dist/cli/handlers/lifecycle-drift.js +64 -0
- package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
- package/dist/cli/handlers/lifecycle.js +188 -28
- package/dist/cli/handlers/misc.d.ts +9 -0
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/misc.js +77 -0
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +17 -3
- package/dist/cli/handlers/promote.d.ts.map +1 -1
- package/dist/cli/handlers/promote.js +89 -15
- package/dist/cli/handlers/query.d.ts.map +1 -1
- package/dist/cli/handlers/query.js +28 -4
- package/dist/cli/handlers/scenario.d.ts.map +1 -1
- package/dist/cli/handlers/scenario.js +8 -7
- package/dist/cli/handlers/search.d.ts +34 -4
- package/dist/cli/handlers/search.d.ts.map +1 -1
- package/dist/cli/handlers/search.js +216 -36
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +55 -1
- package/dist/cli/mcp/lifecycle-tools.d.ts.map +1 -1
- package/dist/cli/mcp/lifecycle-tools.js +3 -2
- package/dist/cli/mcp/resource-handlers.d.ts.map +1 -1
- package/dist/cli/mcp/resource-handlers.js +4 -3
- 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 +55 -2
- package/dist/cli/registry.d.ts +19 -1
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/cloud-lister/aws.d.ts +35 -0
- package/dist/cloud-lister/aws.d.ts.map +1 -0
- package/dist/cloud-lister/aws.js +203 -0
- package/dist/cloud-lister/azure.d.ts +34 -0
- package/dist/cloud-lister/azure.d.ts.map +1 -0
- package/dist/cloud-lister/azure.js +129 -0
- package/dist/cloud-lister/common.d.ts +40 -0
- package/dist/cloud-lister/common.d.ts.map +1 -0
- package/dist/cloud-lister/common.js +83 -0
- package/dist/cloud-lister/credentials.d.ts +50 -0
- package/dist/cloud-lister/credentials.d.ts.map +1 -0
- package/dist/cloud-lister/credentials.js +86 -0
- package/dist/cloud-lister/fakes.d.ts +27 -0
- package/dist/cloud-lister/fakes.d.ts.map +1 -0
- package/dist/cloud-lister/fakes.js +50 -0
- package/dist/cloud-lister/gcp.d.ts +42 -0
- package/dist/cloud-lister/gcp.d.ts.map +1 -0
- package/dist/cloud-lister/gcp.js +143 -0
- package/dist/cloud-lister/guard.d.ts +49 -0
- package/dist/cloud-lister/guard.d.ts.map +1 -0
- package/dist/cloud-lister/guard.js +103 -0
- package/dist/cloud-lister/ids.d.ts +23 -0
- package/dist/cloud-lister/ids.d.ts.map +1 -0
- package/dist/cloud-lister/ids.js +42 -0
- package/dist/cloud-lister/index.d.ts +67 -0
- package/dist/cloud-lister/index.d.ts.map +1 -0
- package/dist/cloud-lister/index.js +102 -0
- package/dist/cloud-lister/kubernetes.d.ts +64 -0
- package/dist/cloud-lister/kubernetes.d.ts.map +1 -0
- package/dist/cloud-lister/kubernetes.js +276 -0
- package/dist/cloud-lister/markers.d.ts +31 -0
- package/dist/cloud-lister/markers.d.ts.map +1 -0
- package/dist/cloud-lister/markers.js +73 -0
- package/dist/cloud-lister/mask.d.ts +31 -0
- package/dist/cloud-lister/mask.d.ts.map +1 -0
- package/dist/cloud-lister/mask.js +74 -0
- package/dist/cloud-lister/sigv4.d.ts +29 -0
- package/dist/cloud-lister/sigv4.d.ts.map +1 -0
- package/dist/cloud-lister/sigv4.js +54 -0
- package/dist/cloud-lister/transport.d.ts +55 -0
- package/dist/cloud-lister/transport.d.ts.map +1 -0
- package/dist/cloud-lister/transport.js +86 -0
- package/dist/cloud-lister/types.d.ts +121 -0
- package/dist/cloud-lister/types.d.ts.map +1 -0
- package/dist/cloud-lister/types.js +24 -0
- package/dist/components/capability-plugin-loader.d.ts.map +1 -1
- package/dist/components/capability-plugin-loader.js +6 -0
- package/dist/components/capability-plugin.d.ts +9 -0
- package/dist/components/capability-plugin.d.ts.map +1 -1
- package/dist/components/capability.d.ts +224 -0
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/cli-support.d.ts +21 -0
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/cli-support.js +58 -14
- package/dist/components/covered-round.d.ts +173 -0
- package/dist/components/covered-round.d.ts.map +1 -0
- package/dist/components/covered-round.js +200 -0
- package/dist/components/declared-reads.d.ts +38 -0
- package/dist/components/declared-reads.d.ts.map +1 -0
- package/dist/components/declared-reads.js +131 -0
- package/dist/components/deploy-units.d.ts.map +1 -1
- package/dist/components/deploy-units.js +4 -0
- package/dist/components/driver.d.ts +42 -1
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/driver.js +74 -3
- package/dist/components/fan-out-run.d.ts +23 -1
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-run.js +82 -14
- package/dist/components/fan-out-support.d.ts +6 -0
- package/dist/components/fan-out-support.d.ts.map +1 -1
- package/dist/components/fan-out-support.js +4 -1
- package/dist/components/fan-out.d.ts +28 -0
- package/dist/components/fan-out.d.ts.map +1 -1
- package/dist/components/groups.d.ts +229 -0
- package/dist/components/groups.d.ts.map +1 -0
- package/dist/components/groups.js +760 -0
- package/dist/components/index.d.ts +7 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +5 -0
- package/dist/components/plan-shape-conformance.d.ts +48 -0
- package/dist/components/plan-shape-conformance.d.ts.map +1 -0
- package/dist/components/plan-shape-conformance.js +122 -0
- package/dist/components/pr-run.d.ts +62 -7
- package/dist/components/pr-run.d.ts.map +1 -1
- package/dist/components/pr-run.js +354 -53
- package/dist/components/promote-rounds.d.ts +9 -0
- package/dist/components/promote-rounds.d.ts.map +1 -1
- package/dist/components/promote-rounds.js +23 -2
- package/dist/components/promote.d.ts +17 -0
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/promote.js +36 -6
- package/dist/components/release-gate.d.ts +23 -1
- package/dist/components/release-gate.d.ts.map +1 -1
- package/dist/components/release-gate.js +97 -33
- package/dist/components/run-groups.d.ts +58 -0
- package/dist/components/run-groups.d.ts.map +1 -0
- package/dist/components/run-groups.js +78 -0
- package/dist/components/starter-plugin.d.ts +1 -0
- package/dist/components/starter-plugin.d.ts.map +1 -1
- package/dist/components/starter-plugin.js +6 -1
- package/dist/components/verbs/index.d.ts +1 -0
- package/dist/components/verbs/index.d.ts.map +1 -1
- package/dist/components/verbs/index.js +1 -0
- package/dist/components/verbs/member-outputs.d.ts +187 -0
- package/dist/components/verbs/member-outputs.d.ts.map +1 -0
- package/dist/components/verbs/member-outputs.js +218 -0
- package/dist/components/wave-plan.d.ts +2 -0
- package/dist/components/wave-plan.d.ts.map +1 -1
- package/dist/components/wave-plan.js +4 -1
- package/dist/config.d.ts +60 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +27 -0
- package/dist/deep-observation.d.ts +1 -13
- package/dist/deep-observation.d.ts.map +1 -1
- package/dist/deep-observation.js +5 -22
- package/dist/drift-record.d.ts +542 -0
- package/dist/drift-record.d.ts.map +1 -0
- package/dist/drift-record.js +886 -0
- package/dist/engine-facts.d.ts +144 -0
- package/dist/engine-facts.d.ts.map +1 -0
- package/dist/engine-facts.js +14 -0
- package/dist/graph-ir.d.ts +153 -2
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/graph-ir.js +224 -6
- package/dist/graph-refs.d.ts +145 -0
- package/dist/graph-refs.d.ts.map +1 -1
- package/dist/graph-refs.js +305 -0
- package/dist/graph-schema/fixtures/adopt.json +15 -0
- package/dist/graph-schema/fixtures/choudoufu.engine-graph.json +169 -0
- package/dist/graph-schema/fixtures/index.json +68 -0
- package/dist/graph-schema/fixtures/plunge.engine-graph.json +158 -0
- package/dist/graph-schema/fixtures.d.ts +23 -0
- package/dist/graph-schema/fixtures.d.ts.map +1 -0
- package/dist/graph-schema/fixtures.js +246 -0
- package/dist/graph-schema/generate.d.ts +15 -0
- package/dist/graph-schema/generate.d.ts.map +1 -0
- package/dist/graph-schema/generate.js +267 -0
- package/dist/graph-schema/graph.schema.json +1387 -0
- package/dist/health.schema.json +2 -1
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/instance-nodes.d.ts +159 -0
- package/dist/instance-nodes.d.ts.map +1 -0
- package/dist/instance-nodes.js +231 -0
- package/dist/lexicon.d.ts +72 -0
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/adoption-file.d.ts +56 -0
- package/dist/lifecycle/adoption-file.d.ts.map +1 -0
- package/dist/lifecycle/adoption-file.js +123 -0
- package/dist/lifecycle/cloud-index.d.ts +186 -0
- package/dist/lifecycle/cloud-index.d.ts.map +1 -0
- package/dist/lifecycle/cloud-index.js +618 -0
- package/dist/lifecycle/derive-edges.d.ts +59 -0
- package/dist/lifecycle/derive-edges.d.ts.map +1 -0
- package/dist/lifecycle/derive-edges.js +126 -0
- package/dist/lifecycle/git.d.ts +10 -9
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/git.js +7 -1
- package/dist/lifecycle/identity-match.d.ts +133 -0
- package/dist/lifecycle/identity-match.d.ts.map +1 -0
- package/dist/lifecycle/identity-match.js +147 -0
- package/dist/lifecycle/index-diff.d.ts +224 -0
- package/dist/lifecycle/index-diff.d.ts.map +1 -0
- package/dist/lifecycle/index-diff.js +327 -0
- package/dist/lifecycle/index-document.d.ts +130 -0
- package/dist/lifecycle/index-document.d.ts.map +1 -0
- package/dist/lifecycle/index-document.js +189 -0
- package/dist/lifecycle/index-drift.d.ts +121 -0
- package/dist/lifecycle/index-drift.d.ts.map +1 -0
- package/dist/lifecycle/index-drift.js +178 -0
- package/dist/lifecycle/index-import.d.ts +168 -0
- package/dist/lifecycle/index-import.d.ts.map +1 -0
- package/dist/lifecycle/index-import.js +515 -0
- package/dist/lifecycle/index-join.d.ts +129 -0
- package/dist/lifecycle/index-join.d.ts.map +1 -0
- package/dist/lifecycle/index-join.js +248 -0
- package/dist/lifecycle/index.d.ts +4 -0
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/index.js +4 -0
- package/dist/lifecycle/observation-baseline.d.ts +61 -21
- package/dist/lifecycle/observation-baseline.d.ts.map +1 -1
- package/dist/lifecycle/observation-baseline.js +144 -19
- package/dist/lifecycle/observe.d.ts.map +1 -1
- package/dist/lifecycle/observe.js +6 -1
- package/dist/lifecycle/query.d.ts +45 -4
- package/dist/lifecycle/query.d.ts.map +1 -1
- package/dist/lifecycle/query.js +89 -7
- package/dist/lifecycle/replay.d.ts +10 -3
- package/dist/lifecycle/replay.d.ts.map +1 -1
- package/dist/lifecycle/replay.js +10 -6
- package/dist/lifecycle/scenario.d.ts +4 -3
- package/dist/lifecycle/scenario.d.ts.map +1 -1
- package/dist/lifecycle/snapshot-store-fake.d.ts +9 -0
- package/dist/lifecycle/snapshot-store-fake.d.ts.map +1 -0
- package/dist/lifecycle/snapshot-store-fake.js +21 -0
- package/dist/lifecycle/snapshot-store-s3.d.ts +102 -0
- package/dist/lifecycle/snapshot-store-s3.d.ts.map +1 -0
- package/dist/lifecycle/snapshot-store-s3.js +254 -0
- package/dist/lifecycle/snapshot-store.d.ts +170 -0
- package/dist/lifecycle/snapshot-store.d.ts.map +1 -0
- package/dist/lifecycle/snapshot-store.js +832 -0
- package/dist/lifecycle/snapshot.d.ts +11 -0
- package/dist/lifecycle/snapshot.d.ts.map +1 -1
- package/dist/lifecycle/snapshot.js +18 -5
- package/dist/lifecycle/type-listing.d.ts +148 -0
- package/dist/lifecycle/type-listing.d.ts.map +1 -0
- package/dist/lifecycle/type-listing.js +166 -0
- package/dist/lint/component-checks.d.ts +15 -1
- package/dist/lint/component-checks.d.ts.map +1 -1
- package/dist/lint/component-checks.js +1 -0
- package/dist/lint/presets/relaxed.json +2 -1
- package/dist/lint/presets/strict.json +2 -1
- package/dist/lint/rules/__fixtures__/comp/comp008/fail/dns.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/fail/dns.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/fail/dns.component.js +13 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/pass/dns.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/pass/dns.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/pass/dns.component.js +8 -0
- package/dist/lint/rules/comp/comp008-applies-signal-only-root.d.ts +33 -0
- package/dist/lint/rules/comp/comp008-applies-signal-only-root.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp008-applies-signal-only-root.js +123 -0
- package/dist/lint/rules/comp/index.d.ts +2 -1
- package/dist/lint/rules/comp/index.d.ts.map +1 -1
- package/dist/lint/rules/comp/index.js +4 -1
- package/dist/observation.d.ts +19 -2
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +18 -1
- package/dist/op/activities/activity-contracts.d.ts +1 -1
- package/dist/op/activities/activity-contracts.js +1 -1
- package/dist/op/activities/change-set.d.ts +6 -4
- package/dist/op/activities/change-set.d.ts.map +1 -1
- package/dist/op/activities/change-set.js +4 -2
- package/dist/op/activity-failure.d.ts +27 -0
- package/dist/op/activity-failure.d.ts.map +1 -1
- package/dist/op/activity-failure.js +31 -0
- package/dist/op/index.d.ts +2 -1
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/index.js +1 -1
- package/dist/op/local-executor.d.ts +5 -1
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-executor.js +22 -8
- package/dist/pr-loop.d.ts +92 -3
- package/dist/pr-loop.d.ts.map +1 -1
- package/dist/pr-loop.js +62 -3
- package/dist/pulumi-urn.d.ts +101 -0
- package/dist/pulumi-urn.d.ts.map +1 -0
- package/dist/pulumi-urn.js +131 -0
- package/dist/release-floors.d.ts +23 -0
- package/dist/release-floors.d.ts.map +1 -0
- package/dist/release-floors.js +22 -0
- package/dist/sensitive-key.d.ts +23 -0
- package/dist/sensitive-key.d.ts.map +1 -0
- package/dist/sensitive-key.js +31 -0
- package/dist/wave-runtime.mjs +234 -234
- package/dist/workspace/adoption-report.d.ts +53 -0
- package/dist/workspace/adoption-report.d.ts.map +1 -0
- package/dist/workspace/adoption-report.js +76 -0
- package/dist/workspace/capabilities-contract.d.ts +7 -0
- package/dist/workspace/capabilities-contract.d.ts.map +1 -1
- package/dist/workspace/capabilities-contract.js +2 -1
- package/dist/workspace/capabilities.schema.json +98 -0
- package/dist/workspace/change-set.schema.json +42 -3
- package/dist/workspace/ci-cloud-identity.d.ts +13 -1
- package/dist/workspace/ci-cloud-identity.d.ts.map +1 -1
- package/dist/workspace/ci-cloud-identity.js +30 -1
- package/dist/workspace/compose-graph.d.ts +10 -1
- package/dist/workspace/compose-graph.d.ts.map +1 -1
- package/dist/workspace/compose-graph.js +6 -1
- package/dist/workspace/conformance/index.d.ts +1 -1
- package/dist/workspace/conformance/index.d.ts.map +1 -1
- package/dist/workspace/conformance/index.js +6 -1
- package/dist/workspace/drift-cli.d.ts +81 -0
- package/dist/workspace/drift-cli.d.ts.map +1 -0
- package/dist/workspace/drift-cli.js +317 -0
- package/dist/workspace/drift.schema.json +672 -0
- package/dist/workspace/graph-cli.d.ts +2 -0
- package/dist/workspace/graph-cli.d.ts.map +1 -1
- package/dist/workspace/graph-cli.js +3 -0
- package/dist/workspace/graph.schema.json +72 -0
- package/dist/workspace/init.d.ts +5 -1
- package/dist/workspace/init.d.ts.map +1 -1
- package/dist/workspace/init.js +55 -9
- package/dist/workspace/ledger.schema.json +1 -1
- package/dist/workspace/nested-graph.d.ts.map +1 -1
- package/dist/workspace/nested-graph.js +2 -0
- package/dist/workspace/pr-report.schema.json +76 -3
- package/dist/workspace/promote-waves.d.ts +112 -0
- package/dist/workspace/promote-waves.d.ts.map +1 -0
- package/dist/workspace/promote-waves.js +290 -0
- package/dist/workspace/promote.d.ts +84 -2
- package/dist/workspace/promote.d.ts.map +1 -1
- package/dist/workspace/promote.js +347 -61
- package/dist/workspace/reason-codes.d.ts +12 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +14 -0
- package/dist/workspace/search-contract.d.ts +3 -3
- package/dist/workspace/search-contract.d.ts.map +1 -1
- package/dist/workspace/search-contract.js +2 -0
- package/dist/workspace/search.schema.json +103 -5
- package/package.json +14 -1
- package/src/__fixtures__/drift-record/README.md +58 -0
- package/src/__fixtures__/drift-record/choudoufu-cone.ndjson +4 -0
- package/src/__fixtures__/drift-record/choudoufu-resource.ndjson +3 -0
- package/src/__fixtures__/drift-record/component-status-ledger.json +65 -0
- package/src/__fixtures__/drift-record/component-status.json +91 -0
- package/src/__fixtures__/drift-record/deep-diff.json +259 -0
- package/src/__fixtures__/drift-record/lifecycle-diff-live.json +825 -0
- package/src/__fixtures__/drift-record/live-diff.json +125 -0
- package/src/audit/discover.e2e.test.ts +14 -0
- package/src/audit/discover.ts +3 -1
- package/src/behaviour.ts +1 -1
- package/src/capabilities/templates.json +145 -0
- package/src/capabilities/templates.test.ts +212 -0
- package/src/capabilities/templates.ts +204 -0
- package/src/change-set-bundle.test.ts +83 -0
- package/src/change-set-graph.ts +80 -9
- package/src/change-set.test.ts +24 -0
- package/src/change-set.ts +77 -14
- package/src/ci-identity-targets.test.ts +23 -0
- package/src/ci-identity.ts +10 -4
- package/src/cli/commands/import-index.test.ts +117 -0
- package/src/cli/commands/import-index.ts +265 -0
- package/src/cli/commands/lint.ts +4 -2
- package/src/cli/handlers/components.test.ts +9 -0
- package/src/cli/handlers/components.ts +12 -2
- package/src/cli/handlers/fan-out.ts +17 -3
- package/src/cli/handlers/graph.test.ts +42 -0
- package/src/cli/handlers/graph.ts +26 -4
- package/src/cli/handlers/index-cloud.ts +32 -0
- package/src/cli/handlers/index-diff.test.ts +68 -0
- package/src/cli/handlers/index-diff.ts +146 -0
- package/src/cli/handlers/ledger-root-member.test.ts +161 -0
- package/src/cli/handlers/lifecycle-drift.ts +68 -0
- package/src/cli/handlers/lifecycle.test.ts +33 -11
- package/src/cli/handlers/lifecycle.ts +205 -30
- package/src/cli/handlers/misc.ts +73 -0
- package/src/cli/handlers/pr-waves-blocked.test.ts +37 -2
- package/src/cli/handlers/pr.ts +16 -3
- package/src/cli/handlers/promote.test.ts +64 -0
- package/src/cli/handlers/promote.ts +81 -6
- package/src/cli/handlers/query.ts +27 -4
- package/src/cli/handlers/run-declared-reads-cli.test.ts +187 -0
- package/src/cli/handlers/run-groups-cli.test.ts +229 -0
- package/src/cli/handlers/scenario.test.ts +13 -0
- package/src/cli/handlers/scenario.ts +8 -7
- package/src/cli/handlers/search-index.test.ts +255 -0
- package/src/cli/handlers/search-json.test.ts +1 -1
- package/src/cli/handlers/search-ownership.test.ts +194 -0
- package/src/cli/handlers/search.ts +271 -38
- package/src/cli/main.test.ts +7 -0
- package/src/cli/main.ts +56 -1
- package/src/cli/mcp/lifecycle-tools.ts +3 -2
- package/src/cli/mcp/resource-handlers.ts +4 -3
- package/src/cli/mcp/workspace-tools.ts +1 -1
- package/src/cli/parse-args.ts +40 -2
- package/src/cli/registry.ts +19 -1
- package/src/cloud-lister/aws.test.ts +202 -0
- package/src/cloud-lister/aws.ts +226 -0
- package/src/cloud-lister/azure.test.ts +132 -0
- package/src/cloud-lister/azure.ts +142 -0
- package/src/cloud-lister/common.ts +115 -0
- package/src/cloud-lister/credentials.ts +110 -0
- package/src/cloud-lister/fakes.ts +66 -0
- package/src/cloud-lister/gcp.test.ts +121 -0
- package/src/cloud-lister/gcp.ts +159 -0
- package/src/cloud-lister/guard.test.ts +198 -0
- package/src/cloud-lister/guard.ts +111 -0
- package/src/cloud-lister/ids.ts +54 -0
- package/src/cloud-lister/index.ts +134 -0
- package/src/cloud-lister/kubernetes.test.ts +160 -0
- package/src/cloud-lister/kubernetes.ts +284 -0
- package/src/cloud-lister/markers.ts +74 -0
- package/src/cloud-lister/mask.ts +77 -0
- package/src/cloud-lister/shape.test.ts +81 -0
- package/src/cloud-lister/sigv4.ts +70 -0
- package/src/cloud-lister/transport.ts +118 -0
- package/src/cloud-lister/types.ts +135 -0
- package/src/components/capability-plugin-loader.ts +4 -0
- package/src/components/capability-plugin.ts +10 -0
- package/src/components/capability.ts +238 -0
- package/src/components/cli-support.ts +70 -14
- package/src/components/covered-round.test.ts +166 -0
- package/src/components/covered-round.ts +293 -0
- package/src/components/declared-reads.test.ts +103 -0
- package/src/components/declared-reads.ts +134 -0
- package/src/components/deploy-units.ts +4 -0
- package/src/components/driver.ts +101 -4
- package/src/components/fan-out-run.ts +95 -15
- package/src/components/fan-out-support.ts +10 -1
- package/src/components/fan-out.ts +30 -0
- package/src/components/groups.test.ts +320 -0
- package/src/components/groups.ts +880 -0
- package/src/components/index.ts +59 -0
- package/src/components/plan-shape-conformance.ts +130 -0
- package/src/components/pr-env-run-bundle.test.ts +2 -0
- package/src/components/pr-run.test.ts +728 -4
- package/src/components/pr-run.ts +395 -55
- package/src/components/promote-rounds.ts +25 -2
- package/src/components/promote.ts +55 -5
- package/src/components/registry.test.ts +1 -1
- package/src/components/release-gate.ts +115 -30
- package/src/components/release-groups.test.ts +362 -0
- package/src/components/run-groups.ts +113 -0
- package/src/components/starter-plugin.ts +6 -0
- package/src/components/verbs/index.ts +1 -0
- package/src/components/verbs/member-outputs.test.ts +205 -0
- package/src/components/verbs/member-outputs.ts +308 -0
- package/src/components/wave-plan.ts +5 -2
- package/src/config.ts +44 -0
- package/src/deep-observation.ts +5 -23
- package/src/drift-record.test.ts +596 -0
- package/src/drift-record.ts +1206 -0
- package/src/engine-facts.guard.test.ts +111 -0
- package/src/engine-facts.test.ts +178 -0
- package/src/engine-facts.ts +154 -0
- package/src/gated-waves-bundle.test.ts +2 -0
- package/src/graph-ir-live.test.ts +92 -0
- package/src/graph-ir.ts +317 -7
- package/src/graph-refs.ts +416 -0
- package/src/graph-schema/fixtures/adopt.json +15 -0
- package/src/graph-schema/fixtures/choudoufu.engine-graph.json +169 -0
- package/src/graph-schema/fixtures/index.json +68 -0
- package/src/graph-schema/fixtures/plunge.engine-graph.json +158 -0
- package/src/graph-schema/fixtures.ts +267 -0
- package/src/graph-schema/generate.ts +263 -0
- package/src/graph-schema/graph-schema.test.ts +153 -0
- package/src/graph-schema/graph.schema.json +1387 -0
- package/src/health.schema.json +2 -1
- package/src/identity.ts +2 -0
- package/src/index.ts +2 -0
- package/src/instance-nodes.ts +288 -0
- package/src/lexicon.ts +76 -0
- package/src/lifecycle/__fixtures__/index-diff/20261026T120000Z-aaaaaaaaaaaa.json +149 -0
- package/src/lifecycle/__fixtures__/index-diff/20261026T130000Z-bbbbbbbbbbbb.json +127 -0
- package/src/lifecycle/adoption-file.test.ts +100 -0
- package/src/lifecycle/adoption-file.ts +154 -0
- package/src/lifecycle/cloud-index.test.ts +517 -0
- package/src/lifecycle/cloud-index.ts +736 -0
- package/src/lifecycle/derive-edges.test.ts +193 -0
- package/src/lifecycle/derive-edges.ts +182 -0
- package/src/lifecycle/git.ts +10 -4
- package/src/lifecycle/identity-match.test.ts +308 -0
- package/src/lifecycle/identity-match.ts +257 -0
- package/src/lifecycle/index-diff.test.ts +198 -0
- package/src/lifecycle/index-diff.ts +476 -0
- package/src/lifecycle/index-document.test.ts +64 -0
- package/src/lifecycle/index-document.ts +299 -0
- package/src/lifecycle/index-drift.test.ts +191 -0
- package/src/lifecycle/index-drift.ts +304 -0
- package/src/lifecycle/index-import.test.ts +255 -0
- package/src/lifecycle/index-import.ts +634 -0
- package/src/lifecycle/index-join.test.ts +250 -0
- package/src/lifecycle/index-join.ts +304 -0
- package/src/lifecycle/index-store-load-bearing.test.ts +187 -0
- package/src/lifecycle/index.ts +4 -0
- package/src/lifecycle/member-ledger.test.ts +25 -7
- package/src/lifecycle/observation-baseline.test.ts +72 -1
- package/src/lifecycle/observation-baseline.ts +190 -27
- package/src/lifecycle/observe.ts +6 -1
- package/src/lifecycle/query.test.ts +69 -1
- package/src/lifecycle/query.ts +103 -10
- package/src/lifecycle/replay.test.ts +9 -5
- package/src/lifecycle/replay.ts +9 -5
- package/src/lifecycle/scenario.ts +4 -3
- package/src/lifecycle/snapshot-store-fake.ts +29 -0
- package/src/lifecycle/snapshot-store-s3.ts +316 -0
- package/src/lifecycle/snapshot-store.test.ts +385 -0
- package/src/lifecycle/snapshot-store.ts +981 -0
- package/src/lifecycle/snapshot.test.ts +13 -0
- package/src/lifecycle/snapshot.ts +23 -6
- package/src/lifecycle/type-listing.test.ts +166 -0
- package/src/lifecycle/type-listing.ts +309 -0
- package/src/lint/component-checks.ts +17 -1
- package/src/lint/config.test.ts +3 -0
- package/src/lint/presets/relaxed.json +2 -1
- package/src/lint/presets/strict.json +2 -1
- package/src/lint/rules/__fixtures__/comp/comp008/fail/dns.component.ts +15 -0
- package/src/lint/rules/__fixtures__/comp/comp008/pass/dns.component.ts +10 -0
- package/src/lint/rules/comp/comp.test.ts +2 -1
- package/src/lint/rules/comp/comp008-applies-signal-only-root.ts +121 -0
- package/src/lint/rules/comp/comp008.test.ts +77 -0
- package/src/lint/rules/comp/index.ts +4 -1
- package/src/observation-edges.test.ts +33 -0
- package/src/observation.ts +36 -1
- package/src/op/activities/activity-contracts.ts +1 -1
- package/src/op/activities/change-set.ts +8 -5
- package/src/op/activity-failure.ts +36 -0
- package/src/op/index.ts +2 -1
- package/src/op/local-executor.test.ts +80 -0
- package/src/op/local-executor.ts +27 -9
- package/src/pr-loop-bundle.test.ts +5 -2
- package/src/pr-loop.test.ts +57 -1
- package/src/pr-loop.ts +154 -6
- package/src/pulumi-urn.ts +151 -0
- package/src/release-floors.ts +22 -0
- package/src/sensitive-key.ts +34 -0
- package/src/workspace/adoption-report.test.ts +61 -0
- package/src/workspace/adoption-report.ts +103 -0
- package/src/workspace/capabilities-contract.test.ts +4 -0
- package/src/workspace/capabilities-contract.ts +9 -1
- package/src/workspace/capabilities.schema.json +98 -0
- package/src/workspace/change-set.schema.json +42 -3
- package/src/workspace/ci-cloud-identity.ts +31 -1
- package/src/workspace/compose-graph.test.ts +12 -0
- package/src/workspace/compose-graph.ts +12 -1
- package/src/workspace/conformance/conformance.e2e.test.ts +2 -1
- package/src/workspace/conformance/index.ts +6 -1
- package/src/workspace/drift-cli.test.ts +65 -0
- package/src/workspace/drift-cli.ts +365 -0
- package/src/workspace/drift.schema.json +672 -0
- package/src/workspace/graph-cli.ts +5 -0
- package/src/workspace/graph.schema.json +72 -0
- package/src/workspace/init.test.ts +38 -1
- package/src/workspace/init.ts +50 -8
- package/src/workspace/intent-gaps.test.ts +18 -2
- package/src/workspace/ledger.schema.json +1 -1
- package/src/workspace/nested-graph.ts +1 -0
- package/src/workspace/pr-report.schema.json +76 -3
- package/src/workspace/promote-waves.test.ts +296 -0
- package/src/workspace/promote-waves.ts +340 -0
- package/src/workspace/promote.test.ts +158 -4
- package/src/workspace/promote.ts +398 -57
- package/src/workspace/reason-codes.test.ts +4 -1
- package/src/workspace/reason-codes.ts +14 -0
- package/src/workspace/search-contract.ts +2 -0
- package/src/workspace/search.schema.json +103 -5
|
@@ -22,6 +22,12 @@
|
|
|
22
22
|
* A stage whose components declare no gate has nowhere to wait, so the
|
|
23
23
|
* promote stops there with nothing more deployed.
|
|
24
24
|
*
|
|
25
|
+
* - **Groups** (ws-107, #4465). With `grouped`, the waves are the grouped
|
|
26
|
+
* fan-out's, so each group sits in one wave and is checked, planned again
|
|
27
|
+
* and run as one: when any member's input moved, every member left of the
|
|
28
|
+
* group is planned again with it. Under `--wave-gate` no group forms
|
|
29
|
+
* (`formRunGroups`), so there is none here.
|
|
30
|
+
*
|
|
25
31
|
* A promote that stops at a round's or a wave's gate writes a resume record
|
|
26
32
|
* ({@link PromoteResume}): the components that applied and the outputs they
|
|
27
33
|
* left. The same promote run again with it skips what applied and carries on
|
|
@@ -37,6 +43,8 @@ import { waveGateName } from "../gated-waves";
|
|
|
37
43
|
import { capabilitySteps } from "./wave-plan";
|
|
38
44
|
import type { ChangeSetDocument } from "../change-set";
|
|
39
45
|
import type { ReleasePlan } from "./release-gate";
|
|
46
|
+
import type { FanOutGroup, FanOutPlan } from "./fan-out";
|
|
47
|
+
import { groupsByComponent } from "./groups";
|
|
40
48
|
|
|
41
49
|
export const PROMOTE_RESUME_SCHEMA = "chant-promote-resume/v1";
|
|
42
50
|
|
|
@@ -90,6 +98,8 @@ export interface PromoteRoundsOptions {
|
|
|
90
98
|
replan: (only: ReadonlySet<string>, outputs: Record<string, Record<string, unknown>>) => Promise<ChangeSetDocument>;
|
|
91
99
|
/** Store a stage's plan and bind its gates (empty resolutions included). */
|
|
92
100
|
bind: (doc: ChangeSetDocument, gates: string[]) => Promise<ReleaseGateBinding>;
|
|
101
|
+
/** The grouped fan-out (#4465): its waves replace the ones `dependsOn` gives, and each group is checked as one. */
|
|
102
|
+
grouped?: FanOutPlan;
|
|
93
103
|
}
|
|
94
104
|
|
|
95
105
|
export interface PromoteRoundsResult {
|
|
@@ -169,7 +179,17 @@ function joinRuns(runs: DriverRunResult[], outputs: Record<string, Record<string
|
|
|
169
179
|
*/
|
|
170
180
|
export async function runPromotionInRounds(options: PromoteRoundsOptions): Promise<PromoteRoundsResult> {
|
|
171
181
|
const byName = new Map(options.components.map((c) => [c.name, c]));
|
|
172
|
-
const
|
|
182
|
+
const grouped = options.grouped?.groups?.length ? options.grouped : undefined;
|
|
183
|
+
const placed = new Set(grouped?.order ?? []);
|
|
184
|
+
// A grouped fan-out over what a resume left holds no wave for what applied earlier; that is skipped anyway.
|
|
185
|
+
const waves = grouped
|
|
186
|
+
? grouped.waves.map((w) => w.filter((name) => byName.has(name)))
|
|
187
|
+
: resolveComponentGraph(options.components.map((c) => ({ ...c, dependsOn: (c.dependsOn ?? []).filter((d) => byName.has(d)) }))).waves;
|
|
188
|
+
if (grouped) {
|
|
189
|
+
const missing = options.components.filter((c) => !placed.has(c.name) && !(options.completed ?? []).includes(c.name)).map((c) => c.name);
|
|
190
|
+
if (missing.length > 0) throw new Error(`the grouped waves leave out ${missing.join(", ")}, which this promote runs`);
|
|
191
|
+
}
|
|
192
|
+
const groupOf = grouped ? groupsByComponent(grouped) : new Map<string, FanOutGroup>();
|
|
173
193
|
const completed = [...(options.completed ?? [])];
|
|
174
194
|
const done = new Set(completed);
|
|
175
195
|
let outputs = { ...options.outputs };
|
|
@@ -181,9 +201,12 @@ export async function runPromotionInRounds(options: PromoteRoundsOptions): Promi
|
|
|
181
201
|
const waveNumber = index + 1;
|
|
182
202
|
const pending = wave.filter((name) => !done.has(name));
|
|
183
203
|
if (pending.length === 0) continue;
|
|
184
|
-
const
|
|
204
|
+
const moved = options.waveGate !== undefined && waveNumber > 1
|
|
185
205
|
? pending
|
|
186
206
|
: pending.filter((name) => movedInputs(byName.get(name)!, options.reads[name], outputs).length > 0);
|
|
207
|
+
// A group is planned again as one: a member whose input moved takes the rest of its group with it.
|
|
208
|
+
const withMates = new Set(moved.flatMap((name) => [name, ...(groupOf.get(name)?.components ?? [])]));
|
|
209
|
+
const check = pending.filter((name) => withMates.has(name));
|
|
187
210
|
const batches: Array<{ names: string[]; binding: ReleaseGateBinding; stage?: PromoteStage; rename?: (g: string) => string }> = [];
|
|
188
211
|
const rest = pending.filter((name) => !check.includes(name));
|
|
189
212
|
if (check.length > 0) {
|
|
@@ -44,6 +44,8 @@ import { CapabilityRegistry, type Capability } from "./capability";
|
|
|
44
44
|
import {
|
|
45
45
|
runInterpretDriver,
|
|
46
46
|
DriverRunFailure,
|
|
47
|
+
deployContext,
|
|
48
|
+
type InterpretGroups,
|
|
47
49
|
type DriverComponent,
|
|
48
50
|
type DriverComponentResult,
|
|
49
51
|
type DriverGate,
|
|
@@ -53,6 +55,9 @@ import {
|
|
|
53
55
|
type DriverStep,
|
|
54
56
|
} from "./driver";
|
|
55
57
|
import type { GateLedgerPort } from "../op/gate";
|
|
58
|
+
import type { GroupRun } from "./capability";
|
|
59
|
+
import type { FanOutGroup, FanOutPlan } from "./fan-out";
|
|
60
|
+
import { planAndRunComponentGroup, runComponentGroup } from "./groups";
|
|
56
61
|
import type { Release } from "../lifecycle/release-store";
|
|
57
62
|
import type { RunProgressEvent } from "./run-progress";
|
|
58
63
|
import type { RunEventSink } from "../run-event-stream";
|
|
@@ -631,6 +636,27 @@ export interface RunPromotionOptions {
|
|
|
631
636
|
onProgress?: (event: RunProgressEvent) => void;
|
|
632
637
|
/** Where the run's events go (#4041, `--events-json`). */
|
|
633
638
|
onRunEvent?: RunEventSink;
|
|
639
|
+
/**
|
|
640
|
+
* The grouped fan-out (ws-107, #4465, `formRunGroups`): each of its groups
|
|
641
|
+
* applies as one, in the wave it places it in. Absent, or without
|
|
642
|
+
* `groups`: every component runs its own deploy, as before.
|
|
643
|
+
*/
|
|
644
|
+
grouped?: FanOutPlan;
|
|
645
|
+
/**
|
|
646
|
+
* The approved plan of each group, as the release gate's plan made it
|
|
647
|
+
* (`ReleasePlan.groups`). A group runs the one whose members are its own;
|
|
648
|
+
* the newest first. A group with none plans in its wave and applies only
|
|
649
|
+
* under `planGroupsAtWave`, and fails otherwise.
|
|
650
|
+
*/
|
|
651
|
+
groupRuns?: readonly GroupRun[];
|
|
652
|
+
/** A promote with no release gate to bind plans each group in its wave (#4465). */
|
|
653
|
+
planGroupsAtWave?: boolean;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/** The run in `runs` that plans exactly the members of `group`. */
|
|
657
|
+
function approvedRunOf(runs: readonly GroupRun[] | undefined, group: FanOutGroup): GroupRun | undefined {
|
|
658
|
+
const want = [...group.components].sort().join("\n");
|
|
659
|
+
return runs?.find((r) => Object.keys(r.plans).sort().join("\n") === want);
|
|
634
660
|
}
|
|
635
661
|
|
|
636
662
|
/**
|
|
@@ -647,18 +673,42 @@ export async function runPromotion(options: RunPromotionOptions): Promise<Driver
|
|
|
647
673
|
.filter((c) => names.has(c.name))
|
|
648
674
|
.map((c) => ({ ...c, dependsOn: (c.dependsOn ?? []).filter((d) => names.has(d)) }));
|
|
649
675
|
const expected = new Map(plan.items.map((i) => [i.component, i.digest]));
|
|
676
|
+
const registry = checkPublishedDigest(options.registry, expected);
|
|
677
|
+
const releaseIdentity = (component: string) => {
|
|
678
|
+
const item = plan.items.find((i) => i.component === component);
|
|
679
|
+
return item ? { version: item.digest, revision: item.source.gitSha } : undefined;
|
|
680
|
+
};
|
|
681
|
+
// ws-107 (#4465): a group applies as one, through its approved plan.
|
|
682
|
+
const grouped = options.grouped?.groups?.length ? options.grouped : undefined;
|
|
683
|
+
const byName = new Map(targets.map((c) => [c.name, c]));
|
|
684
|
+
const groups: InterpretGroups | undefined = grouped
|
|
685
|
+
? {
|
|
686
|
+
waves: grouped.waves,
|
|
687
|
+
groups: grouped.groups!,
|
|
688
|
+
run: (group, componentOutputs) => {
|
|
689
|
+
const each = {
|
|
690
|
+
group,
|
|
691
|
+
components: byName,
|
|
692
|
+
registry,
|
|
693
|
+
env: plan.to,
|
|
694
|
+
ctxOf: (name: string) => deployContext({ env: plan.to, releaseIdentity }, name),
|
|
695
|
+
componentOutputs,
|
|
696
|
+
};
|
|
697
|
+
const approved = approvedRunOf(options.groupRuns, group);
|
|
698
|
+
return approved === undefined && options.planGroupsAtWave ? planAndRunComponentGroup(each) : runComponentGroup({ ...each, run: approved });
|
|
699
|
+
},
|
|
700
|
+
}
|
|
701
|
+
: undefined;
|
|
650
702
|
try {
|
|
651
|
-
return await runInterpretDriver(targets,
|
|
703
|
+
return await runInterpretDriver(targets, registry, {
|
|
652
704
|
env: plan.to,
|
|
653
705
|
componentOutputs: options.componentOutputs ?? {},
|
|
654
706
|
// #2574: a gate approval for this promote or rollback is bound to the
|
|
655
707
|
// release it deploys, as well as the environment and composition.
|
|
656
708
|
releases: expected,
|
|
657
709
|
// #3061: the workload's service.version and vcs.ref.head.revision are the earlier release's own.
|
|
658
|
-
releaseIdentity
|
|
659
|
-
|
|
660
|
-
return item ? { version: item.digest, revision: item.source.gitSha } : undefined;
|
|
661
|
-
},
|
|
710
|
+
releaseIdentity,
|
|
711
|
+
...(groups ? { groups } : {}),
|
|
662
712
|
...(options.onProgress ? { onProgress: options.onProgress } : {}),
|
|
663
713
|
...(options.onRunEvent ? { onRunEvent: options.onRunEvent } : {}),
|
|
664
714
|
...(options.gates ? { gates: options.gates } : {}),
|
|
@@ -99,7 +99,7 @@ describe("createCapabilityRegistry", () => {
|
|
|
99
99
|
// for them to live in instead.
|
|
100
100
|
test("family table lists exactly the agnostic starter families plus the Cloudflare apply leaves (#1293)", () => {
|
|
101
101
|
expect(Object.keys(STARTER_VERB_FAMILIES).sort()).toEqual(
|
|
102
|
-
["build", "cloudflare", "escapeHatch", "publish", "sbom", "secrets", "supplyChainPolicy", "supplyChainSecurity", "waitVerify"].sort(),
|
|
102
|
+
["build", "cloudflare", "engineOutputs", "escapeHatch", "publish", "sbom", "secrets", "supplyChainPolicy", "supplyChainSecurity", "waitVerify"].sort(),
|
|
103
103
|
);
|
|
104
104
|
});
|
|
105
105
|
|
|
@@ -60,7 +60,9 @@
|
|
|
60
60
|
* recorded since (#4035): its record names what ran before that run.
|
|
61
61
|
*/
|
|
62
62
|
|
|
63
|
-
import type { CapabilityRegistry, PlannedOutputs } from "./capability";
|
|
63
|
+
import type { CapabilityRegistry, GroupRun, PlannedOutputs } from "./capability";
|
|
64
|
+
import type { FanOutGroup, FanOutGroupFallback, FanOutPlan } from "./fan-out";
|
|
65
|
+
import { groupsByComponent, planComponentGroup } from "./groups";
|
|
64
66
|
import { deployContext, resolveComponentGraph, resolveStepInput, unresolvedWiringReferences, type DriverComponent, type DriverGate, type DriverPhase, type DriverStep } from "./driver";
|
|
65
67
|
import { componentPlanDigest } from "./gate-plan";
|
|
66
68
|
import { gateName, RELEASE_GATE_OP } from "../op/gate-name";
|
|
@@ -137,6 +139,24 @@ export interface ReleaseChangeSetInput {
|
|
|
137
139
|
* `seededOutputs`, which then holds what the run left. Default: every one.
|
|
138
140
|
*/
|
|
139
141
|
only?: ReadonlySet<string>;
|
|
142
|
+
/**
|
|
143
|
+
* The promote's grouped fan-out (ws-107, #4465, `formRunGroups`). Each of
|
|
144
|
+
* its groups plans with one `planGroup` call in the wave it places it in,
|
|
145
|
+
* and the group digest is folded into each member's part, so the release
|
|
146
|
+
* gate's digest binds the composition. Absent, or without `groups`: every
|
|
147
|
+
* component plans by itself, wave by wave.
|
|
148
|
+
*/
|
|
149
|
+
grouped?: FanOutPlan;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** A group the release gate's plan planned as one (ws-107, #4465). */
|
|
153
|
+
export interface ReleasePlanGroup extends FanOutGroup {
|
|
154
|
+
/** The group digest folded into each member's `planDigest`; `null` when the group failed to plan. */
|
|
155
|
+
digest: string | null;
|
|
156
|
+
/** Why the group failed to plan. Every member is then a failed member. */
|
|
157
|
+
error?: string;
|
|
158
|
+
/** What `runGroup` gets back. It lives in the process that planned, as the promote that applies it is. */
|
|
159
|
+
run?: GroupRun;
|
|
140
160
|
}
|
|
141
161
|
|
|
142
162
|
/** A release's change set for an environment, and what each component was planned against. */
|
|
@@ -148,6 +168,10 @@ export interface ReleasePlan {
|
|
|
148
168
|
plannedOutputs?: Record<string, string[]>;
|
|
149
169
|
/** Per component, the references to a promoted upstream that no value stands for until it applies, sorted. Absent when none. */
|
|
150
170
|
unknownInputs?: Record<string, string[]>;
|
|
171
|
+
/** The groups planned as one (#4465), in the order they planned. Absent when none. */
|
|
172
|
+
groups?: ReleasePlanGroup[];
|
|
173
|
+
/** The components that could have grouped and did not, with why: `grouped.fallbacks`. Absent when none. */
|
|
174
|
+
fallbacks?: FanOutGroupFallback[];
|
|
151
175
|
}
|
|
152
176
|
|
|
153
177
|
const byString = (a: string, b: string): number => (a < b ? -1 : a > b ? 1 : 0);
|
|
@@ -287,10 +311,94 @@ export async function planReleaseSet(input: ReleaseChangeSetInput): Promise<Rele
|
|
|
287
311
|
const inPlan = (name: string): boolean => input.only === undefined || input.only.has(name);
|
|
288
312
|
const isPlannable = (c: DriverComponent): boolean =>
|
|
289
313
|
capabilitySteps(c.deploy).some((s) => registry.has(s.kind) && registry.resolve(s.kind).plan !== undefined);
|
|
290
|
-
const
|
|
314
|
+
const failedPart = (member: string, err: unknown): ChangeSetPart => ({
|
|
315
|
+
member: {
|
|
316
|
+
member,
|
|
317
|
+
lexicon: "chant",
|
|
318
|
+
planner: "chant",
|
|
319
|
+
status: "failed",
|
|
320
|
+
error: err instanceof Error ? err.message : String(err),
|
|
321
|
+
planDigest: null,
|
|
322
|
+
holes: [],
|
|
323
|
+
},
|
|
324
|
+
entries: [],
|
|
325
|
+
});
|
|
326
|
+
/** Read each dependency of `component` once, leaving out `mates`, its own group (#4465), and keep what it read. */
|
|
327
|
+
const readDependencies = async (component: DriverComponent, mates: ReadonlySet<string>): Promise<void> => {
|
|
328
|
+
for (const dep of component.dependsOn ?? []) {
|
|
329
|
+
if (mates.has(dep) || read.has(dep) || !byName.has(dep)) continue;
|
|
330
|
+
read.add(dep);
|
|
331
|
+
// A dependency this promote plans exposes what its plan says (#3999).
|
|
332
|
+
if (plannedBy.has(dep) && isPlannable(byName.get(dep)!)) {
|
|
333
|
+
const known = plannedBy.get(dep)?.known ?? {};
|
|
334
|
+
outputs[dep] = { ...known };
|
|
335
|
+
planned[dep] = Object.keys(known).sort();
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
const found = await readComponentOutputs(byName.get(dep)!, registry, deployContext({ env }, dep), outputs);
|
|
339
|
+
if (found) outputs[dep] = found;
|
|
340
|
+
}
|
|
341
|
+
reads[component.name] = Object.fromEntries(
|
|
342
|
+
(component.dependsOn ?? []).filter((d) => !mates.has(d) && d in outputs).map((d) => [d, structuredClone(outputs[d])]),
|
|
343
|
+
);
|
|
344
|
+
};
|
|
345
|
+
/** The references of `component`'s plannable steps to a promoted upstream outside `mates` that its plan can't say yet. */
|
|
346
|
+
const unknownOf = (component: DriverComponent, mates: ReadonlySet<string>): Set<string> => {
|
|
347
|
+
const unknown = new Set<string>();
|
|
348
|
+
for (const step of capabilitySteps(component.deploy)) {
|
|
349
|
+
if (!registry.has(step.kind) || registry.resolve(step.kind).plan === undefined) continue;
|
|
350
|
+
const { kind: _kind, ...rest } = step;
|
|
351
|
+
for (const r of unresolvedWiringReferences(rest, outputs)) if (plannedBy.has(r.source) && !r.publish && !mates.has(r.source)) unknown.add(r.ref);
|
|
352
|
+
}
|
|
353
|
+
return unknown;
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
// ws-107 (#4465): a group plans once, in the wave the grouped fan-out places it in.
|
|
357
|
+
const grouped = input.grouped?.groups?.length ? input.grouped : undefined;
|
|
358
|
+
const groupOf = grouped ? groupsByComponent(grouped) : new Map<string, FanOutGroup>();
|
|
359
|
+
const groups: ReleasePlanGroup[] = [];
|
|
360
|
+
const planGroupAt = async (group: FanOutGroup): Promise<void> => {
|
|
361
|
+
const mates = new Set(group.components);
|
|
362
|
+
try {
|
|
363
|
+
for (const name of group.components) await readDependencies(byName.get(name)!, mates);
|
|
364
|
+
} catch (err) {
|
|
365
|
+
for (const name of group.components) {
|
|
366
|
+
plannedBy.set(name, undefined);
|
|
367
|
+
parts.push(failedPart(name, err));
|
|
368
|
+
}
|
|
369
|
+
groups.push({ ...group, digest: null, error: err instanceof Error ? err.message : String(err) });
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const g = await planComponentGroup({ group, components: byName, registry, env, ctxOf: (name) => deployContext({ env }, name), outputs });
|
|
373
|
+
const error = g.plans.find((p): p is Extract<typeof p, { error: string }> => "error" in p)?.error;
|
|
374
|
+
groups.push({ ...group, digest: g.digest ?? null, ...(error !== undefined ? { error } : {}), ...(g.run ? { run: g.run } : {}) });
|
|
375
|
+
for (const p of g.plans) {
|
|
376
|
+
if ("error" in p) {
|
|
377
|
+
plannedBy.set(p.component, undefined);
|
|
378
|
+
parts.push(failedPart(p.component, p.error));
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
plannedBy.set(p.component, p.outputs);
|
|
382
|
+
parts.push(...p.parts);
|
|
383
|
+
const unknown = unknownOf(byName.get(p.component)!, mates);
|
|
384
|
+
if (unknown.size > 0) unknownInputs[p.component] = [...unknown].sort();
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
const waves = grouped
|
|
389
|
+
? grouped.waves.map((w) => w.filter((name) => byName.has(name)))
|
|
390
|
+
: resolveComponentGraph(components.map((c) => ({ ...c, dependsOn: (c.dependsOn ?? []).filter((d) => byName.has(d)) }))).waves;
|
|
291
391
|
for (const wave of waves) {
|
|
292
392
|
const planning = wave.filter(inPlan);
|
|
393
|
+
const inWave = new Set(planning);
|
|
394
|
+
// What is left of a group in this plan; one member alone plans by itself.
|
|
395
|
+
const groupsHere = [...new Set(planning.map((name) => groupOf.get(name)).filter((g): g is FanOutGroup => g !== undefined))]
|
|
396
|
+
.map((g) => ({ ...g, components: g.components.filter((c) => inWave.has(c)) }))
|
|
397
|
+
.filter((g) => g.components.length > 1);
|
|
398
|
+
const grouping = new Set(groupsHere.flatMap((g) => g.components));
|
|
399
|
+
for (const group of groupsHere) await planGroupAt(group);
|
|
293
400
|
for (const name of planning) {
|
|
401
|
+
if (grouping.has(name)) continue;
|
|
294
402
|
const component = byName.get(name)!;
|
|
295
403
|
const digest = input.digests.get(name) ?? "";
|
|
296
404
|
const plannable = capabilitySteps(component.deploy).filter((s) => registry.has(s.kind) && registry.resolve(s.kind).plan !== undefined);
|
|
@@ -300,25 +408,11 @@ export async function planReleaseSet(input: ReleaseChangeSetInput): Promise<Rele
|
|
|
300
408
|
}
|
|
301
409
|
const ctx = deployContext({ env }, name);
|
|
302
410
|
try {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
read.add(dep);
|
|
306
|
-
// A dependency this promote plans exposes what its plan says (#3999).
|
|
307
|
-
if (plannedBy.has(dep) && isPlannable(byName.get(dep)!)) {
|
|
308
|
-
const known = plannedBy.get(dep)?.known ?? {};
|
|
309
|
-
outputs[dep] = { ...known };
|
|
310
|
-
planned[dep] = Object.keys(known).sort();
|
|
311
|
-
continue;
|
|
312
|
-
}
|
|
313
|
-
const found = await readComponentOutputs(byName.get(dep)!, registry, deployContext({ env }, dep), outputs);
|
|
314
|
-
if (found) outputs[dep] = found;
|
|
315
|
-
}
|
|
316
|
-
reads[name] = Object.fromEntries((component.dependsOn ?? []).filter((d) => d in outputs).map((d) => [d, structuredClone(outputs[d])]));
|
|
317
|
-
const unknown = new Set<string>();
|
|
411
|
+
await readDependencies(component, new Set());
|
|
412
|
+
const unknown = unknownOf(component, new Set());
|
|
318
413
|
let exposes: PlannedOutputs | undefined;
|
|
319
414
|
for (const step of plannable) {
|
|
320
415
|
const { kind, ...rest } = step;
|
|
321
|
-
for (const r of unresolvedWiringReferences(rest, outputs)) if (plannedBy.has(r.source) && !r.publish) unknown.add(r.ref);
|
|
322
416
|
const result = await registry.resolve(kind).plan!(planContext(ctx, rest, outputs), resolveStepInput(rest, {}, outputs) as never);
|
|
323
417
|
if (result.outputs) exposes = { known: { ...(exposes?.known ?? {}), ...result.outputs.known }, unknown: [...new Set([...(exposes?.unknown ?? []), ...result.outputs.unknown])].sort() };
|
|
324
418
|
parts.push(
|
|
@@ -339,18 +433,7 @@ export async function planReleaseSet(input: ReleaseChangeSetInput): Promise<Rele
|
|
|
339
433
|
if (unknown.size > 0) unknownInputs[name] = [...unknown].sort();
|
|
340
434
|
} catch (err) {
|
|
341
435
|
plannedBy.set(name, undefined);
|
|
342
|
-
parts.push(
|
|
343
|
-
member: {
|
|
344
|
-
member: name,
|
|
345
|
-
lexicon: "chant",
|
|
346
|
-
planner: "chant",
|
|
347
|
-
status: "failed",
|
|
348
|
-
error: err instanceof Error ? err.message : String(err),
|
|
349
|
-
planDigest: null,
|
|
350
|
-
holes: [],
|
|
351
|
-
},
|
|
352
|
-
entries: [],
|
|
353
|
-
});
|
|
436
|
+
parts.push(failedPart(name, err));
|
|
354
437
|
}
|
|
355
438
|
}
|
|
356
439
|
}
|
|
@@ -363,6 +446,8 @@ export async function planReleaseSet(input: ReleaseChangeSetInput): Promise<Rele
|
|
|
363
446
|
reads,
|
|
364
447
|
...(Object.keys(planned).length > 0 ? { plannedOutputs: planned } : {}),
|
|
365
448
|
...(Object.keys(unknownInputs).length > 0 ? { unknownInputs } : {}),
|
|
449
|
+
...(groups.length > 0 ? { groups } : {}),
|
|
450
|
+
...(input.grouped?.fallbacks?.length ? { fallbacks: input.grouped.fallbacks } : {}),
|
|
366
451
|
};
|
|
367
452
|
}
|
|
368
453
|
|