@intentius/chant 0.124.45 → 0.124.48
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/__golden__/wave-loop/op-by-apply-after-fails.json +10 -0
- package/dist/__golden__/wave-loop/op-by-apply-hold.json +10 -0
- package/dist/__golden__/wave-loop/op-by-apply-ignored.json +10 -0
- package/dist/__golden__/wave-loop/op-by-apply-pass.json +10 -0
- package/dist/__golden__/wave-loop/op-by-apply-skip.json +10 -0
- package/dist/__golden__/wave-loop/op-cost-member-clash.json +6 -0
- package/dist/__golden__/wave-loop/op-cost-member.json +13 -0
- package/dist/__golden__/wave-loop/op-denied-source.json +16 -0
- package/dist/__golden__/wave-loop/op-denied.json +16 -0
- package/dist/__golden__/wave-loop/op-discover-rest-short.json +6 -0
- package/dist/__golden__/wave-loop/op-discover-rest-stops.json +13 -0
- package/dist/__golden__/wave-loop/op-discover-rest.json +26 -0
- package/dist/__golden__/wave-loop/op-discover-wide.json +26 -0
- package/dist/__golden__/wave-loop/op-held-on-again.json +16 -0
- package/dist/__golden__/wave-loop/op-held-on-before-apply.json +16 -0
- package/dist/__golden__/wave-loop/op-held-on.json +16 -0
- package/dist/__golden__/wave-loop/op-hooks-apply-fails.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-fail-after-apply.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-fail-before-apply.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-fail-before-plan.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-held.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-hold-before-apply.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-pass.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-refused-at-base.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-share.json +33 -0
- package/dist/__golden__/wave-loop/op-outcome-held.json +10 -0
- package/dist/__golden__/wave-loop/op-outcome-replan-approved.json +10 -0
- package/dist/__golden__/wave-loop/op-outcome-replan-forever.json +10 -0
- package/dist/__golden__/wave-loop/op-outcome-replan.json +10 -0
- package/dist/__golden__/wave-loop/op-outcome-stood-down.json +10 -0
- package/dist/__golden__/wave-loop/op-outcome-unreadable.json +10 -0
- package/dist/__golden__/wave-loop/op-overridden.json +16 -0
- package/dist/__golden__/wave-loop/op-per-run.json +20 -0
- package/dist/__golden__/wave-loop/op-point.json +13 -0
- package/dist/__golden__/wave-loop/op-pr-review.json +10 -0
- package/dist/__golden__/wave-loop/op-sealed.json +10 -0
- package/dist/__golden__/wave-loop/op-spend-change-only.json +10 -0
- package/dist/__golden__/wave-loop/op-spend.json +10 -0
- package/dist/__golden__/wave-loop/op-wave-commands.json +55 -0
- package/dist/__golden__/wave-loop/op-wide-refused.json +26 -0
- package/dist/__golden__/wave-loop/op-wide-waiting.json +29 -0
- package/dist/__golden__/wave-loop/op-wide.json +39 -0
- package/dist/action-pins.d.ts +61 -0
- package/dist/action-pins.d.ts.map +1 -0
- package/dist/action-pins.js +77 -0
- package/dist/capabilities/aws.paths +148 -0
- package/dist/capabilities/base-mappings.json +122 -0
- package/dist/capabilities/catalog.d.ts +89 -0
- package/dist/capabilities/catalog.d.ts.map +1 -0
- package/dist/capabilities/catalog.js +204 -0
- package/dist/capabilities/language.d.ts +103 -0
- package/dist/capabilities/language.d.ts.map +1 -0
- package/dist/capabilities/language.js +335 -0
- package/dist/capabilities/matcher.d.ts +65 -0
- package/dist/capabilities/matcher.d.ts.map +1 -0
- package/dist/capabilities/matcher.js +299 -0
- package/dist/capabilities/view.d.ts +207 -0
- package/dist/capabilities/view.d.ts.map +1 -0
- package/dist/capabilities/view.js +484 -0
- package/dist/cli/commands/carve.d.ts +3 -0
- package/dist/cli/commands/carve.d.ts.map +1 -1
- package/dist/cli/commands/carve.js +36 -7
- package/dist/cli/commands/import-report.d.ts +26 -0
- package/dist/cli/commands/import-report.d.ts.map +1 -0
- package/dist/cli/commands/import-report.js +65 -0
- package/dist/cli/commands/import.d.ts +11 -1
- package/dist/cli/commands/import.d.ts.map +1 -1
- package/dist/cli/commands/import.js +22 -3
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/lint.js +1 -0
- package/dist/cli/commands/migrate.d.ts +13 -1
- package/dist/cli/commands/migrate.d.ts.map +1 -1
- package/dist/cli/commands/migrate.js +134 -10
- package/dist/cli/handlers/approve.d.ts.map +1 -1
- package/dist/cli/handlers/approve.js +21 -2
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.js +6 -1
- package/dist/cli/handlers/declared-graph.d.ts +44 -0
- package/dist/cli/handlers/declared-graph.d.ts.map +1 -0
- package/dist/cli/handlers/declared-graph.js +87 -0
- package/dist/cli/handlers/graph.d.ts +25 -0
- package/dist/cli/handlers/graph.d.ts.map +1 -1
- package/dist/cli/handlers/graph.js +93 -87
- package/dist/cli/handlers/ledger.d.ts +3 -0
- package/dist/cli/handlers/ledger.d.ts.map +1 -0
- package/dist/cli/handlers/ledger.js +55 -0
- package/dist/cli/handlers/migrate.d.ts.map +1 -1
- package/dist/cli/handlers/migrate.js +18 -11
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/misc.js +12 -1
- package/dist/cli/handlers/pr-env.d.ts.map +1 -1
- package/dist/cli/handlers/pr-env.js +4 -3
- package/dist/cli/handlers/pr.d.ts +15 -1
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +143 -39
- package/dist/cli/handlers/query.d.ts +7 -2
- package/dist/cli/handlers/query.d.ts.map +1 -1
- package/dist/cli/handlers/query.js +16 -4
- package/dist/cli/handlers/release.d.ts.map +1 -1
- package/dist/cli/handlers/release.js +6 -3
- package/dist/cli/handlers/search-count.d.ts +89 -0
- package/dist/cli/handlers/search-count.d.ts.map +1 -0
- package/dist/cli/handlers/search-count.js +132 -0
- package/dist/cli/handlers/search.d.ts +356 -6
- package/dist/cli/handlers/search.d.ts.map +1 -1
- package/dist/cli/handlers/search.js +1039 -155
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +88 -17
- package/dist/cli/mcp/server.d.ts.map +1 -1
- package/dist/cli/mcp/server.js +3 -0
- package/dist/cli/mcp/tools/capabilities.d.ts +7 -0
- package/dist/cli/mcp/tools/capabilities.d.ts.map +1 -0
- package/dist/cli/mcp/tools/capabilities.js +27 -0
- package/dist/cli/mcp/workspace-tools.d.ts +3 -1
- package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
- package/dist/cli/mcp/workspace-tools.js +47 -2
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +100 -19
- package/dist/cli/registry.d.ts +36 -4
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/components/builders.d.ts +5 -1
- package/dist/components/builders.d.ts.map +1 -1
- package/dist/components/builders.js +5 -0
- package/dist/components/capability-plugin-loader.d.ts.map +1 -1
- package/dist/components/capability-plugin-loader.js +16 -1
- package/dist/components/capability-plugin.d.ts +14 -0
- package/dist/components/capability-plugin.d.ts.map +1 -1
- package/dist/components/pr-env-ports.d.ts +29 -0
- package/dist/components/pr-env-ports.d.ts.map +1 -0
- package/dist/components/pr-env-ports.js +77 -0
- package/dist/components/pr-env-run.d.ts +5 -21
- package/dist/components/pr-env-run.d.ts.map +1 -1
- package/dist/components/pr-env-run.js +6 -70
- package/dist/components/pr-environment.d.ts +2 -1
- package/dist/components/pr-environment.d.ts.map +1 -1
- package/dist/components/pr-environment.js +1 -1
- package/dist/components/pr-hooks.d.ts +21 -1
- package/dist/components/pr-hooks.d.ts.map +1 -1
- package/dist/components/pr-hooks.js +72 -4
- package/dist/components/pr-pipeline.d.ts +45 -10
- package/dist/components/pr-pipeline.d.ts.map +1 -1
- package/dist/components/pr-pipeline.js +47 -14
- package/dist/components/pr-policy.d.ts +36 -0
- package/dist/components/pr-policy.d.ts.map +1 -1
- package/dist/components/pr-policy.js +36 -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 +5 -1
- package/dist/components/verbs/index.d.ts +2 -0
- package/dist/components/verbs/index.d.ts.map +1 -1
- package/dist/components/verbs/index.js +2 -0
- package/dist/components/verbs/publish-artifact.d.ts +65 -0
- package/dist/components/verbs/publish-artifact.d.ts.map +1 -0
- package/dist/components/verbs/publish-artifact.js +74 -0
- package/dist/components/verbs/publish-image.d.ts +129 -0
- package/dist/components/verbs/publish-image.d.ts.map +1 -0
- package/dist/components/verbs/publish-image.js +145 -0
- package/dist/config-environments.d.ts +112 -0
- package/dist/config-environments.d.ts.map +1 -0
- package/dist/config-environments.js +114 -0
- package/dist/config.d.ts +32 -84
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +13 -96
- package/dist/gate-decision.d.ts +11 -2
- package/dist/gate-decision.d.ts.map +1 -1
- package/dist/gate-decision.js +15 -3
- package/dist/graph-detail.d.ts.map +1 -1
- package/dist/graph-detail.js +15 -3
- package/dist/graph-effective.d.ts +33 -2
- package/dist/graph-effective.d.ts.map +1 -1
- package/dist/graph-effective.js +215 -68
- package/dist/graph-ir.d.ts +48 -0
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/graph-ir.js +130 -0
- package/dist/graph-sub-template.d.ts +11 -0
- package/dist/graph-sub-template.d.ts.map +1 -0
- package/dist/graph-sub-template.js +19 -0
- package/dist/graph-walk.d.ts +66 -0
- package/dist/graph-walk.d.ts.map +1 -0
- package/dist/graph-walk.js +70 -0
- package/dist/import/parser.d.ts +19 -0
- package/dist/import/parser.d.ts.map +1 -1
- package/dist/lexicon.d.ts +80 -6
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.d.ts +11 -0
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/git.d.ts +2 -5
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/ledger-read.d.ts +65 -0
- package/dist/lifecycle/ledger-read.d.ts.map +1 -0
- package/dist/lifecycle/ledger-read.js +160 -0
- package/dist/lifecycle/observe.d.ts +28 -0
- package/dist/lifecycle/observe.d.ts.map +1 -1
- package/dist/lifecycle/observe.js +23 -1
- package/dist/lifecycle/release-workstation.d.ts +7 -0
- package/dist/lifecycle/release-workstation.d.ts.map +1 -1
- package/dist/lifecycle/release-workstation.js +25 -0
- package/dist/lifecycle/run-ledger.d.ts +4 -3
- package/dist/lifecycle/run-ledger.d.ts.map +1 -1
- package/dist/lifecycle/run-ledger.js +1 -0
- package/dist/lint/discover.js +3 -1
- package/dist/lint/post-synth.d.ts +127 -1
- package/dist/lint/post-synth.d.ts.map +1 -1
- package/dist/lint/post-synth.js +84 -2
- package/dist/lint/rule.d.ts +6 -0
- package/dist/lint/rule.d.ts.map +1 -1
- package/dist/lint/rules/op/index.d.ts +1 -0
- package/dist/lint/rules/op/index.d.ts.map +1 -1
- package/dist/lint/rules/op/index.js +2 -0
- package/dist/lint/rules/op/ops019-workspace-op-target.d.ts +32 -0
- package/dist/lint/rules/op/ops019-workspace-op-target.d.ts.map +1 -0
- package/dist/lint/rules/op/ops019-workspace-op-target.js +63 -0
- package/dist/live-endpoint.d.ts +1 -1
- package/dist/live-endpoint.d.ts.map +1 -1
- package/dist/live-endpoint.js +1 -1
- package/dist/observation.d.ts +48 -1
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +21 -5
- package/dist/op/activities/activity-contracts.d.ts +9 -6
- package/dist/op/activities/activity-contracts.d.ts.map +1 -1
- package/dist/op/activities/activity-contracts.js +5 -2
- package/dist/op/activities/index.d.ts +2 -2
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/index.js +1 -1
- package/dist/op/activities/review-agent.d.ts +90 -4
- package/dist/op/activities/review-agent.d.ts.map +1 -1
- package/dist/op/activities/review-agent.js +217 -19
- package/dist/op/activities/work-evidence.d.ts +8 -1
- package/dist/op/activities/work-evidence.d.ts.map +1 -1
- package/dist/op/activities/work-evidence.js +1 -0
- package/dist/op/builders.d.ts +9 -5
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/builders.js +9 -5
- package/dist/op/composites/apply-op.d.ts +29 -2
- package/dist/op/composites/apply-op.d.ts.map +1 -1
- package/dist/op/composites/apply-op.js +20 -1
- package/dist/op/gate-approval.d.ts +11 -5
- package/dist/op/gate-approval.d.ts.map +1 -1
- package/dist/op/gate-approval.js +11 -6
- package/dist/op/gate-quorum.d.ts +100 -3
- package/dist/op/gate-quorum.d.ts.map +1 -1
- package/dist/op/gate-quorum.js +108 -6
- package/dist/op/gate-review.d.ts +9 -0
- package/dist/op/gate-review.d.ts.map +1 -1
- package/dist/op/gate-review.js +13 -0
- package/dist/op/gate.d.ts +44 -3
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/gate.js +25 -4
- package/dist/op/index.d.ts +3 -3
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/index.js +1 -1
- package/dist/op/local-executor.d.ts +38 -3
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-executor.js +48 -6
- package/dist/op/op-waves-run.d.ts +26 -1
- package/dist/op/op-waves-run.d.ts.map +1 -1
- package/dist/op/op-waves-run.js +259 -13
- package/dist/op/op-waves.d.ts +72 -5
- package/dist/op/op-waves.d.ts.map +1 -1
- package/dist/op/op-waves.js +110 -15
- package/dist/op/runtime.d.ts +11 -0
- package/dist/op/runtime.d.ts.map +1 -1
- package/dist/op/schedule-overdue.d.ts +16 -0
- package/dist/op/schedule-overdue.d.ts.map +1 -1
- package/dist/op/schedule-overdue.js +36 -0
- package/dist/op/stage-hooks.d.ts +9 -2
- package/dist/op/stage-hooks.d.ts.map +1 -1
- package/dist/op/stage-hooks.js +7 -5
- package/dist/op/workspace-run-env.d.ts +22 -0
- package/dist/op/workspace-run-env.d.ts.map +1 -0
- package/dist/op/workspace-run-env.js +21 -0
- package/dist/pr-forge.d.ts +24 -0
- package/dist/pr-forge.d.ts.map +1 -1
- package/dist/pr-forge.js +47 -0
- package/dist/pr-post.d.ts +42 -0
- package/dist/pr-post.d.ts.map +1 -1
- package/dist/pr-post.js +67 -1
- package/dist/read-filter.d.ts +65 -0
- package/dist/read-filter.d.ts.map +1 -0
- package/dist/read-filter.js +179 -0
- package/dist/run-event.d.ts +1 -1
- package/dist/run-event.d.ts.map +1 -1
- package/dist/terraform/carve.d.ts +24 -3
- package/dist/terraform/carve.d.ts.map +1 -1
- package/dist/terraform/carve.js +32 -14
- package/dist/terraform/cuts.d.ts +97 -0
- package/dist/terraform/cuts.d.ts.map +1 -0
- package/dist/terraform/cuts.js +138 -0
- package/dist/terraform/folds.d.ts +26 -0
- package/dist/terraform/folds.d.ts.map +1 -0
- package/dist/terraform/folds.js +38 -0
- package/dist/terraform/graph.d.ts.map +1 -1
- package/dist/terraform/graph.js +10 -0
- package/dist/terraform/reach.d.ts +140 -0
- package/dist/terraform/reach.d.ts.map +1 -0
- package/dist/terraform/reach.js +170 -0
- package/dist/terraform/score.d.ts +14 -0
- package/dist/terraform/score.d.ts.map +1 -1
- package/dist/terraform/score.js +14 -31
- package/dist/terraform/state.d.ts.map +1 -1
- package/dist/terraform/state.js +4 -2
- package/dist/terraform/types.d.ts +8 -0
- package/dist/terraform/types.d.ts.map +1 -1
- package/dist/wave-blocked.d.ts +10 -1
- package/dist/wave-blocked.d.ts.map +1 -1
- package/dist/wave-blocked.js +31 -3
- package/dist/wave-runtime.mjs +266 -256
- package/dist/workspace/capabilities-contract.d.ts +66 -0
- package/dist/workspace/capabilities-contract.d.ts.map +1 -0
- package/dist/workspace/capabilities-contract.js +107 -0
- package/dist/workspace/capabilities.schema.json +229 -0
- package/dist/workspace/check.schema.json +11 -2
- package/dist/workspace/checks/ci-branch.d.ts +44 -0
- package/dist/workspace/checks/ci-branch.d.ts.map +1 -0
- package/dist/workspace/checks/ci-branch.js +133 -0
- package/dist/workspace/checks/links.d.ts +3 -0
- package/dist/workspace/checks/links.d.ts.map +1 -1
- package/dist/workspace/checks/links.js +12 -1
- package/dist/workspace/checks/org.d.ts +48 -0
- package/dist/workspace/checks/org.d.ts.map +1 -0
- package/dist/workspace/checks/org.js +156 -0
- package/dist/workspace/checks.d.ts +11 -1
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/checks.js +59 -7
- package/dist/workspace/ci-branches.d.ts +16 -0
- package/dist/workspace/ci-branches.d.ts.map +1 -1
- package/dist/workspace/ci-branches.js +27 -0
- package/dist/workspace/ci-green-cli.js +7 -7
- package/dist/workspace/ci-green-workflow.d.ts +1 -1
- package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
- package/dist/workspace/ci-green-workflow.js +13 -8
- package/dist/workspace/ci-green.d.ts +14 -0
- package/dist/workspace/ci-green.d.ts.map +1 -1
- package/dist/workspace/ci-green.js +44 -11
- package/dist/workspace/ci-run.d.ts +9 -1
- package/dist/workspace/ci-run.d.ts.map +1 -1
- package/dist/workspace/ci-run.js +67 -6
- package/dist/workspace/ci-serve.d.ts +9 -0
- package/dist/workspace/ci-serve.d.ts.map +1 -1
- package/dist/workspace/ci-serve.js +114 -76
- package/dist/workspace/compose-graph.d.ts +23 -0
- package/dist/workspace/compose-graph.d.ts.map +1 -1
- package/dist/workspace/compose-graph.js +3 -1
- package/dist/workspace/composites.d.ts +4 -1
- package/dist/workspace/composites.d.ts.map +1 -1
- package/dist/workspace/composites.js +5 -2
- package/dist/workspace/composites.schema.json +22 -0
- package/dist/workspace/conformance/__writer_fixture__/work/work.schema.json +105 -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 +39 -2
- package/dist/workspace/cross-root-lint.d.ts +56 -0
- package/dist/workspace/cross-root-lint.d.ts.map +1 -0
- package/dist/workspace/cross-root-lint.js +111 -0
- package/dist/workspace/dbt-models-reader.d.ts +44 -0
- package/dist/workspace/dbt-models-reader.d.ts.map +1 -0
- package/dist/workspace/dbt-models-reader.js +356 -0
- package/dist/workspace/dbt-project-common.d.ts +40 -0
- package/dist/workspace/dbt-project-common.d.ts.map +1 -0
- package/dist/workspace/dbt-project-common.js +106 -0
- package/dist/workspace/dbt-project-reader.d.ts +4 -3
- package/dist/workspace/dbt-project-reader.d.ts.map +1 -1
- package/dist/workspace/dbt-project-reader.js +14 -108
- package/dist/workspace/decision-rank.d.ts +26 -0
- package/dist/workspace/decision-rank.d.ts.map +1 -0
- package/dist/workspace/decision-rank.js +16 -0
- package/dist/workspace/declaration.d.ts +43 -2
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.js +45 -11
- package/dist/workspace/declaration.schema.json +133 -24
- package/dist/workspace/environments.d.ts +26 -2
- package/dist/workspace/environments.d.ts.map +1 -1
- package/dist/workspace/environments.js +26 -2
- package/dist/workspace/flyway-dir.d.ts +39 -0
- package/dist/workspace/flyway-dir.d.ts.map +1 -0
- package/dist/workspace/flyway-dir.js +104 -0
- package/dist/workspace/flyway-layout.d.ts +96 -0
- package/dist/workspace/flyway-layout.d.ts.map +1 -0
- package/dist/workspace/flyway-layout.js +308 -0
- package/dist/workspace/graph-cache.d.ts +8 -0
- package/dist/workspace/graph-cache.d.ts.map +1 -1
- package/dist/workspace/graph-cache.js +27 -3
- package/dist/workspace/graph-cli.d.ts +39 -2
- package/dist/workspace/graph-cli.d.ts.map +1 -1
- package/dist/workspace/graph-cli.js +92 -32
- package/dist/workspace/graph.schema.json +182 -0
- package/dist/workspace/intent.d.ts +2 -3
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/intent.js +5 -9
- package/dist/workspace/kind-link-readers.d.ts +59 -2
- package/dist/workspace/kind-link-readers.d.ts.map +1 -1
- package/dist/workspace/kind-link-readers.js +17 -1
- package/dist/workspace/kind-readers.d.ts +3 -0
- package/dist/workspace/kind-readers.d.ts.map +1 -1
- package/dist/workspace/kind-readers.js +7 -1
- package/dist/workspace/kinds.d.ts +66 -2
- package/dist/workspace/kinds.d.ts.map +1 -1
- package/dist/workspace/kinds.js +98 -4
- package/dist/workspace/ledger.schema.json +158 -0
- package/dist/workspace/lexicon-outputs.d.ts +20 -1
- package/dist/workspace/lexicon-outputs.d.ts.map +1 -1
- package/dist/workspace/lexicon-outputs.js +102 -10
- package/dist/workspace/lineage-check.d.ts +3 -0
- package/dist/workspace/lineage-check.d.ts.map +1 -1
- package/dist/workspace/lineage-check.js +23 -4
- package/dist/workspace/links.d.ts +8 -1
- package/dist/workspace/links.d.ts.map +1 -1
- package/dist/workspace/links.js +25 -1
- package/dist/workspace/ls.d.ts +8 -0
- package/dist/workspace/ls.d.ts.map +1 -1
- package/dist/workspace/ls.js +7 -1
- package/dist/workspace/ls.schema.json +7 -0
- package/dist/workspace/member-commands.d.ts +10 -1
- package/dist/workspace/member-commands.d.ts.map +1 -1
- package/dist/workspace/member-commands.js +71 -6
- package/dist/workspace/migrate-links.d.ts +45 -0
- package/dist/workspace/migrate-links.d.ts.map +1 -0
- package/dist/workspace/migrate-links.js +100 -0
- package/dist/workspace/migration-dirs.d.ts +74 -0
- package/dist/workspace/migration-dirs.d.ts.map +1 -0
- package/dist/workspace/migration-dirs.js +254 -0
- package/dist/workspace/nested-graph.d.ts +2 -0
- package/dist/workspace/nested-graph.d.ts.map +1 -1
- package/dist/workspace/nested-graph.js +32 -1
- package/dist/workspace/reason-codes.d.ts +18 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +23 -0
- package/dist/workspace/records-cli.d.ts +11 -0
- package/dist/workspace/records-cli.d.ts.map +1 -1
- package/dist/workspace/records-cli.js +57 -5
- package/dist/workspace/records.schema.json +5 -0
- package/dist/workspace/release-candidates.d.ts +2 -0
- package/dist/workspace/release-candidates.d.ts.map +1 -1
- package/dist/workspace/release-candidates.js +5 -2
- package/dist/workspace/release-train.d.ts +53 -0
- package/dist/workspace/release-train.d.ts.map +1 -0
- package/dist/workspace/release-train.js +134 -0
- package/dist/workspace/release-workflow.d.ts.map +1 -1
- package/dist/workspace/release-workflow.js +4 -3
- package/dist/workspace/repo-ref.d.ts +45 -0
- package/dist/workspace/repo-ref.d.ts.map +1 -0
- package/dist/workspace/repo-ref.js +114 -0
- package/dist/workspace/run-event.schema.json +2 -2
- package/dist/workspace/runs-cli.d.ts +9 -0
- package/dist/workspace/runs-cli.d.ts.map +1 -1
- package/dist/workspace/runs-cli.js +48 -3
- package/dist/workspace/runs.schema.json +7 -0
- package/dist/workspace/search-cli.d.ts +204 -0
- package/dist/workspace/search-cli.d.ts.map +1 -0
- package/dist/workspace/search-cli.js +466 -0
- package/dist/workspace/search-contract.d.ts +56 -0
- package/dist/workspace/search-contract.d.ts.map +1 -0
- package/dist/workspace/search-contract.js +70 -0
- package/dist/workspace/search.schema.json +822 -0
- package/dist/workspace/status-decisions.d.ts +37 -0
- package/dist/workspace/status-decisions.d.ts.map +1 -0
- package/dist/workspace/status-decisions.js +147 -0
- package/dist/workspace/status-gates.d.ts +9 -0
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status.d.ts +4 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/status.js +14 -2
- package/dist/workspace/status.schema.json +6 -0
- package/dist/workspace/work-cli.d.ts.map +1 -1
- package/dist/workspace/work-cli.js +5 -3
- package/dist/workspace/work-evidence-ops.d.ts +83 -0
- package/dist/workspace/work-evidence-ops.d.ts.map +1 -0
- package/dist/workspace/work-evidence-ops.js +169 -0
- package/dist/workspace/work-evidence.d.ts +12 -2
- package/dist/workspace/work-evidence.d.ts.map +1 -1
- package/dist/workspace/work-evidence.js +21 -3
- package/dist/workspace/work-evidence.schema.json +49 -2
- package/dist/workspace/workspace-gates.d.ts +110 -0
- package/dist/workspace/workspace-gates.d.ts.map +1 -0
- package/dist/workspace/workspace-gates.js +140 -0
- package/dist/workspace/workspace-kinds.schema.json +58 -3
- package/dist/workspace/workspace-ledger.d.ts +76 -0
- package/dist/workspace/workspace-ledger.d.ts.map +1 -0
- package/dist/workspace/workspace-ledger.js +91 -0
- package/dist/workspace/workspace-run.d.ts +112 -0
- package/dist/workspace/workspace-run.d.ts.map +1 -0
- package/dist/workspace/workspace-run.js +432 -0
- package/package.json +1 -1
- package/src/__golden__/wave-loop/op-by-apply-after-fails.json +10 -0
- package/src/__golden__/wave-loop/op-by-apply-hold.json +10 -0
- package/src/__golden__/wave-loop/op-by-apply-ignored.json +10 -0
- package/src/__golden__/wave-loop/op-by-apply-pass.json +10 -0
- package/src/__golden__/wave-loop/op-by-apply-skip.json +10 -0
- package/src/__golden__/wave-loop/op-cost-member-clash.json +6 -0
- package/src/__golden__/wave-loop/op-cost-member.json +13 -0
- package/src/__golden__/wave-loop/op-denied-source.json +16 -0
- package/src/__golden__/wave-loop/op-denied.json +16 -0
- package/src/__golden__/wave-loop/op-discover-rest-short.json +6 -0
- package/src/__golden__/wave-loop/op-discover-rest-stops.json +13 -0
- package/src/__golden__/wave-loop/op-discover-rest.json +26 -0
- package/src/__golden__/wave-loop/op-discover-wide.json +26 -0
- package/src/__golden__/wave-loop/op-held-on-again.json +16 -0
- package/src/__golden__/wave-loop/op-held-on-before-apply.json +16 -0
- package/src/__golden__/wave-loop/op-held-on.json +16 -0
- package/src/__golden__/wave-loop/op-hooks-apply-fails.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-fail-after-apply.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-fail-before-apply.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-fail-before-plan.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-held.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-hold-before-apply.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-pass.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-refused-at-base.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-share.json +33 -0
- package/src/__golden__/wave-loop/op-outcome-held.json +10 -0
- package/src/__golden__/wave-loop/op-outcome-replan-approved.json +10 -0
- package/src/__golden__/wave-loop/op-outcome-replan-forever.json +10 -0
- package/src/__golden__/wave-loop/op-outcome-replan.json +10 -0
- package/src/__golden__/wave-loop/op-outcome-stood-down.json +10 -0
- package/src/__golden__/wave-loop/op-outcome-unreadable.json +10 -0
- package/src/__golden__/wave-loop/op-overridden.json +16 -0
- package/src/__golden__/wave-loop/op-per-run.json +20 -0
- package/src/__golden__/wave-loop/op-point.json +13 -0
- package/src/__golden__/wave-loop/op-pr-review.json +10 -0
- package/src/__golden__/wave-loop/op-sealed.json +10 -0
- package/src/__golden__/wave-loop/op-spend-change-only.json +10 -0
- package/src/__golden__/wave-loop/op-spend.json +10 -0
- package/src/__golden__/wave-loop/op-wave-commands.json +55 -0
- package/src/__golden__/wave-loop/op-wide-refused.json +26 -0
- package/src/__golden__/wave-loop/op-wide-waiting.json +29 -0
- package/src/__golden__/wave-loop/op-wide.json +39 -0
- package/src/__snapshots__/okf.test.ts.snap +10 -0
- package/src/action-pins.test.ts +78 -0
- package/src/action-pins.ts +92 -0
- package/src/capabilities/aws.paths +148 -0
- package/src/capabilities/base-mappings.json +122 -0
- package/src/capabilities/catalog.ts +230 -0
- package/src/capabilities/language.test.ts +191 -0
- package/src/capabilities/language.ts +373 -0
- package/src/capabilities/matcher.ts +315 -0
- package/src/capabilities/view-compose.test.ts +76 -0
- package/src/capabilities/view.ts +631 -0
- package/src/cli/commands/carve-score-once.test.ts +99 -0
- package/src/cli/commands/carve.ts +37 -6
- package/src/cli/commands/check-lexicon.test.ts +2 -2
- package/src/cli/commands/import-report.ts +71 -0
- package/src/cli/commands/import.ts +33 -3
- package/src/cli/commands/lint.ts +1 -0
- package/src/cli/commands/migrate-dialect.test.ts +145 -0
- package/src/cli/commands/migrate.ts +132 -11
- package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +4 -4
- package/src/cli/handlers/approve.ts +23 -2
- package/src/cli/handlers/build.ts +7 -1
- package/src/cli/handlers/declared-graph.ts +99 -0
- package/src/cli/handlers/graph.test.ts +94 -3
- package/src/cli/handlers/graph.ts +123 -96
- package/src/cli/handlers/ledger.ts +54 -0
- package/src/cli/handlers/migrate.ts +21 -12
- package/src/cli/handlers/misc.ts +10 -1
- package/src/cli/handlers/pr-env.ts +3 -4
- package/src/cli/handlers/pr.ts +138 -36
- package/src/cli/handlers/query.ts +16 -4
- package/src/cli/handlers/release.ts +6 -3
- package/src/cli/handlers/search-build-roots.test.ts +144 -0
- package/src/cli/handlers/search-count.test.ts +191 -0
- package/src/cli/handlers/search-count.ts +165 -0
- package/src/cli/handlers/search-json.test.ts +333 -0
- package/src/cli/handlers/search-live.test.ts +387 -0
- package/src/cli/handlers/search-paths.test.ts +235 -0
- package/src/cli/handlers/search.ts +1291 -166
- package/src/cli/main.test.ts +43 -3
- package/src/cli/main.ts +88 -17
- package/src/cli/mcp/server.test.ts +3 -3
- package/src/cli/mcp/server.ts +3 -0
- package/src/cli/mcp/tools/capabilities.ts +32 -0
- package/src/cli/mcp/workspace-tools.e2e.test.ts +21 -1
- package/src/cli/mcp/workspace-tools.ts +47 -2
- package/src/cli/parse-args.ts +79 -15
- package/src/cli/registry.ts +36 -4
- package/src/components/builders.ts +8 -0
- package/src/components/capability-plugin-loader.ts +13 -1
- package/src/components/capability-plugin.ts +16 -0
- package/src/components/pr-env-ports.ts +89 -0
- package/src/components/pr-env-run-bundle.test.ts +54 -0
- package/src/components/pr-env-run.ts +5 -76
- package/src/components/pr-environment.ts +2 -1
- package/src/components/pr-hooks.test.ts +73 -5
- package/src/components/pr-hooks.ts +95 -5
- package/src/components/pr-pipeline.ts +64 -16
- package/src/components/pr-policy.test.ts +64 -1
- package/src/components/pr-policy.ts +53 -0
- package/src/components/registry.test.ts +1 -1
- package/src/components/starter-plugin.ts +6 -0
- package/src/components/verbs/index.ts +2 -0
- package/src/components/verbs/publish-artifact.test.ts +60 -0
- package/src/components/verbs/publish-artifact.ts +122 -0
- package/src/components/verbs/publish-image.test.ts +101 -0
- package/src/components/verbs/publish-image.ts +265 -0
- package/src/config-environments.ts +160 -0
- package/src/config.ts +44 -124
- package/src/gate-decision-bundle.test.ts +1 -0
- package/src/gate-decision-identity.test.ts +9 -0
- package/src/gate-decision.ts +26 -3
- package/src/graph-detail.ts +15 -3
- package/src/graph-effective.ts +226 -75
- package/src/graph-ir.test.ts +163 -0
- package/src/graph-ir.ts +174 -0
- package/src/graph-sub-template.ts +22 -0
- package/src/graph-walk.test.ts +44 -0
- package/src/graph-walk.ts +102 -0
- package/src/import/parser.ts +20 -0
- package/src/lexicon.ts +84 -6
- package/src/lifecycle/gate-ledger.ts +8 -0
- package/src/lifecycle/git.ts +2 -2
- package/src/lifecycle/ledger-read.test.ts +107 -0
- package/src/lifecycle/ledger-read.ts +195 -0
- package/src/lifecycle/observe.test.ts +27 -1
- package/src/lifecycle/observe.ts +43 -1
- package/src/lifecycle/release-workstation.ts +24 -0
- package/src/lifecycle/run-ledger.ts +5 -2
- package/src/lint/cross-root.test.ts +122 -0
- package/src/lint/discover.ts +3 -1
- package/src/lint/post-synth.ts +212 -2
- package/src/lint/rule.ts +6 -0
- package/src/lint/rules/op/index.ts +2 -0
- package/src/lint/rules/op/ops019-workspace-op-target.ts +89 -0
- package/src/live-endpoint.ts +1 -1
- package/src/observation.test.ts +25 -0
- package/src/observation.ts +69 -5
- package/src/op/activities/activity-contracts.ts +5 -2
- package/src/op/activities/index.ts +2 -2
- package/src/op/activities/review-agent.test.ts +221 -4
- package/src/op/activities/review-agent.ts +265 -22
- package/src/op/activities/work-evidence.ts +9 -1
- package/src/op/builders.ts +9 -5
- package/src/op/composites/apply-op.test.ts +108 -0
- package/src/op/composites/apply-op.ts +37 -2
- package/src/op/gate-approval.test.ts +6 -1
- package/src/op/gate-approval.ts +12 -6
- package/src/op/gate-quorum-at-base.test.ts +211 -0
- package/src/op/gate-quorum.ts +156 -8
- package/src/op/gate-review.ts +14 -0
- package/src/op/gate.ts +67 -8
- package/src/op/index.ts +3 -2
- package/src/op/local-executor.ts +69 -9
- package/src/op/op-waves-depends-on.test.ts +81 -0
- package/src/op/op-waves-hook-targets.test.ts +4 -2
- package/src/op/op-waves-quorum-product.test.ts +158 -0
- package/src/op/op-waves-run.ts +288 -14
- package/src/op/op-waves.ts +143 -14
- package/src/op/runtime.ts +8 -0
- package/src/op/schedule-overdue.ts +33 -0
- package/src/op/stage-hooks.ts +13 -5
- package/src/op/workspace-run-env.ts +29 -0
- package/src/pr-forge-bundle.test.ts +2 -2
- package/src/pr-forge.test.ts +47 -0
- package/src/pr-forge.ts +68 -0
- package/src/pr-post-open.e2e.test.ts +36 -0
- package/src/pr-post.test.ts +102 -3
- package/src/pr-post.ts +89 -1
- package/src/read-filter.test.ts +54 -0
- package/src/read-filter.ts +193 -0
- package/src/run-event.ts +1 -1
- package/src/stage-hooks-bundle.test.ts +1 -0
- package/src/terraform/carve.ts +52 -15
- package/src/terraform/cuts.test.ts +173 -0
- package/src/terraform/cuts.ts +188 -0
- package/src/terraform/folds.ts +44 -0
- package/src/terraform/graph.ts +9 -0
- package/src/terraform/radius.test.ts +90 -0
- package/src/terraform/reach.test.ts +146 -0
- package/src/terraform/reach.ts +247 -0
- package/src/terraform/score.ts +27 -29
- package/src/terraform/state.ts +3 -1
- package/src/terraform/types.ts +8 -0
- package/src/wave-blocked.ts +28 -3
- package/src/wave-loop-golden.test.ts +4 -3
- package/src/workspace/behold-kinds.test.ts +1 -1
- package/src/workspace/capabilities-contract.test.ts +88 -0
- package/src/workspace/capabilities-contract.ts +132 -0
- package/src/workspace/capabilities.schema.json +229 -0
- package/src/workspace/check-contract.test.ts +7 -6
- package/src/workspace/check.schema.json +11 -2
- package/src/workspace/checks/ci-branch.test.ts +128 -0
- package/src/workspace/checks/ci-branch.ts +141 -0
- package/src/workspace/checks/links.ts +12 -1
- package/src/workspace/checks/org.ts +169 -0
- package/src/workspace/checks.ts +64 -7
- package/src/workspace/ci-branches.ts +31 -0
- package/src/workspace/ci-green-branches.test.ts +153 -0
- package/src/workspace/ci-green-cli.ts +7 -7
- package/src/workspace/ci-green-workflow.test.ts +4 -3
- package/src/workspace/ci-green-workflow.ts +13 -9
- package/src/workspace/ci-green.ts +49 -12
- package/src/workspace/ci-run.test.ts +72 -1
- package/src/workspace/ci-run.ts +68 -8
- package/src/workspace/ci-serve.test.ts +95 -0
- package/src/workspace/ci-serve.ts +106 -65
- package/src/workspace/component-environments.test.ts +25 -2
- package/src/workspace/compose-graph.ts +19 -3
- package/src/workspace/composites.schema.json +22 -0
- package/src/workspace/composites.test.ts +39 -8
- package/src/workspace/composites.ts +6 -2
- package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +105 -1
- package/src/workspace/conformance/conformance.e2e.test.ts +14 -1
- package/src/workspace/conformance/index.ts +31 -2
- package/src/workspace/cross-root-lint.test.ts +90 -0
- package/src/workspace/cross-root-lint.ts +126 -0
- package/src/workspace/dbt-kind.test.ts +3 -2
- package/src/workspace/dbt-models-reader.ts +362 -0
- package/src/workspace/dbt-models.test.ts +248 -0
- package/src/workspace/dbt-project-common.ts +113 -0
- package/src/workspace/dbt-project-reader.ts +29 -112
- package/src/workspace/decision-rank.ts +40 -0
- package/src/workspace/declaration.schema.json +133 -24
- package/src/workspace/declaration.ts +84 -15
- package/src/workspace/environments.ts +40 -4
- package/src/workspace/flyway-dir.ts +113 -0
- package/src/workspace/flyway-layout.ts +337 -0
- package/src/workspace/graph-cache.ts +27 -3
- package/src/workspace/graph-cli.ts +119 -32
- package/src/workspace/graph-contract.test.ts +4 -2
- package/src/workspace/graph.schema.json +182 -0
- package/src/workspace/identity.test.ts +14 -2
- package/src/workspace/intent.ts +6 -14
- package/src/workspace/kind-link-readers.ts +68 -3
- package/src/workspace/kind-readers.e2e.test.ts +28 -0
- package/src/workspace/kind-readers.test.ts +1 -1
- package/src/workspace/kind-readers.ts +7 -1
- package/src/workspace/kinds.test.ts +12 -7
- package/src/workspace/kinds.ts +132 -7
- package/src/workspace/ledger.schema.json +158 -0
- package/src/workspace/lexicon-outputs.ts +132 -13
- package/src/workspace/lineage-check.ts +30 -7
- package/src/workspace/links.ts +24 -1
- package/src/workspace/ls-contract.test.ts +1 -1
- package/src/workspace/ls.schema.json +7 -0
- package/src/workspace/ls.ts +10 -1
- package/src/workspace/member-commands.ts +82 -3
- package/src/workspace/member-file-schema.test.ts +124 -0
- package/src/workspace/migrate-links.test.ts +99 -0
- package/src/workspace/migrate-links.ts +108 -0
- package/src/workspace/migration-dirs.test.ts +272 -0
- package/src/workspace/migration-dirs.ts +267 -0
- package/src/workspace/nested-graph.ts +32 -1
- package/src/workspace/org-scope.test.ts +238 -0
- package/src/workspace/reason-codes.test.ts +13 -1
- package/src/workspace/reason-codes.ts +23 -0
- package/src/workspace/records-cli.ts +58 -5
- package/src/workspace/records.schema.json +5 -0
- package/src/workspace/release-candidates.ts +7 -2
- package/src/workspace/release-train.ts +157 -0
- package/src/workspace/release-workflow.ts +4 -3
- package/src/workspace/repo-ref.ts +113 -0
- package/src/workspace/run-event.schema.json +2 -2
- package/src/workspace/runs-cli.ts +48 -4
- package/src/workspace/runs.schema.json +7 -0
- package/src/workspace/search-cli.e2e.test.ts +305 -0
- package/src/workspace/search-cli.ts +591 -0
- package/src/workspace/search-contract.ts +95 -0
- package/src/workspace/search.schema.json +822 -0
- package/src/workspace/status-contract.test.ts +46 -1
- package/src/workspace/status-decisions.test.ts +100 -0
- package/src/workspace/status-decisions.ts +151 -0
- package/src/workspace/status-gates.ts +9 -0
- package/src/workspace/status.schema.json +6 -0
- package/src/workspace/status.ts +17 -3
- package/src/workspace/where-filters.test.ts +39 -0
- package/src/workspace/work-cli.ts +5 -3
- package/src/workspace/work-evidence-ops.test.ts +176 -0
- package/src/workspace/work-evidence-ops.ts +189 -0
- package/src/workspace/work-evidence.schema.json +49 -2
- package/src/workspace/work-evidence.ts +22 -3
- package/src/workspace/workspace-gates.ts +200 -0
- package/src/workspace/workspace-kinds.schema.json +58 -3
- package/src/workspace/workspace-ledger.ts +130 -0
- package/src/workspace/workspace-run.test.ts +322 -0
- package/src/workspace/workspace-run.ts +461 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `publish-artifact` (aliased `publish-asset`): the object-storage half of the
|
|
3
|
+
* publish family, owned by core (#4408), the same way `publish-image` is.
|
|
4
|
+
* "Put this archive file at the deploy target" is one agnostic verb; what
|
|
5
|
+
* differs per cloud is the upload. Each cloud lexicon contributes that as an
|
|
6
|
+
* {@link ArtifactStorageBackend} through `CapabilityPlugin.storageBackends()`
|
|
7
|
+
* (aws: S3, azure: Blob, gcp: GCS), and the environment picks one (see
|
|
8
|
+
* {@link selectStorageBackend}).
|
|
9
|
+
*
|
|
10
|
+
* This is a sibling of `registryBackends()` rather than a reuse of it: a
|
|
11
|
+
* registry backend only logs a docker client in, while a storage backend
|
|
12
|
+
* moves bytes, and the two are matched against different destinations.
|
|
13
|
+
*
|
|
14
|
+
* Core computes the content digest and the final object URI; the backend only
|
|
15
|
+
* uploads. No rollback.
|
|
16
|
+
*/
|
|
17
|
+
import type { Capability } from "../capability.js";
|
|
18
|
+
export interface PublishArtifactInput {
|
|
19
|
+
/** Path of the artifact inside the build archive (e.g. a jar or zip). */
|
|
20
|
+
from: string;
|
|
21
|
+
/** Destination (e.g. `$env.s3` resolved by the orchestrator). A trailing `/` appends the file's basename. */
|
|
22
|
+
to: string;
|
|
23
|
+
/** Which storage backend to use ("s3", "azure-blob", "gcs"). Normally left out: `$env.publish.backend` or the destination URI picks it. */
|
|
24
|
+
backend?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface PublishArtifactOutput {
|
|
27
|
+
/** Location the artifact was published to, referenced downstream as `@<component>.publish.uri`. */
|
|
28
|
+
uri: string;
|
|
29
|
+
/** Content hash of the published artifact. */
|
|
30
|
+
digest: string;
|
|
31
|
+
}
|
|
32
|
+
/** A cloud's way of putting one local file at a storage URI. */
|
|
33
|
+
export interface ArtifactStorageBackend {
|
|
34
|
+
/** Stable name an environment selects by: "s3", "azure-blob", "gcs". */
|
|
35
|
+
readonly name: string;
|
|
36
|
+
/** True when this backend owns the destination URI. */
|
|
37
|
+
matches(uri: string): boolean;
|
|
38
|
+
/** Upload the local file `from` to the full object URI `to`. */
|
|
39
|
+
upload(args: {
|
|
40
|
+
from: string;
|
|
41
|
+
to: string;
|
|
42
|
+
}): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
export declare class StorageBackendError extends Error {
|
|
45
|
+
constructor(message: string);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Pick the storage backend for one publish. Order: the step's `backend`, then
|
|
49
|
+
* the environment's `ctx.vars.publish.backend`, then the single backend whose
|
|
50
|
+
* `matches` claims the destination, then the only backend there is.
|
|
51
|
+
*/
|
|
52
|
+
export declare function selectStorageBackend(backends: readonly ArtifactStorageBackend[], uri: string, named?: string): ArtifactStorageBackend;
|
|
53
|
+
/** Implemented by a capability that wants the plugins' storage backends injected when a registry is built. */
|
|
54
|
+
export interface StorageBackendConsumer {
|
|
55
|
+
withStorageBackends(backends: readonly ArtifactStorageBackend[]): Capability<never, unknown>;
|
|
56
|
+
}
|
|
57
|
+
export declare function isStorageBackendConsumer(value: unknown): value is StorageBackendConsumer;
|
|
58
|
+
export type PublishArtifactCapability = Capability<PublishArtifactInput, PublishArtifactOutput> & StorageBackendConsumer;
|
|
59
|
+
/** Build the `publish-artifact` verb over the storage backends available. */
|
|
60
|
+
export declare function createPublishArtifactCapability(options?: {
|
|
61
|
+
backends?: readonly ArtifactStorageBackend[];
|
|
62
|
+
}): PublishArtifactCapability;
|
|
63
|
+
/** The starter plugin's `publish-artifact`: storage backends injected from the loaded plugins. */
|
|
64
|
+
export declare const publishArtifactCapability: PublishArtifactCapability;
|
|
65
|
+
//# sourceMappingURL=publish-artifact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish-artifact.d.ts","sourceRoot":"","sources":["../../../src/components/verbs/publish-artifact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,MAAM,WAAW,oBAAoB;IACnC,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,6GAA6G;IAC7G,EAAE,EAAE,MAAM,CAAC;IACX,2IAA2I;IAC3I,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,mGAAmG;IACnG,GAAG,EAAE,MAAM,CAAC;IACZ,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,gEAAgE;AAChE,MAAM,WAAW,sBAAsB;IACrC,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,gEAAgE;IAChE,MAAM,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,SAAS,sBAAsB,EAAE,EAC3C,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,MAAM,GACb,sBAAsB,CAsBxB;AAED,8GAA8G;AAC9G,MAAM,WAAW,sBAAsB;IACrC,mBAAmB,CAAC,QAAQ,EAAE,SAAS,sBAAsB,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;CAC9F;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,sBAAsB,CAExF;AAED,MAAM,MAAM,yBAAyB,GAAG,UAAU,CAAC,oBAAoB,EAAE,qBAAqB,CAAC,GAAG,sBAAsB,CAAC;AAEzH,6EAA6E;AAC7E,wBAAgB,+BAA+B,CAAC,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAA;CAAO,GAAG,yBAAyB,CAkBzI;AAED,kGAAkG;AAClG,eAAO,MAAM,yBAAyB,EAAE,yBAA6D,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `publish-artifact` (aliased `publish-asset`): the object-storage half of the
|
|
3
|
+
* publish family, owned by core (#4408), the same way `publish-image` is.
|
|
4
|
+
* "Put this archive file at the deploy target" is one agnostic verb; what
|
|
5
|
+
* differs per cloud is the upload. Each cloud lexicon contributes that as an
|
|
6
|
+
* {@link ArtifactStorageBackend} through `CapabilityPlugin.storageBackends()`
|
|
7
|
+
* (aws: S3, azure: Blob, gcp: GCS), and the environment picks one (see
|
|
8
|
+
* {@link selectStorageBackend}).
|
|
9
|
+
*
|
|
10
|
+
* This is a sibling of `registryBackends()` rather than a reuse of it: a
|
|
11
|
+
* registry backend only logs a docker client in, while a storage backend
|
|
12
|
+
* moves bytes, and the two are matched against different destinations.
|
|
13
|
+
*
|
|
14
|
+
* Core computes the content digest and the final object URI; the backend only
|
|
15
|
+
* uploads. No rollback.
|
|
16
|
+
*/
|
|
17
|
+
import { createHash } from "node:crypto";
|
|
18
|
+
import { readFileSync } from "node:fs";
|
|
19
|
+
import { archiveRelativePath } from "./build-archive.js";
|
|
20
|
+
export class StorageBackendError extends Error {
|
|
21
|
+
constructor(message) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = "StorageBackendError";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Pick the storage backend for one publish. Order: the step's `backend`, then
|
|
28
|
+
* the environment's `ctx.vars.publish.backend`, then the single backend whose
|
|
29
|
+
* `matches` claims the destination, then the only backend there is.
|
|
30
|
+
*/
|
|
31
|
+
export function selectStorageBackend(backends, uri, named) {
|
|
32
|
+
const names = backends.map((b) => b.name).sort().join(", ") || "none";
|
|
33
|
+
if (named) {
|
|
34
|
+
const found = backends.find((b) => b.name === named);
|
|
35
|
+
if (!found) {
|
|
36
|
+
throw new StorageBackendError(`publish-artifact: no storage backend "${named}" is registered (available: ${names}); declare the lexicon that contributes it in chant.config.ts`);
|
|
37
|
+
}
|
|
38
|
+
return found;
|
|
39
|
+
}
|
|
40
|
+
const matched = backends.filter((b) => b.matches(uri));
|
|
41
|
+
if (matched.length === 1)
|
|
42
|
+
return matched[0];
|
|
43
|
+
if (matched.length > 1) {
|
|
44
|
+
throw new StorageBackendError(`publish-artifact: destination "${uri}" matches several backends (${matched.map((b) => b.name).join(", ")}); set $env.publish.backend`);
|
|
45
|
+
}
|
|
46
|
+
if (backends.length === 1)
|
|
47
|
+
return backends[0];
|
|
48
|
+
throw new StorageBackendError(`publish-artifact: cannot tell which storage backend serves "${uri}" (available: ${names}); set $env.publish.backend`);
|
|
49
|
+
}
|
|
50
|
+
export function isStorageBackendConsumer(value) {
|
|
51
|
+
return typeof value === "object" && value !== null && typeof value.withStorageBackends === "function";
|
|
52
|
+
}
|
|
53
|
+
/** Build the `publish-artifact` verb over the storage backends available. */
|
|
54
|
+
export function createPublishArtifactCapability(options = {}) {
|
|
55
|
+
const backends = options.backends ?? [];
|
|
56
|
+
return {
|
|
57
|
+
kind: "publish-artifact",
|
|
58
|
+
withStorageBackends(next) {
|
|
59
|
+
return createPublishArtifactCapability({ backends: next });
|
|
60
|
+
},
|
|
61
|
+
async run(ctx, input) {
|
|
62
|
+
const localPath = archiveRelativePath(input.from);
|
|
63
|
+
const digest = `sha256:${createHash("sha256").update(readFileSync(localPath)).digest("hex")}`;
|
|
64
|
+
const basename = localPath.split("/").pop() ?? localPath;
|
|
65
|
+
const uri = input.to.endsWith("/") ? `${input.to}${basename}` : input.to;
|
|
66
|
+
const envBackend = ctx.vars?.publish?.backend;
|
|
67
|
+
const backend = selectStorageBackend(backends, uri, input.backend ?? (typeof envBackend === "string" ? envBackend : undefined));
|
|
68
|
+
await backend.upload({ from: localPath, to: uri });
|
|
69
|
+
return { uri, digest };
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/** The starter plugin's `publish-artifact`: storage backends injected from the loaded plugins. */
|
|
74
|
+
export const publishArtifactCapability = createPublishArtifactCapability();
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `publish-image`: the registry half of the publish family, owned by core
|
|
3
|
+
* (#3142, #3143). "Make the image available at the deploy target" is one
|
|
4
|
+
* agnostic verb; what differs per cloud is how the local docker client logs in
|
|
5
|
+
* to the registry. Each cloud lexicon contributes that as a
|
|
6
|
+
* {@link RegistryLoginBackend} through `CapabilityPlugin.registryBackends()`
|
|
7
|
+
* (aws: ECR, azure: ACR, gcp: Artifact Registry), and the environment picks
|
|
8
|
+
* one (see {@link selectRegistryBackend}). So a project may declare several
|
|
9
|
+
* clouds without two plugins registering the same verb.
|
|
10
|
+
*
|
|
11
|
+
* Promotion is by digest and unchanged from the aws-only implementation: load
|
|
12
|
+
* the archived tarball, tag for the destination, log in, push, read the digest
|
|
13
|
+
* back from the push. Optional SBOM/BOM referrers attach via `oras`, best
|
|
14
|
+
* effort. No rollback: a pushed, content-addressed image is not something to
|
|
15
|
+
* undo. See docs/components/build-archive.mdx.
|
|
16
|
+
*/
|
|
17
|
+
import type { Capability } from "../capability.js";
|
|
18
|
+
import { type DockerClient } from "./cloud-executor.js";
|
|
19
|
+
import { type ProcessRunner } from "./process-runner.js";
|
|
20
|
+
/**
|
|
21
|
+
* Common input shape both image-publish backends accept (`publish-image` here, `load-image-on-host` in the aws lexicon): promote the image
|
|
22
|
+
* bytes at archive path `from` to wherever the deploy target can consume
|
|
23
|
+
* them. `to` (registry) and `host` (bare host) are each meaningful to only
|
|
24
|
+
* one backend, so a component authors one step shape (see
|
|
25
|
+
* docs/components/build-archive.mdx) and the env-selected backend (see
|
|
26
|
+
* `selectPublishBackend` below) reads whichever field it needs — the
|
|
27
|
+
* unselected backend's field is simply unused, never a pipeline fork.
|
|
28
|
+
*/
|
|
29
|
+
export interface PublishImageInput {
|
|
30
|
+
/** Path of the image tarball inside the build archive (as produced by `docker-build`; an `archive:`-prefixed reference is accepted and stripped). */
|
|
31
|
+
from: string;
|
|
32
|
+
/** Destination registry — required by `publish-image`, ignored by `load-image-on-host` (e.g. `$env.registry` resolved by the orchestrator). */
|
|
33
|
+
to?: string;
|
|
34
|
+
/** Target host — required by `load-image-on-host`, ignored by `publish-image` (SSM instance id, hostname, or host group). */
|
|
35
|
+
host?: string;
|
|
36
|
+
/** Destination path for the tarball on the host, used only by `load-image-on-host`. Default: `/tmp/chant-archive/<basename of from>`. */
|
|
37
|
+
hostPath?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Which registry login backend to use ("ecr", "acr", "artifact-registry").
|
|
40
|
+
* Normally left out: the environment config (`ctx.vars.publish.backend`) or
|
|
41
|
+
* the registry host picks it.
|
|
42
|
+
*/
|
|
43
|
+
backend?: string;
|
|
44
|
+
/** Additional tags to apply alongside the digest, used only by `publish-image`. */
|
|
45
|
+
tags?: string[];
|
|
46
|
+
/**
|
|
47
|
+
* #610: the artifact's software SBOM (typically wired from a prior
|
|
48
|
+
* `generate-sbom` step's `sbom` output — see ./sbom.ts's
|
|
49
|
+
* `GenerateSbomOutput`) to attach as an OCI referrer on the pushed image
|
|
50
|
+
* digest, via `oras attach`. Used only by `publish-image`; ignored by
|
|
51
|
+
* `load-image-on-host` (registry-less — nothing to attach to). Omit to
|
|
52
|
+
* skip the attach step entirely (the archive-carried copy remains the
|
|
53
|
+
* SBOM's home either way).
|
|
54
|
+
*/
|
|
55
|
+
sbom?: {
|
|
56
|
+
bytes: string;
|
|
57
|
+
mediaType: string;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* #610: the component-level aggregate BOM (wired from
|
|
61
|
+
* ./component-bom.ts's `aggregateComponentBom` output), attached as a
|
|
62
|
+
* second OCI referrer alongside `sbom` when supplied. Optional and
|
|
63
|
+
* independent of `sbom` — a caller may attach either, both, or neither.
|
|
64
|
+
*/
|
|
65
|
+
componentBom?: {
|
|
66
|
+
bytes: string;
|
|
67
|
+
mediaType: string;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/** Result of `publish-image`'s best-effort OCI-referrer attach step (#610) — always present when `input.sbom`/`input.componentBom` was supplied, `undefined` when neither was (nothing to attach, attach step skipped entirely). */
|
|
71
|
+
export interface ReferrerAttachResult {
|
|
72
|
+
/** True once every requested attach (`sbom`, `componentBom`) succeeded. `false` if `oras` was unavailable or any `oras attach` invocation failed. */
|
|
73
|
+
attached: boolean;
|
|
74
|
+
/** Human-readable reason `attached` is `false` (e.g. "oras is not installed"), omitted when `attached` is `true`. */
|
|
75
|
+
reason?: string;
|
|
76
|
+
}
|
|
77
|
+
export interface PublishImageOutput {
|
|
78
|
+
/** Content-addressed digest of the promoted image (`sha256:...`) — what the apply step references. */
|
|
79
|
+
digest: string;
|
|
80
|
+
/** Image reference the apply step can pull/run: `registry/repo@sha256:...` for `publish-image`, a host-local reference for `load-image-on-host`. */
|
|
81
|
+
uri: string;
|
|
82
|
+
/** #610: outcome of the best-effort SBOM/component-BOM referrer attach, when `input.sbom`/`input.componentBom` was supplied. `undefined` for `load-image-on-host` (no attach concept — registry-less) and for `publish-image` calls that supplied neither. */
|
|
83
|
+
referrerAttach?: ReferrerAttachResult;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Common shape both image-publish backends satisfy: promote the image bytes
|
|
87
|
+
* held in the build archive to wherever the deploy target can consume them,
|
|
88
|
+
* and return the identity the apply step references. The backend is
|
|
89
|
+
* selected per environment (`selectPublishBackend`), never per component.
|
|
90
|
+
*/
|
|
91
|
+
export type PublishImageBackend = Capability<PublishImageInput, PublishImageOutput>;
|
|
92
|
+
/** A cloud's way of authenticating the local docker client to its registry. */
|
|
93
|
+
export interface RegistryLoginBackend {
|
|
94
|
+
/** Stable name an environment selects by: "ecr", "acr", "artifact-registry". */
|
|
95
|
+
readonly name: string;
|
|
96
|
+
/** True when this backend owns the registry host (used when the environment does not name one). */
|
|
97
|
+
matches(registry: string): boolean;
|
|
98
|
+
/** Authenticate docker against `registry` (host part of the destination). */
|
|
99
|
+
login(registry: string): Promise<void>;
|
|
100
|
+
}
|
|
101
|
+
export declare class RegistryBackendError extends Error {
|
|
102
|
+
constructor(message: string);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Pick the login backend for one publish. Order: the step's `backend`, then the
|
|
106
|
+
* environment's `ctx.vars.publish.backend`, then the single backend whose
|
|
107
|
+
* `matches` claims the registry host, then the only backend there is.
|
|
108
|
+
*/
|
|
109
|
+
export declare function selectRegistryBackend(backends: readonly RegistryLoginBackend[], registry: string, named?: string): RegistryLoginBackend;
|
|
110
|
+
/** Implemented by a capability that wants the plugins' registry backends injected when a registry is built. */
|
|
111
|
+
export interface RegistryBackendConsumer {
|
|
112
|
+
withRegistryBackends(backends: readonly RegistryLoginBackend[]): Capability<never, unknown>;
|
|
113
|
+
}
|
|
114
|
+
export declare function isRegistryBackendConsumer(value: unknown): value is RegistryBackendConsumer;
|
|
115
|
+
export interface PublishImageOptions {
|
|
116
|
+
docker: DockerClient;
|
|
117
|
+
backends?: readonly RegistryLoginBackend[];
|
|
118
|
+
processRunner?: ProcessRunner;
|
|
119
|
+
}
|
|
120
|
+
export type PublishImageCapability = PublishImageBackend & RegistryBackendConsumer;
|
|
121
|
+
/**
|
|
122
|
+
* Build the `publish-image` verb over a docker client and the registry login
|
|
123
|
+
* backends available. Load, tag, log in via the selected backend, push, and
|
|
124
|
+
* return the pushed digest.
|
|
125
|
+
*/
|
|
126
|
+
export declare function createPublishImageCapability(options: PublishImageOptions): PublishImageCapability;
|
|
127
|
+
/** The starter plugin's `publish-image`: real docker, backends injected from the loaded plugins. */
|
|
128
|
+
export declare const publishImageCapability: PublishImageCapability;
|
|
129
|
+
//# sourceMappingURL=publish-image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish-image.d.ts","sourceRoot":"","sources":["../../../src/components/verbs/publish-image.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAA2B,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE/E;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,qJAAqJ;IACrJ,IAAI,EAAE,MAAM,CAAC;IACb,+IAA+I;IAC/I,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,6HAA6H;IAC7H,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yIAAyI;IACzI,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C;;;;;OAKG;IACH,YAAY,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CACrD;AAED,oOAAoO;AACpO,MAAM,WAAW,oBAAoB;IACnC,qJAAqJ;IACrJ,QAAQ,EAAE,OAAO,CAAC;IAClB,qHAAqH;IACrH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,sGAAsG;IACtG,MAAM,EAAE,MAAM,CAAC;IACf,oJAAoJ;IACpJ,GAAG,EAAE,MAAM,CAAC;IACZ,8PAA8P;IAC9P,cAAc,CAAC,EAAE,oBAAoB,CAAC;CACvC;AAED;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,CAAC;AAIpF,+EAA+E;AAC/E,MAAM,WAAW,oBAAoB;IACnC,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mGAAmG;IACnG,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC,6EAA6E;IAC7E,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC;AAED,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,SAAS,oBAAoB,EAAE,EACzC,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,GACb,oBAAoB,CAsBtB;AAED,+GAA+G;AAC/G,MAAM,WAAW,uBAAuB;IACtC,oBAAoB,CAAC,QAAQ,EAAE,SAAS,oBAAoB,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;CAC7F;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,uBAAuB,CAE1F;AA4DD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAC3C,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,MAAM,MAAM,sBAAsB,GAAG,mBAAmB,GAAG,uBAAuB,CAAC;AAEnF;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,mBAAmB,GAAG,sBAAsB,CAqCjG;AAED,oGAAoG;AACpG,eAAO,MAAM,sBAAsB,EAAE,sBAA6E,CAAC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `publish-image`: the registry half of the publish family, owned by core
|
|
3
|
+
* (#3142, #3143). "Make the image available at the deploy target" is one
|
|
4
|
+
* agnostic verb; what differs per cloud is how the local docker client logs in
|
|
5
|
+
* to the registry. Each cloud lexicon contributes that as a
|
|
6
|
+
* {@link RegistryLoginBackend} through `CapabilityPlugin.registryBackends()`
|
|
7
|
+
* (aws: ECR, azure: ACR, gcp: Artifact Registry), and the environment picks
|
|
8
|
+
* one (see {@link selectRegistryBackend}). So a project may declare several
|
|
9
|
+
* clouds without two plugins registering the same verb.
|
|
10
|
+
*
|
|
11
|
+
* Promotion is by digest and unchanged from the aws-only implementation: load
|
|
12
|
+
* the archived tarball, tag for the destination, log in, push, read the digest
|
|
13
|
+
* back from the push. Optional SBOM/BOM referrers attach via `oras`, best
|
|
14
|
+
* effort. No rollback: a pushed, content-addressed image is not something to
|
|
15
|
+
* undo. See docs/components/build-archive.mdx.
|
|
16
|
+
*/
|
|
17
|
+
import { archiveRelativePath } from "./build-archive.js";
|
|
18
|
+
import { realDocker } from "./cloud-executor.js";
|
|
19
|
+
import { defaultProcessRunner, q } from "./process-runner.js";
|
|
20
|
+
export class RegistryBackendError extends Error {
|
|
21
|
+
constructor(message) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = "RegistryBackendError";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Pick the login backend for one publish. Order: the step's `backend`, then the
|
|
28
|
+
* environment's `ctx.vars.publish.backend`, then the single backend whose
|
|
29
|
+
* `matches` claims the registry host, then the only backend there is.
|
|
30
|
+
*/
|
|
31
|
+
export function selectRegistryBackend(backends, registry, named) {
|
|
32
|
+
const names = backends.map((b) => b.name).sort().join(", ") || "none";
|
|
33
|
+
if (named) {
|
|
34
|
+
const found = backends.find((b) => b.name === named);
|
|
35
|
+
if (!found) {
|
|
36
|
+
throw new RegistryBackendError(`publish-image: no registry backend "${named}" is registered (available: ${names}); declare the lexicon that contributes it in chant.config.ts`);
|
|
37
|
+
}
|
|
38
|
+
return found;
|
|
39
|
+
}
|
|
40
|
+
const matched = backends.filter((b) => b.matches(registry));
|
|
41
|
+
if (matched.length === 1)
|
|
42
|
+
return matched[0];
|
|
43
|
+
if (matched.length > 1) {
|
|
44
|
+
throw new RegistryBackendError(`publish-image: registry "${registry}" matches several backends (${matched.map((b) => b.name).join(", ")}); set $env.publish.backend`);
|
|
45
|
+
}
|
|
46
|
+
if (backends.length === 1)
|
|
47
|
+
return backends[0];
|
|
48
|
+
throw new RegistryBackendError(`publish-image: cannot tell which registry backend serves "${registry}" (available: ${names}); set $env.publish.backend`);
|
|
49
|
+
}
|
|
50
|
+
export function isRegistryBackendConsumer(value) {
|
|
51
|
+
return typeof value === "object" && value !== null && typeof value.withRegistryBackends === "function";
|
|
52
|
+
}
|
|
53
|
+
// ── publish-image ────────────────────────────────────────────────────────────
|
|
54
|
+
/**
|
|
55
|
+
* Attempt to `oras attach` one referrer document (SBOM or component BOM) to
|
|
56
|
+
* `imageRef`'s digest. Writes the document's bytes to a scratch file (`oras
|
|
57
|
+
* attach` reads from a file path, not stdin) and shells out through
|
|
58
|
+
* `runner`. Never throws — a failure here is reported back to the caller as
|
|
59
|
+
* `{ ok: false, reason }` so a missing/erroring `oras` never fails the
|
|
60
|
+
* publish itself (see `attachReferrers`'s doc comment for why).
|
|
61
|
+
*/
|
|
62
|
+
async function attachOneReferrer(runner, imageRef, doc, label) {
|
|
63
|
+
try {
|
|
64
|
+
const scratchFile = `/tmp/chant-referrer-attach/${label}-${Date.now()}.json`;
|
|
65
|
+
await runner.run(`mkdir -p ${q("/tmp/chant-referrer-attach")}`);
|
|
66
|
+
await runner.run(`printf '%s' ${q(doc.bytes)} > ${q(scratchFile)}`);
|
|
67
|
+
await runner.run(`oras attach --artifact-type ${q(doc.mediaType)} ${q(imageRef)} ${q(scratchFile)}:${q(doc.mediaType)}`);
|
|
68
|
+
return { ok: true };
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
return { ok: false, reason: err instanceof Error ? err.message : String(err) };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Best-effort OCI-referrer attach for a just-pushed image (#610): attaches
|
|
76
|
+
* `input.sbom` and/or `input.componentBom`, when supplied, to `imageRef` via
|
|
77
|
+
* `oras attach`. Guarded on `oras` availability — a missing binary is
|
|
78
|
+
* reported back as `{ attached: false, reason }` rather than thrown, since
|
|
79
|
+
* the image itself is already successfully promoted by the time this step
|
|
80
|
+
* runs (attach is additive registry-side convenience on top of the
|
|
81
|
+
* archive-carried copy, per this module's doc comment, never a condition the
|
|
82
|
+
* core promote-by-digest job depends on). Returns `undefined` when neither
|
|
83
|
+
* `input.sbom` nor `input.componentBom` was supplied — nothing to attach,
|
|
84
|
+
* skipped entirely, no `oras` call at all.
|
|
85
|
+
*/
|
|
86
|
+
async function attachReferrers(runner, imageRef, input) {
|
|
87
|
+
if (!input.sbom && !input.componentBom)
|
|
88
|
+
return undefined;
|
|
89
|
+
if (!(await runner.available("oras"))) {
|
|
90
|
+
return { attached: false, reason: `"oras" is not installed or not on PATH — required to attach OCI referrers` };
|
|
91
|
+
}
|
|
92
|
+
const results = [];
|
|
93
|
+
if (input.sbom)
|
|
94
|
+
results.push(await attachOneReferrer(runner, imageRef, input.sbom, "sbom"));
|
|
95
|
+
if (input.componentBom)
|
|
96
|
+
results.push(await attachOneReferrer(runner, imageRef, input.componentBom, "component-bom"));
|
|
97
|
+
const failed = results.find((r) => !r.ok);
|
|
98
|
+
return failed ? { attached: false, reason: failed.reason } : { attached: true };
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Build the `publish-image` verb over a docker client and the registry login
|
|
102
|
+
* backends available. Load, tag, log in via the selected backend, push, and
|
|
103
|
+
* return the pushed digest.
|
|
104
|
+
*/
|
|
105
|
+
export function createPublishImageCapability(options) {
|
|
106
|
+
const { docker } = options;
|
|
107
|
+
const backends = options.backends ?? [];
|
|
108
|
+
const processRunner = options.processRunner ?? defaultProcessRunner();
|
|
109
|
+
return {
|
|
110
|
+
kind: "publish-image",
|
|
111
|
+
withRegistryBackends(next) {
|
|
112
|
+
return createPublishImageCapability({ docker, processRunner, backends: next });
|
|
113
|
+
},
|
|
114
|
+
async run(ctx, input) {
|
|
115
|
+
if (!input.to)
|
|
116
|
+
throw new Error(`publish-image "${input.from}": "to" (destination registry) is required`);
|
|
117
|
+
const repo = input.to.replace(/\/+$/, "");
|
|
118
|
+
const registry = repo.split("/")[0];
|
|
119
|
+
const envBackend = ctx.vars?.publish?.backend;
|
|
120
|
+
const backend = selectRegistryBackend(backends, registry, input.backend ?? (typeof envBackend === "string" ? envBackend : undefined));
|
|
121
|
+
// `docker load` reports the archived image's local reference: a name:tag
|
|
122
|
+
// for a tagged build, or an image id. It is a valid `docker tag` source
|
|
123
|
+
// but never a registry digest, so the promoted digest is read back from
|
|
124
|
+
// the push below.
|
|
125
|
+
const { digest: localRef } = await docker.load({ inFile: archiveRelativePath(input.from) });
|
|
126
|
+
// Publish under a tag: docker can neither tag nor push a digest-qualified
|
|
127
|
+
// reference, so the transport is a tag and the stable identifier is the
|
|
128
|
+
// digest the push returns.
|
|
129
|
+
const pushRef = `${repo}:latest`;
|
|
130
|
+
await docker.tag({ source: localRef, target: pushRef });
|
|
131
|
+
await backend.login(registry);
|
|
132
|
+
const { digest: pushed } = await docker.push({ image: pushRef });
|
|
133
|
+
const digest = pushed.includes("@") ? pushed.slice(pushed.indexOf("@") + 1) : pushed;
|
|
134
|
+
for (const tag of input.tags ?? []) {
|
|
135
|
+
const tagged = `${repo}:${tag}`;
|
|
136
|
+
await docker.tag({ source: localRef, target: tagged });
|
|
137
|
+
await docker.push({ image: tagged });
|
|
138
|
+
}
|
|
139
|
+
const referrerAttach = await attachReferrers(processRunner, `${repo}@${digest}`, input);
|
|
140
|
+
return { digest, uri: `${repo}@${digest}`, ...(referrerAttach ? { referrerAttach } : {}) };
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
/** The starter plugin's `publish-image`: real docker, backends injected from the loaded plugins. */
|
|
145
|
+
export const publishImageCapability = createPublishImageCapability({ docker: realDocker });
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pure helpers over a loaded config's `environments` and `ownership`:
|
|
3
|
+
* names, patterns, endpoints and the ownership stack. ./config.ts re-exports
|
|
4
|
+
* them. They import nothing at runtime, so ./components/pr-environment.ts and
|
|
5
|
+
* ./live-endpoint.ts use them without bundling the config loader.
|
|
6
|
+
*/
|
|
7
|
+
import type { ChantConfig } from "./config.js";
|
|
8
|
+
/**
|
|
9
|
+
* One project-declared environment (chant #1166). Historically always a bare
|
|
10
|
+
* name (`"floci"`); an entry can now instead carry the endpoint that
|
|
11
|
+
* environment's `--live` reads should target (`{ name: "floci", endpoint:
|
|
12
|
+
* "http://localhost:4566" }`), so a project pointed at a local emulator is
|
|
13
|
+
* self-sufficient — no ambient `AWS_ENDPOINT_URL` export required to avoid
|
|
14
|
+
* silently querying real AWS. See {@link environmentName}, {@link
|
|
15
|
+
* environmentNames}, {@link environmentEndpoint} below, and
|
|
16
|
+
* `./live-endpoint.ts`'s `applyLiveEndpoint`, the CLI-side consumer.
|
|
17
|
+
*
|
|
18
|
+
* The array's order is the member's promotion order (#4030, see
|
|
19
|
+
* `./workspace/promotion-order.ts`), and `canary: true` marks a step as the
|
|
20
|
+
* canary step of that order. The canary is declared and surfaced; chant does
|
|
21
|
+
* not yet act on it.
|
|
22
|
+
*
|
|
23
|
+
* `executor` names the forge and the committed workflow that deploys the
|
|
24
|
+
* environment (#4402), so a reader such as behold knows a release there runs
|
|
25
|
+
* through CI rather than a local `chant run`. chant declares and prints it
|
|
26
|
+
* (`chant workspace graph --composites`); it never dispatches it.
|
|
27
|
+
*/
|
|
28
|
+
export type EnvironmentDeclaration = string | {
|
|
29
|
+
name: string;
|
|
30
|
+
endpoint?: string;
|
|
31
|
+
canary?: boolean;
|
|
32
|
+
executor?: EnvironmentExecutor;
|
|
33
|
+
};
|
|
34
|
+
/** The forges an environment's executor can name (#4402). */
|
|
35
|
+
export declare const EXECUTOR_FORGES: readonly ["github", "gitlab", "forgejo"];
|
|
36
|
+
/** The forge workflow that deploys one environment (#4402). */
|
|
37
|
+
export interface EnvironmentExecutor {
|
|
38
|
+
forge: (typeof EXECUTOR_FORGES)[number];
|
|
39
|
+
/** The committed workflow file the forge runs, such as `deploy-prod.yml` under `.github/workflows/`, or `.gitlab-ci.yml`. */
|
|
40
|
+
workflow: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* `ownership.env`: a literal environment identity, or a reference to a
|
|
44
|
+
* declared build parameter whose resolved value becomes the identity (#1396).
|
|
45
|
+
*/
|
|
46
|
+
export type OwnershipEnv = string | {
|
|
47
|
+
param: string;
|
|
48
|
+
};
|
|
49
|
+
/** The declared name of one `environments` entry, whichever form it takes. */
|
|
50
|
+
export declare function environmentName(entry: EnvironmentDeclaration): string;
|
|
51
|
+
/**
|
|
52
|
+
* Every declared environment's name, in `environments` order. `undefined` in,
|
|
53
|
+
* `undefined` out — mirrors the field itself being optional, so a caller that
|
|
54
|
+
* already writes `config.environments?.something` can keep doing so:
|
|
55
|
+
* `environmentNames(config.environments)?.includes(name)`.
|
|
56
|
+
*/
|
|
57
|
+
export declare function environmentNames(environments: EnvironmentDeclaration[] | undefined): string[] | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Whether a declared environment name is a glob pattern rather than a literal
|
|
60
|
+
* (#1221) — it contains at least one `*`.
|
|
61
|
+
*/
|
|
62
|
+
export declare function isEnvironmentPattern(declaredName: string): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Anchored `*`-glob match (#1221): each `*` in `pattern` matches any run of
|
|
65
|
+
* characters (possibly empty); everything else matches itself. Deliberately
|
|
66
|
+
* the whole surface — no `?`, no character classes, no regex. A pattern with
|
|
67
|
+
* no `*` degenerates to string equality.
|
|
68
|
+
*/
|
|
69
|
+
export declare function matchesEnvironmentPattern(pattern: string, name: string): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Environment-membership test (#1221): is `name` covered by this project's
|
|
72
|
+
* declared `environments`? A literal entry matches by equality; an entry
|
|
73
|
+
* containing `*` matches as a glob pattern (`"pr-*"` covers `pr-42`).
|
|
74
|
+
* Literals are checked first across the whole list, then patterns — so a
|
|
75
|
+
* name that is declared outright never depends on pattern order. `undefined`
|
|
76
|
+
* / empty `environments` returns `false`; callers that treat "no declared
|
|
77
|
+
* environments" as "anything goes" (e.g. {@link unknownEnvError} in
|
|
78
|
+
* `./env.ts`) guard that case themselves.
|
|
79
|
+
*/
|
|
80
|
+
export declare function matchesDeclaredEnvironment(environments: EnvironmentDeclaration[] | undefined, name: string): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* The endpoint `name` declares (chant #1166) — `undefined` for a bare-string
|
|
83
|
+
* entry, an entry with no `endpoint` set, or a name this project doesn't
|
|
84
|
+
* declare at all. `./live-endpoint.ts`'s `applyLiveEndpoint` is the consumer:
|
|
85
|
+
* it injects this into the ambient env var each observing lexicon's CLI
|
|
86
|
+
* shell-out reads (e.g. `AWS_ENDPOINT_URL`), unless that var is already set —
|
|
87
|
+
* ambient always wins.
|
|
88
|
+
*
|
|
89
|
+
* A pattern entry (#1221) can carry an endpoint too: `{ name: "pr-*",
|
|
90
|
+
* endpoint }` supplies the endpoint for every `pr-<n>` environment. A literal
|
|
91
|
+
* entry always wins over a pattern — declaring `pr-special` alongside
|
|
92
|
+
* `pr-*` resolves `pr-special` to the literal entry's endpoint (or none).
|
|
93
|
+
*/
|
|
94
|
+
export declare function environmentEndpoint(environments: EnvironmentDeclaration[] | undefined, name: string): string | undefined;
|
|
95
|
+
/**
|
|
96
|
+
* The executor `name` declares (#4402), resolved like {@link
|
|
97
|
+
* environmentEndpoint}: a literal entry wins over a pattern, and a literal
|
|
98
|
+
* entry with no executor does not fall through to a pattern's.
|
|
99
|
+
*/
|
|
100
|
+
export declare function environmentExecutor(environments: EnvironmentDeclaration[] | undefined, name: string): EnvironmentExecutor | undefined;
|
|
101
|
+
/** Whether an `ownership.env` entry is a build-parameter reference rather than a literal. */
|
|
102
|
+
export declare function isOwnershipParamRef(env: OwnershipEnv | undefined): env is {
|
|
103
|
+
param: string;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* The ownership stack identity alone — `ownership.stack` when marking is on
|
|
107
|
+
* (no `stack`, or `enabled: false`, means off). For callers that need the
|
|
108
|
+
* stack and nothing else (a field manager, a prune selector) and so have no
|
|
109
|
+
* build parameters to resolve `env` against.
|
|
110
|
+
*/
|
|
111
|
+
export declare function resolveOwnershipStack(config: Pick<ChantConfig, "ownership">): string | undefined;
|
|
112
|
+
//# sourceMappingURL=config-environments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-environments.d.ts","sourceRoot":"","sources":["../src/config-environments.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAEpI,6DAA6D;AAC7D,eAAO,MAAM,eAAe,YAAI,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAU,CAAC;AAExE,+DAA+D;AAC/D,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;IACxC,6HAA6H;IAC7H,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,CAErE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,sBAAsB,EAAE,GAAG,SAAS,GAAG,MAAM,EAAE,GAAG,SAAS,CAEzG;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAElE;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAehF;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,sBAAsB,EAAE,GAAG,SAAS,EAClD,IAAI,EAAE,MAAM,GACX,OAAO,CAIT;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,sBAAsB,EAAE,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKxH;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,sBAAsB,EAAE,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAKrI;AAED,6FAA6F;AAC7F,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,YAAY,GAAG,SAAS,GAAG,GAAG,IAAI;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAE3F;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,GAAG,MAAM,GAAG,SAAS,CAIhG"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pure helpers over a loaded config's `environments` and `ownership`:
|
|
3
|
+
* names, patterns, endpoints and the ownership stack. ./config.ts re-exports
|
|
4
|
+
* them. They import nothing at runtime, so ./components/pr-environment.ts and
|
|
5
|
+
* ./live-endpoint.ts use them without bundling the config loader.
|
|
6
|
+
*/
|
|
7
|
+
/** The forges an environment's executor can name (#4402). */
|
|
8
|
+
export const EXECUTOR_FORGES = ["github", "gitlab", "forgejo"];
|
|
9
|
+
/** The declared name of one `environments` entry, whichever form it takes. */
|
|
10
|
+
export function environmentName(entry) {
|
|
11
|
+
return typeof entry === "string" ? entry : entry.name;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Every declared environment's name, in `environments` order. `undefined` in,
|
|
15
|
+
* `undefined` out — mirrors the field itself being optional, so a caller that
|
|
16
|
+
* already writes `config.environments?.something` can keep doing so:
|
|
17
|
+
* `environmentNames(config.environments)?.includes(name)`.
|
|
18
|
+
*/
|
|
19
|
+
export function environmentNames(environments) {
|
|
20
|
+
return environments?.map(environmentName);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Whether a declared environment name is a glob pattern rather than a literal
|
|
24
|
+
* (#1221) — it contains at least one `*`.
|
|
25
|
+
*/
|
|
26
|
+
export function isEnvironmentPattern(declaredName) {
|
|
27
|
+
return declaredName.includes("*");
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Anchored `*`-glob match (#1221): each `*` in `pattern` matches any run of
|
|
31
|
+
* characters (possibly empty); everything else matches itself. Deliberately
|
|
32
|
+
* the whole surface — no `?`, no character classes, no regex. A pattern with
|
|
33
|
+
* no `*` degenerates to string equality.
|
|
34
|
+
*/
|
|
35
|
+
export function matchesEnvironmentPattern(pattern, name) {
|
|
36
|
+
const parts = pattern.split("*");
|
|
37
|
+
if (parts.length === 1)
|
|
38
|
+
return pattern === name;
|
|
39
|
+
const first = parts[0];
|
|
40
|
+
const last = parts[parts.length - 1];
|
|
41
|
+
if (!name.startsWith(first))
|
|
42
|
+
return false;
|
|
43
|
+
let cursor = first.length;
|
|
44
|
+
for (let i = 1; i < parts.length - 1; i++) {
|
|
45
|
+
const part = parts[i];
|
|
46
|
+
if (part === "")
|
|
47
|
+
continue;
|
|
48
|
+
const at = name.indexOf(part, cursor);
|
|
49
|
+
if (at === -1)
|
|
50
|
+
return false;
|
|
51
|
+
cursor = at + part.length;
|
|
52
|
+
}
|
|
53
|
+
return name.length - cursor >= last.length && name.endsWith(last);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Environment-membership test (#1221): is `name` covered by this project's
|
|
57
|
+
* declared `environments`? A literal entry matches by equality; an entry
|
|
58
|
+
* containing `*` matches as a glob pattern (`"pr-*"` covers `pr-42`).
|
|
59
|
+
* Literals are checked first across the whole list, then patterns — so a
|
|
60
|
+
* name that is declared outright never depends on pattern order. `undefined`
|
|
61
|
+
* / empty `environments` returns `false`; callers that treat "no declared
|
|
62
|
+
* environments" as "anything goes" (e.g. {@link unknownEnvError} in
|
|
63
|
+
* `./env.ts`) guard that case themselves.
|
|
64
|
+
*/
|
|
65
|
+
export function matchesDeclaredEnvironment(environments, name) {
|
|
66
|
+
const names = environmentNames(environments) ?? [];
|
|
67
|
+
if (names.includes(name))
|
|
68
|
+
return true;
|
|
69
|
+
return names.some((declared) => isEnvironmentPattern(declared) && matchesEnvironmentPattern(declared, name));
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The endpoint `name` declares (chant #1166) — `undefined` for a bare-string
|
|
73
|
+
* entry, an entry with no `endpoint` set, or a name this project doesn't
|
|
74
|
+
* declare at all. `./live-endpoint.ts`'s `applyLiveEndpoint` is the consumer:
|
|
75
|
+
* it injects this into the ambient env var each observing lexicon's CLI
|
|
76
|
+
* shell-out reads (e.g. `AWS_ENDPOINT_URL`), unless that var is already set —
|
|
77
|
+
* ambient always wins.
|
|
78
|
+
*
|
|
79
|
+
* A pattern entry (#1221) can carry an endpoint too: `{ name: "pr-*",
|
|
80
|
+
* endpoint }` supplies the endpoint for every `pr-<n>` environment. A literal
|
|
81
|
+
* entry always wins over a pattern — declaring `pr-special` alongside
|
|
82
|
+
* `pr-*` resolves `pr-special` to the literal entry's endpoint (or none).
|
|
83
|
+
*/
|
|
84
|
+
export function environmentEndpoint(environments, name) {
|
|
85
|
+
const found = environments?.find((e) => environmentName(e) === name) ??
|
|
86
|
+
environments?.find((e) => isEnvironmentPattern(environmentName(e)) && matchesEnvironmentPattern(environmentName(e), name));
|
|
87
|
+
return found && typeof found !== "string" ? found.endpoint : undefined;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The executor `name` declares (#4402), resolved like {@link
|
|
91
|
+
* environmentEndpoint}: a literal entry wins over a pattern, and a literal
|
|
92
|
+
* entry with no executor does not fall through to a pattern's.
|
|
93
|
+
*/
|
|
94
|
+
export function environmentExecutor(environments, name) {
|
|
95
|
+
const found = environments?.find((e) => environmentName(e) === name) ??
|
|
96
|
+
environments?.find((e) => isEnvironmentPattern(environmentName(e)) && matchesEnvironmentPattern(environmentName(e), name));
|
|
97
|
+
return found && typeof found !== "string" ? found.executor : undefined;
|
|
98
|
+
}
|
|
99
|
+
/** Whether an `ownership.env` entry is a build-parameter reference rather than a literal. */
|
|
100
|
+
export function isOwnershipParamRef(env) {
|
|
101
|
+
return typeof env === "object" && env !== null && typeof env.param === "string";
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* The ownership stack identity alone — `ownership.stack` when marking is on
|
|
105
|
+
* (no `stack`, or `enabled: false`, means off). For callers that need the
|
|
106
|
+
* stack and nothing else (a field manager, a prune selector) and so have no
|
|
107
|
+
* build parameters to resolve `env` against.
|
|
108
|
+
*/
|
|
109
|
+
export function resolveOwnershipStack(config) {
|
|
110
|
+
const o = config.ownership;
|
|
111
|
+
if (!o || !o.stack || o.enabled === false)
|
|
112
|
+
return undefined;
|
|
113
|
+
return o.stack;
|
|
114
|
+
}
|