@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-metrics.d.ts","sourceRoot":"","sources":["../../src/lifecycle/delivery-metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAElE,wFAAwF;AACxF,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAI7C;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,GAAG,UAAU,GAAG,IAAI,CAErF;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,GAAG,OAAO,CAE5E;AAED,mGAAmG;AACnG,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,4DAA4D;AAC5D,MAAM,WAAW,cAAc;IAC7B,2IAA2I;IAC3I,SAAS,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,MAAM,GAAG,SAAS,CAAC;IACzD,mFAAmF;IACnF,eAAe,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC1D,oCAAoC;IACpC,OAAO,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAClD,mFAAmF;IACnF,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,gBAAgB,GAAG,IAAI,CAAC;IAC1D,sGAAsG;IACtG,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CAC/C;AAED,qDAAqD;AACrD,MAAM,WAAW,aAAa;IAC5B,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,mDAAmD;AACnD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,mFAAmF;IACnF,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,gHAAgH;IAChH,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,MAAM,EAAE,KAAK,CAAC,SAAS,GAAG,aAAa,CAAC,CAAC;IACzC,2DAA2D;IAC3D,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,0FAA0F;IAC1F,YAAY,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/B,oHAAoH;IACpH,UAAU,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7B,wFAAwF;IACxF,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,2CAA2C;AAC3C,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE;QACX,wGAAwG;QACxG,KAAK,EAAE,MAAM,CAAC;QACd,sGAAsG;QACtG,SAAS,EAAE,MAAM,CAAC;QAClB,gGAAgG;QAChG,IAAI,EAAE,MAAM,CAAC;QACb,mDAAmD;QACnD,WAAW,EAAE,MAAM,CAAC;QACpB,yDAAyD;QACzD,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,QAAQ,EAAE;QACR,0FAA0F;QAC1F,OAAO,EAAE,MAAM,CAAC;QAChB,oEAAoE;QACpE,WAAW,EAAE,MAAM,CAAC;QACpB,4FAA4F;QAC5F,UAAU,EAAE,MAAM,CAAC;QACnB,uEAAuE;QACvE,OAAO,EAAE,MAAM,CAAC;QAChB,2DAA2D;QAC3D,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;KAC9B,CAAC;IACF,aAAa,EAAE;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;QACf,4EAA4E;QAC5E,OAAO,EAAE,MAAM,CAAC;QAChB,wFAAwF;QACxF,UAAU,EAAE,MAAM,CAAC;QACnB,kFAAkF;QAClF,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;KACrB,CAAC;IACF,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;KAC9B,CAAC;IACF,sDAAsD;IACtD,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAYD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,SAAS,aAAa,EAAE,EACjC,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,aAAa,EACrB,iBAAiB,GAAE,MAAoC,GACtD,kBAAkB,CA4FpB"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The four DORA metrics of one environment's deploy records (#4039): how
|
|
3
|
+
* often it deploys, the lead time from commit to running release, the change
|
|
4
|
+
* failure rate and the time to restore.
|
|
5
|
+
*
|
|
6
|
+
* Everything here is pure. The caller reads the ledgers, the release files
|
|
7
|
+
* and the ci tags, and hands this module one environment's records with
|
|
8
|
+
* lookups for the rest; `workspace/delivery-metrics.ts` does that for
|
|
9
|
+
* `chant workspace metrics`.
|
|
10
|
+
*
|
|
11
|
+
* A deploy is one record in `<env>/releases.jsonl`: one component deployed
|
|
12
|
+
* once. A redeploy, which puts the running release back, is counted apart and
|
|
13
|
+
* is not a deploy for the metrics. A deploy fails when, within the failure window after it, the commit
|
|
14
|
+
* it deployed is revoked (a counted `ci/revoked/<sha>` tag, #4033) or the
|
|
15
|
+
* environment is rolled back from it. Which records are rollbacks, and which
|
|
16
|
+
* put the current release back, is decided in {@link rollbackOf} and
|
|
17
|
+
* {@link isRedeploy} and nowhere else, so a new kind of rollback record
|
|
18
|
+
* (#4035) changes those two functions only.
|
|
19
|
+
*/
|
|
20
|
+
/** The failure window when the declaration's `metrics.failureWindowDays` is not set. */
|
|
21
|
+
export const DEFAULT_FAILURE_WINDOW_DAYS = 7;
|
|
22
|
+
const DAY_MS = 86400000;
|
|
23
|
+
/**
|
|
24
|
+
* The earlier deploy a rollback record restores, or null when the record is
|
|
25
|
+
* not a rollback. Today a rollback is a record `chant components rollback`
|
|
26
|
+
* wrote, which names what it restores in `restores` (#2531). Every rule below
|
|
27
|
+
* that asks whether a record rolled an environment back asks this function.
|
|
28
|
+
*/
|
|
29
|
+
export function rollbackOf(record) {
|
|
30
|
+
return record.restores ?? null;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Whether the record put the current release back (`chant components
|
|
34
|
+
* redeploy`, #2604). A redeploy deploys the same release again, so it neither
|
|
35
|
+
* restores a failed deploy nor stands between a deploy and its rollback.
|
|
36
|
+
*/
|
|
37
|
+
export function isRedeploy(record) {
|
|
38
|
+
return record.redeploys !== undefined;
|
|
39
|
+
}
|
|
40
|
+
function median(values) {
|
|
41
|
+
if (values.length === 0)
|
|
42
|
+
return null;
|
|
43
|
+
const s = [...values].sort((a, b) => a - b);
|
|
44
|
+
const mid = Math.floor(s.length / 2);
|
|
45
|
+
return Math.round(s.length % 2 === 1 ? s[mid] : (s[mid - 1] + s[mid]) / 2);
|
|
46
|
+
}
|
|
47
|
+
const at = (iso) => Date.parse(iso);
|
|
48
|
+
const ref = (r) => ({ runId: r.runId, timestamp: r.timestamp });
|
|
49
|
+
/**
|
|
50
|
+
* The metrics of one environment's records. `records` is the whole ledger of
|
|
51
|
+
* the environment, every component, in ledger order: deploys before the
|
|
52
|
+
* window still decide lead times, and deploys after a failure decide its
|
|
53
|
+
* restore. Only deploys whose `timestamp` falls in `window` are counted.
|
|
54
|
+
*/
|
|
55
|
+
export function environmentMetrics(env, records, lookups, window, failureWindowDays = DEFAULT_FAILURE_WINDOW_DAYS) {
|
|
56
|
+
// Ledger order breaks timestamp ties, as `latestPerComponent` does.
|
|
57
|
+
const sorted = records.map((r, i) => ({ r, i })).sort((a, b) => at(a.r.timestamp) - at(b.r.timestamp) || a.i - b.i).map((x) => x.r);
|
|
58
|
+
const since = at(window.since);
|
|
59
|
+
const until = at(window.until);
|
|
60
|
+
const failureMs = failureWindowDays * DAY_MS;
|
|
61
|
+
const inWindow = (r) => at(r.timestamp) >= since && at(r.timestamp) <= until;
|
|
62
|
+
const facts = sorted.map((r) => {
|
|
63
|
+
const releaseDigest = lookups.releaseOf(r) ?? null;
|
|
64
|
+
const commit = (releaseDigest !== null ? lookups.commitOfRelease(releaseDigest) : null) ?? r.gitSha;
|
|
65
|
+
return { r, releaseDigest, commit, revocation: lookups.revocationOf(commit) };
|
|
66
|
+
});
|
|
67
|
+
// A redeploy puts the running release back: it is counted apart, and
|
|
68
|
+
// neither fails nor restores on its own.
|
|
69
|
+
const deployments = facts.filter((f) => inWindow(f.r) && !isRedeploy(f.r));
|
|
70
|
+
const failures = [];
|
|
71
|
+
for (const [i, f] of facts.entries()) {
|
|
72
|
+
if (!inWindow(f.r) || isRedeploy(f.r))
|
|
73
|
+
continue;
|
|
74
|
+
const t = at(f.r.timestamp);
|
|
75
|
+
const later = facts.slice(i + 1).filter((g) => g.r.component === f.r.component);
|
|
76
|
+
// Revoked within the window after the deploy. A tag with no time, or one
|
|
77
|
+
// made before the deploy, revokes what was deployed all the same.
|
|
78
|
+
const revoked = f.revocation !== null && (f.revocation.tagged === null || at(f.revocation.tagged) - t <= failureMs) ? f.revocation : null;
|
|
79
|
+
// Rolled back from it: the next deploy of the component that is not a
|
|
80
|
+
// redeploy is a rollback, within the window.
|
|
81
|
+
const next = later.find((g) => !isRedeploy(g.r));
|
|
82
|
+
const rolledBack = next !== undefined && rollbackOf(next.r) !== null && at(next.r.timestamp) - t <= failureMs ? next.r : null;
|
|
83
|
+
if (!revoked && !rolledBack)
|
|
84
|
+
continue;
|
|
85
|
+
const restore = later.find((g) => !isRedeploy(g.r) && g.revocation === null);
|
|
86
|
+
failures.push({
|
|
87
|
+
component: f.r.component,
|
|
88
|
+
timestamp: f.r.timestamp,
|
|
89
|
+
runId: f.r.runId,
|
|
90
|
+
releaseDigest: f.releaseDigest,
|
|
91
|
+
label: f.releaseDigest !== null ? lookups.labelOf(f.releaseDigest) : null,
|
|
92
|
+
commit: f.commit,
|
|
93
|
+
causes: [...(revoked ? ["revoked"] : []), ...(rolledBack ? ["rolled-back"] : [])],
|
|
94
|
+
revoked,
|
|
95
|
+
rolledBackBy: rolledBack ? ref(rolledBack) : null,
|
|
96
|
+
restoredBy: restore ? ref(restore.r) : null,
|
|
97
|
+
restoreSeconds: restore ? Math.round((at(restore.r.timestamp) - t) / 1000) : null,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
// Lead time: one change per release, or per commit deployed from no
|
|
101
|
+
// release, timed at its first deploy in this environment.
|
|
102
|
+
const firstDeploy = new Map();
|
|
103
|
+
for (const f of facts) {
|
|
104
|
+
const key = f.releaseDigest !== null ? `release:${f.releaseDigest}` : `commit:${f.r.gitSha}`;
|
|
105
|
+
if (!firstDeploy.has(key))
|
|
106
|
+
firstDeploy.set(key, f);
|
|
107
|
+
}
|
|
108
|
+
const leads = [];
|
|
109
|
+
let fromRelease = 0;
|
|
110
|
+
let unknown = 0;
|
|
111
|
+
for (const f of firstDeploy.values()) {
|
|
112
|
+
if (!inWindow(f.r))
|
|
113
|
+
continue;
|
|
114
|
+
const committed = lookups.commitTime(f.commit);
|
|
115
|
+
if (committed === null) {
|
|
116
|
+
unknown++;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
leads.push(Math.max(0, (at(f.r.timestamp) - committed) / 1000));
|
|
120
|
+
if (f.releaseDigest !== null)
|
|
121
|
+
fromRelease++;
|
|
122
|
+
}
|
|
123
|
+
const weeks = Math.max(until - since, DAY_MS) / (7 * DAY_MS);
|
|
124
|
+
const restored = failures.filter((x) => x.restoreSeconds !== null);
|
|
125
|
+
return {
|
|
126
|
+
env,
|
|
127
|
+
deployments: {
|
|
128
|
+
count: deployments.length,
|
|
129
|
+
redeploys: facts.filter((f) => inWindow(f.r) && isRedeploy(f.r)).length,
|
|
130
|
+
runs: new Set(deployments.map((f) => f.r.runId)).size,
|
|
131
|
+
fromRelease: deployments.filter((f) => f.releaseDigest !== null).length,
|
|
132
|
+
perWeek: Math.round((deployments.length / weeks) * 100) / 100,
|
|
133
|
+
},
|
|
134
|
+
leadTime: { changes: leads.length, fromRelease, fromCommit: leads.length - fromRelease, unknown, medianSeconds: median(leads) },
|
|
135
|
+
changeFailure: {
|
|
136
|
+
deployments: deployments.length,
|
|
137
|
+
failed: failures.length,
|
|
138
|
+
revoked: failures.filter((x) => x.revoked !== null).length,
|
|
139
|
+
rolledBack: failures.filter((x) => x.rolledBackBy !== null).length,
|
|
140
|
+
rate: deployments.length === 0 ? null : Math.round((failures.length / deployments.length) * 10000) / 10000,
|
|
141
|
+
},
|
|
142
|
+
restore: { restored: restored.length, open: failures.length - restored.length, medianSeconds: median(restored.map((x) => x.restoreSeconds)) },
|
|
143
|
+
failures,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a promote, rollback or redeploy left behind when it did not deploy
|
|
3
|
+
* every component it planned (#4035).
|
|
4
|
+
*
|
|
5
|
+
* The release ledger records a component only once its deploy succeeded, so
|
|
6
|
+
* after a run that applied partly it still names the earlier release for
|
|
7
|
+
* every component that failed, and nothing says that component may be
|
|
8
|
+
* running part of the new one. A deploy outcome is the record of that run:
|
|
9
|
+
* one line per run in `<env>/outcomes.jsonl` on `chant/lifecycle`, beside
|
|
10
|
+
* the environment's `releases.jsonl` and under the same member prefix,
|
|
11
|
+
* naming each planned component and what happened to it.
|
|
12
|
+
*
|
|
13
|
+
* It is written only when the run ended with some components deployed and
|
|
14
|
+
* others not, or with a component that failed. A run that stopped at a gate
|
|
15
|
+
* before deploying anything changed nothing in the environment; its pending
|
|
16
|
+
* gate is what `workspace status` shows for it.
|
|
17
|
+
*
|
|
18
|
+
* The file is append-only, like the release ledger. Whether the environment
|
|
19
|
+
* is still mixed is derived when it is read ({@link ./mixed-environment.ts}):
|
|
20
|
+
* a component the outcome names as failed or gated stays unsettled until the
|
|
21
|
+
* release ledger has a newer record of it, which a redeploy, a rollback or
|
|
22
|
+
* the same promote run again writes.
|
|
23
|
+
*/
|
|
24
|
+
import type { PromotionPlan } from "../components/promote.js";
|
|
25
|
+
import type { DriverRunResult } from "../components/driver.js";
|
|
26
|
+
/** The file a deploy outcome is appended to, under the environment's directory. */
|
|
27
|
+
export declare const OUTCOMES_FILE = "outcomes.jsonl";
|
|
28
|
+
/** What a run did to one component it planned. */
|
|
29
|
+
export type DeployOutcomeState = "deployed" | "failed" | "gated" | "not-run";
|
|
30
|
+
export interface DeployOutcomeComponent {
|
|
31
|
+
component: string;
|
|
32
|
+
/** `deployed` (a release record was written), `failed`, `gated` (stopped at a gate after the steps before it ran), or `not-run`. */
|
|
33
|
+
outcome: DeployOutcomeState;
|
|
34
|
+
/** The artifact digest the run was deploying. */
|
|
35
|
+
digest: string;
|
|
36
|
+
/** The release the run was deploying for this component, or null when it named none. */
|
|
37
|
+
releaseDigest: string | null;
|
|
38
|
+
}
|
|
39
|
+
/** One line of `<env>/outcomes.jsonl`. */
|
|
40
|
+
export interface DeployOutcome {
|
|
41
|
+
version: 1;
|
|
42
|
+
env: string;
|
|
43
|
+
verb: "promote" | "rollback" | "redeploy";
|
|
44
|
+
/** The run id the run's release records carry. */
|
|
45
|
+
runId: string;
|
|
46
|
+
/** The timestamp the run's release records carry. */
|
|
47
|
+
timestamp: string;
|
|
48
|
+
actor: string;
|
|
49
|
+
/** The release the run deployed under (`--release`), or null. */
|
|
50
|
+
releaseDigest: string | null;
|
|
51
|
+
/** How the run ended. */
|
|
52
|
+
status: "fail" | "gated";
|
|
53
|
+
components: DeployOutcomeComponent[];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The outcome to record for a run, or null when there is nothing to record:
|
|
57
|
+
* every planned component deployed, or the run stopped at a gate with
|
|
58
|
+
* nothing deployed and nothing failed.
|
|
59
|
+
*/
|
|
60
|
+
export declare function deployOutcomeOf(input: {
|
|
61
|
+
verb: DeployOutcome["verb"];
|
|
62
|
+
plan: PromotionPlan;
|
|
63
|
+
run: Pick<DriverRunResult, "status" | "results">;
|
|
64
|
+
/** The release the run deployed under, if any. */
|
|
65
|
+
releaseDigest: string | null;
|
|
66
|
+
runId: string;
|
|
67
|
+
timestamp: string;
|
|
68
|
+
actor: string;
|
|
69
|
+
}): DeployOutcome | null;
|
|
70
|
+
/** Parse the lines of an `outcomes.jsonl`, oldest first. A line that is not an outcome is counted and skipped. */
|
|
71
|
+
export declare function parseDeployOutcomes(text: string | null): {
|
|
72
|
+
outcomes: DeployOutcome[];
|
|
73
|
+
malformed: number;
|
|
74
|
+
};
|
|
75
|
+
/** Append one outcome to `<env>/outcomes.jsonl`. Does not push; the caller pushes with the release records. */
|
|
76
|
+
export declare function appendDeployOutcome(outcome: DeployOutcome, opts?: {
|
|
77
|
+
cwd?: string;
|
|
78
|
+
}): Promise<string>;
|
|
79
|
+
/** Every outcome recorded for `env`, oldest first, read where `readReleaseLedger` reads; `[]` when none is. */
|
|
80
|
+
export declare function readDeployOutcomes(env: string, opts?: import("./git.js").LedgerLocation): Promise<DeployOutcome[]>;
|
|
81
|
+
//# sourceMappingURL=deploy-outcome.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-outcome.d.ts","sourceRoot":"","sources":["../../src/lifecycle/deploy-outcome.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,mFAAmF;AACnF,eAAO,MAAM,aAAa,mBAAmB,CAAC;AAE9C,kDAAkD;AAClD,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAE7E,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,oIAAoI;IACpI,OAAO,EAAE,kBAAkB,CAAC;IAC5B,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,wFAAwF;IACxF,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,0CAA0C;AAC1C,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,CAAC,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;IAC1C,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,yBAAyB;IACzB,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,UAAU,EAAE,sBAAsB,EAAE,CAAC;CACtC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5B,IAAI,EAAE,aAAa,CAAC;IACpB,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,SAAS,CAAC,CAAC;IACjD,kDAAkD;IAClD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,aAAa,GAAG,IAAI,CA2BvB;AAkBD,kHAAkH;AAClH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG;IAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAazG;AAED,+GAA+G;AAC/G,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAG1G;AAED,+GAA+G;AAC/G,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAGrH"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a promote, rollback or redeploy left behind when it did not deploy
|
|
3
|
+
* every component it planned (#4035).
|
|
4
|
+
*
|
|
5
|
+
* The release ledger records a component only once its deploy succeeded, so
|
|
6
|
+
* after a run that applied partly it still names the earlier release for
|
|
7
|
+
* every component that failed, and nothing says that component may be
|
|
8
|
+
* running part of the new one. A deploy outcome is the record of that run:
|
|
9
|
+
* one line per run in `<env>/outcomes.jsonl` on `chant/lifecycle`, beside
|
|
10
|
+
* the environment's `releases.jsonl` and under the same member prefix,
|
|
11
|
+
* naming each planned component and what happened to it.
|
|
12
|
+
*
|
|
13
|
+
* It is written only when the run ended with some components deployed and
|
|
14
|
+
* others not, or with a component that failed. A run that stopped at a gate
|
|
15
|
+
* before deploying anything changed nothing in the environment; its pending
|
|
16
|
+
* gate is what `workspace status` shows for it.
|
|
17
|
+
*
|
|
18
|
+
* The file is append-only, like the release ledger. Whether the environment
|
|
19
|
+
* is still mixed is derived when it is read ({@link ./mixed-environment.ts}):
|
|
20
|
+
* a component the outcome names as failed or gated stays unsettled until the
|
|
21
|
+
* release ledger has a newer record of it, which a redeploy, a rollback or
|
|
22
|
+
* the same promote run again writes.
|
|
23
|
+
*/
|
|
24
|
+
import { sortedJsonReplacer } from "../utils.js";
|
|
25
|
+
/** The file a deploy outcome is appended to, under the environment's directory. */
|
|
26
|
+
export const OUTCOMES_FILE = "outcomes.jsonl";
|
|
27
|
+
/**
|
|
28
|
+
* The outcome to record for a run, or null when there is nothing to record:
|
|
29
|
+
* every planned component deployed, or the run stopped at a gate with
|
|
30
|
+
* nothing deployed and nothing failed.
|
|
31
|
+
*/
|
|
32
|
+
export function deployOutcomeOf(input) {
|
|
33
|
+
const { plan, run } = input;
|
|
34
|
+
if (run.status === "ok")
|
|
35
|
+
return null;
|
|
36
|
+
const components = plan.items.map((item) => {
|
|
37
|
+
const result = run.results.find((r) => r.component === item.component);
|
|
38
|
+
const outcome = !result ? "not-run" : result.status === "ok" ? "deployed" : result.status === "gated" ? "gated" : "failed";
|
|
39
|
+
return {
|
|
40
|
+
component: item.component,
|
|
41
|
+
outcome,
|
|
42
|
+
digest: item.digest,
|
|
43
|
+
releaseDigest: input.releaseDigest ?? item.source.releaseDigest ?? null,
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
const deployed = components.some((c) => c.outcome === "deployed");
|
|
47
|
+
const failed = components.some((c) => c.outcome === "failed");
|
|
48
|
+
if (!deployed && !failed)
|
|
49
|
+
return null;
|
|
50
|
+
return {
|
|
51
|
+
version: 1,
|
|
52
|
+
env: plan.to,
|
|
53
|
+
verb: input.verb,
|
|
54
|
+
runId: input.runId,
|
|
55
|
+
timestamp: input.timestamp,
|
|
56
|
+
actor: input.actor,
|
|
57
|
+
releaseDigest: input.releaseDigest,
|
|
58
|
+
status: run.status,
|
|
59
|
+
components,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const STATES = ["deployed", "failed", "gated", "not-run"];
|
|
63
|
+
function isOutcome(v) {
|
|
64
|
+
const o = v;
|
|
65
|
+
return (o !== null &&
|
|
66
|
+
typeof o === "object" &&
|
|
67
|
+
o.version === 1 &&
|
|
68
|
+
typeof o.env === "string" &&
|
|
69
|
+
typeof o.runId === "string" &&
|
|
70
|
+
typeof o.timestamp === "string" &&
|
|
71
|
+
Array.isArray(o.components) &&
|
|
72
|
+
o.components.every((c) => c && typeof c.component === "string" && STATES.includes(c.outcome) && typeof c.digest === "string"));
|
|
73
|
+
}
|
|
74
|
+
/** Parse the lines of an `outcomes.jsonl`, oldest first. A line that is not an outcome is counted and skipped. */
|
|
75
|
+
export function parseDeployOutcomes(text) {
|
|
76
|
+
const outcomes = [];
|
|
77
|
+
let malformed = 0;
|
|
78
|
+
for (const line of (text ?? "").split("\n").map((l) => l.trim()).filter(Boolean)) {
|
|
79
|
+
try {
|
|
80
|
+
const parsed = JSON.parse(line);
|
|
81
|
+
if (isOutcome(parsed))
|
|
82
|
+
outcomes.push(parsed);
|
|
83
|
+
else
|
|
84
|
+
malformed++;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
malformed++;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return { outcomes, malformed };
|
|
91
|
+
}
|
|
92
|
+
/** Append one outcome to `<env>/outcomes.jsonl`. Does not push; the caller pushes with the release records. */
|
|
93
|
+
export async function appendDeployOutcome(outcome, opts) {
|
|
94
|
+
const { appendLedgerLine } = await import("./git.js");
|
|
95
|
+
return appendLedgerLine(outcome.env, OUTCOMES_FILE, JSON.stringify(outcome, sortedJsonReplacer), "Deploy outcome", opts);
|
|
96
|
+
}
|
|
97
|
+
/** Every outcome recorded for `env`, oldest first, read where `readReleaseLedger` reads; `[]` when none is. */
|
|
98
|
+
export async function readDeployOutcomes(env, opts) {
|
|
99
|
+
const { readBlobFromPath } = await import("./git.js");
|
|
100
|
+
return parseDeployOutcomes(await readBlobFromPath(env, OUTCOMES_FILE, opts)).outcomes;
|
|
101
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Store the change set a gate binds (#4022), mapped onto the member's graph.
|
|
3
|
+
*
|
|
4
|
+
* {@link storeGateChangeSet} is what a gate that binds a change-set document's
|
|
5
|
+
* digest calls before it decides the gate: `components pr-apply`, and
|
|
6
|
+
* `components promote --release` before it decides a release gate or writes
|
|
7
|
+
* an `empty` resolution (#4045). It reads the member's
|
|
8
|
+
* graph the way `chant workspace graph` reads it, from the member's own
|
|
9
|
+
* `chant graph --format ir`, maps each entry onto a node
|
|
10
|
+
* (`../change-set-graph.ts`), and stores the document under its digest
|
|
11
|
+
* (`./change-set-store.ts`).
|
|
12
|
+
*
|
|
13
|
+
* Each entry mapped onto a node that has a source location also records that
|
|
14
|
+
* file from the repository root as `source` (#4025), which the overlap report
|
|
15
|
+
* in `workspace status` attributes the entry to work items by.
|
|
16
|
+
*
|
|
17
|
+
* The graph is read only when the digest is not stored yet. A graph that
|
|
18
|
+
* can't be read never stops the gate: the document is stored with `graph:
|
|
19
|
+
* null` and every `node` null, and the caller gets a warning to print.
|
|
20
|
+
*/
|
|
21
|
+
import type { ChangeSetDocument, ChangeSetGraph } from "../change-set.js";
|
|
22
|
+
/**
|
|
23
|
+
* Reads the node ids of the graph of the project at `projectDir`, with each
|
|
24
|
+
* node's source file (relative to `projectDir`) when the graph gives one.
|
|
25
|
+
*/
|
|
26
|
+
export type GraphIdReader = (projectDir: string) => Promise<{
|
|
27
|
+
ids: string[];
|
|
28
|
+
sources?: Record<string, string>;
|
|
29
|
+
} | {
|
|
30
|
+
error: string;
|
|
31
|
+
}>;
|
|
32
|
+
/**
|
|
33
|
+
* The node ids of `chant graph --format ir` in `projectDir`, run under the
|
|
34
|
+
* chant that directory resolves (its own `node_modules/.bin/chant`, else this
|
|
35
|
+
* one), as `chant workspace graph` runs each member. `args` are passed after
|
|
36
|
+
* `graph --format ir`, such as the run's `--param` flags.
|
|
37
|
+
*/
|
|
38
|
+
export declare function readGraphIds(projectDir: string, args?: readonly string[]): Promise<{
|
|
39
|
+
ids: string[];
|
|
40
|
+
sources: Record<string, string>;
|
|
41
|
+
} | {
|
|
42
|
+
error: string;
|
|
43
|
+
}>;
|
|
44
|
+
/**
|
|
45
|
+
* Replace how a gate reads the graph wherever the default is taken, such as
|
|
46
|
+
* in `components pr-apply`; `undefined` restores {@link readGraphIds}. For
|
|
47
|
+
* tests that drive a gate and read node ids in process, so they don't start a
|
|
48
|
+
* `chant graph` child process (`gate-change-set.e2e.test.ts` covers that one).
|
|
49
|
+
*/
|
|
50
|
+
export declare function setGraphIdReader(reader: GraphIdReader | undefined): void;
|
|
51
|
+
/** The graph reader a gate uses: the one {@link setGraphIdReader} set, else {@link readGraphIds} with `args`. */
|
|
52
|
+
export declare function gateGraphReader(args?: readonly string[]): GraphIdReader;
|
|
53
|
+
export interface StoreGateChangeSetInput {
|
|
54
|
+
/** The document whose `digest` the gate binds. */
|
|
55
|
+
doc: ChangeSetDocument;
|
|
56
|
+
/** The member's directory: where the graph is read and whose ledger it is stored in. */
|
|
57
|
+
cwd: string;
|
|
58
|
+
/** The commit the document was planned at, recorded as the graph's `at`. */
|
|
59
|
+
at?: string | null;
|
|
60
|
+
/** How to read the graph. Defaults to {@link gateGraphReader}. */
|
|
61
|
+
readGraph?: GraphIdReader;
|
|
62
|
+
}
|
|
63
|
+
export interface StoreGateChangeSetResult {
|
|
64
|
+
digest: string;
|
|
65
|
+
/** True when this call wrote the document; false when it was stored already. */
|
|
66
|
+
written: boolean;
|
|
67
|
+
/** The graph the stored document's nodes come from, null when none could be read. Absent when it was stored already. */
|
|
68
|
+
graph?: ChangeSetGraph | null;
|
|
69
|
+
/** Why no graph was read, when none was. */
|
|
70
|
+
warning?: string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Store `doc` under its digest in the member's ledger at `cwd`, mapped onto
|
|
74
|
+
* the member's graph, unless it is stored already. Does not push; the gate's
|
|
75
|
+
* pending fact or resolution pushes the branch after it.
|
|
76
|
+
*/
|
|
77
|
+
export declare function storeGateChangeSet(input: StoreGateChangeSetInput): Promise<StoreGateChangeSetResult>;
|
|
78
|
+
//# sourceMappingURL=gate-change-set.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-change-set.d.ts","sourceRoot":"","sources":["../../src/lifecycle/gate-change-set.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIvE;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAIrI;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,GAAE,SAAS,MAAM,EAAO,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAgCpK;AAID;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,GAAG,IAAI,CAExE;AAED,iHAAiH;AACjH,wBAAgB,eAAe,CAAC,IAAI,GAAE,SAAS,MAAM,EAAO,GAAG,aAAa,CAE3E;AAED,MAAM,WAAW,uBAAuB;IACtC,kDAAkD;IAClD,GAAG,EAAE,iBAAiB,CAAC;IACvB,wFAAwF;IACxF,GAAG,EAAE,MAAM,CAAC;IACZ,4EAA4E;IAC5E,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,kEAAkE;IAClE,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,OAAO,EAAE,OAAO,CAAC;IACjB,wHAAwH;IACxH,KAAK,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAuBD;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAuB1G"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Store the change set a gate binds (#4022), mapped onto the member's graph.
|
|
3
|
+
*
|
|
4
|
+
* {@link storeGateChangeSet} is what a gate that binds a change-set document's
|
|
5
|
+
* digest calls before it decides the gate: `components pr-apply`, and
|
|
6
|
+
* `components promote --release` before it decides a release gate or writes
|
|
7
|
+
* an `empty` resolution (#4045). It reads the member's
|
|
8
|
+
* graph the way `chant workspace graph` reads it, from the member's own
|
|
9
|
+
* `chant graph --format ir`, maps each entry onto a node
|
|
10
|
+
* (`../change-set-graph.ts`), and stores the document under its digest
|
|
11
|
+
* (`./change-set-store.ts`).
|
|
12
|
+
*
|
|
13
|
+
* Each entry mapped onto a node that has a source location also records that
|
|
14
|
+
* file from the repository root as `source` (#4025), which the overlap report
|
|
15
|
+
* in `workspace status` attributes the entry to work items by.
|
|
16
|
+
*
|
|
17
|
+
* The graph is read only when the digest is not stored yet. A graph that
|
|
18
|
+
* can't be read never stops the gate: the document is stored with `graph:
|
|
19
|
+
* null` and every `node` null, and the caller gets a warning to print.
|
|
20
|
+
*/
|
|
21
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
22
|
+
import { posix } from "node:path";
|
|
23
|
+
import { mapChangeSetToGraph } from "../change-set-graph.js";
|
|
24
|
+
import { persistChangeSet, readStoredChangeSet } from "./change-set-store.js";
|
|
25
|
+
import { resolveMemberLedger } from "./member-ledger.js";
|
|
26
|
+
const GRAPH_TIMEOUT_MS = 300000;
|
|
27
|
+
/**
|
|
28
|
+
* The node ids of `chant graph --format ir` in `projectDir`, run under the
|
|
29
|
+
* chant that directory resolves (its own `node_modules/.bin/chant`, else this
|
|
30
|
+
* one), as `chant workspace graph` runs each member. `args` are passed after
|
|
31
|
+
* `graph --format ir`, such as the run's `--param` flags.
|
|
32
|
+
*/
|
|
33
|
+
export async function readGraphIds(projectDir, args = []) {
|
|
34
|
+
const { readerToolchain, resolveToolchain } = await import("../workspace/member-commands.js");
|
|
35
|
+
const { readMemberIr } = await import("../workspace/compose-graph.js");
|
|
36
|
+
const { findWorkspaceRoot } = await import("../project-root.js");
|
|
37
|
+
const root = findWorkspaceRoot(projectDir)?.dir ?? projectDir;
|
|
38
|
+
const toolchain = resolveToolchain(projectDir, root, readerToolchain());
|
|
39
|
+
const [command, ...pre] = toolchain.command;
|
|
40
|
+
const out = await new Promise((resolveRun) => {
|
|
41
|
+
const child = spawn(command, [...pre, "graph", "--format", "ir", ...args], { cwd: projectDir, stdio: ["ignore", "pipe", "pipe"] });
|
|
42
|
+
let stdout = "";
|
|
43
|
+
let stderr = "";
|
|
44
|
+
const timer = setTimeout(() => child.kill("SIGKILL"), GRAPH_TIMEOUT_MS);
|
|
45
|
+
child.stdout.on("data", (d) => (stdout += d));
|
|
46
|
+
child.stderr.on("data", (d) => (stderr += d));
|
|
47
|
+
child.on("error", (err) => {
|
|
48
|
+
clearTimeout(timer);
|
|
49
|
+
resolveRun({ code: null, stdout, stderr: err.message });
|
|
50
|
+
});
|
|
51
|
+
child.on("close", (code) => {
|
|
52
|
+
clearTimeout(timer);
|
|
53
|
+
resolveRun({ code, stdout, stderr });
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
if (out.code !== 0) {
|
|
57
|
+
const line = out.stderr.split("\n").map((l) => l.trim()).find(Boolean);
|
|
58
|
+
return { error: `chant graph --format ir exited ${out.code ?? "on a signal"}${line ? `: ${line}` : ""}` };
|
|
59
|
+
}
|
|
60
|
+
const read = readMemberIr(out.stdout);
|
|
61
|
+
if ("reason" in read)
|
|
62
|
+
return { error: read.reason.message };
|
|
63
|
+
const sources = {};
|
|
64
|
+
for (const n of read.ir.nodes)
|
|
65
|
+
if (n.sourceLoc?.file)
|
|
66
|
+
sources[n.id] = n.sourceLoc.file;
|
|
67
|
+
return { ids: read.ir.nodes.map((n) => n.id), sources };
|
|
68
|
+
}
|
|
69
|
+
let graphReaderOverride;
|
|
70
|
+
/**
|
|
71
|
+
* Replace how a gate reads the graph wherever the default is taken, such as
|
|
72
|
+
* in `components pr-apply`; `undefined` restores {@link readGraphIds}. For
|
|
73
|
+
* tests that drive a gate and read node ids in process, so they don't start a
|
|
74
|
+
* `chant graph` child process (`gate-change-set.e2e.test.ts` covers that one).
|
|
75
|
+
*/
|
|
76
|
+
export function setGraphIdReader(reader) {
|
|
77
|
+
graphReaderOverride = reader;
|
|
78
|
+
}
|
|
79
|
+
/** The graph reader a gate uses: the one {@link setGraphIdReader} set, else {@link readGraphIds} with `args`. */
|
|
80
|
+
export function gateGraphReader(args = []) {
|
|
81
|
+
return graphReaderOverride ?? ((dir) => readGraphIds(dir, args));
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Each node's source file as a path from the repository root (#4025): the
|
|
85
|
+
* graph gives it relative to the member's directory at `cwd`. Undefined when
|
|
86
|
+
* the graph gives none or `cwd` is in no git repository.
|
|
87
|
+
*/
|
|
88
|
+
function repoSources(cwd, sources) {
|
|
89
|
+
if (!sources || Object.keys(sources).length === 0)
|
|
90
|
+
return undefined;
|
|
91
|
+
let prefix;
|
|
92
|
+
try {
|
|
93
|
+
prefix = execFileSync("git", ["rev-parse", "--show-prefix"], { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
const out = new Map();
|
|
99
|
+
for (const [id, file] of Object.entries(sources)) {
|
|
100
|
+
const path = posix.normalize(posix.join(prefix, file.split("\\").join("/")));
|
|
101
|
+
if (!path.startsWith("../") && path !== "..")
|
|
102
|
+
out.set(id, path);
|
|
103
|
+
}
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Store `doc` under its digest in the member's ledger at `cwd`, mapped onto
|
|
108
|
+
* the member's graph, unless it is stored already. Does not push; the gate's
|
|
109
|
+
* pending fact or resolution pushes the branch after it.
|
|
110
|
+
*/
|
|
111
|
+
export async function storeGateChangeSet(input) {
|
|
112
|
+
const { doc, cwd } = input;
|
|
113
|
+
const loc = { cwd };
|
|
114
|
+
if ((await readStoredChangeSet(doc.digest, loc)).status !== "missing")
|
|
115
|
+
return { digest: doc.digest, written: false };
|
|
116
|
+
const ledger = await resolveMemberLedger(cwd);
|
|
117
|
+
const member = ledger.members.length > 0 ? ledger.members.join("/") : null;
|
|
118
|
+
let nodes = null;
|
|
119
|
+
let warning;
|
|
120
|
+
try {
|
|
121
|
+
const read = await (input.readGraph ?? gateGraphReader())(cwd);
|
|
122
|
+
if ("error" in read)
|
|
123
|
+
warning = read.error;
|
|
124
|
+
else
|
|
125
|
+
nodes = { member, at: input.at ?? null, ids: read.ids, sources: repoSources(cwd, read.sources) };
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
warning = err instanceof Error ? err.message : String(err);
|
|
129
|
+
}
|
|
130
|
+
const mapped = mapChangeSetToGraph(doc, nodes);
|
|
131
|
+
const { written } = await persistChangeSet(mapped, loc);
|
|
132
|
+
return {
|
|
133
|
+
digest: doc.digest,
|
|
134
|
+
written,
|
|
135
|
+
graph: mapped.graph ?? null,
|
|
136
|
+
...(warning ? { warning: `the change set is stored without graph nodes: ${warning}` } : {}),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
@@ -2,6 +2,7 @@ import { type GateOrigin } from "./gate-origin.js";
|
|
|
2
2
|
import type { GateApprover, GatePolicyDecision, ResolvedGateApproval } from "../op/gate-approval.js";
|
|
3
3
|
import type { GateApprovalSource } from "../op/op-waves.js";
|
|
4
4
|
import type { GateRunLocator } from "../op/gate-run-locator.js";
|
|
5
|
+
import { type LedgerLocation } from "./git.js";
|
|
5
6
|
export { DEFAULT_GATE_EXPIRY, isApprovalUrl, resolveApprovalUrl } from "./gate-pending.js";
|
|
6
7
|
export { isPendingGateExpired, latestPendingGate, latestResolutionForPlan, latestResolutionSince, type PlanBoundResolution, } from "./gate-ledger-select.js";
|
|
7
8
|
/** The directory on the `chant/lifecycle` branch that holds gate ledgers, under a member's prefix when it has one. */
|
|
@@ -75,6 +76,16 @@ export interface GateResolutionRecord {
|
|
|
75
76
|
* such a record proves is that somebody approved *something*.
|
|
76
77
|
*/
|
|
77
78
|
planDigest?: string;
|
|
79
|
+
/**
|
|
80
|
+
* The commit the gate was waiting on (#4020), copied off the pending fact the
|
|
81
|
+
* approval answers, or the run's own commit for a resolution a run writes
|
|
82
|
+
* itself (a decision point's answer, a review, a carried approval). It is not
|
|
83
|
+
* the approver's checkout, and a seal does not cover it. Absent on a
|
|
84
|
+
* resolution written before 0.124.28 and when no commit was known.
|
|
85
|
+
*/
|
|
86
|
+
gitSha?: string;
|
|
87
|
+
/** The run the gate was waiting on (#4020), copied the same way as {@link GateResolutionRecord.gitSha}. */
|
|
88
|
+
runId?: string;
|
|
78
89
|
/**
|
|
79
90
|
* The checkpoint this approval lets a run resume from (#3947), copied off
|
|
80
91
|
* the pending fact it answers. Set only on an approval of a gate that
|
|
@@ -88,6 +99,26 @@ export interface GateResolutionRecord {
|
|
|
88
99
|
* recorded for its own environment and plan.
|
|
89
100
|
*/
|
|
90
101
|
environment?: string;
|
|
102
|
+
/**
|
|
103
|
+
* The release this approval is for (#4045, ws-104 question 2), copied off
|
|
104
|
+
* the pending fact it answers. Set on a release gate, the gate `chant
|
|
105
|
+
* components promote --release` passes for an environment. A release gate
|
|
106
|
+
* counts only a resolution recorded for its own release, environment and
|
|
107
|
+
* change-set document digest (`planDigest`), so it names the release it
|
|
108
|
+
* admitted. Absent on every other gate, and on a resolution written before
|
|
109
|
+
* 0.124.28.
|
|
110
|
+
*/
|
|
111
|
+
releaseDigest?: string;
|
|
112
|
+
/**
|
|
113
|
+
* The resolution passes a release gate over an empty change set (#4045,
|
|
114
|
+
* ws-104 question 6): the promote wrote it itself, with the actor running
|
|
115
|
+
* it in `resolvedBy`, because the change set its `planDigest` names changes
|
|
116
|
+
* nothing. A gate counts it only after it reads the stored document under
|
|
117
|
+
* `planDigest` and finds it empty, and neither a quorum nor a signing rule
|
|
118
|
+
* applies to it. It never counts as a person's approval. Absent on every
|
|
119
|
+
* other resolution.
|
|
120
|
+
*/
|
|
121
|
+
empty?: true;
|
|
91
122
|
/**
|
|
92
123
|
* The channel this resolution was authored on (chant#2384) — set by the
|
|
93
124
|
* writer, never by the caller. `chant approve` records `"cli"`, the
|
|
@@ -220,8 +251,19 @@ export interface PendingGateRecord {
|
|
|
220
251
|
gate: string;
|
|
221
252
|
/** The gate's human-readable description, when it declared one — what `chant operator status` shows a reader who wasn't there for the run. */
|
|
222
253
|
description?: string;
|
|
223
|
-
/**
|
|
254
|
+
/**
|
|
255
|
+
* The run that reached the gate. An Op run records its own id; a run with no
|
|
256
|
+
* id of its own (a component gate) records the CI run id when it ran in CI
|
|
257
|
+
* (#4020). Absent outside CI for a run that mints none.
|
|
258
|
+
*/
|
|
224
259
|
runId?: string;
|
|
260
|
+
/**
|
|
261
|
+
* The commit the run reached the gate at (#4020): the checkout's `HEAD`, else
|
|
262
|
+
* the commit the CI job started for. It is the commit the gate waits on, and
|
|
263
|
+
* `chant approve` copies it onto the resolution. Absent on a record written
|
|
264
|
+
* before 0.124.28 and when the run knew no commit.
|
|
265
|
+
*/
|
|
266
|
+
gitSha?: string;
|
|
225
267
|
/** ISO-8601 timestamp, caller-supplied (library code never calls `Date.now()` internally). */
|
|
226
268
|
timestamp: string;
|
|
227
269
|
/** ISO-8601 expiry, from the gate's `timeout` (default {@link DEFAULT_GATE_EXPIRY}). Past it, the fact is stale and a run re-records it. */
|
|
@@ -262,6 +304,13 @@ export interface PendingGateRecord {
|
|
|
262
304
|
* can pick one.
|
|
263
305
|
*/
|
|
264
306
|
environment?: string;
|
|
307
|
+
/**
|
|
308
|
+
* The release the run reached this gate for (#4045): on a release gate, the
|
|
309
|
+
* `releaseDigest` of the release `chant components promote --release`
|
|
310
|
+
* deploys. `chant approve` copies it onto the approval with the plan.
|
|
311
|
+
* Absent on every other gate, and on a fact written before 0.124.28.
|
|
312
|
+
*/
|
|
313
|
+
releaseDigest?: string;
|
|
265
314
|
/**
|
|
266
315
|
* The channel the run that reached this gate was driven from (chant#2384).
|
|
267
316
|
*
|
|
@@ -342,9 +391,7 @@ export declare function appendPendingGate(input: PendingGateInput, opts?: {
|
|
|
342
391
|
* graceful-degradation stance `readConvergeLedger` takes. Returns empty arrays
|
|
343
392
|
* (never throws) when `op` has nothing recorded yet.
|
|
344
393
|
*/
|
|
345
|
-
export declare function readGateLedger(op: string, opts?: {
|
|
346
|
-
cwd?: string;
|
|
347
|
-
}): Promise<{
|
|
394
|
+
export declare function readGateLedger(op: string, opts?: LedgerLocation): Promise<{
|
|
348
395
|
resolutions: GateResolutionRecord[];
|
|
349
396
|
pending: PendingGateRecord[];
|
|
350
397
|
malformed: number;
|