@intentius/chant 0.124.27 → 0.124.29
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/README.md +1 -1
- package/dist/__golden__/wave-loop/fan-out-gated.json +8 -0
- package/dist/__golden__/wave-loop/fan-out-no-members.json +4 -0
- package/dist/__golden__/wave-loop/fan-out-only.json +6 -0
- package/dist/__golden__/wave-loop/op-by-apply-hold.json +2 -0
- package/dist/__golden__/wave-loop/op-cost-member.json +3 -0
- package/dist/__golden__/wave-loop/op-held-on-before-apply.json +1 -0
- package/dist/__golden__/wave-loop/op-held-on.json +2 -0
- package/dist/__golden__/wave-loop/op-hooks-held.json +2 -0
- package/dist/__golden__/wave-loop/op-hooks-hold-before-apply.json +2 -0
- package/dist/__golden__/wave-loop/op-hooks-refused-at-base.json +3 -0
- package/dist/__golden__/wave-loop/op-hooks-share.json +3 -0
- package/dist/__golden__/wave-loop/op-per-run.json +7 -0
- package/dist/__golden__/wave-loop/op-pr-review.json +7 -0
- package/dist/__golden__/wave-loop/op-sealed.json +3 -0
- package/dist/__golden__/wave-loop/op-spend.json +3 -0
- package/dist/__golden__/wave-loop/op-wave-commands.json +7 -0
- package/dist/__golden__/wave-loop/op-wide-waiting.json +4 -0
- package/dist/build-params.d.ts +34 -1
- package/dist/build-params.d.ts.map +1 -1
- package/dist/build-params.js +31 -1
- package/dist/change-set-graph.d.ts +63 -0
- package/dist/change-set-graph.d.ts.map +1 -0
- package/dist/change-set-graph.js +130 -0
- package/dist/change-set.d.ts +62 -3
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +36 -4
- package/dist/chant-version.d.ts +9 -0
- package/dist/chant-version.d.ts.map +1 -0
- package/dist/chant-version.js +16 -0
- package/dist/cli/build-params-cli.d.ts +7 -1
- package/dist/cli/build-params-cli.d.ts.map +1 -1
- package/dist/cli/build-params-cli.js +17 -8
- package/dist/cli/commands/build.d.ts +8 -0
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +15 -11
- package/dist/cli/commands/check-lexicon-docs.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon-docs.js +30 -2
- package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon.js +13 -2
- package/dist/cli/commands/init-lexicon/templates/docs.d.ts +4 -1
- package/dist/cli/commands/init-lexicon/templates/docs.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon/templates/docs.js +6 -6
- package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon.js +17 -8
- package/dist/cli/handlers/approve.d.ts.map +1 -1
- package/dist/cli/handlers/approve.js +64 -4
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.js +43 -4
- package/dist/cli/handlers/change-set.d.ts +10 -0
- package/dist/cli/handlers/change-set.d.ts.map +1 -1
- package/dist/cli/handlers/change-set.js +51 -1
- package/dist/cli/handlers/fan-out.d.ts +10 -1
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.js +54 -6
- package/dist/cli/handlers/lifecycle-gc.d.ts +19 -0
- package/dist/cli/handlers/lifecycle-gc.d.ts.map +1 -0
- package/dist/cli/handlers/lifecycle-gc.js +143 -0
- package/dist/cli/handlers/pr.d.ts +16 -2
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +269 -37
- package/dist/cli/handlers/promote.d.ts +7 -0
- package/dist/cli/handlers/promote.d.ts.map +1 -1
- package/dist/cli/handlers/promote.js +440 -28
- package/dist/cli/handlers/release.d.ts +91 -0
- package/dist/cli/handlers/release.d.ts.map +1 -0
- package/dist/cli/handlers/release.js +589 -0
- package/dist/cli/handlers/run.d.ts +38 -2
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/handlers/run.js +234 -16
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +143 -17
- package/dist/cli/mcp/workspace-tools.js +1 -1
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +73 -5
- package/dist/cli/registry.d.ts +43 -5
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/cli/run-events.d.ts +30 -0
- package/dist/cli/run-events.d.ts.map +1 -0
- package/dist/cli/run-events.js +49 -0
- package/dist/cli/version.d.ts +3 -5
- package/dist/cli/version.d.ts.map +1 -1
- package/dist/cli/version.js +3 -13
- package/dist/codegen/docs-in-site.d.ts +71 -0
- package/dist/codegen/docs-in-site.d.ts.map +1 -0
- package/dist/codegen/docs-in-site.js +177 -0
- package/dist/codegen/docs-types.d.ts +14 -1
- package/dist/codegen/docs-types.d.ts.map +1 -1
- package/dist/codegen/docs.d.ts +18 -1
- package/dist/codegen/docs.d.ts.map +1 -1
- package/dist/codegen/docs.js +40 -7
- package/dist/codegen/rehype-base-url.mjs +15 -9
- package/dist/components/auto-release.d.ts +6 -1
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/auto-release.js +3 -0
- package/dist/components/capability.d.ts +9 -0
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/cli-support.d.ts +6 -0
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/cli-support.js +10 -9
- package/dist/components/driver.d.ts +50 -9
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/driver.js +116 -54
- package/dist/components/fan-out-inputs.d.ts +69 -0
- package/dist/components/fan-out-inputs.d.ts.map +1 -0
- package/dist/components/fan-out-inputs.js +169 -0
- package/dist/components/fan-out-record.d.ts +13 -0
- package/dist/components/fan-out-record.d.ts.map +1 -1
- package/dist/components/fan-out-record.js +16 -0
- package/dist/components/fan-out-run.d.ts +7 -0
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-run.js +85 -26
- package/dist/components/fan-out.d.ts +4 -0
- package/dist/components/fan-out.d.ts.map +1 -1
- package/dist/components/pr-pipeline.d.ts +25 -0
- package/dist/components/pr-pipeline.d.ts.map +1 -1
- package/dist/components/pr-pipeline.js +22 -4
- package/dist/components/pr-run.d.ts +11 -0
- package/dist/components/pr-run.d.ts.map +1 -1
- package/dist/components/pr-run.js +20 -1
- package/dist/components/promote-order.d.ts +38 -0
- package/dist/components/promote-order.d.ts.map +1 -0
- package/dist/components/promote-order.js +62 -0
- package/dist/components/promote.d.ts +38 -2
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/promote.js +77 -2
- package/dist/components/release-compile.d.ts +142 -0
- package/dist/components/release-compile.d.ts.map +1 -0
- package/dist/components/release-compile.js +382 -0
- package/dist/components/release-gate.d.ts +135 -0
- package/dist/components/release-gate.d.ts.map +1 -0
- package/dist/components/release-gate.js +288 -0
- package/dist/components/release-promote.d.ts +96 -0
- package/dist/components/release-promote.d.ts.map +1 -0
- package/dist/components/release-promote.js +204 -0
- package/dist/components/run-progress.d.ts +7 -0
- package/dist/components/run-progress.d.ts.map +1 -1
- package/dist/components/wave-plan.d.ts +8 -1
- package/dist/components/wave-plan.d.ts.map +1 -1
- package/dist/components/wave-plan.js +11 -3
- package/dist/config.d.ts +45 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -0
- package/dist/flag-params.d.ts +54 -0
- package/dist/flag-params.d.ts.map +1 -0
- package/dist/flag-params.js +130 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/lifecycle/__fixtures__/publish-fakes.d.ts +120 -0
- package/dist/lifecycle/__fixtures__/publish-fakes.d.ts.map +1 -0
- package/dist/lifecycle/__fixtures__/publish-fakes.js +304 -0
- package/dist/lifecycle/change-set-store.d.ts +68 -0
- package/dist/lifecycle/change-set-store.d.ts.map +1 -0
- package/dist/lifecycle/change-set-store.js +97 -0
- package/dist/lifecycle/commit-sha.d.ts +13 -0
- package/dist/lifecycle/commit-sha.d.ts.map +1 -0
- package/dist/lifecycle/commit-sha.js +21 -0
- package/dist/lifecycle/delivery-metrics.d.ts +139 -0
- package/dist/lifecycle/delivery-metrics.d.ts.map +1 -0
- package/dist/lifecycle/delivery-metrics.js +145 -0
- package/dist/lifecycle/deploy-outcome.d.ts +81 -0
- package/dist/lifecycle/deploy-outcome.d.ts.map +1 -0
- package/dist/lifecycle/deploy-outcome.js +101 -0
- package/dist/lifecycle/gate-change-set.d.ts +78 -0
- package/dist/lifecycle/gate-change-set.d.ts.map +1 -0
- package/dist/lifecycle/gate-change-set.js +138 -0
- package/dist/lifecycle/gate-ledger.d.ts +51 -4
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.js +18 -0
- package/dist/lifecycle/git.d.ts +30 -1
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/git.js +31 -5
- package/dist/lifecycle/index.d.ts +4 -0
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/index.js +4 -0
- package/dist/lifecycle/mixed-environment.d.ts +95 -0
- package/dist/lifecycle/mixed-environment.d.ts.map +1 -0
- package/dist/lifecycle/mixed-environment.js +154 -0
- package/dist/lifecycle/publish-attachments.d.ts +79 -0
- package/dist/lifecycle/publish-attachments.d.ts.map +1 -0
- package/dist/lifecycle/publish-attachments.js +179 -0
- package/dist/lifecycle/publish-credentials.d.ts +37 -0
- package/dist/lifecycle/publish-credentials.d.ts.map +1 -0
- package/dist/lifecycle/publish-credentials.js +69 -0
- package/dist/lifecycle/publish-declaration.d.ts +97 -0
- package/dist/lifecycle/publish-declaration.d.ts.map +1 -0
- package/dist/lifecycle/publish-declaration.js +83 -0
- package/dist/lifecycle/publish-forge.d.ts +53 -0
- package/dist/lifecycle/publish-forge.d.ts.map +1 -0
- package/dist/lifecycle/publish-forge.js +298 -0
- package/dist/lifecycle/publish-npm.d.ts +61 -0
- package/dist/lifecycle/publish-npm.d.ts.map +1 -0
- package/dist/lifecycle/publish-npm.js +242 -0
- package/dist/lifecycle/publish-oci.d.ts +64 -0
- package/dist/lifecycle/publish-oci.d.ts.map +1 -0
- package/dist/lifecycle/publish-oci.js +383 -0
- package/dist/lifecycle/publish-record.d.ts +66 -0
- package/dist/lifecycle/publish-record.d.ts.map +1 -0
- package/dist/lifecycle/publish-record.js +84 -0
- package/dist/lifecycle/publish-targets.d.ts +45 -0
- package/dist/lifecycle/publish-targets.d.ts.map +1 -0
- package/dist/lifecycle/publish-targets.js +85 -0
- package/dist/lifecycle/release-cut.d.ts +154 -0
- package/dist/lifecycle/release-cut.d.ts.map +1 -0
- package/dist/lifecycle/release-cut.js +366 -0
- package/dist/lifecycle/release-join.d.ts +95 -0
- package/dist/lifecycle/release-join.d.ts.map +1 -0
- package/dist/lifecycle/release-join.js +139 -0
- package/dist/lifecycle/release-ledger.d.ts +54 -0
- package/dist/lifecycle/release-ledger.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.js +53 -20
- package/dist/lifecycle/release-publish.d.ts +312 -0
- package/dist/lifecycle/release-publish.d.ts.map +1 -0
- package/dist/lifecycle/release-publish.js +335 -0
- package/dist/lifecycle/release-revocation.d.ts +80 -0
- package/dist/lifecycle/release-revocation.d.ts.map +1 -0
- package/dist/lifecycle/release-revocation.js +123 -0
- package/dist/lifecycle/release-store.d.ts +200 -0
- package/dist/lifecycle/release-store.d.ts.map +1 -0
- package/dist/lifecycle/release-store.js +320 -0
- package/dist/lifecycle/release-verify.d.ts +61 -0
- package/dist/lifecycle/release-verify.d.ts.map +1 -0
- package/dist/lifecycle/release-verify.js +92 -0
- package/dist/lifecycle/release-workstation.d.ts +91 -0
- package/dist/lifecycle/release-workstation.d.ts.map +1 -0
- package/dist/lifecycle/release-workstation.js +180 -0
- package/dist/lifecycle/retention-policy.d.ts +45 -0
- package/dist/lifecycle/retention-policy.d.ts.map +1 -0
- package/dist/lifecycle/retention-policy.js +43 -0
- package/dist/lifecycle/retention.d.ts +185 -0
- package/dist/lifecycle/retention.d.ts.map +1 -0
- package/dist/lifecycle/retention.js +400 -0
- package/dist/lifecycle/run-ledger.d.ts +4 -0
- package/dist/lifecycle/run-ledger.d.ts.map +1 -1
- package/dist/lifecycle/run-ledger.js +2 -0
- package/dist/op/activities/change-coverage.d.ts.map +1 -1
- package/dist/op/activities/change-coverage.js +4 -2
- package/dist/op/activities/source-release.d.ts.map +1 -1
- package/dist/op/activities/source-release.js +7 -3
- package/dist/op/activities/source-rollback.d.ts.map +1 -1
- package/dist/op/activities/source-rollback.js +7 -3
- package/dist/op/gate-name.d.ts +11 -2
- package/dist/op/gate-name.d.ts.map +1 -1
- package/dist/op/gate-name.js +12 -3
- package/dist/op/gate-run-locator.d.ts +22 -0
- package/dist/op/gate-run-locator.d.ts.map +1 -1
- package/dist/op/gate-run-locator.js +31 -0
- package/dist/op/gate.d.ts +27 -3
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/gate.js +57 -3
- package/dist/op/local-executor.d.ts +36 -1
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-executor.js +158 -52
- package/dist/op/op-waves-run.d.ts.map +1 -1
- package/dist/op/op-waves-run.js +4 -0
- package/dist/op/run-live.d.ts +2 -0
- package/dist/op/run-live.d.ts.map +1 -1
- package/dist/op/run-live.js +1 -1
- package/dist/op/runtime.d.ts +46 -0
- package/dist/op/runtime.d.ts.map +1 -1
- package/dist/op/runtimes/local.d.ts.map +1 -1
- package/dist/op/runtimes/local.js +8 -0
- package/dist/plan-summary.d.ts.map +1 -1
- package/dist/plan-summary.js +8 -2
- package/dist/point-decision.d.ts +2 -0
- package/dist/point-decision.d.ts.map +1 -1
- package/dist/point-decision.js +9 -2
- package/dist/pr-loop.d.ts +7 -0
- package/dist/pr-loop.d.ts.map +1 -1
- package/dist/pr-loop.js +23 -4
- package/dist/pr-report-url.d.ts +82 -0
- package/dist/pr-report-url.d.ts.map +1 -0
- package/dist/pr-report-url.js +174 -0
- package/dist/provenance.d.ts +2 -2
- package/dist/provenance.d.ts.map +1 -1
- package/dist/run-event-store.d.ts +104 -0
- package/dist/run-event-store.d.ts.map +1 -0
- package/dist/run-event-store.js +251 -0
- package/dist/run-event-stream.d.ts +133 -0
- package/dist/run-event-stream.d.ts.map +1 -0
- package/dist/run-event-stream.js +242 -0
- package/dist/run-event.d.ts +285 -0
- package/dist/run-event.d.ts.map +1 -0
- package/dist/run-event.js +209 -0
- package/dist/wave-runtime.mjs +262 -226
- package/dist/workspace/__fixtures__/flag-workspace.d.ts +31 -0
- package/dist/workspace/__fixtures__/flag-workspace.d.ts.map +1 -0
- package/dist/workspace/__fixtures__/flag-workspace.js +114 -0
- package/dist/workspace/__fixtures__/run-event-check.d.ts +19 -0
- package/dist/workspace/__fixtures__/run-event-check.d.ts.map +1 -0
- package/dist/workspace/__fixtures__/run-event-check.js +59 -0
- package/dist/workspace/change-set-show.d.ts +56 -0
- package/dist/workspace/change-set-show.d.ts.map +1 -0
- package/dist/workspace/change-set-show.js +54 -0
- package/dist/workspace/change-set-show.schema.json +102 -0
- package/dist/workspace/change-set.schema.json +32 -1
- package/dist/workspace/changes-cli.d.ts.map +1 -1
- package/dist/workspace/changes-cli.js +10 -1
- package/dist/workspace/changes.d.ts +37 -0
- package/dist/workspace/changes.d.ts.map +1 -1
- package/dist/workspace/changes.js +49 -2
- package/dist/workspace/changes.schema.json +135 -0
- package/dist/workspace/check.schema.json +4 -2
- package/dist/workspace/checks/records.d.ts +9 -1
- package/dist/workspace/checks/records.d.ts.map +1 -1
- package/dist/workspace/checks/records.js +35 -1
- package/dist/workspace/checks.d.ts +1 -0
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/checks.js +2 -1
- package/dist/workspace/ci-green-cli.d.ts +19 -4
- package/dist/workspace/ci-green-cli.d.ts.map +1 -1
- package/dist/workspace/ci-green-cli.js +75 -12
- package/dist/workspace/ci-green-forge.d.ts +20 -3
- package/dist/workspace/ci-green-forge.d.ts.map +1 -1
- package/dist/workspace/ci-green-forge.js +6 -4
- package/dist/workspace/ci-green-workflow.d.ts +11 -0
- package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
- package/dist/workspace/ci-green-workflow.js +6 -0
- package/dist/workspace/ci-green.d.ts +281 -13
- package/dist/workspace/ci-green.d.ts.map +1 -1
- package/dist/workspace/ci-green.js +456 -38
- package/dist/workspace/ci-last-green.schema.json +32 -2
- package/dist/workspace/ci-list.schema.json +525 -0
- package/dist/workspace/commit-links.d.ts +85 -0
- package/dist/workspace/commit-links.d.ts.map +1 -0
- package/dist/workspace/commit-links.js +163 -0
- package/dist/workspace/declaration.d.ts +35 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.js +27 -1
- package/dist/workspace/declaration.schema.json +76 -0
- package/dist/workspace/declared-kinds.d.ts +16 -0
- package/dist/workspace/declared-kinds.d.ts.map +1 -1
- package/dist/workspace/declared-kinds.js +25 -0
- package/dist/workspace/delivery-metrics.d.ts +91 -0
- package/dist/workspace/delivery-metrics.d.ts.map +1 -0
- package/dist/workspace/delivery-metrics.js +217 -0
- package/dist/workspace/delivery-metrics.schema.json +519 -0
- package/dist/workspace/flags-read.d.ts +37 -0
- package/dist/workspace/flags-read.d.ts.map +1 -0
- package/dist/workspace/flags-read.js +103 -0
- package/dist/workspace/flags.d.ts +100 -0
- package/dist/workspace/flags.d.ts.map +1 -0
- package/dist/workspace/flags.js +98 -0
- package/dist/workspace/graph-cli.js +1 -1
- package/dist/workspace/identity-gate-rule.d.ts +37 -0
- package/dist/workspace/identity-gate-rule.d.ts.map +1 -1
- package/dist/workspace/identity-gate-rule.js +72 -7
- package/dist/workspace/identity.d.ts +12 -0
- package/dist/workspace/identity.d.ts.map +1 -1
- package/dist/workspace/identity.js +13 -1
- package/dist/workspace/intent-cli.d.ts +11 -2
- package/dist/workspace/intent-cli.d.ts.map +1 -1
- package/dist/workspace/intent-cli.js +54 -5
- package/dist/workspace/intent-trace.d.ts +219 -0
- package/dist/workspace/intent-trace.d.ts.map +1 -0
- package/dist/workspace/intent-trace.js +314 -0
- package/dist/workspace/intent.d.ts +36 -7
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/intent.js +192 -22
- package/dist/workspace/intent.schema.json +702 -6
- package/dist/workspace/ls.d.ts +4 -0
- package/dist/workspace/ls.d.ts.map +1 -1
- package/dist/workspace/ls.js +2 -0
- package/dist/workspace/ls.schema.json +3 -1
- package/dist/workspace/member-pipeline.d.ts +6 -0
- package/dist/workspace/member-pipeline.d.ts.map +1 -1
- package/dist/workspace/member-pipeline.js +6 -0
- package/dist/workspace/overlap.d.ts +146 -0
- package/dist/workspace/overlap.d.ts.map +1 -0
- package/dist/workspace/overlap.js +276 -0
- package/dist/workspace/promotion-order.d.ts +41 -0
- package/dist/workspace/promotion-order.d.ts.map +1 -0
- package/dist/workspace/promotion-order.js +95 -0
- package/dist/workspace/reason-codes.d.ts +4 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +7 -1
- package/dist/workspace/records.d.ts +15 -2
- package/dist/workspace/records.d.ts.map +1 -1
- package/dist/workspace/records.js +32 -0
- package/dist/workspace/records.schema.json +21 -2
- package/dist/workspace/reference-kinds/flag/flag.kind.mjs +32 -0
- package/dist/workspace/reference-kinds/flag/flag.schema.json +53 -0
- package/dist/workspace/releases.d.ts +81 -0
- package/dist/workspace/releases.d.ts.map +1 -0
- package/dist/workspace/releases.js +103 -0
- package/dist/workspace/releases.schema.json +513 -0
- package/dist/workspace/run-event.schema.json +295 -0
- package/dist/workspace/status-gates.d.ts +34 -1
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status-gates.js +31 -2
- package/dist/workspace/status-stewards.d.ts +4 -0
- package/dist/workspace/status-stewards.d.ts.map +1 -1
- package/dist/workspace/status-stewards.js +2 -0
- package/dist/workspace/status.d.ts +117 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/status.js +218 -4
- package/dist/workspace/status.schema.json +268 -2
- package/dist/workspace/trust/ci-tag-statement.d.ts +102 -0
- package/dist/workspace/trust/ci-tag-statement.d.ts.map +1 -0
- package/dist/workspace/trust/ci-tag-statement.js +123 -0
- package/dist/workspace/trust/op-run-statement.d.ts +91 -0
- package/dist/workspace/trust/op-run-statement.d.ts.map +1 -0
- package/dist/workspace/trust/op-run-statement.js +143 -0
- package/dist/workspace/trust/rotation.d.ts +18 -2
- package/dist/workspace/trust/rotation.d.ts.map +1 -1
- package/dist/workspace/trust/rotation.js +65 -16
- package/dist/workspace/trust/seal.d.ts +11 -0
- package/dist/workspace/trust/seal.d.ts.map +1 -1
- package/dist/workspace/trust/seal.js +9 -0
- package/dist/workspace/trust/ssh-commit.d.ts.map +1 -1
- package/dist/workspace/trust/ssh-commit.js +10 -10
- package/dist/workspace/wip.d.ts.map +1 -1
- package/dist/workspace/wip.js +11 -3
- package/package.json +1 -1
- package/src/__golden__/wave-loop/fan-out-gated.json +8 -0
- package/src/__golden__/wave-loop/fan-out-no-members.json +4 -0
- package/src/__golden__/wave-loop/fan-out-only.json +6 -0
- package/src/__golden__/wave-loop/op-by-apply-hold.json +2 -0
- package/src/__golden__/wave-loop/op-cost-member.json +3 -0
- package/src/__golden__/wave-loop/op-held-on-before-apply.json +1 -0
- package/src/__golden__/wave-loop/op-held-on.json +2 -0
- package/src/__golden__/wave-loop/op-hooks-held.json +2 -0
- package/src/__golden__/wave-loop/op-hooks-hold-before-apply.json +2 -0
- package/src/__golden__/wave-loop/op-hooks-refused-at-base.json +3 -0
- package/src/__golden__/wave-loop/op-hooks-share.json +3 -0
- package/src/__golden__/wave-loop/op-per-run.json +7 -0
- package/src/__golden__/wave-loop/op-pr-review.json +7 -0
- package/src/__golden__/wave-loop/op-sealed.json +3 -0
- package/src/__golden__/wave-loop/op-spend.json +3 -0
- package/src/__golden__/wave-loop/op-wave-commands.json +7 -0
- package/src/__golden__/wave-loop/op-wide-waiting.json +4 -0
- package/src/build-params.test.ts +46 -0
- package/src/build-params.ts +55 -1
- package/src/change-set-graph.test.ts +72 -0
- package/src/change-set-graph.ts +141 -0
- package/src/change-set.ts +87 -6
- package/src/chant-version.ts +16 -0
- package/src/cli/build-params-cli.ts +22 -9
- package/src/cli/commands/build.ts +25 -11
- package/src/cli/commands/check-lexicon-docs.test.ts +51 -0
- package/src/cli/commands/check-lexicon-docs.ts +39 -2
- package/src/cli/commands/check-lexicon.ts +14 -2
- package/src/cli/commands/init-lexicon/templates/docs.ts +7 -6
- package/src/cli/commands/init-lexicon.test.ts +25 -0
- package/src/cli/commands/init-lexicon.ts +18 -8
- package/src/cli/handlers/approve-release.test.ts +84 -0
- package/src/cli/handlers/approve-revoked.test.ts +155 -0
- package/src/cli/handlers/approve.ts +65 -2
- package/src/cli/handlers/build.test.ts +67 -0
- package/src/cli/handlers/build.ts +46 -4
- package/src/cli/handlers/change-set.ts +49 -1
- package/src/cli/handlers/fan-out.test.ts +228 -1
- package/src/cli/handlers/fan-out.ts +53 -6
- package/src/cli/handlers/intent-trace.e2e.test.ts +201 -0
- package/src/cli/handlers/lifecycle-gc.test.ts +126 -0
- package/src/cli/handlers/lifecycle-gc.ts +146 -0
- package/src/cli/handlers/operator.test.ts +37 -0
- package/src/cli/handlers/pr.test.ts +341 -0
- package/src/cli/handlers/pr.ts +292 -47
- package/src/cli/handlers/promote.test.ts +669 -7
- package/src/cli/handlers/promote.ts +464 -29
- package/src/cli/handlers/release-implicit.e2e.test.ts +161 -0
- package/src/cli/handlers/release-join.e2e.test.ts +185 -0
- package/src/cli/handlers/release-publish-targets.e2e.test.ts +295 -0
- package/src/cli/handlers/release-verify.e2e.test.ts +117 -0
- package/src/cli/handlers/release-workstation-ci.e2e.test.ts +135 -0
- package/src/cli/handlers/release.e2e.test.ts +199 -0
- package/src/cli/handlers/release.ts +593 -0
- package/src/cli/handlers/run-auto-release.test.ts +80 -0
- package/src/cli/handlers/run-events-cmd.test.ts +92 -0
- package/src/cli/handlers/run-release.test.ts +55 -0
- package/src/cli/handlers/run.test.ts +30 -0
- package/src/cli/handlers/run.ts +243 -18
- package/src/cli/main.test.ts +8 -0
- package/src/cli/main.ts +143 -17
- package/src/cli/mcp/never-over-mcp.test.ts +2 -0
- package/src/cli/mcp/workspace-tools.ts +1 -1
- package/src/cli/parse-args.ts +56 -5
- package/src/cli/registry.ts +43 -5
- package/src/cli/run-events.ts +57 -0
- package/src/cli/version.ts +3 -13
- package/src/codegen/docs-in-site.test.ts +166 -0
- package/src/codegen/docs-in-site.ts +182 -0
- package/src/codegen/docs-site/AgentPrompt.astro +26 -1
- package/src/codegen/docs-types.ts +14 -1
- package/src/codegen/docs.ts +60 -7
- package/src/codegen/rehype-base-url.d.mts +3 -1
- package/src/codegen/rehype-base-url.mjs +15 -9
- package/src/codegen/rehype-base-url.test.ts +34 -0
- package/src/components/auto-release.test.ts +30 -0
- package/src/components/auto-release.ts +9 -1
- package/src/components/capability.ts +9 -0
- package/src/components/cli-support.test.ts +82 -0
- package/src/components/cli-support.ts +16 -9
- package/src/components/driver.test.ts +24 -0
- package/src/components/driver.ts +165 -56
- package/src/components/fan-out-inputs.test.ts +85 -0
- package/src/components/fan-out-inputs.ts +192 -0
- package/src/components/fan-out-record.test.ts +10 -0
- package/src/components/fan-out-record.ts +19 -0
- package/src/components/fan-out-run.ts +104 -35
- package/src/components/fan-out.ts +4 -0
- package/src/components/pr-pipeline.ts +35 -4
- package/src/components/pr-run.ts +30 -1
- package/src/components/promote-order.test.ts +90 -0
- package/src/components/promote-order.ts +75 -0
- package/src/components/promote.test.ts +10 -1
- package/src/components/promote.ts +94 -3
- package/src/components/release-compile.test.ts +147 -0
- package/src/components/release-compile.ts +459 -0
- package/src/components/release-gate.test.ts +215 -0
- package/src/components/release-gate.ts +355 -0
- package/src/components/release-promote.test.ts +159 -0
- package/src/components/release-promote.ts +232 -0
- package/src/components/run-progress.ts +7 -0
- package/src/components/wave-plan.ts +16 -3
- package/src/config.ts +15 -1
- package/src/flag-params.test.ts +144 -0
- package/src/flag-params.ts +134 -0
- package/src/index.ts +2 -0
- package/src/lifecycle/__fixtures__/publish-fakes.ts +351 -0
- package/src/lifecycle/change-set-store.test.ts +217 -0
- package/src/lifecycle/change-set-store.ts +113 -0
- package/src/lifecycle/commit-sha.ts +23 -0
- package/src/lifecycle/delivery-metrics.ts +263 -0
- package/src/lifecycle/deploy-outcome.ts +147 -0
- package/src/lifecycle/gate-change-set.e2e.test.ts +122 -0
- package/src/lifecycle/gate-change-set.ts +164 -0
- package/src/lifecycle/gate-ledger.test.ts +33 -0
- package/src/lifecycle/gate-ledger.ts +68 -3
- package/src/lifecycle/git.ts +61 -8
- package/src/lifecycle/index.ts +4 -0
- package/src/lifecycle/mixed-environment.test.ts +97 -0
- package/src/lifecycle/mixed-environment.ts +204 -0
- package/src/lifecycle/publish-attachments.ts +196 -0
- package/src/lifecycle/publish-credentials.ts +84 -0
- package/src/lifecycle/publish-declaration.ts +95 -0
- package/src/lifecycle/publish-forge.ts +325 -0
- package/src/lifecycle/publish-npm.ts +259 -0
- package/src/lifecycle/publish-oci.ts +396 -0
- package/src/lifecycle/publish-record.ts +113 -0
- package/src/lifecycle/publish-resume.test.ts +168 -0
- package/src/lifecycle/publish-targets.test.ts +494 -0
- package/src/lifecycle/publish-targets.ts +100 -0
- package/src/lifecycle/release-cut-signed.test.ts +180 -0
- package/src/lifecycle/release-cut.test.ts +483 -0
- package/src/lifecycle/release-cut.ts +503 -0
- package/src/lifecycle/release-flag.test.ts +112 -0
- package/src/lifecycle/release-join.test.ts +68 -0
- package/src/lifecycle/release-join.ts +182 -0
- package/src/lifecycle/release-ledger.test.ts +14 -0
- package/src/lifecycle/release-ledger.ts +85 -17
- package/src/lifecycle/release-publish.test.ts +225 -0
- package/src/lifecycle/release-publish.ts +568 -0
- package/src/lifecycle/release-revocation.ts +147 -0
- package/src/lifecycle/release-store.ts +434 -0
- package/src/lifecycle/release-verify.test.ts +110 -0
- package/src/lifecycle/release-verify.ts +120 -0
- package/src/lifecycle/release-workstation.test.ts +204 -0
- package/src/lifecycle/release-workstation.ts +216 -0
- package/src/lifecycle/retention-growth.e2e.test.ts +279 -0
- package/src/lifecycle/retention-policy.ts +63 -0
- package/src/lifecycle/retention.test.ts +363 -0
- package/src/lifecycle/retention.ts +508 -0
- package/src/lifecycle/run-ledger.test.ts +10 -0
- package/src/lifecycle/run-ledger.ts +6 -0
- package/src/op/activities/change-coverage.ts +4 -1
- package/src/op/activities/source-release.ts +8 -3
- package/src/op/activities/source-rollback.ts +8 -4
- package/src/op/commit-run-gate-deploy-join.test.ts +117 -0
- package/src/op/gate-name.ts +13 -3
- package/src/op/gate-release.test.ts +126 -0
- package/src/op/gate-run-locator.test.ts +110 -0
- package/src/op/gate-run-locator.ts +35 -0
- package/src/op/gate.ts +88 -6
- package/src/op/local-executor.ts +207 -52
- package/src/op/op-waves-run.ts +4 -0
- package/src/op/run-events.test.ts +166 -0
- package/src/op/run-live.ts +1 -1
- package/src/op/runtime.ts +39 -0
- package/src/op/runtimes/local.test.ts +16 -0
- package/src/op/runtimes/local.ts +9 -0
- package/src/plan-summary.test.ts +20 -0
- package/src/plan-summary.ts +8 -1
- package/src/point-decision.ts +12 -2
- package/src/pr-loop.ts +25 -4
- package/src/pr-report-url.test.ts +131 -0
- package/src/pr-report-url.ts +209 -0
- package/src/provenance.ts +2 -2
- package/src/run-event-store.test.ts +144 -0
- package/src/run-event-store.ts +273 -0
- package/src/run-event-stream.test.ts +175 -0
- package/src/run-event-stream.ts +309 -0
- package/src/run-event.test.ts +277 -0
- package/src/run-event.ts +471 -0
- package/src/wave-loop-golden.test.ts +9 -0
- package/src/workspace/__fixtures__/flag-workspace.ts +132 -0
- package/src/workspace/__fixtures__/older-records/change-set-984534ea9.json +100 -0
- package/src/workspace/__fixtures__/older-records/older-records.json +326 -0
- package/src/workspace/__fixtures__/run-event-check.ts +58 -0
- package/src/workspace/ancestry-index.test.ts +93 -0
- package/src/workspace/change-set-show.schema.json +102 -0
- package/src/workspace/change-set-show.ts +72 -0
- package/src/workspace/change-set.schema.json +32 -1
- package/src/workspace/changes-cli.ts +10 -1
- package/src/workspace/changes.schema.json +135 -0
- package/src/workspace/changes.test.ts +1 -1
- package/src/workspace/changes.ts +84 -2
- package/src/workspace/check.schema.json +4 -2
- package/src/workspace/checks/records.ts +35 -1
- package/src/workspace/checks.ts +2 -1
- package/src/workspace/ci-green-cli.ts +75 -13
- package/src/workspace/ci-green-forge.ts +24 -4
- package/src/workspace/ci-green-runs.test.ts +242 -0
- package/src/workspace/ci-green-signed.test.ts +302 -0
- package/src/workspace/ci-green-workflow.test.ts +16 -0
- package/src/workspace/ci-green-workflow.ts +12 -0
- package/src/workspace/ci-green.test.ts +131 -2
- package/src/workspace/ci-green.ts +635 -42
- package/src/workspace/ci-last-green.schema.json +32 -2
- package/src/workspace/ci-list.schema.json +525 -0
- package/src/workspace/commit-links.test.ts +279 -0
- package/src/workspace/commit-links.ts +183 -0
- package/src/workspace/declaration.schema.json +76 -0
- package/src/workspace/declaration.test.ts +28 -0
- package/src/workspace/declaration.ts +60 -2
- package/src/workspace/declared-kinds.ts +40 -1
- package/src/workspace/delivery-metrics.schema.json +519 -0
- package/src/workspace/delivery-metrics.test.ts +236 -0
- package/src/workspace/delivery-metrics.ts +286 -0
- package/src/workspace/flags-read.ts +121 -0
- package/src/workspace/flags.test.ts +141 -0
- package/src/workspace/flags.ts +157 -0
- package/src/workspace/graph-cli.ts +1 -1
- package/src/workspace/identity-gate-rule.ts +91 -7
- package/src/workspace/identity.ts +14 -1
- package/src/workspace/intent-cli.ts +46 -5
- package/src/workspace/intent-trace.test.ts +173 -0
- package/src/workspace/intent-trace.ts +484 -0
- package/src/workspace/intent.schema.json +702 -6
- package/src/workspace/intent.ts +196 -26
- package/src/workspace/ls.schema.json +3 -1
- package/src/workspace/ls.ts +6 -0
- package/src/workspace/member-pipeline.test.ts +17 -0
- package/src/workspace/member-pipeline.ts +9 -0
- package/src/workspace/older-records.test.ts +412 -0
- package/src/workspace/overlap.test.ts +165 -0
- package/src/workspace/overlap.ts +340 -0
- package/src/workspace/promotion-order.ts +97 -0
- package/src/workspace/read-contract.e2e.test.ts +5 -1
- package/src/workspace/reason-codes.test.ts +7 -1
- package/src/workspace/reason-codes.ts +7 -1
- package/src/workspace/record-assets.test.ts +2 -1
- package/src/workspace/records-contract.e2e.test.ts +2 -1
- package/src/workspace/records.schema.json +21 -2
- package/src/workspace/records.ts +36 -2
- package/src/workspace/reference-kinds/flag/flag.kind.mjs +32 -0
- package/src/workspace/reference-kinds/flag/flag.schema.json +53 -0
- package/src/workspace/releases.schema.json +513 -0
- package/src/workspace/releases.test.ts +108 -0
- package/src/workspace/releases.ts +133 -0
- package/src/workspace/run-event.schema.json +295 -0
- package/src/workspace/status-contract.test.ts +81 -1
- package/src/workspace/status-gates.ts +64 -1
- package/src/workspace/status-mixed.test.ts +152 -0
- package/src/workspace/status-revoked.test.ts +153 -0
- package/src/workspace/status-stewards.ts +6 -0
- package/src/workspace/status.schema.json +268 -2
- package/src/workspace/status.ts +334 -4
- package/src/workspace/trust/ci-tag-statement.ts +151 -0
- package/src/workspace/trust/op-run-statement.ts +148 -0
- package/src/workspace/trust/rotation.ts +61 -14
- package/src/workspace/trust/seal.ts +10 -0
- package/src/workspace/trust/ssh-commit.ts +10 -9
- package/src/workspace/wip.ts +11 -2
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/astro.config.mjs +0 -14
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/package.json +0 -16
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/src/content/docs/index.mdx +0 -8
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/src/content.config.ts +0 -15
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/tsconfig.json +0 -10
|
@@ -25,6 +25,14 @@ import type { GateResolutionRecord, PendingGateRecord } from "../lifecycle/gate-
|
|
|
25
25
|
import { isPendingGateExpired, latestPendingGate, latestResolutionForPlan, parseGateLedger } from "../lifecycle/gate-ledger";
|
|
26
26
|
import { humanQuorumSince, tallyGateApprovals, type GateApprovalRule } from "../op/gate";
|
|
27
27
|
import type { ReasonCode } from "./reason-codes";
|
|
28
|
+
import type { ReleaseRevocation } from "../lifecycle/release-revocation";
|
|
29
|
+
import { CHANGE_SETS_DIR, changeSetFile } from "../lifecycle/change-set-store";
|
|
30
|
+
|
|
31
|
+
/** The stored change-set directory beside a gate ledger directory: `<prefix>_change-sets`. */
|
|
32
|
+
function changeSetDirFor(gatesDir: string): string {
|
|
33
|
+
const at = gatesDir.lastIndexOf("/");
|
|
34
|
+
return at < 0 ? CHANGE_SETS_DIR : `${gatesDir.slice(0, at)}/${CHANGE_SETS_DIR}`;
|
|
35
|
+
}
|
|
28
36
|
|
|
29
37
|
/** Why a member's gates can't be listed. Closed: a new code is a contract change. */
|
|
30
38
|
export const GATE_REASON_CODES = [
|
|
@@ -58,9 +66,34 @@ export interface StatusGate {
|
|
|
58
66
|
env: string | null;
|
|
59
67
|
/** The plan the run reached the gate with, or null for a gate that binds no plan. */
|
|
60
68
|
planDigest: string | null;
|
|
69
|
+
/**
|
|
70
|
+
* The release the gate binds (#4045), from the pending fact: on a release
|
|
71
|
+
* gate, the one `chant components promote --release` passes, recorded
|
|
72
|
+
* under the op `release`. Absent on every other gate and on a fact written
|
|
73
|
+
* before chant 0.124.28.
|
|
74
|
+
*/
|
|
75
|
+
releaseDigest?: string;
|
|
61
76
|
state: GateState;
|
|
77
|
+
/**
|
|
78
|
+
* Set on a release gate whose release was cut from a revoked commit
|
|
79
|
+
* (#4033, ws-105): the revoked tag on that commit. The gate is then
|
|
80
|
+
* `superseded` (or `expired`), and `chant approve` refuses it with
|
|
81
|
+
* `release-revoked`. Added by `workspace status`; absent otherwise.
|
|
82
|
+
*/
|
|
83
|
+
revoked?: ReleaseRevocation;
|
|
62
84
|
/** When the run recorded the pending fact the state is read against. */
|
|
63
85
|
recordedAt: string;
|
|
86
|
+
/** The commit the run reached the gate at (#4020), from the pending fact. Absent on a fact written before chant 0.124.28. */
|
|
87
|
+
gitSha?: string;
|
|
88
|
+
/** The run that reached the gate (#4020), from the pending fact: an Op run id, or the CI run id. Absent when the run had none. */
|
|
89
|
+
runId?: string;
|
|
90
|
+
/**
|
|
91
|
+
* The change set the gate binds (#4022): `planDigest`, when a change-set
|
|
92
|
+
* document is stored under it in the member's `_change-sets/`, read with
|
|
93
|
+
* `chant change-set show <digest>`. Absent when none is stored, as for a
|
|
94
|
+
* component gate, which binds a lifecycle-plan digest.
|
|
95
|
+
*/
|
|
96
|
+
changeSet?: string;
|
|
64
97
|
expiresAt: string;
|
|
65
98
|
/** The approvals that count toward the gate for this plan, oldest first. */
|
|
66
99
|
approvals: StatusGateApproval[];
|
|
@@ -113,6 +146,21 @@ function git(cwd: string, args: string[]): string {
|
|
|
113
146
|
return execFileSync("git", args, { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"], maxBuffer: 64 * 1024 * 1024 });
|
|
114
147
|
}
|
|
115
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Lists the file names in a stored change-set directory on the branch at
|
|
151
|
+
* `commit`, or an empty set when it doesn't exist or can't be read: a gate
|
|
152
|
+
* then shows no link, and its state is read the same.
|
|
153
|
+
*/
|
|
154
|
+
export type ChangeSetLister = (dir: string, commit: string, cwd: string) => Promise<Set<string>>;
|
|
155
|
+
|
|
156
|
+
export const defaultChangeSetLister: ChangeSetLister = async (dir, commit, cwd) => {
|
|
157
|
+
try {
|
|
158
|
+
return new Set(git(cwd, ["ls-tree", "--name-only", `${commit}:${dir}`]).split("\n").filter(Boolean));
|
|
159
|
+
} catch {
|
|
160
|
+
return new Set();
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
116
164
|
export const defaultGateLedgerReader: GateLedgerReader = async (dir, commit, cwd) => {
|
|
117
165
|
try {
|
|
118
166
|
git(cwd, ["rev-parse", "--verify", "--quiet", `${commit}:${dir}`]);
|
|
@@ -143,7 +191,10 @@ const approvalOf = (r: GateResolutionRecord): StatusGateApproval => ({ principal
|
|
|
143
191
|
function decide(component: string, standing: PendingGateRecord, facts: PendingGateRecord[], all: GateResolutionRecord[], now: string, rule: GateApprovalRule | null): StatusGate {
|
|
144
192
|
const gate = standing.gate;
|
|
145
193
|
// #3163: under identity.gates, an unsigned approval, or one from outside the class, doesn't count, as a run reads it.
|
|
146
|
-
|
|
194
|
+
// #4045: nor does an approval for another release, and an `empty` pass is never an approval.
|
|
195
|
+
const resolutions = all
|
|
196
|
+
.filter((r) => r.gate !== gate || (r.empty !== true && r.releaseDigest === standing.releaseDigest))
|
|
197
|
+
.filter((r) => rule === null || r.gate !== gate || rule.refuses(r) === null);
|
|
147
198
|
const env = standing.environment ?? null;
|
|
148
199
|
const since = standing.timestamp;
|
|
149
200
|
const planDigest = standing.planDigest;
|
|
@@ -177,8 +228,11 @@ function decide(component: string, standing: PendingGateRecord, facts: PendingGa
|
|
|
177
228
|
name: gate,
|
|
178
229
|
env,
|
|
179
230
|
planDigest: planDigest ?? null,
|
|
231
|
+
...(standing.releaseDigest !== undefined ? { releaseDigest: standing.releaseDigest } : {}),
|
|
180
232
|
state,
|
|
181
233
|
recordedAt: standing.timestamp,
|
|
234
|
+
...(standing.gitSha ? { gitSha: standing.gitSha } : {}),
|
|
235
|
+
...(standing.runId ? { runId: standing.runId } : {}),
|
|
182
236
|
expiresAt: standing.expiresAt,
|
|
183
237
|
approvals: approvals.map(approvalOf),
|
|
184
238
|
needed,
|
|
@@ -226,6 +280,7 @@ export async function readMemberGates(
|
|
|
226
280
|
now: string,
|
|
227
281
|
read: GateLedgerReader = defaultGateLedgerReader,
|
|
228
282
|
rules: GateRuleLookup = () => null,
|
|
283
|
+
listChangeSets: ChangeSetLister = defaultChangeSetLister,
|
|
229
284
|
): Promise<{ gates: StatusGate[]; ledger: StatusGateLedger }> {
|
|
230
285
|
const ledger: StatusGateLedger = { layout, path: dir, shared: false, malformed: 0, reason: null };
|
|
231
286
|
if (commit === null) {
|
|
@@ -247,5 +302,13 @@ export async function readMemberGates(
|
|
|
247
302
|
gates.push(...read.gates);
|
|
248
303
|
ledger.malformed += read.malformed;
|
|
249
304
|
}
|
|
305
|
+
// #4022: link each gate to the change set stored under its plan digest,
|
|
306
|
+
// in the same member's `_change-sets/` beside `_gates/`.
|
|
307
|
+
if (gates.some((g) => g.planDigest !== null)) {
|
|
308
|
+
const stored = await listChangeSets(changeSetDirFor(dir), commit, cwd);
|
|
309
|
+
for (const g of gates) {
|
|
310
|
+
if (g.planDigest !== null && stored.has(changeSetFile(g.planDigest))) g.changeSet = g.planDigest;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
250
313
|
return { gates, ledger };
|
|
251
314
|
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #4035: an environment a promote left mixed, as `workspace status --json`
|
|
3
|
+
* shows it: what each component runs, and the redeploy and rollback lines
|
|
4
|
+
* that settle it. Against temp repos; nothing is pushed.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, expect, test } from "vitest";
|
|
8
|
+
import { withTestDir } from "@intentius/chant-test-utils";
|
|
9
|
+
import { spawnSync } from "node:child_process";
|
|
10
|
+
import { writeFileSync } from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { Ajv2020 } from "ajv/dist/2020";
|
|
13
|
+
import statusSchema from "./status.schema.json";
|
|
14
|
+
import { formatStatus, workspaceStatus, type StatusDocument } from "./status";
|
|
15
|
+
import { appendCut, makeRelease, persistRelease, type Release } from "../lifecycle/release-store";
|
|
16
|
+
import { appendReleaseRecord, type ReleaseRecordInput } from "../lifecycle/release-ledger";
|
|
17
|
+
import { appendDeployOutcome } from "../lifecycle/deploy-outcome";
|
|
18
|
+
import { contentDigest } from "../content-digest";
|
|
19
|
+
|
|
20
|
+
const validateStatus = new Ajv2020({ strict: true, allErrors: true }).compile(statusSchema);
|
|
21
|
+
const NOW = "2026-10-17T14:00:00.000Z";
|
|
22
|
+
|
|
23
|
+
function git(cwd: string, ...args: string[]): string {
|
|
24
|
+
const r = spawnSync("git", args, { cwd, encoding: "utf-8" });
|
|
25
|
+
if (r.status !== 0) throw new Error(`git ${args.join(" ")}: ${r.stderr}`);
|
|
26
|
+
return r.stdout.trim();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function result(doc: StatusDocument): Extract<StatusDocument, { members: unknown }> {
|
|
30
|
+
if ("error" in doc) throw new Error(`${doc.error.code}: ${doc.error.message}`);
|
|
31
|
+
expect(validateStatus(doc), JSON.stringify(validateStatus.errors, null, 2)).toBe(true);
|
|
32
|
+
return doc;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** A workspace whose root member has releases v1.0.0 and v1.1.0 of api and web, and runs v1.0.0 in prod. */
|
|
36
|
+
async function setup(dir: string): Promise<{ v1: Release; v2: Release; deploy: (input: Partial<ReleaseRecordInput> & { component: string; timestamp: string; releaseDigest: string }) => Promise<void> }> {
|
|
37
|
+
git(dir, "init", "-q", "-b", "main");
|
|
38
|
+
git(dir, "config", "user.email", "t@chant.dev");
|
|
39
|
+
git(dir, "config", "user.name", "T");
|
|
40
|
+
writeFileSync(
|
|
41
|
+
join(dir, "chant.workspace.json"),
|
|
42
|
+
JSON.stringify({ name: "acme", schema: 1, members: [{ name: "root", dir: ".", kind: "other", because: "the fixture" }] }, null, 2),
|
|
43
|
+
);
|
|
44
|
+
git(dir, "add", ".");
|
|
45
|
+
git(dir, "commit", "-q", "-m", "init");
|
|
46
|
+
const first = git(dir, "rev-parse", "HEAD");
|
|
47
|
+
git(dir, "commit", "-q", "--allow-empty", "-m", "next");
|
|
48
|
+
const second = git(dir, "rev-parse", "HEAD");
|
|
49
|
+
const at = (commit: string) =>
|
|
50
|
+
makeRelease({
|
|
51
|
+
member: null,
|
|
52
|
+
commit,
|
|
53
|
+
artifactDigests: ["api", "web"].map((component) => ({ component, kind: "image" as const, path: `${component}.tar`, digest: contentDigest(`${component} ${commit}`) })),
|
|
54
|
+
targets: [{ env: "prod", templates: [], params: [] }],
|
|
55
|
+
});
|
|
56
|
+
const v1 = at(first);
|
|
57
|
+
const v2 = at(second);
|
|
58
|
+
for (const [r, label, ts] of [[v1, "v1.0.0", "10"], [v2, "v1.1.0", "11"]] as const) {
|
|
59
|
+
await persistRelease(r, [], { cwd: dir });
|
|
60
|
+
await appendCut({ releaseDigest: r.releaseDigest, label, actor: "alice", timestamp: `2026-10-17T${ts}:00:00.000Z`, runOrigin: null }, { cwd: dir });
|
|
61
|
+
}
|
|
62
|
+
const deploy = async (input: Partial<ReleaseRecordInput> & { component: string; timestamp: string; releaseDigest: string }) => {
|
|
63
|
+
await appendReleaseRecord(
|
|
64
|
+
{ env: "prod", digest: contentDigest(`${input.component} ${input.releaseDigest}`), gitSha: first, runId: "r", actor: "ci", ...input },
|
|
65
|
+
{ cwd: dir },
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
for (const component of ["api", "web"]) await deploy({ component, timestamp: "2026-10-17T12:00:00.000Z", releaseDigest: v1.releaseDigest });
|
|
69
|
+
return { v1, v2, deploy };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
describe("a mixed environment in workspace status (#4035)", () => {
|
|
73
|
+
test("a partly applied promote shows the environment mixed, with the redeploy and rollback lines, until it is settled", async () => {
|
|
74
|
+
await withTestDir(async (dir) => {
|
|
75
|
+
const { v1, v2, deploy } = await setup(dir);
|
|
76
|
+
|
|
77
|
+
// Before the promote: one release, nothing mixed.
|
|
78
|
+
const before = result(await workspaceStatus({ cwd: dir, env: "prod", now: NOW }));
|
|
79
|
+
expect(before.members[0].environments[0]).not.toHaveProperty("mixed");
|
|
80
|
+
|
|
81
|
+
// The promote of v1.1.0 deploys api and fails on web.
|
|
82
|
+
const at = "2026-10-17T13:00:00.000Z";
|
|
83
|
+
await deploy({ component: "api", timestamp: at, releaseDigest: v2.releaseDigest, runId: "run-9", promotedFrom: { env: "staging", runId: "run-8", timestamp: "2026-10-17T12:30:00.000Z" } });
|
|
84
|
+
await appendDeployOutcome(
|
|
85
|
+
{
|
|
86
|
+
version: 1, env: "prod", verb: "promote", runId: "run-9", timestamp: at, actor: "bob", releaseDigest: v2.releaseDigest, status: "fail",
|
|
87
|
+
components: [
|
|
88
|
+
{ component: "api", outcome: "deployed", digest: contentDigest(`api ${v2.releaseDigest}`), releaseDigest: v2.releaseDigest },
|
|
89
|
+
{ component: "web", outcome: "failed", digest: contentDigest(`web ${v2.releaseDigest}`), releaseDigest: v2.releaseDigest },
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
{ cwd: dir },
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const doc = result(await workspaceStatus({ cwd: dir, env: "prod", now: NOW }));
|
|
96
|
+
const prod = doc.members[0].environments[0];
|
|
97
|
+
expect(prod.mixed).toEqual({
|
|
98
|
+
components: [
|
|
99
|
+
{ component: "api", digest: contentDigest(`api ${v2.releaseDigest}`), releaseDigest: v2.releaseDigest, releaseLabel: "v1.1.0", state: "settled", attempt: null },
|
|
100
|
+
{
|
|
101
|
+
component: "web",
|
|
102
|
+
digest: contentDigest(`web ${v1.releaseDigest}`),
|
|
103
|
+
releaseDigest: v1.releaseDigest,
|
|
104
|
+
releaseLabel: "v1.0.0",
|
|
105
|
+
state: "failed",
|
|
106
|
+
attempt: { verb: "promote", runId: "run-9", timestamp: at, digest: contentDigest(`web ${v2.releaseDigest}`), releaseDigest: v2.releaseDigest, releaseLabel: "v1.1.0" },
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
redeploy: ["chant components redeploy prod --component web"],
|
|
110
|
+
rollback: "chant components rollback prod --release v1.0.0",
|
|
111
|
+
});
|
|
112
|
+
expect(formatStatus(doc)).toContain(" prod is mixed: api runs release v1.1.0; web failed (promote run-9), recorded release v1.0.0");
|
|
113
|
+
expect(formatStatus(doc)).toContain(" redeploy: chant components redeploy prod --component web");
|
|
114
|
+
expect(formatStatus(doc)).toContain(" roll back: chant components rollback prod --release v1.0.0");
|
|
115
|
+
|
|
116
|
+
// A redeploy of web settles it, but prod still runs two releases.
|
|
117
|
+
await deploy({ component: "web", timestamp: "2026-10-17T13:10:00.000Z", releaseDigest: v1.releaseDigest, redeploys: { env: "prod", runId: "r", timestamp: "2026-10-17T12:00:00.000Z" } });
|
|
118
|
+
const redeployed = result(await workspaceStatus({ cwd: dir, env: "prod", now: NOW })).members[0].environments[0];
|
|
119
|
+
expect(redeployed.mixed).toMatchObject({
|
|
120
|
+
components: [{ component: "api", state: "settled", releaseLabel: "v1.1.0" }, { component: "web", state: "settled", releaseLabel: "v1.0.0" }],
|
|
121
|
+
redeploy: [],
|
|
122
|
+
rollback: "chant components rollback prod --release v1.0.0",
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// The same promote run again puts web on v1.1.0: one release, nothing mixed.
|
|
126
|
+
await deploy({ component: "web", timestamp: "2026-10-17T13:20:00.000Z", releaseDigest: v2.releaseDigest });
|
|
127
|
+
const settled = result(await workspaceStatus({ cwd: dir, env: "prod", now: NOW })).members[0].environments[0];
|
|
128
|
+
expect(settled).not.toHaveProperty("mixed");
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test("a revoked release's rollback line names the release the environment ran before it", async () => {
|
|
133
|
+
await withTestDir(async (dir) => {
|
|
134
|
+
const { v2, deploy } = await setup(dir);
|
|
135
|
+
for (const component of ["api", "web"]) await deploy({ component, timestamp: "2026-10-17T13:00:00.000Z", releaseDigest: v2.releaseDigest });
|
|
136
|
+
writeFileSync(
|
|
137
|
+
join(dir, "chant.workspace.json"),
|
|
138
|
+
JSON.stringify({ name: "acme", schema: 1, members: [{ name: "root", dir: ".", kind: "other", because: "the fixture" }], ci: { green: { branch: "main", phases: { test: ["test"] }, require: ["test"] } } }, null, 2),
|
|
139
|
+
);
|
|
140
|
+
git(dir, "commit", "-q", "-am", "ci.green");
|
|
141
|
+
const record = { schema: 1, tag: "revoked", commit: v2.commit, branch: "main", at: "2026-10-17T13:30:00.000Z", phase: "test", run: { name: "test", id: 77, conclusion: "failure", url: null } };
|
|
142
|
+
git(dir, "tag", "-a", "-m", `ci: phase test failed\n\n${JSON.stringify(record, null, 2)}\n`, `ci/revoked/${v2.commit}`, v2.commit);
|
|
143
|
+
|
|
144
|
+
const prod = result(await workspaceStatus({ cwd: dir, env: "prod", now: NOW })).members[0].environments[0];
|
|
145
|
+
expect(prod.releases.map((r) => [r.component, r.revoked?.rollback])).toEqual([
|
|
146
|
+
["api", "chant components rollback prod --release v1.0.0"],
|
|
147
|
+
["web", "chant components rollback prod --release v1.0.0"],
|
|
148
|
+
]);
|
|
149
|
+
expect(prod).not.toHaveProperty("mixed");
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
});
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #4033 (ws-105): a release cut from a revoked commit, read at read time from
|
|
3
|
+
* the `ci/revoked/<sha>` tag. `workspace status` flags an environment that
|
|
4
|
+
* runs it, with the rollback line, and reads its pending gate as superseded;
|
|
5
|
+
* `release list` marks it. Against temp repos; nothing is pushed.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { afterEach, describe, expect, test, vi } from "vitest";
|
|
9
|
+
import { withTestDir } from "@intentius/chant-test-utils";
|
|
10
|
+
import { spawnSync } from "node:child_process";
|
|
11
|
+
import { writeFileSync } from "node:fs";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
import { Ajv2020 } from "ajv/dist/2020";
|
|
14
|
+
import statusSchema from "./status.schema.json";
|
|
15
|
+
import releasesSchema from "./releases.schema.json";
|
|
16
|
+
import { formatStatus, workspaceStatus, type StatusDocument } from "./status";
|
|
17
|
+
import { releasesDocument } from "./releases";
|
|
18
|
+
import { contract } from "./__fixtures__/contract-repo";
|
|
19
|
+
import { appendCut, makeRelease, persistRelease, type Release } from "../lifecycle/release-store";
|
|
20
|
+
import { appendReleaseRecord } from "../lifecycle/release-ledger";
|
|
21
|
+
import { appendPendingGate } from "../lifecycle/gate-ledger";
|
|
22
|
+
import type { CommandContext } from "../cli/registry";
|
|
23
|
+
import { contentDigest } from "../content-digest";
|
|
24
|
+
|
|
25
|
+
const validateStatus = new Ajv2020({ strict: true, allErrors: true }).compile(statusSchema);
|
|
26
|
+
const { expectValid: expectValidReleases } = contract(releasesSchema);
|
|
27
|
+
|
|
28
|
+
function git(cwd: string, ...args: string[]): string {
|
|
29
|
+
const r = spawnSync("git", args, { cwd, encoding: "utf-8" });
|
|
30
|
+
if (r.status !== 0) throw new Error(`git ${args.join(" ")}: ${r.stderr}`);
|
|
31
|
+
return r.stdout.trim();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const DOC = `jcs1-sha256:${"d".repeat(64)}`;
|
|
35
|
+
const NOW = "2026-10-16T14:00:00.000Z";
|
|
36
|
+
|
|
37
|
+
/** A workspace whose root member runs release v1.0.0 in prod and waits at its staging gate, and a second release v1.1.0 from a later commit. */
|
|
38
|
+
async function setup(dir: string): Promise<{ old: string; release: Release; next: Release }> {
|
|
39
|
+
git(dir, "init", "-q", "-b", "main");
|
|
40
|
+
git(dir, "config", "user.email", "t@chant.dev");
|
|
41
|
+
git(dir, "config", "user.name", "T");
|
|
42
|
+
writeFileSync(
|
|
43
|
+
join(dir, "chant.workspace.json"),
|
|
44
|
+
JSON.stringify({ name: "acme", schema: 1, members: [{ name: "root", dir: ".", kind: "other", because: "the fixture" }], ci: { green: { branch: "main", phases: { test: ["test"] }, require: ["test"] } } }, null, 2),
|
|
45
|
+
);
|
|
46
|
+
git(dir, "add", ".");
|
|
47
|
+
git(dir, "commit", "-q", "-m", "init");
|
|
48
|
+
const old = git(dir, "rev-parse", "HEAD");
|
|
49
|
+
git(dir, "commit", "-q", "--allow-empty", "-m", "next");
|
|
50
|
+
const later = git(dir, "rev-parse", "HEAD");
|
|
51
|
+
const at = (commit: string) =>
|
|
52
|
+
makeRelease({ member: null, commit, artifactDigests: [], targets: ["staging", "prod"].map((env) => ({ env, templates: [{ component: "api", path: "t.json", digest: `sha256:${"c".repeat(64)}` }], params: [] })) });
|
|
53
|
+
const release = at(old);
|
|
54
|
+
const next = at(later);
|
|
55
|
+
for (const [r, label, ts] of [[release, "v1.0.0", "10"], [next, "v1.1.0", "11"]] as const) {
|
|
56
|
+
await persistRelease(r, [], { cwd: dir });
|
|
57
|
+
await appendCut({ releaseDigest: r.releaseDigest, label, actor: "alice", timestamp: `2026-10-16T${ts}:00:00.000Z`, runOrigin: null }, { cwd: dir });
|
|
58
|
+
}
|
|
59
|
+
const deploy = { component: "api", digest: contentDigest("api image"), runId: "r", actor: "ci" };
|
|
60
|
+
await appendReleaseRecord({ ...deploy, env: "prod", gitSha: old, timestamp: "2026-10-16T12:00:00.000Z", releaseDigest: release.releaseDigest }, { cwd: dir });
|
|
61
|
+
await appendReleaseRecord({ ...deploy, env: "staging", gitSha: later, timestamp: "2026-10-16T12:00:00.000Z", releaseDigest: next.releaseDigest }, { cwd: dir });
|
|
62
|
+
for (const [r, env] of [[release, "staging"], [next, "prod"]] as const) {
|
|
63
|
+
await appendPendingGate(
|
|
64
|
+
{ op: "release", gate: `${env}-release`, timestamp: "2026-10-16T13:00:00.000Z", expiresAt: "2999-01-01T00:00:00.000Z", planDigest: DOC, environment: env, releaseDigest: r.releaseDigest },
|
|
65
|
+
{ cwd: dir },
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
return { old, release, next };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function revoke(dir: string, sha: string): void {
|
|
72
|
+
const record = { schema: 1, tag: "revoked", commit: sha, branch: "main", at: "2026-10-16T12:30:00.000Z", phase: "test", run: { name: "test", id: 77, conclusion: "failure", url: "https://example.test/runs/77" } };
|
|
73
|
+
git(dir, "tag", "-a", "-m", `ci: phase test failed in test (failure)\n\n${JSON.stringify(record, null, 2)}\n`, `ci/revoked/${sha}`, sha);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function result(doc: StatusDocument): Extract<StatusDocument, { members: unknown }> {
|
|
77
|
+
if ("error" in doc) throw new Error(`${doc.error.code}: ${doc.error.message}`);
|
|
78
|
+
expect(validateStatus(doc), JSON.stringify(validateStatus.errors, null, 2)).toBe(true);
|
|
79
|
+
return doc;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
describe("a revoked release in workspace status and release list (#4033)", () => {
|
|
83
|
+
test("an environment running a release cut from a revoked commit is flagged with the rollback line, and the release's pending gate is superseded", async () => {
|
|
84
|
+
await withTestDir(async (dir) => {
|
|
85
|
+
const { old, release, next } = await setup(dir);
|
|
86
|
+
|
|
87
|
+
// Before the revocation nothing is flagged.
|
|
88
|
+
const before = result(await workspaceStatus({ cwd: dir, env: "prod", compareTo: "staging", now: NOW }));
|
|
89
|
+
expect(before.members[0].environments[0].releases[0]).not.toHaveProperty("revoked");
|
|
90
|
+
expect(before.members[0].gates.map((g) => [g.name, g.state])).toEqual([["prod-release", "pending"], ["staging-release", "pending"]]);
|
|
91
|
+
|
|
92
|
+
revoke(dir, old);
|
|
93
|
+
const doc = result(await workspaceStatus({ cwd: dir, env: "prod", compareTo: "staging", now: NOW }));
|
|
94
|
+
const [prod, staging] = doc.members[0].environments;
|
|
95
|
+
expect(prod.releases[0].revoked).toEqual({
|
|
96
|
+
commit: old,
|
|
97
|
+
tag: `ci/revoked/${old}`,
|
|
98
|
+
tagged: expect.any(String),
|
|
99
|
+
phase: "test",
|
|
100
|
+
run: { name: "test", id: 77, conclusion: "failure", url: "https://example.test/runs/77" },
|
|
101
|
+
signer: null,
|
|
102
|
+
releaseDigest: release.releaseDigest,
|
|
103
|
+
label: "v1.0.0",
|
|
104
|
+
rollback: "chant components rollback prod --component api",
|
|
105
|
+
});
|
|
106
|
+
// staging runs the later release, which is not revoked.
|
|
107
|
+
expect(staging.releases[0]).not.toHaveProperty("revoked");
|
|
108
|
+
|
|
109
|
+
const [prodGate, stagingGate] = doc.members[0].gates;
|
|
110
|
+
expect(prodGate).toMatchObject({ name: "prod-release", releaseDigest: next.releaseDigest, state: "pending" });
|
|
111
|
+
expect(prodGate).not.toHaveProperty("revoked");
|
|
112
|
+
expect(stagingGate).toMatchObject({ name: "staging-release", releaseDigest: release.releaseDigest, state: "superseded", revoked: { commit: old, tag: `ci/revoked/${old}`, phase: "test" } });
|
|
113
|
+
|
|
114
|
+
expect(formatStatus(doc)).toContain(
|
|
115
|
+
` prod: api runs release v1.0.0, revoked by ci/revoked/${old} (phase test failed in test (run 77)); roll back: chant components rollback prod --component api`,
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test("release list marks the revoked release, in JSON and in text", async () => {
|
|
121
|
+
await withTestDir(async (dir) => {
|
|
122
|
+
const { old } = await setup(dir);
|
|
123
|
+
revoke(dir, old);
|
|
124
|
+
const doc = await releasesDocument({ cwd: dir });
|
|
125
|
+
expectValidReleases(doc);
|
|
126
|
+
if ("error" in doc) throw new Error(doc.error.message);
|
|
127
|
+
expect(doc.releases.map((r) => [r.label, r.revoked?.tag ?? null])).toEqual([
|
|
128
|
+
["v1.1.0", null],
|
|
129
|
+
["v1.0.0", `ci/revoked/${old}`],
|
|
130
|
+
]);
|
|
131
|
+
|
|
132
|
+
const out: string[] = [];
|
|
133
|
+
const err: string[] = [];
|
|
134
|
+
vi.spyOn(console, "log").mockImplementation((...m: unknown[]) => { out.push(m.join(" ")); });
|
|
135
|
+
vi.spyOn(console, "error").mockImplementation((...m: unknown[]) => { err.push(m.join(" ")); });
|
|
136
|
+
const cwd = process.cwd();
|
|
137
|
+
try {
|
|
138
|
+
process.chdir(dir);
|
|
139
|
+
const { runReleaseList } = await import("../cli/handlers/release");
|
|
140
|
+
expect(await runReleaseList({ args: {} } as unknown as CommandContext)).toBe(0);
|
|
141
|
+
} finally {
|
|
142
|
+
process.chdir(cwd);
|
|
143
|
+
}
|
|
144
|
+
expect(out.find((l) => l.startsWith("v1.0.0"))).toMatch(/ {2}revoked$/);
|
|
145
|
+
expect(out.find((l) => l.startsWith("v1.1.0"))).not.toMatch(/revoked/);
|
|
146
|
+
expect(err).toContain(` v1.0.0: revoked by ci/revoked/${old}, phase test failed in test (run 77)`);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
afterEach(() => {
|
|
151
|
+
vi.restoreAllMocks();
|
|
152
|
+
});
|
|
153
|
+
});
|
|
@@ -78,6 +78,10 @@ export interface StatusStewardRun {
|
|
|
78
78
|
status: OpRunRecord["status"];
|
|
79
79
|
started: string;
|
|
80
80
|
ended: string;
|
|
81
|
+
/** The commit the run built from (#4020). Absent on a record written before chant 0.124.28. */
|
|
82
|
+
gitSha?: string;
|
|
83
|
+
/** The CI run the Op ran in (#4020), when it ran in CI: the shape a release's `runOrigin` has. */
|
|
84
|
+
runOrigin?: OpRunRecord["runOrigin"];
|
|
81
85
|
/**
|
|
82
86
|
* The gate the run stopped at, for a `gated` run: its name, when the run
|
|
83
87
|
* stopped there, the op it is recorded under (the Op's own, or the
|
|
@@ -411,6 +415,8 @@ export async function readMemberStewards(
|
|
|
411
415
|
status: newest.status,
|
|
412
416
|
started: newest.started,
|
|
413
417
|
ended: newest.ended,
|
|
418
|
+
...(newest.gitSha ? { gitSha: newest.gitSha } : {}),
|
|
419
|
+
...(newest.runOrigin ? { runOrigin: newest.runOrigin } : {}),
|
|
414
420
|
gate: newest.gate ? gateOf(newest.gate, op.name) : null,
|
|
415
421
|
point: point?.wait ?? null,
|
|
416
422
|
phases: newest.phases.map((p) => ({
|