@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
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync } from "fs";
|
|
2
2
|
import { join, resolve, basename, dirname } from "path";
|
|
3
3
|
import { formatSuccess, formatWarning, formatError } from "../format";
|
|
4
|
-
import type { TemplateIR, ResourceIR, ParameterIR, ParseContext } from "../../import/parser";
|
|
4
|
+
import type { TemplateIR, ResourceIR, ParameterIR, ParseContext, ImportDiagnostic } from "../../import/parser";
|
|
5
5
|
import type { GeneratedFile, TypeScriptGenerator } from "../../import/generator";
|
|
6
6
|
import { listInstalledLexicons, loadPlugin, loadPlugins, resolveProjectLexicons } from "../plugins";
|
|
7
7
|
import type { ExportedTemplate, LexiconPlugin, ResourceSelector } from "../../lexicon";
|
|
8
8
|
import { parseYAMLDocument, splitYAMLDocuments } from "../../yaml";
|
|
9
9
|
import { importLexiconPackage } from "../../lexicon-module";
|
|
10
10
|
import { resolveParserOptions } from "../../import/parser-options";
|
|
11
|
+
import { summarizeImportDiagnostics } from "./import-report";
|
|
11
12
|
import { EmbeddedImports, type EmbeddedContent, type RegisteredEmbeddedImporter } from "../../import/embedded";
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -31,6 +32,8 @@ export interface ImportOptions {
|
|
|
31
32
|
* fails the import before anything is parsed.
|
|
32
33
|
*/
|
|
33
34
|
parserOptions?: string[];
|
|
35
|
+
/** `--validate` (#4398): check the parsed template on the lexicon's emulator before writing. */
|
|
36
|
+
validate?: boolean;
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
/**
|
|
@@ -52,6 +55,12 @@ export interface ImportResult {
|
|
|
52
55
|
* it was named (`--lexicon`, `--kustomize`) (#2965).
|
|
53
56
|
*/
|
|
54
57
|
detected?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* What the parser flagged for review (#4398), then what `--validate`
|
|
60
|
+
* rejected. `--report` writes them as SARIF and `--strict` fails while a
|
|
61
|
+
* `warning` or `error` is open; see `./import-report.ts`.
|
|
62
|
+
*/
|
|
63
|
+
diagnostics?: ImportDiagnostic[];
|
|
55
64
|
}
|
|
56
65
|
|
|
57
66
|
/**
|
|
@@ -353,6 +362,7 @@ export async function importCommand(options: ImportOptions): Promise<ImportResul
|
|
|
353
362
|
output: options.output,
|
|
354
363
|
force: options.force,
|
|
355
364
|
parserOptions: options.parserOptions,
|
|
365
|
+
validate: options.validate,
|
|
356
366
|
});
|
|
357
367
|
}
|
|
358
368
|
|
|
@@ -391,7 +401,7 @@ export async function importCommand(options: ImportOptions): Promise<ImportResul
|
|
|
391
401
|
);
|
|
392
402
|
}
|
|
393
403
|
|
|
394
|
-
const result = await parseAndWrite(plugin, content, outputDir, options.force, warnings, generatedFiles, plugin.name, projectDir, options.parserOptions);
|
|
404
|
+
const result = await parseAndWrite(plugin, content, outputDir, options.force, warnings, generatedFiles, plugin.name, projectDir, options.parserOptions, options.validate);
|
|
395
405
|
return { ...result, detected: true };
|
|
396
406
|
}
|
|
397
407
|
|
|
@@ -412,6 +422,8 @@ export interface ContentImportOptions {
|
|
|
412
422
|
force?: boolean;
|
|
413
423
|
/** `--parser-option` entries for the lexicon's parser (#2994); see {@link ImportOptions.parserOptions}. */
|
|
414
424
|
parserOptions?: string[];
|
|
425
|
+
/** `--validate`; see {@link ImportOptions.validate}. */
|
|
426
|
+
validate?: boolean;
|
|
415
427
|
}
|
|
416
428
|
|
|
417
429
|
export async function importFromContent(options: ContentImportOptions): Promise<ImportResult> {
|
|
@@ -432,7 +444,7 @@ export async function importFromContent(options: ContentImportOptions): Promise<
|
|
|
432
444
|
return { success: false, generatedFiles: [], warnings: [], error: `Lexicon "${options.lexicon}" not available.` };
|
|
433
445
|
}
|
|
434
446
|
const projectDir = resolve(options.output ? dirname(options.output) : ".");
|
|
435
|
-
return parseAndWrite(plugin, options.content, outputDir, options.force, [], [], plugin.name, projectDir, options.parserOptions);
|
|
447
|
+
return parseAndWrite(plugin, options.content, outputDir, options.force, [], [], plugin.name, projectDir, options.parserOptions, options.validate);
|
|
436
448
|
}
|
|
437
449
|
|
|
438
450
|
/**
|
|
@@ -568,6 +580,7 @@ async function parseAndWrite(
|
|
|
568
580
|
lexicon: string,
|
|
569
581
|
projectDir: string,
|
|
570
582
|
parserOptionEntries?: readonly string[],
|
|
583
|
+
validate?: boolean,
|
|
571
584
|
): Promise<ImportResult> {
|
|
572
585
|
// A lexicon can recognize a template (detectTemplate) without being able to
|
|
573
586
|
// import it (grafana had no parser until #2945). Every path funnels through here, so
|
|
@@ -609,6 +622,18 @@ async function parseAndWrite(
|
|
|
609
622
|
if (ir.warnings) {
|
|
610
623
|
warnings.push(...ir.warnings);
|
|
611
624
|
}
|
|
625
|
+
// Findings for review (#4398), and what the lexicon's emulator rejects.
|
|
626
|
+
const diagnostics: ImportDiagnostic[] = [...(ir.diagnostics ?? [])];
|
|
627
|
+
if (validate) {
|
|
628
|
+
if (!plugin.validateImport) {
|
|
629
|
+
return { success: false, generatedFiles: [], warnings: [], error: `lexicon "${plugin.name}" has no emulator to validate an import against`, lexicon: plugin.name };
|
|
630
|
+
}
|
|
631
|
+
try {
|
|
632
|
+
diagnostics.push(...(await plugin.validateImport(ir, resolved.options)));
|
|
633
|
+
} catch (err) {
|
|
634
|
+
return { success: false, generatedFiles: [], warnings: [], error: `--validate failed to run: ${err instanceof Error ? err.message : String(err)}`, lexicon: plugin.name };
|
|
635
|
+
}
|
|
636
|
+
}
|
|
612
637
|
// Embedded content the owner could not carry, or that no installed lexicon imports.
|
|
613
638
|
if (embedded) warnings.push(...embedded.warnings);
|
|
614
639
|
|
|
@@ -660,6 +685,7 @@ async function parseAndWrite(
|
|
|
660
685
|
generatedFiles,
|
|
661
686
|
warnings,
|
|
662
687
|
lexicon,
|
|
688
|
+
...(diagnostics.length > 0 ? { diagnostics } : {}),
|
|
663
689
|
};
|
|
664
690
|
}
|
|
665
691
|
|
|
@@ -894,6 +920,10 @@ export function printImportResult(result: ImportResult): void {
|
|
|
894
920
|
console.log(`${result.detected ? "Detected lexicon" : "Lexicon"}: ${result.lexicon}`);
|
|
895
921
|
}
|
|
896
922
|
|
|
923
|
+
if (result.diagnostics && result.diagnostics.length > 0) {
|
|
924
|
+
console.error(summarizeImportDiagnostics(result.diagnostics));
|
|
925
|
+
}
|
|
926
|
+
|
|
897
927
|
if (result.generatedFiles.length > 0) {
|
|
898
928
|
console.log(formatSuccess("Generated files:"));
|
|
899
929
|
for (const file of result.generatedFiles) {
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chant migrate` naming and the target-server `--validate` (#4399): a side is
|
|
3
|
+
* `lexicon` or `lexicon/dialect`, a directory is a source only when the
|
|
4
|
+
* lexicon says so, and a result's own `validate` replaces the external linter.
|
|
5
|
+
*/
|
|
6
|
+
import { afterEach, beforeEach, describe, expect, test } from "vitest";
|
|
7
|
+
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
8
|
+
import { tmpdir } from "node:os";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { lexiconOfSide, migrateCommand } from "./migrate";
|
|
11
|
+
import type { LexiconPlugin, MigrationResult, MigrationSource } from "../../lexicon";
|
|
12
|
+
|
|
13
|
+
const seen: Array<{ from: string; to: string | undefined }> = [];
|
|
14
|
+
|
|
15
|
+
function sqlPlugin(over: { directory?: boolean; result?: Partial<MigrationResult>; transform?: MigrationSource["transform"] } = {}): LexiconPlugin {
|
|
16
|
+
return {
|
|
17
|
+
name: "sql",
|
|
18
|
+
serializer: { name: "sql", rulePrefix: "SQL", serialize: () => "" },
|
|
19
|
+
async generate() {},
|
|
20
|
+
async validate() {},
|
|
21
|
+
async coverage() {},
|
|
22
|
+
async package() {},
|
|
23
|
+
migrationSource(from: string, to?: string) {
|
|
24
|
+
seen.push({ from, to });
|
|
25
|
+
if (from !== "sql/postgres" || (to !== undefined && to !== "sql/clickhouse")) return undefined;
|
|
26
|
+
return {
|
|
27
|
+
detect: (content: string) => content.includes("CREATE TABLE"),
|
|
28
|
+
...(over.directory ? { directory: true } : {}),
|
|
29
|
+
transform: over.transform ?? (async () => ({ output: "-- ddl\n", provenance: [], diagnostics: [], ...over.result })),
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const base = { emit: "sql" as const, strict: false, validate: false, useComposites: false };
|
|
36
|
+
|
|
37
|
+
describe("lexiconOfSide", () => {
|
|
38
|
+
test("is the part before the slash", () => {
|
|
39
|
+
expect(lexiconOfSide("sql/clickhouse")).toBe("sql");
|
|
40
|
+
expect(lexiconOfSide("gitlab")).toBe("gitlab");
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe("migrateCommand with lexicon/dialect sides", () => {
|
|
45
|
+
let dir: string;
|
|
46
|
+
beforeEach(() => {
|
|
47
|
+
dir = mkdtempSync(join(tmpdir(), "chant-migrate-dialect-"));
|
|
48
|
+
seen.length = 0;
|
|
49
|
+
});
|
|
50
|
+
afterEach(() => rmSync(dir, { recursive: true, force: true }));
|
|
51
|
+
const file = () => {
|
|
52
|
+
const f = join(dir, "schema.sql");
|
|
53
|
+
writeFileSync(f, "CREATE TABLE t (id int);");
|
|
54
|
+
return f;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
test("finds the plugin by the lexicon part, and hands the source both sides as written", async () => {
|
|
58
|
+
const r = await migrateCommand({ ...base, sourceFile: file(), from: "sql/postgres", to: "sql/clickhouse", output: join(dir, "out.sql"), plugins: [sqlPlugin()] });
|
|
59
|
+
expect(r.exitCode).toBe(0);
|
|
60
|
+
expect(seen).toEqual([{ from: "sql/postgres", to: "sql/clickhouse" }]);
|
|
61
|
+
expect(readFileSync(join(dir, "out.sql"), "utf8")).toBe("-- ddl\n");
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test("a dialect the lexicon does not know is refused by name", async () => {
|
|
65
|
+
const r = await migrateCommand({ ...base, sourceFile: file(), from: "sql/postgres", to: "sql/mysql", plugins: [sqlPlugin()] });
|
|
66
|
+
expect(r.exitCode).toBe(1);
|
|
67
|
+
expect(r.error).toContain('Lexicon "sql/mysql" does not support migration from "sql/postgres"');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("creates the output's directory", async () => {
|
|
71
|
+
const out = join(dir, "a/b/out.sql");
|
|
72
|
+
const r = await migrateCommand({ ...base, sourceFile: file(), from: "sql/postgres", to: "sql/clickhouse", output: out, plugins: [sqlPlugin()] });
|
|
73
|
+
expect(r.exitCode).toBe(0);
|
|
74
|
+
expect(readFileSync(out, "utf8")).toBe("-- ddl\n");
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("a directory is refused unless the source reads directories; then detect is skipped and content is empty", async () => {
|
|
78
|
+
const member = join(dir, "db");
|
|
79
|
+
mkdirSync(member);
|
|
80
|
+
const refused = await migrateCommand({ ...base, sourceFile: member, from: "sql/postgres", to: "sql/clickhouse", plugins: [sqlPlugin()] });
|
|
81
|
+
expect(refused.exitCode).toBe(1);
|
|
82
|
+
expect(refused.error).toContain("is a directory");
|
|
83
|
+
let got: { content: string; sourceFile?: string } | undefined;
|
|
84
|
+
const ok = await migrateCommand({
|
|
85
|
+
...base,
|
|
86
|
+
sourceFile: member,
|
|
87
|
+
from: "sql/postgres",
|
|
88
|
+
to: "sql/clickhouse",
|
|
89
|
+
output: join(dir, "o.sql"),
|
|
90
|
+
plugins: [sqlPlugin({ directory: true, transform: async (content, opts) => ((got = { content, sourceFile: opts.sourceFile }), { output: "x", provenance: [], diagnostics: [] }) })],
|
|
91
|
+
});
|
|
92
|
+
expect(ok.exitCode).toBe(0);
|
|
93
|
+
expect(got).toEqual({ content: "", sourceFile: member });
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe("--validate with a result that checks itself", () => {
|
|
98
|
+
let dir: string;
|
|
99
|
+
beforeEach(() => {
|
|
100
|
+
dir = mkdtempSync(join(tmpdir(), "chant-migrate-validate-"));
|
|
101
|
+
});
|
|
102
|
+
afterEach(() => rmSync(dir, { recursive: true, force: true }));
|
|
103
|
+
const run = (result: Partial<MigrationResult>, extra: { strict?: boolean } = {}) => {
|
|
104
|
+
const f = join(dir, "schema.sql");
|
|
105
|
+
writeFileSync(f, "CREATE TABLE t (id int);");
|
|
106
|
+
return migrateCommand({ ...base, ...extra, validate: true, sourceFile: f, from: "sql/postgres", to: "sql/clickhouse", output: join(dir, "o.sql"), plugins: [sqlPlugin({ result })] });
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
test("a clean check passes and its diagnostics join the result", async () => {
|
|
110
|
+
const r = await run({ validate: async () => [] });
|
|
111
|
+
expect(r.exitCode).toBe(0);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test("a refused statement fails the run without --strict, and is in the diagnostics", async () => {
|
|
115
|
+
const r = await run({ validate: async () => [{ ruleId: "SQLRV012", severity: "error", message: "t: the emulator rejected the statement." }] });
|
|
116
|
+
expect(r.exitCode).toBe(1);
|
|
117
|
+
expect(r.diagnostics.map((d) => d.ruleId)).toEqual(["SQLRV012"]);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test("a server that cannot start is a validation that did not run, which fails", async () => {
|
|
121
|
+
const r = await run({
|
|
122
|
+
validate: async () => {
|
|
123
|
+
throw new Error("Docker is not available, so the ClickHouse emulator cannot start");
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
expect(r.exitCode).toBe(1);
|
|
127
|
+
expect(r.error).toContain("--validate did not run: Docker is not available");
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("without --validate the check is not run", async () => {
|
|
131
|
+
let ran = false;
|
|
132
|
+
const f = join(dir, "schema.sql");
|
|
133
|
+
writeFileSync(f, "CREATE TABLE t (id int);");
|
|
134
|
+
const r = await migrateCommand({
|
|
135
|
+
...base,
|
|
136
|
+
sourceFile: f,
|
|
137
|
+
from: "sql/postgres",
|
|
138
|
+
to: "sql/clickhouse",
|
|
139
|
+
output: join(dir, "o.sql"),
|
|
140
|
+
plugins: [sqlPlugin({ result: { validate: async () => ((ran = true), []) } })],
|
|
141
|
+
});
|
|
142
|
+
expect(r.exitCode).toBe(0);
|
|
143
|
+
expect(ran).toBe(false);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
@@ -6,19 +6,30 @@
|
|
|
6
6
|
* stdout/stderr surfaces, and exit codes.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { readFileSync, writeFileSync } from "node:fs";
|
|
9
|
+
import { mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
10
|
+
import { dirname } from "node:path";
|
|
10
11
|
import { spawnSync } from "node:child_process";
|
|
11
12
|
import { formatError, formatInfo } from "../format";
|
|
12
13
|
import { formatSarif } from "../reporters/stylish";
|
|
13
14
|
import type { LexiconPlugin } from "../../lexicon";
|
|
14
15
|
import type { LintRule, LintDiagnostic } from "../../lint/rule";
|
|
15
16
|
import { ensureTypeScriptLoader } from "../../ts-loader";
|
|
17
|
+
import { planMigrateLinks } from "../../workspace/migrate-links";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A side of `--from` or `--to`: a lexicon, or a lexicon and one of its
|
|
21
|
+
* dialects, `sql/clickhouse` (#4399). The plugin is the part before the slash.
|
|
22
|
+
*/
|
|
23
|
+
export function lexiconOfSide(side: string): string {
|
|
24
|
+
const slash = side.indexOf("/");
|
|
25
|
+
return slash === -1 ? side : side.slice(0, slash);
|
|
26
|
+
}
|
|
16
27
|
|
|
17
28
|
export interface MigrateCliOpts {
|
|
18
29
|
sourceFile: string;
|
|
19
30
|
from: string;
|
|
20
31
|
to: string;
|
|
21
|
-
emit: "yaml" | "ts";
|
|
32
|
+
emit: "yaml" | "ts" | "sql";
|
|
22
33
|
strict: boolean;
|
|
23
34
|
validate: boolean;
|
|
24
35
|
useComposites: boolean;
|
|
@@ -39,10 +50,13 @@ export interface MigrateCliResult {
|
|
|
39
50
|
error?: string;
|
|
40
51
|
/** Markdown summary lines printed to stderr */
|
|
41
52
|
markdownSummary?: string;
|
|
53
|
+
/** What was done about workspace links, or why nothing was (#4399) */
|
|
54
|
+
linkNote?: string;
|
|
42
55
|
}
|
|
43
56
|
|
|
44
57
|
export async function migrateCommand(opts: MigrateCliOpts): Promise<MigrateCliResult> {
|
|
45
|
-
const
|
|
58
|
+
const targetLexicon = lexiconOfSide(opts.to);
|
|
59
|
+
const targetPlugin = opts.plugins.find((p) => p.name === targetLexicon);
|
|
46
60
|
if (!targetPlugin) {
|
|
47
61
|
return {
|
|
48
62
|
exitCode: 1,
|
|
@@ -59,7 +73,7 @@ export async function migrateCommand(opts: MigrateCliOpts): Promise<MigrateCliRe
|
|
|
59
73
|
error: `Lexicon "${opts.to}" does not support migration`,
|
|
60
74
|
};
|
|
61
75
|
}
|
|
62
|
-
const source = targetPlugin.migrationSource(opts.from);
|
|
76
|
+
const source = targetPlugin.migrationSource(opts.from, opts.to);
|
|
63
77
|
if (!source) {
|
|
64
78
|
return {
|
|
65
79
|
exitCode: 1,
|
|
@@ -70,8 +84,23 @@ export async function migrateCommand(opts: MigrateCliOpts): Promise<MigrateCliRe
|
|
|
70
84
|
}
|
|
71
85
|
|
|
72
86
|
let content: string;
|
|
87
|
+
// A directory is a workspace member: the source reads it itself (#4399).
|
|
88
|
+
let isDirectory = false;
|
|
89
|
+
try {
|
|
90
|
+
isDirectory = statSync(opts.sourceFile).isDirectory();
|
|
91
|
+
} catch {
|
|
92
|
+
// The read below names the problem.
|
|
93
|
+
}
|
|
94
|
+
if (isDirectory && !source.directory) {
|
|
95
|
+
return {
|
|
96
|
+
exitCode: 1,
|
|
97
|
+
diagnostics: [],
|
|
98
|
+
provenance: [],
|
|
99
|
+
error: `${opts.sourceFile} is a directory, and migrating from "${opts.from}" reads a file`,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
73
102
|
try {
|
|
74
|
-
content = readFileSync(opts.sourceFile, "utf-8");
|
|
103
|
+
content = isDirectory ? "" : readFileSync(opts.sourceFile, "utf-8");
|
|
75
104
|
} catch (err) {
|
|
76
105
|
return {
|
|
77
106
|
exitCode: 1,
|
|
@@ -81,7 +110,7 @@ export async function migrateCommand(opts: MigrateCliOpts): Promise<MigrateCliRe
|
|
|
81
110
|
};
|
|
82
111
|
}
|
|
83
112
|
|
|
84
|
-
if (!source.detect(content)) {
|
|
113
|
+
if (!isDirectory && !source.detect(content)) {
|
|
85
114
|
return {
|
|
86
115
|
exitCode: 1,
|
|
87
116
|
diagnostics: [],
|
|
@@ -113,6 +142,7 @@ export async function migrateCommand(opts: MigrateCliOpts): Promise<MigrateCliRe
|
|
|
113
142
|
// Write output (--output file or stdout)
|
|
114
143
|
if (opts.output && opts.output !== "-") {
|
|
115
144
|
try {
|
|
145
|
+
mkdirSync(dirname(opts.output), { recursive: true });
|
|
116
146
|
writeFileSync(opts.output, result.output);
|
|
117
147
|
} catch (err) {
|
|
118
148
|
return {
|
|
@@ -126,9 +156,34 @@ export async function migrateCommand(opts: MigrateCliOpts): Promise<MigrateCliRe
|
|
|
126
156
|
process.stdout.write(result.output);
|
|
127
157
|
}
|
|
128
158
|
|
|
159
|
+
// The target's own server (--validate), when the source has one (#4399).
|
|
160
|
+
// A refusal always fails the run; so does a server that could not start,
|
|
161
|
+
// since a validation that did not run is not a pass.
|
|
162
|
+
let validationFailed = false;
|
|
163
|
+
if (opts.validate && result.validate) {
|
|
164
|
+
try {
|
|
165
|
+
const found = await result.validate();
|
|
166
|
+
result.diagnostics.push(...found);
|
|
167
|
+
if (found.some((d) => d.severity === "error")) {
|
|
168
|
+
validationFailed = true;
|
|
169
|
+
console.error(`Validator found ${found.filter((d) => d.severity === "error").length} refused statement(s):\n${found.map((d) => ` ${String(d.message)}`).join("\n")}`);
|
|
170
|
+
} else {
|
|
171
|
+
console.error("Validator (target server) OK");
|
|
172
|
+
}
|
|
173
|
+
} catch (err) {
|
|
174
|
+
return {
|
|
175
|
+
exitCode: 1,
|
|
176
|
+
output: result.output,
|
|
177
|
+
diagnostics: result.diagnostics,
|
|
178
|
+
provenance: result.provenance,
|
|
179
|
+
error: `--validate did not run: ${err instanceof Error ? err.message : String(err)}`,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
129
184
|
// External validator (--validate) — glci preferred, glab fallback.
|
|
130
185
|
let validatorWarning: string | undefined;
|
|
131
|
-
if (opts.validate && opts.emit === "yaml") {
|
|
186
|
+
if (opts.validate && !result.validate && opts.emit === "yaml") {
|
|
132
187
|
const v = tryValidateExternal(result.output);
|
|
133
188
|
if (!v.ran) {
|
|
134
189
|
validatorWarning = "neither glci nor glab is on PATH; skipping --validate";
|
|
@@ -157,11 +212,35 @@ export async function migrateCommand(opts: MigrateCliOpts): Promise<MigrateCliRe
|
|
|
157
212
|
}
|
|
158
213
|
}
|
|
159
214
|
|
|
215
|
+
// Links from the output's workspace member to the outputs it reads (#4399).
|
|
216
|
+
let linkNote: string | undefined;
|
|
217
|
+
if (result.links && result.links.length > 0) {
|
|
218
|
+
const outcome = planMigrateLinks({
|
|
219
|
+
sourcePath: opts.sourceFile,
|
|
220
|
+
outputPath: opts.output && opts.output !== "-" ? opts.output : undefined,
|
|
221
|
+
outputs: result.links,
|
|
222
|
+
});
|
|
223
|
+
if (outcome && "skipped" in outcome) linkNote = outcome.skipped;
|
|
224
|
+
else if (outcome) {
|
|
225
|
+
const { plan } = outcome;
|
|
226
|
+
if (plan.added.length === 0) {
|
|
227
|
+
linkNote = `member ${plan.consumer} already links every output it reads from ${plan.producer}`;
|
|
228
|
+
} else {
|
|
229
|
+
try {
|
|
230
|
+
writeFileSync(plan.file, plan.text);
|
|
231
|
+
linkNote = `added ${plan.added.length} link${plan.added.length === 1 ? "" : "s"} from member ${plan.consumer} to ${plan.producer} in ${plan.file}`;
|
|
232
|
+
} catch (err) {
|
|
233
|
+
linkNote = `could not write the links to ${plan.file}: ${err instanceof Error ? err.message : String(err)}`;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
160
239
|
// SARIF report (--report <path>) — reuse the lint-side formatSarif so any
|
|
161
240
|
// CI SARIF ingest path treats migration findings uniformly.
|
|
162
241
|
if (opts.reportFile) {
|
|
163
242
|
try {
|
|
164
|
-
const rules = await loadMigrationRules(
|
|
243
|
+
const rules = await loadMigrationRules(targetLexicon);
|
|
165
244
|
const lintShape = result.diagnostics as unknown as LintDiagnostic[];
|
|
166
245
|
const sarif = formatSarif(lintShape, rules);
|
|
167
246
|
writeFileSync(opts.reportFile, sarif);
|
|
@@ -172,7 +251,8 @@ export async function migrateCommand(opts: MigrateCliOpts): Promise<MigrateCliRe
|
|
|
172
251
|
}
|
|
173
252
|
|
|
174
253
|
// Markdown summary (always to stderr — leaves stdout clean for piping)
|
|
175
|
-
let markdownSummary =
|
|
254
|
+
let markdownSummary =
|
|
255
|
+
targetLexicon === "gitlab" ? formatMarkdownSummary(result.provenance, result.diagnostics, content) : formatDiagnosticSummary(result.provenance, result.diagnostics);
|
|
176
256
|
// Append the security posture section when security analysis ran (#306).
|
|
177
257
|
if (result.securityPosture) {
|
|
178
258
|
markdownSummary += `\n\n${result.securityPosture}`;
|
|
@@ -182,7 +262,7 @@ export async function migrateCommand(opts: MigrateCliOpts): Promise<MigrateCliRe
|
|
|
182
262
|
// The transformer already escalates needs-review → error when opts.strict
|
|
183
263
|
// is passed via MigrationSource.transform(); we double-check here.
|
|
184
264
|
const errorDiagnostics = result.diagnostics.filter((d) => d.severity === "error");
|
|
185
|
-
const exitCode = opts.strict && errorDiagnostics.length > 0 ? 1 : 0;
|
|
265
|
+
const exitCode = validationFailed || (opts.strict && errorDiagnostics.length > 0) ? 1 : 0;
|
|
186
266
|
|
|
187
267
|
return {
|
|
188
268
|
exitCode,
|
|
@@ -190,6 +270,7 @@ export async function migrateCommand(opts: MigrateCliOpts): Promise<MigrateCliRe
|
|
|
190
270
|
diagnostics: result.diagnostics,
|
|
191
271
|
provenance: result.provenance,
|
|
192
272
|
markdownSummary,
|
|
273
|
+
...(linkNote ? { linkNote } : {}),
|
|
193
274
|
};
|
|
194
275
|
}
|
|
195
276
|
|
|
@@ -231,7 +312,7 @@ export function tryValidateExternal(yamlText: string): ValidatorResult {
|
|
|
231
312
|
* Returns an empty array if the lexicon doesn't expose them.
|
|
232
313
|
*/
|
|
233
314
|
async function loadMigrationRules(targetLexicon: string): Promise<LintRule[]> {
|
|
234
|
-
//
|
|
315
|
+
// gitlab and sql expose migration rules. Hard-coded imports keep
|
|
235
316
|
// the dependency direction explicit; widen the switch when more
|
|
236
317
|
// lexicons ship their own migrate paths.
|
|
237
318
|
if (targetLexicon === "gitlab") {
|
|
@@ -243,9 +324,46 @@ async function loadMigrationRules(targetLexicon: string): Promise<LintRule[]> {
|
|
|
243
324
|
return [];
|
|
244
325
|
}
|
|
245
326
|
}
|
|
327
|
+
// The sql lexicon's needs-review catalog (#4399), one rule per finding id.
|
|
328
|
+
if (targetLexicon === "sql") {
|
|
329
|
+
try {
|
|
330
|
+
ensureTypeScriptLoader();
|
|
331
|
+
const mod = await import("@intentius/chant-lexicon-sql/clickhouse/review-catalog");
|
|
332
|
+
const rules = (mod as { REVIEW_RULES: Record<string, { id: string; name: string; summary: string; docs: readonly string[] }> }).REVIEW_RULES;
|
|
333
|
+
return Object.values(rules).map((r): LintRule => ({
|
|
334
|
+
id: r.id,
|
|
335
|
+
severity: "warning",
|
|
336
|
+
category: "correctness",
|
|
337
|
+
description: `${r.name}: ${r.summary}`,
|
|
338
|
+
helpUri: r.docs[0] ?? "https://intentius.io/chant/lexicons/sql/migrate-postgres-to-clickhouse/",
|
|
339
|
+
check: () => [],
|
|
340
|
+
}));
|
|
341
|
+
} catch {
|
|
342
|
+
return [];
|
|
343
|
+
}
|
|
344
|
+
}
|
|
246
345
|
return [];
|
|
247
346
|
}
|
|
248
347
|
|
|
348
|
+
/**
|
|
349
|
+
* The report for a pair that is not GitHub to GitLab: the counts and the
|
|
350
|
+
* diagnostics, with none of that pair's workflow advice (#4399).
|
|
351
|
+
*/
|
|
352
|
+
export function formatDiagnosticSummary(provenance: Array<Record<string, unknown>>, diagnostics: Array<Record<string, unknown>>): string {
|
|
353
|
+
const totals = { error: 0, warning: 0, info: 0 };
|
|
354
|
+
for (const d of diagnostics) {
|
|
355
|
+
const sev = d.severity as string;
|
|
356
|
+
if (sev === "error" || sev === "warning" || sev === "info") totals[sev]++;
|
|
357
|
+
}
|
|
358
|
+
const lines = ["", "## Migration report", "", `- Translated: ${provenance.length}`, `- Diagnostics: ${totals.error} error, ${totals.warning} warning, ${totals.info} info`];
|
|
359
|
+
if (diagnostics.length > 0) {
|
|
360
|
+
lines.push("", "### Diagnostics", "", "| Severity | Rule | Message |", "|---|---|---|");
|
|
361
|
+
for (const d of diagnostics.slice(0, 50)) lines.push(`| ${String(d.severity)} | ${String(d.ruleId)} | ${String(d.message).replace(/\|/g, "\\|").slice(0, 160)} |`);
|
|
362
|
+
if (diagnostics.length > 50) lines.push(`| ... | ... | ${diagnostics.length - 50} more diagnostics omitted |`);
|
|
363
|
+
}
|
|
364
|
+
return lines.join("\n");
|
|
365
|
+
}
|
|
366
|
+
|
|
249
367
|
/**
|
|
250
368
|
* Format the migration report as Markdown, mirroring the output format
|
|
251
369
|
* prescribed by the upstream gitlab-org/ci-cd/github-actions-to-gitlab-ci
|
|
@@ -471,6 +589,9 @@ export function printMigrateResult(result: MigrateCliResult): void {
|
|
|
471
589
|
if (result.markdownSummary) {
|
|
472
590
|
console.error(result.markdownSummary);
|
|
473
591
|
}
|
|
592
|
+
if (result.linkNote) {
|
|
593
|
+
console.error(`\nWorkspace links: ${result.linkNote}`);
|
|
594
|
+
}
|
|
474
595
|
if (result.exitCode === 0) {
|
|
475
596
|
console.error(formatInfo("\nMigration complete."));
|
|
476
597
|
} else {
|
|
@@ -14,10 +14,10 @@ jobs:
|
|
|
14
14
|
runs-on: ubuntu-latest
|
|
15
15
|
container: node:22
|
|
16
16
|
steps:
|
|
17
|
-
- uses: actions/checkout@v7
|
|
17
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
18
18
|
- run: chant run --components shared-alb --env staging --dump-outputs shared-alb.outputs.json
|
|
19
19
|
- name: Upload shared-alb outputs
|
|
20
|
-
uses: actions/upload-artifact@v4
|
|
20
|
+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
21
21
|
with:
|
|
22
22
|
name: shared-alb-outputs
|
|
23
23
|
path: shared-alb.outputs.json
|
|
@@ -27,9 +27,9 @@ jobs:
|
|
|
27
27
|
- shared-alb
|
|
28
28
|
container: node:22
|
|
29
29
|
steps:
|
|
30
|
-
- uses: actions/checkout@v7
|
|
30
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
31
31
|
- name: Download shared-alb outputs
|
|
32
|
-
uses: actions/download-artifact@v4
|
|
32
|
+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
33
33
|
with:
|
|
34
34
|
name: shared-alb-outputs
|
|
35
35
|
path: .
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
} from "../../op/gate-approval";
|
|
23
23
|
import { approverOf, humanQuorumSince, tallyGateApprovals } from "../../op/gate";
|
|
24
24
|
import { quorumRuleLine, quorumRules, trustQuorumJudge, UNPROVEN_JUDGE, type GateQuorumJudge } from "../../op/gate-quorum";
|
|
25
|
-
import { FAN_OUT_GATE_OP, OVERRIDE_GATE_OP, RELEASE_GATE_OP, WORKSPACE_UPGRADE_GATE_OP } from "../../op/gate-name";
|
|
25
|
+
import { FAN_OUT_GATE_OP, OVERRIDE_GATE_OP, RELEASE_GATE_OP, WORKSPACE_EXIT_GATE_OP, WORKSPACE_PROMOTE_GATE_OP, WORKSPACE_UPGRADE_GATE_OP } from "../../op/gate-name";
|
|
26
26
|
import { PR_GATE_OP } from "../../pr-loop";
|
|
27
27
|
import { pushLifecycleReport, requireLifecycleLedger } from "../../lifecycle/git";
|
|
28
28
|
import { LIFECYCLE_LOCAL_NOTE, isLifecycleLocalNote } from "../../lifecycle/local-note";
|
|
@@ -128,8 +128,12 @@ export async function runApprove(ctx: CommandContext): Promise<number> {
|
|
|
128
128
|
? `The next \`chant components fan-out\` decides this gate from scratch and records a fresh pending fact.`
|
|
129
129
|
: PR_GATE_OP.test(opName)
|
|
130
130
|
? `The next \`chant components pr-apply\` decides this gate from scratch and records a fresh pending fact.`
|
|
131
|
+
: opName === WORKSPACE_PROMOTE_GATE_OP
|
|
132
|
+
? `The next \`chant workspace promote ${gate}\` decides this gate from scratch and records a fresh pending fact.`
|
|
131
133
|
: opName === WORKSPACE_UPGRADE_GATE_OP
|
|
132
134
|
? `The next \`chant workspace upgrade ${gate}\` decides this gate from scratch and records a fresh pending fact.`
|
|
135
|
+
: opName === WORKSPACE_EXIT_GATE_OP
|
|
136
|
+
? `The next \`chant workspace exit\` decides this gate from scratch and records a fresh pending fact.`
|
|
133
137
|
: opName === RELEASE_GATE_OP
|
|
134
138
|
? `The next \`chant components promote --release\` decides this gate from scratch and records a fresh pending fact.`
|
|
135
139
|
: `The next \`chant run ${opName}\` decides this gate from scratch and records a fresh pending fact.`,
|
|
@@ -180,8 +184,12 @@ export async function runApprove(ctx: CommandContext): Promise<number> {
|
|
|
180
184
|
? `Repeat the \`chant components fan-out\` command and it walks through gate "${gate}".`
|
|
181
185
|
: PR_GATE_OP.test(opName)
|
|
182
186
|
? `The pull request's apply (\`chant components pr-apply\`) walks through gate "${gate}" when it plans this same digest.`
|
|
187
|
+
: opName === WORKSPACE_PROMOTE_GATE_OP
|
|
188
|
+
? `Repeat \`chant workspace promote ${gate}\`, and it applies the patch this approval names.`
|
|
183
189
|
: opName === WORKSPACE_UPGRADE_GATE_OP
|
|
184
190
|
? `Repeat \`chant workspace upgrade ${gate}\` with the same target, and it applies the patch this approval names.`
|
|
191
|
+
: opName === WORKSPACE_EXIT_GATE_OP
|
|
192
|
+
? `Repeat \`chant workspace exit\` with the same members, and it applies the patch this approval names.`
|
|
185
193
|
: opName === RELEASE_GATE_OP
|
|
186
194
|
? `Repeat the same \`chant components promote --release\`, and it walks through gate "${gate}" when it plans this same change set for this release.`
|
|
187
195
|
: `Run \`chant run ${opName}\` and it walks through gate "${gate}".`),
|
|
@@ -330,7 +338,7 @@ export async function recordGateApproval(
|
|
|
330
338
|
// so there is no `*.op.ts` to find and nothing is wrong when none is there.
|
|
331
339
|
// #3949: a gate that lists this one as an alias, after an Op was restructured.
|
|
332
340
|
const successor = aliasingGate([...ops.values()].map((o) => o.config), opName, gate);
|
|
333
|
-
if (!successor && !ops.has(opName) && opName !== FAN_OUT_GATE_OP && opName !== WORKSPACE_UPGRADE_GATE_OP && opName !== OVERRIDE_GATE_OP && opName !== RELEASE_GATE_OP) {
|
|
341
|
+
if (!successor && !ops.has(opName) && opName !== FAN_OUT_GATE_OP && opName !== WORKSPACE_UPGRADE_GATE_OP && opName !== WORKSPACE_EXIT_GATE_OP && opName !== WORKSPACE_PROMOTE_GATE_OP && opName !== OVERRIDE_GATE_OP && opName !== RELEASE_GATE_OP) {
|
|
334
342
|
console.error(formatWarning({
|
|
335
343
|
message: `Op "${opName}" was not found among discovered *.op.ts declarations — recording the resolution anyway`,
|
|
336
344
|
}));
|
|
@@ -599,6 +607,21 @@ export async function recordGateApproval(
|
|
|
599
607
|
// decision is written next to the approval, so a pass can be traced to the
|
|
600
608
|
// rule that allowed it.
|
|
601
609
|
const approval = standingForOrigin?.approval;
|
|
610
|
+
// #4290, #4324: roles come from .chant/trust.json at base, for an approver
|
|
611
|
+
// a seal proves. The quorum and the policy both read these, never --role.
|
|
612
|
+
const judge = trustQuorumJudge({ signers: scope.policy, roles: scope.policy.roles });
|
|
613
|
+
const trusted = judge({
|
|
614
|
+
version: 1,
|
|
615
|
+
op: opName,
|
|
616
|
+
gate,
|
|
617
|
+
...(environment !== undefined ? { environment } : {}),
|
|
618
|
+
...(planDigest !== undefined ? { planDigest } : {}),
|
|
619
|
+
resolvedBy,
|
|
620
|
+
...(relayedBy ? { relayedBy } : {}),
|
|
621
|
+
timestamp,
|
|
622
|
+
...(checkpointDigest !== undefined ? { checkpointDigest } : {}),
|
|
623
|
+
...(seal ? { seal } : {}),
|
|
624
|
+
}).roles;
|
|
602
625
|
let policyDecision: GatePolicyDecision | undefined;
|
|
603
626
|
if (approval?.policy) {
|
|
604
627
|
try {
|
|
@@ -610,6 +633,7 @@ export async function recordGateApproval(
|
|
|
610
633
|
gate,
|
|
611
634
|
resolvedBy,
|
|
612
635
|
approver,
|
|
636
|
+
roles: trusted,
|
|
613
637
|
...(planDigest !== undefined ? { planDigest } : {}),
|
|
614
638
|
...(approval.context ? { context: approval.context } : {}),
|
|
615
639
|
}),
|
|
@@ -680,9 +704,14 @@ export async function recordGateApproval(
|
|
|
680
704
|
"after it plans again. A moved plan or another commit starts it at the first phase.",
|
|
681
705
|
));
|
|
682
706
|
}
|
|
707
|
+
const untrusted = (approver.roles ?? []).filter((r) => !trusted.includes(r));
|
|
708
|
+
if (untrusted.length > 0) {
|
|
709
|
+
console.error(formatInfo(
|
|
710
|
+
`--role ${untrusted.join(", ")} is recorded on the approval and trusted by nothing: a gate's quorum and policy read ` +
|
|
711
|
+
`${record.resolvedBy}'s roles from .chant/trust.json at base, and only for an approval sealed by a signer listed at base (chant approve --sign).`,
|
|
712
|
+
));
|
|
713
|
+
}
|
|
683
714
|
if (approval) {
|
|
684
|
-
// #4290: the rules count roles from .chant/trust.json at base, for a proven approver.
|
|
685
|
-
const judge = trustQuorumJudge({ signers: scope.policy, roles: scope.policy.roles });
|
|
686
715
|
for (const line of describeApprovalProgress(approval, record, ledger.resolutions, standingForOrigin, ledger.pending, judge)) {
|
|
687
716
|
console.error(formatInfo(line));
|
|
688
717
|
}
|
|
@@ -171,6 +171,12 @@ async function runGenerateComponents(ctx: CommandContext): Promise<number> {
|
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
+
// #4327: ci.locks: plan adds the lock and unlock jobs. Read from the declaration, as the security groups are; GitLab keeps its own jobs.
|
|
175
|
+
let locks: "plan" | undefined;
|
|
176
|
+
if (found && args.prLoop && lexicon !== "gitlab") {
|
|
177
|
+
locks = (await import("../../workspace/ci-locks")).ciLocksAt(resolve(args.path)) === "plan" ? "plan" : undefined;
|
|
178
|
+
}
|
|
179
|
+
|
|
174
180
|
// Which lexicons support generate mode is a property of the loaded lexicon
|
|
175
181
|
// plugins (those implementing `generateComponentPipeline`, #688), not a
|
|
176
182
|
// hard-coded core list — `generateComponentsPipeline` returns a descriptive
|
|
@@ -192,7 +198,7 @@ async function runGenerateComponents(ctx: CommandContext): Promise<number> {
|
|
|
192
198
|
: {}),
|
|
193
199
|
// #3183: a plan job per pull request and an apply job per merge.
|
|
194
200
|
// #4292: on the branch ci.branches routes the member to, when it routes it.
|
|
195
|
-
...(args.prLoop ? { prLoop: { ...prLoopOption(args, reportUrl, reviewRules, isolatedRunners), ...(plan?.branch ? { branch: plan.branch } : {}), ...(identity ? { identity } : {}), ...(prEnvIdentity ? { prEnvIdentity } : {}) } } : {}),
|
|
201
|
+
...(args.prLoop ? { prLoop: { ...prLoopOption(args, reportUrl, reviewRules, isolatedRunners), ...(plan?.branch ? { branch: plan.branch } : {}), ...(identity ? { identity } : {}), ...(prEnvIdentity ? { prEnvIdentity } : {}), ...(locks ? { locks } : {}) } } : {}),
|
|
196
202
|
// #4002: the job image and the lines that install what it lacks, chant itself included.
|
|
197
203
|
...(args.image ? { image: args.image } : {}),
|
|
198
204
|
...(args.beforeScript?.length ? { beforeScript: args.beforeScript } : {}),
|