@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
|
@@ -48,8 +48,9 @@
|
|
|
48
48
|
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
49
49
|
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
50
50
|
import { GENERATED_MARKER } from "../discovery/files";
|
|
51
|
+
import { ACTION_PINS, tagComments, usesRef } from "../action-pins";
|
|
51
52
|
import { emitYAMLEntry, parseYAMLDocument } from "../yaml";
|
|
52
|
-
import type
|
|
53
|
+
import { greenBranches, type CiBuild, type CiGreen } from "./declaration";
|
|
53
54
|
import { matchesCheckRun } from "./ci-green";
|
|
54
55
|
import { githubSecretOrJobToken } from "../ci-jobs";
|
|
55
56
|
import { COMPOSE_BRANCH_PREFIX } from "../lifecycle/compose-refs";
|
|
@@ -228,7 +229,7 @@ export function renderCiGreenWorkflow(input: WorkflowInput): string {
|
|
|
228
229
|
? [
|
|
229
230
|
" - name: Mint a GitHub App token that may push tags to commits that change workflows",
|
|
230
231
|
" id: app-token",
|
|
231
|
-
|
|
232
|
+
` uses: ${usesRef(ACTION_PINS.createGithubAppToken2)}`,
|
|
232
233
|
" with:",
|
|
233
234
|
` app-id: \${{ vars.${push.appIdVar} }}`,
|
|
234
235
|
` private-key: \${{ secrets.${push.appKeySecret} }}`,
|
|
@@ -247,7 +248,7 @@ export function renderCiGreenWorkflow(input: WorkflowInput): string {
|
|
|
247
248
|
" types:",
|
|
248
249
|
" - completed",
|
|
249
250
|
" branches:",
|
|
250
|
-
` - ${q(
|
|
251
|
+
...greenBranches(green).map((b) => ` - ${q(b)}`),
|
|
251
252
|
// #4169: a build the tick asked for runs at a ci/build/<sha> tag, and its completion ticks too.
|
|
252
253
|
...(newestPhases(green) ? [` - ${q("ci/build/**")}`] : []),
|
|
253
254
|
// #4220: a composed commit's phases run on its chant/compose/<name> branch, and their completion ticks too.
|
|
@@ -273,12 +274,12 @@ export function renderCiGreenWorkflow(input: WorkflowInput): string {
|
|
|
273
274
|
" timeout-minutes: 15",
|
|
274
275
|
" steps:",
|
|
275
276
|
...mint,
|
|
276
|
-
|
|
277
|
+
` - uses: ${usesRef(ACTION_PINS.checkout6)}`,
|
|
277
278
|
" with:",
|
|
278
279
|
` ref: ${q(green.branch)}`,
|
|
279
280
|
" fetch-depth: 0",
|
|
280
281
|
...token,
|
|
281
|
-
|
|
282
|
+
` - uses: ${usesRef(ACTION_PINS.setupNode6)}`,
|
|
282
283
|
" with:",
|
|
283
284
|
" node-version: \"24\"",
|
|
284
285
|
...cache,
|
|
@@ -292,7 +293,7 @@ export function renderCiGreenWorkflow(input: WorkflowInput): string {
|
|
|
292
293
|
...(input.runnerKeySecret ? [` CHANT_RUNNER_KEY: \${{ secrets.${input.runnerKeySecret} }}`] : []),
|
|
293
294
|
` run: ${tick}`,
|
|
294
295
|
];
|
|
295
|
-
return lines.join("\n") + "\n";
|
|
296
|
+
return tagComments(lines.join("\n") + "\n");
|
|
296
297
|
}
|
|
297
298
|
|
|
298
299
|
/** Whether any phase sets `build` (#4169): then the tick may re-run jobs and start workflows. */
|
|
@@ -370,7 +371,7 @@ export function buildTriggerEdits(green: CiGreen, sources: readonly WorkflowSour
|
|
|
370
371
|
delete on.schedule;
|
|
371
372
|
const push = isObject(on.push) ? { ...on.push } : {};
|
|
372
373
|
const branches = Array.isArray(push.branches) ? push.branches.filter((b): b is string => typeof b === "string") : [];
|
|
373
|
-
const withBranch = branches
|
|
374
|
+
const withBranch = [...branches, ...greenBranches(green).filter((b) => !branches.includes(b))];
|
|
374
375
|
push.branches = compose && !withBranch.includes(COMPOSE_BRANCHES) ? [...withBranch, COMPOSE_BRANCHES] : withBranch;
|
|
375
376
|
const { push: _push, workflow_dispatch: dispatch, ...rest } = on;
|
|
376
377
|
text = writeTopLevel(text, "on", { push, workflow_dispatch: dispatch ?? {}, ...rest });
|
|
@@ -388,8 +389,11 @@ export function buildTriggerEdits(green: CiGreen, sources: readonly WorkflowSour
|
|
|
388
389
|
if (!("workflow_dispatch" in next)) next = { ...next, workflow_dispatch: {} };
|
|
389
390
|
if (next !== on) text = writeTopLevel(text, "on", next);
|
|
390
391
|
// #4220: a compose branch's commits each get a verdict, so its runs are keyed by commit, as the trunk branch's are.
|
|
391
|
-
|
|
392
|
-
const
|
|
392
|
+
// #4325: each branch ci.green judges is keyed by commit.
|
|
393
|
+
const heads = greenBranches(green).map((b) => `github.ref == 'refs/heads/${b}'`);
|
|
394
|
+
const several = heads.length > 1;
|
|
395
|
+
const keyed = compose ? `(${[...heads, `startsWith(github.ref, 'refs/heads/${COMPOSE_BRANCH_PREFIX}')`].join(" || ")})` : several ? `(${heads.join(" || ")})` : `github.ref == '${main}'`;
|
|
396
|
+
const unkeyed = compose || several ? `!${keyed}` : `github.ref != '${main}'`;
|
|
393
397
|
// Written as lines: the emitter would quote the expression, and GitHub reads it the same either way.
|
|
394
398
|
text = writeTopLevel(text, "concurrency", [
|
|
395
399
|
"concurrency:",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
|
|
56
56
|
import { judgeCommits, mergeCommits, readWorkIndex, type CommitLink } from "./commit-links";
|
|
57
57
|
import { execFileSync } from "node:child_process";
|
|
58
|
-
import { readDeclaration, readerVersion, WORKSPACE_ERROR_CODES, WorkspaceReadError, type CiGreen, type CiPhase, type CiSource } from "./declaration";
|
|
58
|
+
import { greenBranches, readDeclaration, readerVersion, WORKSPACE_ERROR_CODES, WorkspaceReadError, type CiGreen, type CiPhase, type CiSource } from "./declaration";
|
|
59
59
|
import type { CheckRun, CiForge, OpRunRef } from "./ci-green-forge";
|
|
60
60
|
import type { OpRunRecord } from "../op/runtime";
|
|
61
61
|
import { readRunLedger } from "../lifecycle/run-ledger";
|
|
@@ -514,8 +514,25 @@ export function readGreen(cwd: string): { green: CiGreen; top: string; workspace
|
|
|
514
514
|
return { green, top, workspace: { name: declaration.name, root: located.root, file: declaration.file } };
|
|
515
515
|
}
|
|
516
516
|
|
|
517
|
+
/**
|
|
518
|
+
* `green` judging `branch` (#4325): `ci.green` names several branches when
|
|
519
|
+
* `ci.branches` routes members to branches of their own, and each is judged
|
|
520
|
+
* as the single branch always was. Without `branch` the first is judged.
|
|
521
|
+
* Refuses a branch `ci.green` does not name.
|
|
522
|
+
*/
|
|
523
|
+
export function greenOn(green: CiGreen, branch: string | undefined): CiGreen {
|
|
524
|
+
const { branches: _all, ...rest } = green;
|
|
525
|
+
if (branch === undefined || branch === green.branch) return rest;
|
|
526
|
+
if (!greenBranches(green).includes(branch)) {
|
|
527
|
+
throw new CiGreenError("ci-branch-unknown", `ci.green judges ${greenBranches(green).join(", ")}, not ${branch}; add it to ci.green.branch to give it a green verdict`);
|
|
528
|
+
}
|
|
529
|
+
return { ...rest, branch };
|
|
530
|
+
}
|
|
531
|
+
|
|
517
532
|
export interface TickRequest {
|
|
518
533
|
cwd: string;
|
|
534
|
+
/** Judge this one branch of `ci.green.branch` (#4325). Without it a tick judges every branch the declaration names. */
|
|
535
|
+
branch?: string;
|
|
519
536
|
/**
|
|
520
537
|
* Where check runs come from. A function is called only when the source
|
|
521
538
|
* is `checks`, so a tick from runs needs no forge token. Required for
|
|
@@ -547,6 +564,8 @@ export interface ComposedBranchTick {
|
|
|
547
564
|
|
|
548
565
|
export interface TickResult {
|
|
549
566
|
branch: string;
|
|
567
|
+
/** The other branches `ci.green` names (#4325), each judged as this one is. Their tags are in `made`. Absent for a one-branch declaration. */
|
|
568
|
+
routed?: TickResult[];
|
|
550
569
|
window: string;
|
|
551
570
|
/** The ref the commits were read from. */
|
|
552
571
|
ref: string;
|
|
@@ -601,7 +620,16 @@ export function ciTagSigner(top: string, base: string, pem: string, what = "the
|
|
|
601
620
|
export async function ciTick(req: TickRequest): Promise<TickResult> {
|
|
602
621
|
const read = readGreen(req.cwd);
|
|
603
622
|
const top = read.top;
|
|
604
|
-
const
|
|
623
|
+
const names = greenBranches(read.green);
|
|
624
|
+
if (req.branch === undefined && names.length > 1) {
|
|
625
|
+
const first = await ciTick({ ...req, branch: names[0]! });
|
|
626
|
+
const routed: TickResult[] = [];
|
|
627
|
+
for (const b of names.slice(1)) routed.push(await ciTick({ ...req, branch: b }));
|
|
628
|
+
return { ...first, routed, made: [...first.made, ...routed.flatMap((r) => r.made)] };
|
|
629
|
+
}
|
|
630
|
+
const green: CiGreen = { ...greenOn(read.green, req.branch), source: req.source ?? read.green.source };
|
|
631
|
+
// Compose branches are walked from trunk, so only the first branch's tick walks them.
|
|
632
|
+
const walksCompose = green.branch === read.green.branch;
|
|
605
633
|
const forge = green.source === "checks" ? (typeof req.forge === "function" ? req.forge() : req.forge) : undefined;
|
|
606
634
|
if (green.source === "checks" && !forge) throw new Error("ci.green.source is checks, so the tick reads check runs and needs a forge");
|
|
607
635
|
const remote = req.remote ?? "origin";
|
|
@@ -671,7 +699,7 @@ export async function ciTick(req: TickRequest): Promise<TickResult> {
|
|
|
671
699
|
if (links) for (const c of planned) c.work = links.get(c.sha);
|
|
672
700
|
// Compose branches (#4168 4.3): each composed commit within the window is judged as trunk's are, and its tags name its branch.
|
|
673
701
|
const composed: ComposedBranchTick[] = [];
|
|
674
|
-
for (const b of remoteComposeBranches(top, remote)) {
|
|
702
|
+
for (const b of walksCompose ? remoteComposeBranches(top, remote) : []) {
|
|
675
703
|
const own = git(top, ["log", "--first-parent", `--max-age=${cutoff}`, "--format=%H %ct", b.ref, `^${tracking}`])
|
|
676
704
|
.split("\n")
|
|
677
705
|
.filter(Boolean)
|
|
@@ -904,18 +932,20 @@ export interface RequestBuildResult {
|
|
|
904
932
|
*/
|
|
905
933
|
export async function requestBuild(req: { cwd: string; at: string; remote?: string; forge?: CiForge; now?: Date }): Promise<RequestBuildResult> {
|
|
906
934
|
const read = readGreen(req.cwd);
|
|
907
|
-
const {
|
|
935
|
+
const { top } = read;
|
|
936
|
+
const green = greenOn(read.green, undefined);
|
|
937
|
+
const names = greenBranches(read.green);
|
|
908
938
|
const remote = req.remote ?? "origin";
|
|
909
|
-
const
|
|
939
|
+
const trackingOf = (b: string): string => `refs/remotes/${remote}/${b}`;
|
|
910
940
|
try {
|
|
911
|
-
git(top, ["fetch", "--quiet", "--no-tags", remote, `+refs/heads/${
|
|
941
|
+
git(top, ["fetch", "--quiet", "--no-tags", remote, ...names.map((b) => `+refs/heads/${b}:${trackingOf(b)}`), `+refs/tags/${CI_BUILD_TAG_PREFIX}*:refs/tags/${CI_BUILD_TAG_PREFIX}*`]);
|
|
912
942
|
} catch (err) {
|
|
913
|
-
throw new Error(`could not fetch ${
|
|
943
|
+
throw new Error(`could not fetch ${names.join(", ")} and the build requests from ${remote}: ${stderrOf(err)}`);
|
|
914
944
|
}
|
|
915
945
|
if (req.at.startsWith("-") || tryGit(top, ["rev-parse", "--verify", "--quiet", `${req.at}^{commit}`]) === null) throw new WorkspaceReadError("revision-unknown", `--at ${req.at} names no commit in this repository`);
|
|
916
946
|
const sha = git(top, ["rev-parse", `${req.at}^{commit}`]);
|
|
917
|
-
const onBranch =
|
|
918
|
-
if (!onBranch) throw new Error(`${sha.slice(0, 12)} is not a first-parent commit of ${remote}/${
|
|
947
|
+
const onBranch = names.some((b) => tryGit(top, ["rev-list", "--first-parent", trackingOf(b)])?.split("\n").includes(sha));
|
|
948
|
+
if (!onBranch) throw new Error(`${sha.slice(0, 12)} is not a first-parent commit of ${names.map((b) => `${remote}/${b}`).join(" or ")}, and only those are judged green`);
|
|
919
949
|
const existing = readBuildRequests(top).get(sha);
|
|
920
950
|
const request = existing ?? requestedBuild(green, sha, green.require, req.now ?? new Date());
|
|
921
951
|
const warnings: string[] = [];
|
|
@@ -1101,6 +1131,7 @@ export function whyWorkUnknown(work: CommitLink | null | undefined): string | un
|
|
|
1101
1131
|
|
|
1102
1132
|
/** The text `chant ci tick` prints. */
|
|
1103
1133
|
export function formatTick(r: TickResult, dryRun = false): string {
|
|
1134
|
+
if (r.routed) return [formatTick({ ...r, routed: undefined }, dryRun), ...r.routed.map((b) => formatTick(b, dryRun))].join("\n");
|
|
1104
1135
|
const lines = [`${r.branch}, commits within ${r.window}${r.source === "runs" ? ", judged from chant runs" : ""}: ${r.commits.length}`];
|
|
1105
1136
|
for (const c of r.commits) {
|
|
1106
1137
|
const short = c.sha.slice(0, 12);
|
|
@@ -1187,10 +1218,12 @@ export const LAST_GREEN_NEWER = 50;
|
|
|
1187
1218
|
* green tag and no revoked tag. It reads local refs and tags and never
|
|
1188
1219
|
* fetches, so a reader fetches first (`git fetch origin --tags`).
|
|
1189
1220
|
*/
|
|
1190
|
-
export function lastGreen(req: { cwd: string; remote?: string; from?: string }): LastGreenDocument {
|
|
1221
|
+
export function lastGreen(req: { cwd: string; remote?: string; from?: string; branch?: string }): LastGreenDocument {
|
|
1191
1222
|
const head = { $schema: CI_LAST_GREEN_SCHEMA_ID, contract: CI_LAST_GREEN_CONTRACT_VERSION, chant: readerVersion() };
|
|
1192
1223
|
try {
|
|
1193
|
-
const
|
|
1224
|
+
const read = readGreen(req.cwd);
|
|
1225
|
+
const { top, workspace } = read;
|
|
1226
|
+
const green = greenOn(read.green, req.branch);
|
|
1194
1227
|
const branchRef = branchRefOf(top, green, req.remote);
|
|
1195
1228
|
let ref = branchRef;
|
|
1196
1229
|
if (req.from !== undefined) {
|
|
@@ -1355,6 +1388,8 @@ function recordedPhase(green: CountedCiTag | undefined, phase: string): CiListPh
|
|
|
1355
1388
|
|
|
1356
1389
|
export interface ListRequest {
|
|
1357
1390
|
cwd: string;
|
|
1391
|
+
/** List this branch of `ci.green.branch` (#4325). The first when absent. */
|
|
1392
|
+
branch?: string;
|
|
1358
1393
|
remote?: string;
|
|
1359
1394
|
/** Keep only the newest n commits. */
|
|
1360
1395
|
limit?: number;
|
|
@@ -1380,7 +1415,9 @@ export interface ListRequest {
|
|
|
1380
1415
|
export async function ciList(req: ListRequest): Promise<CiListDocument> {
|
|
1381
1416
|
const head = { $schema: CI_LIST_SCHEMA_ID, contract: CI_LIST_CONTRACT_VERSION, chant: readerVersion() };
|
|
1382
1417
|
try {
|
|
1383
|
-
const
|
|
1418
|
+
const read = readGreen(req.cwd);
|
|
1419
|
+
const { top, workspace } = read;
|
|
1420
|
+
const green = greenOn(read.green, req.branch);
|
|
1384
1421
|
const ref = branchRefOf(top, green, req.remote);
|
|
1385
1422
|
|
|
1386
1423
|
const logArgs = ["log", "--first-parent", "--format=%H %ct"];
|
|
@@ -17,7 +17,7 @@ import { join } from "node:path";
|
|
|
17
17
|
import { afterAll, beforeAll, describe, expect, test } from "vitest";
|
|
18
18
|
import { cleanScratch, declaration, git, repoFixture, scratchDir, writeFiles } from "./__fixtures__/contract-repo";
|
|
19
19
|
import { checkRunEventLines } from "./__fixtures__/run-event-check";
|
|
20
|
-
import { ciJobCommand, ciJobEnv, ciJobFailure, ciJobOp, ciLoopOptions, ciRun, CiRunError, ciStatusContext, ciStatusFromEnv, ciStatusUrl, formatCiRun } from "./ci-run";
|
|
20
|
+
import { chantNodeModules, ciJobCommand, ciJobEnv, ciJobFailure, ciJobOp, ciLoopOptions, ciRun, CiRunError, ciStatusContext, ciStatusFromEnv, ciStatusUrl, formatCiRun } from "./ci-run";
|
|
21
21
|
import type { CommitStatus, ForgeStatus, PrForge } from "../pr-forge";
|
|
22
22
|
import { FORGE_TOKEN_VARS } from "../ci-handover";
|
|
23
23
|
import { ciList, ciTick, evaluateCommit, readOpRunSource, revokedAnnotation } from "./ci-green";
|
|
@@ -1040,6 +1040,77 @@ describe("the plan's steps hold no forge token (#4295)", () => {
|
|
|
1040
1040
|
});
|
|
1041
1041
|
});
|
|
1042
1042
|
|
|
1043
|
+
/** A scheduled watch Op's file, shaped as discovery reads one (entity.props = OpConfig), importing nothing. */
|
|
1044
|
+
const WATCH_OP = (name: string): string =>
|
|
1045
|
+
`export default { props: { name: ${JSON.stringify(name)}, overview: "t", schedule: { cron: "0 * * * *" }, labels: { Watch: "true" }, phases: [{ name: "Run", steps: [] }] } };\n`;
|
|
1046
|
+
|
|
1047
|
+
describe("chant ci run plan checks the scheduled Ops at --base for the note (#4328)", () => {
|
|
1048
|
+
/**
|
|
1049
|
+
* The base declares watch Op `drift`, with its generated workflow. The
|
|
1050
|
+
* change deletes it and adds `sneaky`. The note names the Op the base has,
|
|
1051
|
+
* since the check reads the Ops at --base, and never the change's own.
|
|
1052
|
+
*/
|
|
1053
|
+
function stale(): { app: string; base: string; sha: string } {
|
|
1054
|
+
const { root, app } = workspace();
|
|
1055
|
+
writeFiles(root, {
|
|
1056
|
+
"app/chant.config.json": "{}",
|
|
1057
|
+
"app/ops/drift.op.ts": WATCH_OP("drift"),
|
|
1058
|
+
".forgejo/workflows/app-drift.yml": "on: schedule\n",
|
|
1059
|
+
});
|
|
1060
|
+
const base = commitAt(root, 1, "app/b.txt");
|
|
1061
|
+
execFileSync("git", ["rm", "-q", "app/ops/drift.op.ts"], { cwd: root });
|
|
1062
|
+
writeFiles(root, { "app/ops/sneaky.op.ts": WATCH_OP("sneaky"), ".forgejo/workflows/app-sneaky.yml": "on: schedule\n" });
|
|
1063
|
+
const sha = commitAt(root, 0.5, "app/c.txt");
|
|
1064
|
+
return { app, base, sha };
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
function overdueForge(): { forge: PrForge; notes: string[]; asked: string[] } {
|
|
1068
|
+
const notes: string[] = [];
|
|
1069
|
+
const asked: string[] = [];
|
|
1070
|
+
const forge = {
|
|
1071
|
+
kind: "forgejo",
|
|
1072
|
+
host: "forgejo.localhost",
|
|
1073
|
+
async setStatus() {},
|
|
1074
|
+
async upsertNote(_pr: number, _marker: string, body: string) {
|
|
1075
|
+
notes.push(body);
|
|
1076
|
+
return "1";
|
|
1077
|
+
},
|
|
1078
|
+
// Every Op last ran a year ago: overdue whichever is asked about.
|
|
1079
|
+
async scheduledRuns(q: { op: string }) {
|
|
1080
|
+
asked.push(q.op);
|
|
1081
|
+
return { last: "2025-10-01T00:00:00Z" };
|
|
1082
|
+
},
|
|
1083
|
+
} as unknown as PrForge;
|
|
1084
|
+
return { forge, notes, asked };
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
test("on the runner, the note warns of the base's overdue Op and not of one the change added", async () => {
|
|
1088
|
+
const { app, base, sha } = stale();
|
|
1089
|
+
const forge = overdueForge();
|
|
1090
|
+
const r = await ciRun({ image: JOB_IMAGE, cwd: app, job: "plan", env: "prod", forge: "forgejo", base, pr: 7, chant: fakeChant(), hostEnv: { ...HOST, FAKE_REPORT: planReport(sha) }, passEnv: ["FAKE_REPORT"], planForge: forge.forge, push: false, output: join(scratchDir("chant-ci-overdue-"), "pr") });
|
|
1091
|
+
expect(r.status).toBe("ok");
|
|
1092
|
+
expect(forge.asked).toEqual(["drift"]);
|
|
1093
|
+
expect(forge.notes).toHaveLength(1);
|
|
1094
|
+
expect(forge.notes[0]).toContain("Op `drift` is overdue");
|
|
1095
|
+
expect(forge.notes[0]).not.toContain("sneaky");
|
|
1096
|
+
expect(r.warnings).toEqual([expect.stringMatching(/Op `drift` is overdue/)]);
|
|
1097
|
+
});
|
|
1098
|
+
|
|
1099
|
+
test("in place, the check still reads the base, not the checkout the change runs in", async () => {
|
|
1100
|
+
const { app, base, sha } = stale();
|
|
1101
|
+
const forge = overdueForge();
|
|
1102
|
+
const r = await ciRun({ cwd: app, job: "plan", env: "prod", forge: "forgejo", base, pr: 7, chant: fakeChant(), hostEnv: { ...HOST, GITHUB_JOB: "plan", FAKE_REPORT: planReport(sha) }, inPlace: true, push: false, planForge: forge.forge });
|
|
1103
|
+
expect(r.status).toBe("ok");
|
|
1104
|
+
expect(forge.asked).toEqual(["drift"]);
|
|
1105
|
+
expect(forge.notes[0]).toContain("Op `drift` is overdue");
|
|
1106
|
+
});
|
|
1107
|
+
|
|
1108
|
+
test("the base checkout resolves packages from the node_modules the running chant is installed in", () => {
|
|
1109
|
+
expect(chantNodeModules("/opt/ci/node_modules/@intentius/chant/dist/workspace/ci-run.js")).toBe("/opt/ci/node_modules");
|
|
1110
|
+
expect(chantNodeModules("/src/chant/packages/core/src/workspace/ci-run.ts")).toBeUndefined();
|
|
1111
|
+
});
|
|
1112
|
+
});
|
|
1113
|
+
|
|
1043
1114
|
/**
|
|
1044
1115
|
* #4330: a pull request environment's jobs run through `ci run` too. The
|
|
1045
1116
|
* stand-in chant keeps each action's arguments, environment, directory and
|
package/src/workspace/ci-run.ts
CHANGED
|
@@ -53,7 +53,9 @@
|
|
|
53
53
|
* report with its own token (`postPlanReport`, ../pr-post.ts). In place, a
|
|
54
54
|
* generated job holds no token and its `plan-note` job posts; a job that
|
|
55
55
|
* still holds one was generated before #4295, and the runner posts for it
|
|
56
|
-
* with a warning to regenerate.
|
|
56
|
+
* with a warning to regenerate. Either way the note's overdue check (#4289)
|
|
57
|
+
* reads the scheduled Ops from a fresh checkout of `--base`, as the
|
|
58
|
+
* plan-note job reads them at the target branch's commit (#4328).
|
|
57
59
|
*
|
|
58
60
|
* Signing is opt-in (#4156). With no runner key the record is unsigned, and
|
|
59
61
|
* a reader counts it with no signer. A key `.chant/trust.json` does not list
|
|
@@ -81,14 +83,16 @@
|
|
|
81
83
|
*/
|
|
82
84
|
|
|
83
85
|
import { execFileSync } from "node:child_process";
|
|
84
|
-
import { copyFileSync, cpSync, existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
|
86
|
+
import { copyFileSync, cpSync, existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, realpathSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
85
87
|
import { tmpdir } from "node:os";
|
|
86
|
-
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
88
|
+
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
89
|
+
import { fileURLToPath } from "node:url";
|
|
87
90
|
import { PR_APPLY_RECORD, PR_ENV_POST_JOB, PR_ENV_REPORT_DIR, PR_LOOP_REPORT_DIR, prEnvJobs, prLoopJobs, prLoopSetup, PR_LOOP_IMAGE, type PrEnvJob, type PrLoopJob, type PrLoopPipelineOptions } from "../components/pr-pipeline";
|
|
88
91
|
import { detectForge, ForgeEnvironmentError, forgeFromEnv, FORGE_KINDS, type CommitStatus, type ForgeKind, type PrForge } from "../pr-forge";
|
|
89
92
|
import { holdsForgeToken, withoutForgeTokens } from "../ci-handover";
|
|
90
93
|
import { postPlanReport } from "../pr-post";
|
|
91
|
-
import {
|
|
94
|
+
import { overdueOpsAt } from "../op/schedule-overdue";
|
|
95
|
+
import { PR_APPLY_GATE, type PrOverdue } from "../pr-loop";
|
|
92
96
|
import type { CommandContext } from "../cli/registry";
|
|
93
97
|
import { formatError, formatWarning } from "../cli/format";
|
|
94
98
|
import { CHANT_CI_RUN_FORGE_ENV, CHANT_CI_RUN_ID_ENV, FORGE_RUN_ENV, resolveCiJob, type RunOrigin } from "../lifecycle/release-ledger";
|
|
@@ -738,7 +742,9 @@ export async function ciRun(req: CiRunRequest): Promise<CiRunResult> {
|
|
|
738
742
|
// A generated wave job's command, as prLoopWaveJobs writes it. #4161: a local job's command posts no status or note.
|
|
739
743
|
const forgeCommand = req.noForge ? found.command.replace(` --forge ${req.forge}`, "") : found.command;
|
|
740
744
|
const noStatus = req.local && !/ --no-status(?: |$)/.test(forgeCommand);
|
|
741
|
-
|
|
745
|
+
// #4325: a record or apply on a routed branch is told the branch, as the forge's ref would tell it in a pipeline. `ci serve` has no such ref.
|
|
746
|
+
const branch = req.job !== "plan" && req.loop?.branch !== undefined && !/ --branch(?: |=)/.test(forgeCommand) ? ` --branch ${/^[A-Za-z0-9._\/=:@%+,-]+$/.test(req.loop.branch) ? req.loop.branch : `'${req.loop.branch.replace(/'/g, `'\\''`)}'`}` : "";
|
|
747
|
+
const command = `${forgeCommand}${branch}${req.wave !== undefined ? ` --wave ${req.wave}` : ""}${noStatus ? " --no-status" : ""}`;
|
|
742
748
|
const job = { ...found, command, ...(req.wave !== undefined ? { wave: req.wave } : {}) };
|
|
743
749
|
const own = ciJobEnv(job, {
|
|
744
750
|
forge: req.forge,
|
|
@@ -759,7 +765,7 @@ export async function ciRun(req: CiRunRequest): Promise<CiRunResult> {
|
|
|
759
765
|
const redact = ciRedactor(req.inPlace ? { ...longValues(jobEnv), ...own } : jobEnv, req.secrets);
|
|
760
766
|
try {
|
|
761
767
|
const ran = await runCiJob(req, { cwd, top, commit, place, job, jobEnv, ...(redact ? { redact } : {}) });
|
|
762
|
-
const posted = poster ? await postFromReport(req, poster, ran, { commit, ...(place.member ? { member: place.member } : {}) }) : [];
|
|
768
|
+
const posted = poster ? await postFromReport(req, poster, ran, { top, dir: place.dir, commit, ...(place.member ? { member: place.member } : {}) }) : [];
|
|
763
769
|
const envPost = req.job === "env-up" ? await envPostAfterUp(req, { cwd, top, head: commit, place, jobs, hostEnv, ran }) : undefined;
|
|
764
770
|
const withPost = envPost ? ("result" in envPost ? { ...ran, post: envPost.result } : { ...ran, warnings: [...ran.warnings, envPost.warning] }) : ran;
|
|
765
771
|
const withPosts = posted.length > 0 ? { ...withPost, warnings: [...withPost.warnings, ...posted] } : withPost;
|
|
@@ -831,10 +837,11 @@ async function postFromReport(
|
|
|
831
837
|
req: CiRunRequest,
|
|
832
838
|
poster: NonNullable<ReturnType<typeof planPoster>>,
|
|
833
839
|
ran: CiRunResult,
|
|
834
|
-
at: { commit: string; member?: string },
|
|
840
|
+
at: { top: string; dir: string; commit: string; member?: string },
|
|
835
841
|
): Promise<string[]> {
|
|
836
842
|
if ("error" in poster) return [poster.error];
|
|
837
843
|
const warnings = poster.warning ? [poster.warning] : [];
|
|
844
|
+
const checked: string[] = [];
|
|
838
845
|
const dir = ran.report ?? resolve(req.cwd, req.output ?? PR_LOOP_REPORT_DIR);
|
|
839
846
|
const posted = await postPlanReport({
|
|
840
847
|
forge: poster.forge,
|
|
@@ -844,9 +851,62 @@ async function postFromReport(
|
|
|
844
851
|
env: req.env,
|
|
845
852
|
...(at.member ? { member: at.member } : {}),
|
|
846
853
|
result: ran.status === "ok" ? "success" : "failure",
|
|
854
|
+
// #4328: as pr-post does (#4289), with the Ops read at --base, never from the change's checkout.
|
|
855
|
+
overdue: () => overdueAtBase(req, { forge: poster.forge, top: at.top, dir: at.dir, ...(at.member ? { member: at.member } : {}), log: (line) => checked.push(line) }),
|
|
847
856
|
});
|
|
848
857
|
if (posted.refused) warnings.push(`the plan report was not posted: ${posted.refused}`);
|
|
849
|
-
return [...warnings, ...posted.warnings];
|
|
858
|
+
return [...warnings, ...checked, ...posted.warnings];
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
/**
|
|
862
|
+
* The overdue check for the plan's note (#4289, #4328), at `--base`, as the
|
|
863
|
+
* plan-note job's `pr-post` runs it at the target branch's commit. The Ops
|
|
864
|
+
* are read from a fresh checkout of the base outside the repository, never
|
|
865
|
+
* from the checkout the change's code ran in, in place or not. That checkout
|
|
866
|
+
* resolves packages from the `node_modules` the running chant is installed
|
|
867
|
+
* in ({@link chantNodeModules}), so an Op file's `@intentius/chant` is the
|
|
868
|
+
* chant running the job, not one the change installed. Without `--base`
|
|
869
|
+
* nothing is checked, and `log` says so.
|
|
870
|
+
*/
|
|
871
|
+
async function overdueAtBase(
|
|
872
|
+
req: CiRunRequest,
|
|
873
|
+
at: { forge: PrForge; top: string; dir: string; member?: string; log: (line: string) => void },
|
|
874
|
+
): Promise<PrOverdue[]> {
|
|
875
|
+
if (!at.forge.scheduledRuns) return [];
|
|
876
|
+
if (!req.base) {
|
|
877
|
+
at.log("the scheduled Ops were not checked: the check reads them at the target branch's commit, so pass --base <sha>");
|
|
878
|
+
return [];
|
|
879
|
+
}
|
|
880
|
+
let checkout: { dir: string; remove(): void };
|
|
881
|
+
try {
|
|
882
|
+
checkout = freshCheckout(at.top, resolveJobCommit(at.top, req.base));
|
|
883
|
+
} catch (err) {
|
|
884
|
+
at.log(`the scheduled Ops were not checked: ${message(err)}`);
|
|
885
|
+
return [];
|
|
886
|
+
}
|
|
887
|
+
try {
|
|
888
|
+
const modules = chantNodeModules();
|
|
889
|
+
const link = join(checkout.dir, "node_modules");
|
|
890
|
+
if (modules && !existsSync(link)) symlinkSync(modules, link, "dir");
|
|
891
|
+
return await overdueOpsAt({ forge: at.forge, cwd: at.dir === "." ? checkout.dir : join(checkout.dir, at.dir), ...(at.member ? { member: at.member } : {}), log: at.log });
|
|
892
|
+
} finally {
|
|
893
|
+
checkout.remove();
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
/**
|
|
898
|
+
* The `node_modules` directory the running chant is installed in, or
|
|
899
|
+
* undefined when it runs from a source checkout, where chant's own packages
|
|
900
|
+
* resolve without one (../ts-loader.ts).
|
|
901
|
+
*/
|
|
902
|
+
export function chantNodeModules(from: string = fileURLToPath(import.meta.url)): string | undefined {
|
|
903
|
+
let dir = dirname(from);
|
|
904
|
+
for (;;) {
|
|
905
|
+
if (basename(dir) === "node_modules") return dir;
|
|
906
|
+
const parent = dirname(dir);
|
|
907
|
+
if (parent === dir) return undefined;
|
|
908
|
+
dir = parent;
|
|
909
|
+
}
|
|
850
910
|
}
|
|
851
911
|
|
|
852
912
|
/**
|
|
@@ -602,3 +602,98 @@ describe("ci serve runs fast-forwards only, and honours [skip ci] (#4122)", () =
|
|
|
602
602
|
expect(ofType(events, "not-run")).toHaveLength(1);
|
|
603
603
|
});
|
|
604
604
|
});
|
|
605
|
+
|
|
606
|
+
describe("ci serve follows ci.branches (#4325)", () => {
|
|
607
|
+
/** A forge with a head per branch, and the branches it was asked about. */
|
|
608
|
+
function branchForge(heads: Record<string, string>): CiServeForge & { heads: Record<string, string>; polled: string[] } {
|
|
609
|
+
const f = {
|
|
610
|
+
heads,
|
|
611
|
+
polled: [] as string[],
|
|
612
|
+
async pullRequestFor() {
|
|
613
|
+
return null;
|
|
614
|
+
},
|
|
615
|
+
async openPullRequests(base: string) {
|
|
616
|
+
f.polled.push(base);
|
|
617
|
+
return [];
|
|
618
|
+
},
|
|
619
|
+
async branchHead(branch: string) {
|
|
620
|
+
return f.heads[branch];
|
|
621
|
+
},
|
|
622
|
+
};
|
|
623
|
+
return f;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
/** The workspace with `ci.branches` routing `app` to `release`, and a `release` branch on the forge. */
|
|
627
|
+
function routed(globs: string[] = ["app"]): ReturnType<typeof workspace> & { release: string } {
|
|
628
|
+
const w = workspace();
|
|
629
|
+
writeFiles(w.root, { "chant.workspace.json": declaration([{ name: "app", dir: "app", kind: "other", because: "the app" }], { ci: { branches: { release: globs } } }) });
|
|
630
|
+
commit(w.root, "app/route.txt", "route app to release");
|
|
631
|
+
git(w.root, "push", "-q", "origin", "main");
|
|
632
|
+
git(w.root, "checkout", "-q", "-b", "release");
|
|
633
|
+
const release = commit(w.root, "app/rel.txt");
|
|
634
|
+
git(w.root, "push", "-q", "origin", "release");
|
|
635
|
+
git(w.root, "checkout", "-q", "main");
|
|
636
|
+
return { ...w, main: git(w.root, "rev-parse", "main"), release };
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
test("a routed member polls its route alone, and its record job gets --branch", async () => {
|
|
640
|
+
const { root, app, main, release } = routed();
|
|
641
|
+
const forge = branchForge({ main, release });
|
|
642
|
+
const { opts, events } = serve(app, forge);
|
|
643
|
+
await ciServePass(opts);
|
|
644
|
+
expect(forge.polled).toEqual(["release"]);
|
|
645
|
+
expect(ofType(events, "baseline")).toEqual([{ type: "baseline", commit: release }]);
|
|
646
|
+
|
|
647
|
+
git(root, "checkout", "-q", "release");
|
|
648
|
+
const next = commit(root, "app/rel2.txt");
|
|
649
|
+
git(root, "push", "-q", "origin", "release");
|
|
650
|
+
git(root, "checkout", "-q", "main");
|
|
651
|
+
forge.heads.release = next;
|
|
652
|
+
const pass = await ciServePass(opts);
|
|
653
|
+
expect(pass.jobs).toEqual([expect.objectContaining({ job: "record", commit: next, base: release, status: "ok" })]);
|
|
654
|
+
const argv = argsOf(pass.jobs[0]!.report!, "pr-record");
|
|
655
|
+
expect(argv[argv.indexOf("--branch") + 1]).toBe("release");
|
|
656
|
+
// A push to main is not this member's.
|
|
657
|
+
forge.heads.main = "0".repeat(40);
|
|
658
|
+
expect((await ciServePass(opts)).jobs).toEqual([]);
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
test("a member no glob matches polls main and passes no --branch", async () => {
|
|
662
|
+
const { root, app, main } = routed(["other-*"]);
|
|
663
|
+
const forge = branchForge({ main });
|
|
664
|
+
const { opts } = serve(app, forge);
|
|
665
|
+
await ciServePass(opts);
|
|
666
|
+
expect(forge.polled).toEqual(["main"]);
|
|
667
|
+
const merged = commit(root, "app/merged.txt");
|
|
668
|
+
git(root, "push", "-q", "origin", "main");
|
|
669
|
+
forge.heads.main = merged;
|
|
670
|
+
const pass = await ciServePass(opts);
|
|
671
|
+
expect(pass.jobs).toEqual([expect.objectContaining({ job: "record", commit: merged, base: main })]);
|
|
672
|
+
expect(argsOf(pass.jobs[0]!.report!, "pr-record")).not.toContain("--branch");
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
test("the workspace root polls main and each routed branch, each from its own head", async () => {
|
|
676
|
+
const { root, main, release } = routed();
|
|
677
|
+
const forge = branchForge({ main, release });
|
|
678
|
+
const { opts } = serve(root, forge);
|
|
679
|
+
await ciServePass(opts);
|
|
680
|
+
expect(forge.polled).toEqual(["main", "release"]);
|
|
681
|
+
git(root, "checkout", "-q", "release");
|
|
682
|
+
const next = commit(root, "app/rel2.txt");
|
|
683
|
+
git(root, "push", "-q", "origin", "release");
|
|
684
|
+
git(root, "checkout", "-q", "main");
|
|
685
|
+
forge.heads.release = next;
|
|
686
|
+
const pass = await ciServePass(opts);
|
|
687
|
+
expect(pass.jobs).toEqual([expect.objectContaining({ job: "record", commit: next, base: release })]);
|
|
688
|
+
const state = readCiServeState(join(opts.stateDir!, `${prApplyGroup("prod")}.json`), { forge: "forgejo", repo: "demo/estate", env: "prod", branch: "main" });
|
|
689
|
+
expect(state.target).toBe(main);
|
|
690
|
+
expect(state.targets).toEqual({ release: next });
|
|
691
|
+
expect((await ciServePass(opts)).jobs).toEqual([]);
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
test("a --branch that disagrees with the route is refused", async () => {
|
|
695
|
+
const { app, main, release } = routed();
|
|
696
|
+
const { opts } = serve(app, branchForge({ main, release }), { job: { loop: { branch: "main" } } });
|
|
697
|
+
await expect(ciServePass(opts)).rejects.toThrow(/routes member app to release/);
|
|
698
|
+
});
|
|
699
|
+
});
|