@intentius/chant 0.124.46 → 0.124.49
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/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/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 +41 -14
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.js +6 -1
- package/dist/cli/handlers/graph-reader.d.ts +26 -0
- package/dist/cli/handlers/graph-reader.d.ts.map +1 -0
- package/dist/cli/handlers/graph-reader.js +41 -0
- package/dist/cli/handlers/graph.d.ts.map +1 -1
- package/dist/cli/handlers/graph.js +14 -0
- 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.js +2 -2
- 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 +183 -40
- 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.d.ts +2 -4
- package/dist/cli/handlers/search.d.ts.map +1 -1
- package/dist/cli/handlers/search.js +13 -39
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +87 -14
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +47 -2
- package/dist/cli/registry.d.ts +22 -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-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/pr-run.d.ts +3 -0
- package/dist/components/pr-run.d.ts.map +1 -1
- package/dist/components/pr-run.js +1 -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 +20 -0
- package/dist/config-environments.d.ts.map +1 -1
- package/dist/config-environments.js +12 -0
- package/dist/config.d.ts +25 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -2
- package/dist/gate-decision.d.ts +20 -2
- package/dist/gate-decision.d.ts.map +1 -1
- package/dist/gate-decision.js +30 -3
- package/dist/graph-ir.d.ts +25 -0
- package/dist/graph-ir.d.ts.map +1 -1
- 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 +94 -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/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/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/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-base.d.ts +25 -0
- package/dist/op/gate-approval-base.d.ts.map +1 -0
- package/dist/op/gate-approval-base.js +71 -0
- package/dist/op/gate-approval.d.ts +18 -9
- package/dist/op/gate-approval.d.ts.map +1 -1
- package/dist/op/gate-approval.js +13 -31
- package/dist/op/gate-name.d.ts +13 -0
- package/dist/op/gate-name.d.ts.map +1 -1
- package/dist/op/gate-name.js +14 -1
- 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 +47 -5
- 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 +45 -3
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-executor.js +68 -7
- 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-loop.d.ts +10 -0
- package/dist/pr-loop.d.ts.map +1 -1
- package/dist/pr-loop.js +4 -0
- package/dist/pr-migrations.d.ts +62 -0
- package/dist/pr-migrations.d.ts.map +1 -0
- package/dist/pr-migrations.js +50 -0
- package/dist/pr-post.d.ts +42 -0
- package/dist/pr-post.d.ts.map +1 -1
- package/dist/pr-post.js +68 -2
- 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 +264 -254
- package/dist/workspace/check.schema.json +13 -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/gate-approval.d.ts +58 -0
- package/dist/workspace/checks/gate-approval.d.ts.map +1 -0
- package/dist/workspace/checks/gate-approval.js +103 -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 +12 -1
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/checks.js +63 -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 +14 -0
- package/dist/workspace/compose-graph.d.ts.map +1 -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/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 +50 -2
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.js +57 -11
- package/dist/workspace/declaration.schema.json +166 -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/exit-cli.d.ts +44 -0
- package/dist/workspace/exit-cli.d.ts.map +1 -0
- package/dist/workspace/exit-cli.js +198 -0
- package/dist/workspace/exit.d.ts +159 -0
- package/dist/workspace/exit.d.ts.map +1 -0
- package/dist/workspace/exit.js +480 -0
- package/dist/workspace/exit.schema.json +257 -0
- 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 +3 -1
- package/dist/workspace/graph-cache.d.ts.map +1 -1
- package/dist/workspace/graph-cache.js +12 -1
- package/dist/workspace/graph-cli.d.ts.map +1 -1
- package/dist/workspace/graph-cli.js +26 -8
- package/dist/workspace/graph.schema.json +34 -0
- package/dist/workspace/import-fetch.d.ts +38 -0
- package/dist/workspace/import-fetch.d.ts.map +1 -0
- package/dist/workspace/import-fetch.js +99 -0
- package/dist/workspace/import-init.d.ts +26 -0
- package/dist/workspace/import-init.d.ts.map +1 -0
- package/dist/workspace/import-init.js +130 -0
- package/dist/workspace/import-source.d.ts +147 -0
- package/dist/workspace/import-source.d.ts.map +1 -0
- package/dist/workspace/import-source.js +370 -0
- package/dist/workspace/init.d.ts +4 -0
- package/dist/workspace/init.d.ts.map +1 -1
- package/dist/workspace/init.js +70 -3
- 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 +6 -0
- package/dist/workspace/kind-readers.d.ts.map +1 -1
- package/dist/workspace/kind-readers.js +18 -0
- package/dist/workspace/kinds.d.ts +90 -3
- package/dist/workspace/kinds.d.ts.map +1 -1
- package/dist/workspace/kinds.js +161 -7
- 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/lineage-upgrade.d.ts.map +1 -1
- package/dist/workspace/lineage-upgrade.js +13 -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.map +1 -1
- package/dist/workspace/member-commands.js +54 -5
- 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/new-migrations.d.ts +47 -0
- package/dist/workspace/new-migrations.d.ts.map +1 -0
- package/dist/workspace/new-migrations.js +91 -0
- package/dist/workspace/pr-report.schema.json +46 -0
- package/dist/workspace/promote.d.ts +96 -0
- package/dist/workspace/promote.d.ts.map +1 -0
- package/dist/workspace/promote.js +263 -0
- package/dist/workspace/reason-codes.d.ts +21 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +25 -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-contract.d.ts +1 -1
- package/dist/workspace/search-contract.d.ts.map +1 -1
- 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 +108 -10
- 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/action-pins.test.ts +78 -0
- package/src/action-pins.ts +92 -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/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 +33 -4
- package/src/cli/handlers/build.ts +7 -1
- package/src/cli/handlers/graph-reader.test.ts +31 -0
- package/src/cli/handlers/graph-reader.ts +51 -0
- package/src/cli/handlers/graph.ts +14 -0
- 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 +2 -2
- package/src/cli/handlers/pr.ts +176 -37
- package/src/cli/handlers/query.ts +16 -4
- package/src/cli/handlers/release.ts +6 -3
- package/src/cli/handlers/search.ts +13 -34
- package/src/cli/main.test.ts +17 -0
- package/src/cli/main.ts +87 -14
- package/src/cli/parse-args.ts +35 -2
- package/src/cli/registry.ts +22 -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-run-bundle.test.ts +1 -0
- 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/pr-run.ts +4 -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 +28 -1
- package/src/config.ts +24 -1
- package/src/gate-decision-bundle.test.ts +5 -2
- package/src/gate-decision-identity.test.ts +20 -0
- package/src/gate-decision.ts +46 -3
- package/src/graph-ir.ts +27 -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 +98 -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/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/rules/op/index.ts +2 -0
- package/src/lint/rules/op/ops019-workspace-op-target.ts +89 -0
- 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-at-base.test.ts +97 -0
- package/src/op/gate-approval-base.ts +72 -0
- package/src/op/gate-approval.test.ts +6 -1
- package/src/op/gate-approval.ts +22 -27
- package/src/op/gate-name.ts +16 -1
- 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 +69 -9
- package/src/op/index.ts +3 -2
- package/src/op/local-executor.ts +91 -11
- 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-loop-bundle.test.ts +3 -2
- package/src/pr-loop.test.ts +52 -0
- package/src/pr-loop.ts +12 -0
- package/src/pr-migrations.ts +97 -0
- package/src/pr-post-open.e2e.test.ts +36 -0
- package/src/pr-post.test.ts +102 -3
- package/src/pr-post.ts +90 -2
- 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/__fixtures__/import/spacelift.json +9 -0
- package/src/workspace/__fixtures__/import/tfc.json +13 -0
- package/src/workspace/behold-kinds.test.ts +2 -1
- package/src/workspace/check-contract.test.ts +8 -6
- package/src/workspace/check.schema.json +13 -2
- package/src/workspace/checks/ci-branch.test.ts +128 -0
- package/src/workspace/checks/ci-branch.ts +141 -0
- package/src/workspace/checks/gate-approval.test.ts +77 -0
- package/src/workspace/checks/gate-approval.ts +121 -0
- package/src/workspace/checks/links.ts +12 -1
- package/src/workspace/checks/org.ts +169 -0
- package/src/workspace/checks.ts +68 -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 +9 -2
- 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/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 +166 -24
- package/src/workspace/declaration.ts +101 -15
- package/src/workspace/environments.ts +40 -4
- package/src/workspace/exit-cli.ts +219 -0
- package/src/workspace/exit.schema.json +257 -0
- package/src/workspace/exit.test.ts +185 -0
- package/src/workspace/exit.ts +560 -0
- package/src/workspace/flyway-dir.ts +113 -0
- package/src/workspace/flyway-layout.ts +337 -0
- package/src/workspace/graph-cache.ts +12 -2
- package/src/workspace/graph-cli.ts +25 -10
- package/src/workspace/graph-contract.test.ts +4 -2
- package/src/workspace/graph.schema.json +34 -0
- package/src/workspace/identity.test.ts +29 -2
- package/src/workspace/import-fetch.ts +151 -0
- package/src/workspace/import-init.ts +147 -0
- package/src/workspace/import-source.test.ts +183 -0
- package/src/workspace/import-source.ts +462 -0
- package/src/workspace/init.test.ts +55 -1
- package/src/workspace/init.ts +66 -4
- package/src/workspace/intent.ts +6 -14
- package/src/workspace/kind-link-readers.ts +68 -3
- package/src/workspace/kind-readers.test.ts +36 -0
- package/src/workspace/kind-readers.ts +18 -1
- package/src/workspace/kinds.test.ts +35 -7
- package/src/workspace/kinds.ts +212 -11
- 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/lineage-upgrade.test.ts +20 -0
- package/src/workspace/lineage-upgrade.ts +16 -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 +60 -2
- 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/new-migrations.test.ts +98 -0
- package/src/workspace/new-migrations.ts +109 -0
- package/src/workspace/org-scope.test.ts +238 -0
- package/src/workspace/pr-report.schema.json +46 -0
- package/src/workspace/promote.test.ts +114 -0
- package/src/workspace/promote.ts +302 -0
- package/src/workspace/reason-codes.test.ts +10 -1
- package/src/workspace/reason-codes.ts +25 -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/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 +108 -10
- 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
|
@@ -59,6 +59,11 @@
|
|
|
59
59
|
* contains the other. Each is a warning. A local branch ahead of the
|
|
60
60
|
* forge's keeps its facts, and the job's push sends them. Nothing here
|
|
61
61
|
* pushes the ledger.
|
|
62
|
+
* - Routed branches (#4325). `ci.branches` decides the branches one serve
|
|
63
|
+
* polls: a routed member's route alone, an unrouted member's `--branch`
|
|
64
|
+
* (default `main`), and at the workspace root `main` and each routed
|
|
65
|
+
* branch. Jobs on a routed branch get `--branch`. The state file keeps a
|
|
66
|
+
* head per branch (`target`, then `targets`).
|
|
62
67
|
*
|
|
63
68
|
* - Land branches (#4168 4.4). With `land`, each `chant/land/<name>` branch
|
|
64
69
|
* pushed to the remote is a change asking to land without a pull request.
|
|
@@ -104,6 +109,7 @@ import { CI_JOB_OPS, ciJobPlace, ciLoopOptions, ciSecretsOf, ciRun, ciStatusFrom
|
|
|
104
109
|
import { CiGreenError, ciTick, judgePreMerge, lastGreen, RUNNER_KEY_ENV, signedRunsRequired, type CommitVerdict } from "./ci-green";
|
|
105
110
|
import { gitTop } from "./tree";
|
|
106
111
|
import { readDeclaration } from "./declaration";
|
|
112
|
+
import { servedBranches } from "./ci-branches";
|
|
107
113
|
import { locateWorkspace } from "./which-chant";
|
|
108
114
|
import { ciServeRunnerKey, formatRunnerKeySetup, setupRunnerKey } from "./ci-runner-key";
|
|
109
115
|
|
|
@@ -124,8 +130,8 @@ export interface CiServeForge {
|
|
|
124
130
|
* apply of the newest green commit (#4168 step 9).
|
|
125
131
|
*/
|
|
126
132
|
export type CiServeTrigger =
|
|
127
|
-
| { job: "plan"; commit: string; base: string; pr: number; rerun?: boolean }
|
|
128
|
-
| { job: "apply" | "record"; commit: string; base: string; rerun?: boolean };
|
|
133
|
+
| { job: "plan"; commit: string; base: string; pr: number; rerun?: boolean; branch?: string }
|
|
134
|
+
| { job: "apply" | "record"; commit: string; base: string; rerun?: boolean; branch?: string };
|
|
129
135
|
|
|
130
136
|
/**
|
|
131
137
|
* The `git` forge kind (#4016 gap 6): the branch head from `git ls-remote`
|
|
@@ -193,6 +199,8 @@ export interface CiServeState {
|
|
|
193
199
|
member?: string;
|
|
194
200
|
/** The target branch's head the last apply was measured to, or the last head seen and not applied. */
|
|
195
201
|
target?: string;
|
|
202
|
+
/** The same for each further branch `ci.branches` routes (#4325), by branch. `target` is the first served branch's. */
|
|
203
|
+
targets?: Record<string, string>;
|
|
196
204
|
jobs: Record<string, CiServeJobState>;
|
|
197
205
|
/** Plans seen and not run, by state key, with why (#4122). */
|
|
198
206
|
skipped?: Record<string, "skip-ci">;
|
|
@@ -381,7 +389,12 @@ export function defaultCiServeStateDir(cwd: string): string {
|
|
|
381
389
|
interface ServePlace {
|
|
382
390
|
top: string;
|
|
383
391
|
member?: string;
|
|
392
|
+
/** The first branch served: the one the state file's `target` follows. */
|
|
384
393
|
branch: string;
|
|
394
|
+
/** Every branch served (#4325), `branch` first: a routed member's route, or at the workspace root the default and each routed branch. */
|
|
395
|
+
branches: string[];
|
|
396
|
+
/** The served branches a job is told with `--branch`: the ones `ci.branches` names. */
|
|
397
|
+
routed: string[];
|
|
385
398
|
group: string;
|
|
386
399
|
stateDir: string;
|
|
387
400
|
stateFile: string;
|
|
@@ -394,7 +407,21 @@ function servePlace(opts: CiServeOptions): ServePlace {
|
|
|
394
407
|
const { member } = ciJobPlace(cwd, top);
|
|
395
408
|
const group = prApplyGroup(opts.env, member);
|
|
396
409
|
const stateDir = opts.stateDir ? resolve(cwd, opts.stateDir) : defaultCiServeStateDir(cwd);
|
|
397
|
-
|
|
410
|
+
// #4325: ci.branches decides which branches this serve polls. A workspace that can't be read routes nothing.
|
|
411
|
+
let routes: Record<string, string[]> | undefined;
|
|
412
|
+
try {
|
|
413
|
+
routes = readDeclaration(locateWorkspace(cwd).tree).ci?.branches;
|
|
414
|
+
} catch {
|
|
415
|
+
routes = undefined;
|
|
416
|
+
}
|
|
417
|
+
const named = opts.job?.loop?.branch;
|
|
418
|
+
let served: ReturnType<typeof servedBranches>;
|
|
419
|
+
try {
|
|
420
|
+
served = servedBranches(routes, member, named ?? "main", named !== undefined);
|
|
421
|
+
} catch (err) {
|
|
422
|
+
throw new CiRunError(message(err));
|
|
423
|
+
}
|
|
424
|
+
return { top, ...(member ? { member } : {}), branch: served.served[0]!, branches: served.served, routed: served.routed, group, stateDir, stateFile: join(stateDir, `${group}.json`) };
|
|
398
425
|
}
|
|
399
426
|
|
|
400
427
|
/** The state file, or a new one. */
|
|
@@ -439,73 +466,81 @@ export async function ciServeObserve(opts: CiServeOptions, rt: CiServeRuntime =
|
|
|
439
466
|
};
|
|
440
467
|
const triggers: CiServeTrigger[] = [];
|
|
441
468
|
const events: CiServeEvent[] = [];
|
|
442
|
-
const [head, prs] = await Promise.all([opts.client.branchHead(place.branch), opts.client.openPullRequests(place.branch)]);
|
|
443
469
|
// #4168: a new target commit is recorded. With applyOnMerge the newest green commit is applied, below.
|
|
444
470
|
const onMerge = "record" as const;
|
|
471
|
+
const authors = opts.authors?.length ? new Set(opts.authors.map((a) => a.toLowerCase())) : undefined;
|
|
445
472
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
const
|
|
457
|
-
const entry = state.jobs[ciServeKey({ job: onMerge, commit: head })];
|
|
458
|
-
if (move === "unknown") {
|
|
459
|
-
events.push({ type: "error", message: `${place.branch} is at ${head.slice(0, 12)} on the forge, and that commit could not be fetched; the next poll tries again` });
|
|
460
|
-
} else if (move === "other" || (!entry && skipsCi(place.top, head))) {
|
|
461
|
-
// #4122: a move that is not a fast-forward, or a head that asks for no run, is seen and not applied.
|
|
462
|
-
update((s) => {
|
|
463
|
-
s.target = head;
|
|
464
|
-
});
|
|
465
|
-
events.push({ type: "not-run", job: onMerge, commit: head, reason: move === "other" ? "not-fast-forward" : "skip-ci", ...(move === "other" ? { branch: place.branch, from } : {}) });
|
|
466
|
-
} else if (!entry) triggers.push({ job: onMerge, commit: head, base: from });
|
|
467
|
-
else if (opts.rerunFailed && failedEntry(entry, ciServeKey(entry), rt)) triggers.push({ job: onMerge, commit: head, base: entry.base, rerun: true });
|
|
468
|
-
} else {
|
|
469
|
-
const key = ciServeKey({ job: onMerge, commit: head });
|
|
470
|
-
const entry = state.jobs[key];
|
|
471
|
-
if (opts.rerunFailed && failedEntry(entry, key, rt)) triggers.push({ job: onMerge, commit: head, base: entry.base, rerun: true });
|
|
472
|
-
}
|
|
473
|
+
// #4325: each served branch is polled on its own, with its own head to measure moves from.
|
|
474
|
+
for (const branch of place.branches) {
|
|
475
|
+
const [head, prs] = await Promise.all([opts.client.branchHead(branch), opts.client.openPullRequests(branch)]);
|
|
476
|
+
const first = branch === place.branch;
|
|
477
|
+
const target = first ? state.target : state.targets?.[branch];
|
|
478
|
+
const setTarget = (s: CiServeState, sha: string): void => {
|
|
479
|
+
if (first) s.target = sha;
|
|
480
|
+
else s.targets = { ...s.targets, [branch]: sha };
|
|
481
|
+
};
|
|
482
|
+
// A job on a routed branch is told which, so its apply routes members as the pushed branch does.
|
|
483
|
+
const routed = place.routed.includes(branch) ? { branch } : {};
|
|
473
484
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
if (
|
|
477
|
-
|
|
485
|
+
if (head === undefined) {
|
|
486
|
+
events.push({ type: "no-branch", branch });
|
|
487
|
+
} else if (target === undefined) {
|
|
488
|
+
// What the branch held before this runner watched it was applied by whatever ran then.
|
|
489
|
+
update((s) => setTarget(s, head));
|
|
490
|
+
events.push({ type: "baseline", commit: head });
|
|
491
|
+
} else if (head !== target) {
|
|
492
|
+
const from = target;
|
|
493
|
+
const move = targetMove(place.top, branch, from, head);
|
|
494
|
+
const entry = state.jobs[ciServeKey({ job: onMerge, commit: head })];
|
|
495
|
+
if (move === "unknown") {
|
|
496
|
+
events.push({ type: "error", message: `${branch} is at ${head.slice(0, 12)} on the forge, and that commit could not be fetched; the next poll tries again` });
|
|
497
|
+
} else if (move === "other" || (!entry && skipsCi(place.top, head))) {
|
|
498
|
+
// #4122: a move that is not a fast-forward, or a head that asks for no run, is seen and not applied.
|
|
499
|
+
update((s) => setTarget(s, head));
|
|
500
|
+
events.push({ type: "not-run", job: onMerge, commit: head, reason: move === "other" ? "not-fast-forward" : "skip-ci", ...(move === "other" ? { branch, from } : {}) });
|
|
501
|
+
} else if (!entry) triggers.push({ job: onMerge, commit: head, base: from, ...routed });
|
|
502
|
+
else if (opts.rerunFailed && failedEntry(entry, ciServeKey(entry), rt)) triggers.push({ job: onMerge, commit: head, base: entry.base, rerun: true, ...routed });
|
|
503
|
+
} else {
|
|
504
|
+
const key = ciServeKey({ job: onMerge, commit: head });
|
|
478
505
|
const entry = state.jobs[key];
|
|
479
|
-
if (
|
|
480
|
-
else if (opts.rerunFailed && failedEntry(entry, key, rt)) triggers.push({ job: "apply", commit: green, base: entry.base, rerun: true });
|
|
506
|
+
if (opts.rerunFailed && failedEntry(entry, key, rt)) triggers.push({ job: onMerge, commit: head, base: entry.base, rerun: true, ...routed });
|
|
481
507
|
}
|
|
482
|
-
}
|
|
483
508
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
continue;
|
|
509
|
+
if (opts.applyOnMerge && head !== undefined) {
|
|
510
|
+
const green = newestGreen(place.top, opts.cwd, branch, place.routed.includes(branch));
|
|
511
|
+
if (green) {
|
|
512
|
+
const key = ciServeKey({ job: "apply", commit: green });
|
|
513
|
+
const entry = state.jobs[key];
|
|
514
|
+
if (!entry) triggers.push({ job: "apply", commit: green, base: green, ...routed });
|
|
515
|
+
else if (opts.rerunFailed && failedEntry(entry, key, rt)) triggers.push({ job: "apply", commit: green, base: entry.base, rerun: true, ...routed });
|
|
516
|
+
}
|
|
493
517
|
}
|
|
494
|
-
|
|
495
|
-
const
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
if (
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
518
|
+
|
|
519
|
+
for (const pr of prs) {
|
|
520
|
+
if (pr.fork) {
|
|
521
|
+
events.push({ type: "skipped", pr: pr.number, reason: "fork" });
|
|
522
|
+
continue;
|
|
523
|
+
}
|
|
524
|
+
if (authors && !authors.has((pr.author ?? "").toLowerCase())) {
|
|
525
|
+
events.push({ type: "skipped", pr: pr.number, reason: "author", ...(pr.author ? { author: pr.author } : {}) });
|
|
526
|
+
continue;
|
|
527
|
+
}
|
|
528
|
+
const key = ciServeKey({ job: "plan", commit: pr.headSha, pr: pr.number });
|
|
529
|
+
const entry = state.jobs[key];
|
|
530
|
+
const base = pr.baseSha ?? head;
|
|
531
|
+
if (!base || state.skipped?.[key]) continue;
|
|
532
|
+
if (!entry) {
|
|
533
|
+
// #4122: a head whose message asks for no run is seen and not planned.
|
|
534
|
+
if (gitStatus(place.top, ["cat-file", "-e", `${pr.headSha}^{commit}`]).code !== 0) tryGit(place.top, ["fetch", "--quiet", "--no-tags", "origin", `refs/pull/${pr.number}/head`]);
|
|
535
|
+
if (skipsCi(place.top, pr.headSha)) {
|
|
536
|
+
update((s) => {
|
|
537
|
+
s.skipped = { ...s.skipped, [key]: "skip-ci" };
|
|
538
|
+
});
|
|
539
|
+
events.push({ type: "not-run", job: "plan", commit: pr.headSha, pr: pr.number, reason: "skip-ci" });
|
|
540
|
+
} else triggers.push({ job: "plan", commit: pr.headSha, base, pr: pr.number, ...routed });
|
|
541
|
+
}
|
|
542
|
+
else if (opts.rerunFailed && failedEntry(entry, key, rt)) triggers.push({ job: "plan", commit: pr.headSha, base: entry.base, pr: pr.number, rerun: true, ...routed });
|
|
507
543
|
}
|
|
508
|
-
else if (opts.rerunFailed && failedEntry(entry, key, rt)) triggers.push({ job: "plan", commit: pr.headSha, base: entry.base, pr: pr.number, rerun: true });
|
|
509
544
|
}
|
|
510
545
|
return { triggers, events };
|
|
511
546
|
}
|
|
@@ -581,7 +616,10 @@ export async function ciServeSchedule(opts: CiServeOptions, triggers: readonly C
|
|
|
581
616
|
const entry: CiServeJobState = { job: t.job, commit: t.commit, base: t.base, ...pr, status: "running", runId, attempts: attempt, startedAt: now().toISOString() };
|
|
582
617
|
update((s) => {
|
|
583
618
|
s.jobs[key] = entry;
|
|
584
|
-
if (t.job === "record" && !t.rerun)
|
|
619
|
+
if (t.job === "record" && !t.rerun) {
|
|
620
|
+
if (t.branch === undefined || t.branch === place.branch) s.target = t.commit;
|
|
621
|
+
else s.targets = { ...s.targets, [t.branch]: t.commit };
|
|
622
|
+
}
|
|
585
623
|
});
|
|
586
624
|
emit({ type: "started", job: t.job, commit: t.commit, ...pr, base: t.base, runId, attempt, ...(resume && existsSync(resume) ? { resume } : {}) });
|
|
587
625
|
|
|
@@ -621,13 +659,15 @@ async function runJob(
|
|
|
621
659
|
let merged: number | undefined;
|
|
622
660
|
try {
|
|
623
661
|
// The pull request's head is on the forge's refs/pull/<n>/head, the target's on the branch.
|
|
624
|
-
tryGit(place.top, ["fetch", "--quiet", "--no-tags", "origin", t.job === "plan" ? `refs/pull/${t.pr}/head` : place.branch]);
|
|
662
|
+
tryGit(place.top, ["fetch", "--quiet", "--no-tags", "origin", t.job === "plan" ? `refs/pull/${t.pr}/head` : (t.branch ?? place.branch)]);
|
|
625
663
|
const hostEnv = { ...(opts.job?.hostEnv ?? process.env), GITHUB_REPOSITORY: opts.repo };
|
|
626
664
|
// An apply is for a merge: pass the pull request whose merge commit it is, so the commit status link and the run index use `<pr>/<commit>`. None found, or a forge that errs, is today's behaviour.
|
|
627
665
|
if (t.job === "record" && opts.client.pullRequestFor) merged = (await opts.client.pullRequestFor(t.commit).catch(() => null)) ?? undefined;
|
|
628
666
|
const run = opts.run ?? ciRun;
|
|
629
667
|
const r = await run({
|
|
630
668
|
...opts.job,
|
|
669
|
+
// #4325: a job on a routed branch is told the branch, so it routes members as a push to it does.
|
|
670
|
+
...(t.branch !== undefined ? { loop: { ...opts.job?.loop, branch: t.branch } } : {}),
|
|
631
671
|
hostEnv,
|
|
632
672
|
cwd: opts.cwd,
|
|
633
673
|
job: t.job,
|
|
@@ -656,10 +696,11 @@ async function runJob(
|
|
|
656
696
|
* fetching the ci tags, or undefined when none is green or the workspace
|
|
657
697
|
* declares no `ci.green`.
|
|
658
698
|
*/
|
|
659
|
-
function newestGreen(top: string, cwd: string, branch: string): string | undefined {
|
|
699
|
+
function newestGreen(top: string, cwd: string, branch: string, routed = false): string | undefined {
|
|
660
700
|
tryGit(top, ["fetch", "--quiet", "origin", `+refs/heads/${branch}:refs/remotes/origin/${branch}`, "+refs/tags/ci/*:refs/tags/ci/*"]);
|
|
661
701
|
try {
|
|
662
|
-
|
|
702
|
+
// #4325: a routed branch has its own verdict, and none when ci.green does not name it.
|
|
703
|
+
const doc = lastGreen({ cwd, ...(routed ? { branch } : {}) });
|
|
663
704
|
return "commit" in doc && doc.commit ? doc.commit.sha : undefined;
|
|
664
705
|
} catch {
|
|
665
706
|
return undefined;
|
|
@@ -14,9 +14,12 @@ import Ajv2020 from "ajv/dist/2020";
|
|
|
14
14
|
import { afterEach, beforeEach, describe, expect, test } from "vitest";
|
|
15
15
|
import { computeComponentGraph } from "../components/cli-support";
|
|
16
16
|
import componentSchema from "../components/component.schema.json";
|
|
17
|
+
import { ChantConfigSchema, environmentExecutor } from "../config";
|
|
17
18
|
import { componentEnvironments, memberEnvironments, type EnvironmentReason } from "./environments";
|
|
18
19
|
import type { MemberRuntimes } from "./runtimes";
|
|
19
20
|
|
|
21
|
+
const NO_EXECUTOR = { forge: null, workflow: null, reason: { code: "executor-none-declared", message: expect.any(String) } };
|
|
22
|
+
|
|
20
23
|
const runtimes = (environments: MemberRuntimes["environments"], lexicons: string[] = []): MemberRuntimes => ({ lexicons, default: "local", reasons: [], environments });
|
|
21
24
|
|
|
22
25
|
const SITES = [
|
|
@@ -68,13 +71,14 @@ describe("graph --composites lists each environment with the component's site (#
|
|
|
68
71
|
const member = memberEnvironments(runtimes(["prod", "fly"], ["fly"]), { envs: [], reason: null });
|
|
69
72
|
const envs = componentEnvironments("app", member, "local", SITES, ["fly"]);
|
|
70
73
|
expect(envs).toEqual([
|
|
71
|
-
{ name: "local", default: true, source: "builtin", site: null, command: "chant run --components app" },
|
|
72
|
-
{ name: "prod", default: false, source: "config", site: { runtime: "local", url: null, domain: null, lifecycle: null }, command: "chant run --components app --env prod" },
|
|
74
|
+
{ name: "local", default: true, source: "builtin", site: null, executor: NO_EXECUTOR, command: "chant run --components app" },
|
|
75
|
+
{ name: "prod", default: false, source: "config", site: { runtime: "local", url: null, domain: null, lifecycle: null }, executor: NO_EXECUTOR, command: "chant run --components app --env prod" },
|
|
73
76
|
{
|
|
74
77
|
name: "fly",
|
|
75
78
|
default: false,
|
|
76
79
|
source: "config",
|
|
77
80
|
site: { runtime: "fly", url: "https://shop.fly.dev", domain: "shop.example.com", lifecycle: "origin" },
|
|
81
|
+
executor: NO_EXECUTOR,
|
|
78
82
|
command: "chant run --components app --on fly --env fly",
|
|
79
83
|
},
|
|
80
84
|
]);
|
|
@@ -103,3 +107,22 @@ describe("graph --composites lists each environment with the component's site (#
|
|
|
103
107
|
expect(envs.find((e) => e.name === "pr-7")).toMatchObject({ source: "component", site: { url: "https://pr-7.example.com" } });
|
|
104
108
|
});
|
|
105
109
|
});
|
|
110
|
+
|
|
111
|
+
describe("an environment's executor in chant.config.ts (#4402)", () => {
|
|
112
|
+
const prod = { name: "prod", executor: { forge: "github" as const, workflow: "deploy-prod.yml" } };
|
|
113
|
+
|
|
114
|
+
test("is optional on an environment entry, and refuses an unknown forge, an empty workflow and a stray field", () => {
|
|
115
|
+
expect(ChantConfigSchema.safeParse({ environments: ["staging", prod] }).success).toBe(true);
|
|
116
|
+
expect(ChantConfigSchema.safeParse({ environments: [{ name: "prod", executor: { forge: "jenkins", workflow: "x.yml" } }] }).success).toBe(false);
|
|
117
|
+
expect(ChantConfigSchema.safeParse({ environments: [{ name: "prod", executor: { forge: "github", workflow: "" } }] }).success).toBe(false);
|
|
118
|
+
expect(ChantConfigSchema.safeParse({ environments: [{ name: "prod", executor: { forge: "github", workflow: "x.yml", ref: "main" } }] }).success).toBe(false);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test("resolves a literal entry before a pattern, and a literal without one doesn't take the pattern's", () => {
|
|
122
|
+
const envs = [prod, "pr-special", { name: "pr-*", executor: { forge: "gitlab" as const, workflow: ".gitlab-ci.yml" } }];
|
|
123
|
+
expect(environmentExecutor(envs, "prod")).toEqual(prod.executor);
|
|
124
|
+
expect(environmentExecutor(envs, "pr-7")).toEqual({ forge: "gitlab", workflow: ".gitlab-ci.yml" });
|
|
125
|
+
expect(environmentExecutor(envs, "pr-special")).toBeUndefined();
|
|
126
|
+
expect(environmentExecutor(envs, "staging")).toBeUndefined();
|
|
127
|
+
});
|
|
128
|
+
});
|
|
@@ -100,6 +100,12 @@ export interface ComposedMember {
|
|
|
100
100
|
* the outer `nodes` with `outer/inner/id` ids.
|
|
101
101
|
*/
|
|
102
102
|
nested?: NestedWorkspace;
|
|
103
|
+
/**
|
|
104
|
+
* For a member of kind `repo` (#3168): the repository and pinned revision it
|
|
105
|
+
* names, and `read`, the repo identity the other repository's own graph
|
|
106
|
+
* document gave, or null. Its nodes fold in as a nested workspace's do.
|
|
107
|
+
*/
|
|
108
|
+
repo?: { url: string; rev: string; workspace: string; read: string | null };
|
|
103
109
|
/**
|
|
104
110
|
* The factory and listing the member's box block declares (#3146, ws-077),
|
|
105
111
|
* read from the declaration at the revision read. Set by
|
|
@@ -181,7 +187,8 @@ export type ComposedDangling = IRDanglingRef & { member: string; nested?: string
|
|
|
181
187
|
|
|
182
188
|
export interface WorkspaceGraph {
|
|
183
189
|
version: number;
|
|
184
|
-
|
|
190
|
+
/** `repo` (#3168): the repository the document came from, its origin URL redacted, or null; absent from a chant before it. */
|
|
191
|
+
workspace: { name: string; root: string; repo?: string | null };
|
|
185
192
|
members: ComposedMember[];
|
|
186
193
|
nodes: ComposedNode[];
|
|
187
194
|
edges: ComposedEdge[];
|
|
@@ -335,7 +342,7 @@ function sorted(rec: Record<string, string[]>): Record<string, string[]> {
|
|
|
335
342
|
* `read` holds the links each member's kind reader found in its files (#3932).
|
|
336
343
|
*/
|
|
337
344
|
export function composeWorkspaceGraph(
|
|
338
|
-
workspace: { name: string; root: string },
|
|
345
|
+
workspace: { name: string; root: string; repo?: string | null },
|
|
339
346
|
inputs: ComposeInput[],
|
|
340
347
|
links?: { declaration: Declaration; kinds?: KindRegistry; read?: ReadonlyMap<string, KindLinkRead> },
|
|
341
348
|
): WorkspaceGraph {
|
|
@@ -607,6 +607,28 @@
|
|
|
607
607
|
}
|
|
608
608
|
]
|
|
609
609
|
},
|
|
610
|
+
"executor": {
|
|
611
|
+
"description": "The forge and committed workflow that deploys this environment, as the member's chant.config.ts declares on the environment's entry (#4402): a literal entry before a pattern. forge and workflow are null when none is declared, and reason then says why. Never derived from a generated workflow's name. Added by chant 0.124.47; a document from an older chant has no executor.",
|
|
612
|
+
"type": "object",
|
|
613
|
+
"required": ["forge", "workflow", "reason"],
|
|
614
|
+
"properties": {
|
|
615
|
+
"forge": { "enum": ["github", "gitlab", "forgejo", null] },
|
|
616
|
+
"workflow": { "type": ["string", "null"], "description": "The workflow file the forge runs, such as deploy-prod.yml under .github/workflows/, or .gitlab-ci.yml." },
|
|
617
|
+
"reason": {
|
|
618
|
+
"oneOf": [
|
|
619
|
+
{ "type": "null" },
|
|
620
|
+
{
|
|
621
|
+
"type": "object",
|
|
622
|
+
"required": ["code", "message"],
|
|
623
|
+
"properties": {
|
|
624
|
+
"code": { "enum": ["executor-none-declared", "executor-config-unreadable"] },
|
|
625
|
+
"message": { "type": "string" }
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
]
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
},
|
|
610
632
|
"command": {
|
|
611
633
|
"type": "string",
|
|
612
634
|
"description": "The command that deploys the component to this environment on its default runtime, run in the member's directory: chant run --components <name>, with --on <runtime> when the default runtime isn't local, and --env <env> for any environment but the default."
|
|
@@ -17,6 +17,7 @@ import { MEMBER_RUN_REASON_CODES } from "./compose-graph";
|
|
|
17
17
|
import {
|
|
18
18
|
COMPOSITES_CONTRACT_VERSION,
|
|
19
19
|
COMPOSITES_ENVIRONMENT_REASON_CODES,
|
|
20
|
+
COMPOSITES_EXECUTOR_REASON_CODES,
|
|
20
21
|
COMPOSITES_ERROR_CODES,
|
|
21
22
|
COMPOSITES_OUTPUT_SCHEMA_ID,
|
|
22
23
|
COMPOSITES_REASON_CODES,
|
|
@@ -30,6 +31,8 @@ import {
|
|
|
30
31
|
import { GRAPH_ERROR_CODES } from "./graph-cli";
|
|
31
32
|
import schema from "./composites.schema.json";
|
|
32
33
|
|
|
34
|
+
const NO_EXECUTOR = { forge: null, workflow: null, reason: { code: "executor-none-declared", message: expect.any(String) } };
|
|
35
|
+
|
|
33
36
|
afterAll(cleanScratch);
|
|
34
37
|
|
|
35
38
|
const { expectValid } = contract(schema);
|
|
@@ -61,7 +64,7 @@ const componentIr = (components: { name: string; composites?: string[]; archetyp
|
|
|
61
64
|
const local = (name: string) => ({ name: "local", lexicon: null, default: true, command: `chant run --components ${name}` });
|
|
62
65
|
|
|
63
66
|
/** The default environment, named by nothing but chant itself. */
|
|
64
|
-
const localEnv = (name: string) => ({ name: "local", default: true, source: "builtin", site: null, command: `chant run --components ${name}` });
|
|
67
|
+
const localEnv = (name: string) => ({ name: "local", default: true, source: "builtin", site: null, executor: NO_EXECUTOR, command: `chant run --components ${name}` });
|
|
65
68
|
|
|
66
69
|
/**
|
|
67
70
|
* app declares three instances and exports ImageUri; delivery links to it and
|
|
@@ -117,6 +120,7 @@ describe("composites output schema", () => {
|
|
|
117
120
|
expect(schema.$defs.member.properties.reason.oneOf[1].properties!.code.enum).toEqual([...MEMBER_RUN_REASON_CODES]);
|
|
118
121
|
expect(schema.$defs.member.properties.runtimeReasons.items.properties.code.enum).toEqual([...COMPOSITES_RUNTIME_REASON_CODES]);
|
|
119
122
|
expect(schema.$defs.member.properties.environmentReasons.items.properties.code.enum).toEqual([...COMPOSITES_ENVIRONMENT_REASON_CODES]);
|
|
123
|
+
expect(schema.$defs.environment.properties.executor.properties.reason.oneOf[1].properties!.code.enum).toEqual([...COMPOSITES_EXECUTOR_REASON_CODES]);
|
|
120
124
|
});
|
|
121
125
|
});
|
|
122
126
|
|
|
@@ -381,11 +385,11 @@ describe("the environments each component may deploy to (#2695)", () => {
|
|
|
381
385
|
const g = result((await workspaceComposites({ cwd: declared() })).doc);
|
|
382
386
|
expectValid(g);
|
|
383
387
|
expect(g.components.find((c) => c.id === "jobs/queue-runner")!.environments).toEqual([
|
|
384
|
-
{ name: "local", default: true, source: "builtin", site: null, command: "chant run --components queue-runner" },
|
|
385
|
-
{ name: "staging", default: false, source: "config", site: null, command: "chant run --components queue-runner --env staging" },
|
|
386
|
-
{ name: "prod", default: false, source: "config", site: null, command: "chant run --components queue-runner --env prod" },
|
|
388
|
+
{ name: "local", default: true, source: "builtin", site: null, executor: NO_EXECUTOR, command: "chant run --components queue-runner" },
|
|
389
|
+
{ name: "staging", default: false, source: "config", site: null, executor: NO_EXECUTOR, command: "chant run --components queue-runner --env staging" },
|
|
390
|
+
{ name: "prod", default: false, source: "config", site: null, executor: NO_EXECUTOR, command: "chant run --components queue-runner --env prod" },
|
|
387
391
|
// The pattern pr-* is no environment by itself, and it covers the ledger's pr-42.
|
|
388
|
-
{ name: "pr-42", default: false, source: "ledger", site: null, command: "chant run --components queue-runner --env pr-42" },
|
|
392
|
+
{ name: "pr-42", default: false, source: "ledger", site: null, executor: NO_EXECUTOR, command: "chant run --components queue-runner --env pr-42" },
|
|
389
393
|
]);
|
|
390
394
|
const jobs = g.members.find((m) => m.name === "jobs")!;
|
|
391
395
|
expect(jobs.environmentReasons).toEqual([{ code: "environments-ledger-undeclared", message: expect.stringContaining("retired") }]);
|
|
@@ -397,7 +401,7 @@ describe("the environments each component may deploy to (#2695)", () => {
|
|
|
397
401
|
// delivery has no _members/delivery, so the flat staging ledger is its; its config declares nothing, so anything goes.
|
|
398
402
|
expect(g.components.find((c) => c.id === "delivery/edge")!.environments).toEqual([
|
|
399
403
|
localEnv("edge"),
|
|
400
|
-
{ name: "staging", default: false, source: "ledger", site: null, command: "chant run --components edge --env staging" },
|
|
404
|
+
{ name: "staging", default: false, source: "ledger", site: null, executor: NO_EXECUTOR, command: "chant run --components edge --env staging" },
|
|
401
405
|
]);
|
|
402
406
|
expect(g.members.find((m) => m.name === "delivery")!.environmentReasons.map((r) => r.code)).toEqual(["environments-none-declared"]);
|
|
403
407
|
expect(g.members.find((m) => m.name === "docs")!.environmentReasons).toEqual([]);
|
|
@@ -409,8 +413,8 @@ describe("the environments each component may deploy to (#2695)", () => {
|
|
|
409
413
|
const g = result((await workspaceComposites({ cwd: root })).doc);
|
|
410
414
|
expectValid(g);
|
|
411
415
|
expect(g.components.find((c) => c.id === "jobs/queue-runner")!.environments).toEqual([
|
|
412
|
-
{ name: "local", default: true, source: "config", site: null, command: "chant run --components queue-runner" },
|
|
413
|
-
{ name: "prod", default: false, source: "config", site: null, command: "chant run --components queue-runner --env prod" },
|
|
416
|
+
{ name: "local", default: true, source: "config", site: null, executor: NO_EXECUTOR, command: "chant run --components queue-runner" },
|
|
417
|
+
{ name: "prod", default: false, source: "config", site: null, executor: NO_EXECUTOR, command: "chant run --components queue-runner --env prod" },
|
|
414
418
|
]);
|
|
415
419
|
expect(g.members.find((m) => m.name === "jobs")!.environmentReasons).toEqual([]);
|
|
416
420
|
});
|
|
@@ -445,4 +449,31 @@ describe("the environments each component may deploy to (#2695)", () => {
|
|
|
445
449
|
expect(g.members.find((m) => m.name === "jobs")!.environmentReasons).toEqual([{ code: "environments-ledger-unreadable", message: "boom" }]);
|
|
446
450
|
expect(g.components.find((c) => c.id === "jobs/queue-runner")!.environments.map((e) => e.name)).toEqual(["local", "prod"]);
|
|
447
451
|
});
|
|
452
|
+
|
|
453
|
+
test("each environment names the forge workflow the config declares for it, a literal before a pattern (#4402)", async () => {
|
|
454
|
+
const root = declared();
|
|
455
|
+
writeFileSync(
|
|
456
|
+
join(root, "jobs", "chant.config.ts"),
|
|
457
|
+
'export default { environments: ["staging", { name: "prod", executor: { forge: "github", workflow: "deploy-prod.yml" } }, { name: "pr-*", executor: { forge: "forgejo", workflow: "preview.yml" } }] };\n',
|
|
458
|
+
);
|
|
459
|
+
const g = result((await workspaceComposites({ cwd: root })).doc);
|
|
460
|
+
expectValid(g);
|
|
461
|
+
const executors = Object.fromEntries(g.components.find((c) => c.id === "jobs/queue-runner")!.environments.map((e) => [e.name, e.executor]));
|
|
462
|
+
expect(executors).toEqual({
|
|
463
|
+
local: NO_EXECUTOR,
|
|
464
|
+
staging: NO_EXECUTOR,
|
|
465
|
+
prod: { forge: "github", workflow: "deploy-prod.yml", reason: null },
|
|
466
|
+
"pr-42": { forge: "forgejo", workflow: "preview.yml", reason: null },
|
|
467
|
+
});
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
test("a config that can't be read says no executor is known (#4402)", async () => {
|
|
471
|
+
const root = declared();
|
|
472
|
+
writeFileSync(join(root, "jobs", "chant.config.ts"), 'throw new Error("no config here");\nexport default {};\n');
|
|
473
|
+
const g = result((await workspaceComposites({ cwd: root })).doc);
|
|
474
|
+
expectValid(g);
|
|
475
|
+
for (const e of g.components.find((c) => c.id === "jobs/queue-runner")!.environments) {
|
|
476
|
+
expect(e.executor).toEqual({ forge: null, workflow: null, reason: { code: "executor-config-unreadable", message: expect.stringContaining(e.name) } });
|
|
477
|
+
}
|
|
478
|
+
});
|
|
448
479
|
});
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
* And each component lists the environments it may deploy to (#2695,
|
|
37
37
|
* `environments.ts`): `local`, the environments its member's config declares,
|
|
38
38
|
* and those with a release in the member's ledger on `chant/lifecycle`, with
|
|
39
|
-
* the command line for each
|
|
39
|
+
* the command line for each, and the forge workflow that deploys each one
|
|
40
|
+
* when the member's config names it (#4402).
|
|
40
41
|
*/
|
|
41
42
|
|
|
42
43
|
import { formatError } from "../cli/format";
|
|
@@ -50,7 +51,7 @@ import { emitDocument, type UnitResult } from "./member-commands";
|
|
|
50
51
|
import { readerVersion, WORKSPACE_ERROR_CODES, type ErrorLocation, type WorkspaceErrorCode } from "./declaration";
|
|
51
52
|
import type { ReasonCode } from "./reason-codes";
|
|
52
53
|
import type { ComponentEnvironmentDeclaration } from "../components/component";
|
|
53
|
-
import { componentEnvironments, ENVIRONMENT_REASON_CODES, memberEnvironments, readLedgerEnvironments, type ComponentEnvironment, type EnvironmentReason, type LedgerEnvironmentReader, type MemberEnvironments } from "./environments";
|
|
54
|
+
import { componentEnvironments, ENVIRONMENT_REASON_CODES, EXECUTOR_REASON_CODES, memberEnvironments, readLedgerEnvironments, type ComponentEnvironment, type EnvironmentReason, type LedgerEnvironmentReader, type MemberEnvironments } from "./environments";
|
|
54
55
|
import { componentRuntimes, readRuntimesIn, RUNTIME_REASON_CODES, type ComponentRuntime, type MemberRuntimes, type PluginLoader, type RuntimeReason } from "./runtimes";
|
|
55
56
|
|
|
56
57
|
/** `$id` of the JSON Schema for the document, shipped beside this file. */
|
|
@@ -83,6 +84,9 @@ export const COMPOSITES_RUNTIME_REASON_CODES = RUNTIME_REASON_CODES;
|
|
|
83
84
|
/** Why a member's environments are only `local`, or leave out one its ledger has (#2695). Closed. */
|
|
84
85
|
export const COMPOSITES_ENVIRONMENT_REASON_CODES = ENVIRONMENT_REASON_CODES;
|
|
85
86
|
|
|
87
|
+
/** Why an environment row's executor names no forge workflow (#4402). Closed. */
|
|
88
|
+
export const COMPOSITES_EXECUTOR_REASON_CODES = EXECUTOR_REASON_CODES;
|
|
89
|
+
|
|
86
90
|
export interface CompositesMember {
|
|
87
91
|
name: string;
|
|
88
92
|
dir: string;
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"uniqueItems": true
|
|
80
80
|
},
|
|
81
81
|
"evidence": {
|
|
82
|
-
"description": "The proof of done: public links,
|
|
82
|
+
"description": "The proof of done: public links, workspace files pinned by the hash of their bytes (chant workspace records pin <path>), or ops results on the chant/lifecycle branch (#3171). May be empty while the work is open; a done item with none gets the warning work-done-unpinned. An entry that names a criterion from acceptance carries the verification it is and its result, and a manual verdict names who gave it in by (#2772).",
|
|
83
83
|
"type": "array",
|
|
84
84
|
"items": {
|
|
85
85
|
"oneOf": [
|
|
@@ -88,6 +88,9 @@
|
|
|
88
88
|
},
|
|
89
89
|
{
|
|
90
90
|
"$ref": "#/definitions/evidencePin"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"$ref": "#/definitions/evidenceOps"
|
|
91
94
|
}
|
|
92
95
|
]
|
|
93
96
|
}
|
|
@@ -305,6 +308,107 @@
|
|
|
305
308
|
]
|
|
306
309
|
}
|
|
307
310
|
},
|
|
311
|
+
"evidenceOps": {
|
|
312
|
+
"description": "An ops result on the chant/lifecycle branch (#3171): a run, a deploy, a gate answer or a release plan, named the way graph --intent's trace names a link. chant workspace work evidence and the workEvidence activity check it against the ledger before writing it, and a cited run's outcome agrees with result.",
|
|
313
|
+
"type": "object",
|
|
314
|
+
"additionalProperties": false,
|
|
315
|
+
"required": [
|
|
316
|
+
"title",
|
|
317
|
+
"ops"
|
|
318
|
+
],
|
|
319
|
+
"properties": {
|
|
320
|
+
"title": {
|
|
321
|
+
"type": "string",
|
|
322
|
+
"minLength": 1
|
|
323
|
+
},
|
|
324
|
+
"ops": {
|
|
325
|
+
"type": "object",
|
|
326
|
+
"additionalProperties": false,
|
|
327
|
+
"required": [
|
|
328
|
+
"ledger",
|
|
329
|
+
"ref",
|
|
330
|
+
"field",
|
|
331
|
+
"value",
|
|
332
|
+
"sha256"
|
|
333
|
+
],
|
|
334
|
+
"properties": {
|
|
335
|
+
"ledger": {
|
|
336
|
+
"description": "Which ledger: an Op run, a deploy record, a gate answer or a release plan.",
|
|
337
|
+
"enum": [
|
|
338
|
+
"run",
|
|
339
|
+
"deploy",
|
|
340
|
+
"gate",
|
|
341
|
+
"plan"
|
|
342
|
+
]
|
|
343
|
+
},
|
|
344
|
+
"ref": {
|
|
345
|
+
"description": "The ledger file, as chant/lifecycle:<path>.",
|
|
346
|
+
"type": "string",
|
|
347
|
+
"pattern": "^chant/lifecycle:"
|
|
348
|
+
},
|
|
349
|
+
"field": {
|
|
350
|
+
"description": "The field of the record that picks it out of the file, such as id, runId, timestamp or digest.",
|
|
351
|
+
"type": "string",
|
|
352
|
+
"minLength": 1
|
|
353
|
+
},
|
|
354
|
+
"value": {
|
|
355
|
+
"description": "That field's value.",
|
|
356
|
+
"type": "string",
|
|
357
|
+
"minLength": 1
|
|
358
|
+
},
|
|
359
|
+
"sha256": {
|
|
360
|
+
"description": "Hex SHA-256 of the record as the ledger stores it: the line, or the plan file.",
|
|
361
|
+
"type": "string",
|
|
362
|
+
"pattern": "^[0-9a-f]{64}$"
|
|
363
|
+
},
|
|
364
|
+
"env": {
|
|
365
|
+
"description": "The environment, for a run or a deploy.",
|
|
366
|
+
"type": "string"
|
|
367
|
+
},
|
|
368
|
+
"outcome": {
|
|
369
|
+
"description": "The run's status, for a run.",
|
|
370
|
+
"enum": [
|
|
371
|
+
"ok",
|
|
372
|
+
"fail"
|
|
373
|
+
]
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
},
|
|
377
|
+
"as_of": {
|
|
378
|
+
"description": "When the result was cited, as an ISO 8601 timestamp.",
|
|
379
|
+
"type": [
|
|
380
|
+
"string",
|
|
381
|
+
"null"
|
|
382
|
+
]
|
|
383
|
+
},
|
|
384
|
+
"criterion": {
|
|
385
|
+
"description": "The acceptance criterion this evidence is for, by id (#2772).",
|
|
386
|
+
"type": "string",
|
|
387
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"
|
|
388
|
+
},
|
|
389
|
+
"verification": {
|
|
390
|
+
"$ref": "#/definitions/verification"
|
|
391
|
+
},
|
|
392
|
+
"result": {
|
|
393
|
+
"description": "Whether the evidence shows the criterion met.",
|
|
394
|
+
"enum": [
|
|
395
|
+
"pass",
|
|
396
|
+
"fail"
|
|
397
|
+
]
|
|
398
|
+
},
|
|
399
|
+
"by": {
|
|
400
|
+
"description": "Who produced the evidence: the lease holder for a steward's, the person for a manual verdict.",
|
|
401
|
+
"type": "string",
|
|
402
|
+
"minLength": 1
|
|
403
|
+
}
|
|
404
|
+
},
|
|
405
|
+
"dependencies": {
|
|
406
|
+
"criterion": [
|
|
407
|
+
"verification",
|
|
408
|
+
"result"
|
|
409
|
+
]
|
|
410
|
+
}
|
|
411
|
+
},
|
|
308
412
|
"evidencePin": {
|
|
309
413
|
"description": "A file in the workspace, pinned by the hash of its bytes. chant workspace records reports a file that changed or went missing since.",
|
|
310
414
|
"type": "object",
|