@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,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a run's events are kept on this host, and how to read them back
|
|
3
|
+
* (#4042). `chant run events <run>` replays a run from here and `--follow`
|
|
4
|
+
* tails it.
|
|
5
|
+
*
|
|
6
|
+
* Each run gets one file, `<git-common-dir>/chant/run-events/<run id>.jsonl`,
|
|
7
|
+
* holding the lines the one writer (`./run-event.ts`) produced, byte for byte
|
|
8
|
+
* as `--events-json` prints them. It sits beside the in-flight records
|
|
9
|
+
* (`./op/run-live.ts`), outside the working tree and off `chant/lifecycle`:
|
|
10
|
+
* the run ledger's growth is #4036's concern and these files add none to it.
|
|
11
|
+
* Unlike the in-flight record they are kept after the run settles, until
|
|
12
|
+
* `chant lifecycle gc --yes` deletes the ones its retention policy lets go
|
|
13
|
+
* (#4036, {@link planRunEventPrune}).
|
|
14
|
+
*
|
|
15
|
+
* Every write is best-effort. A run whose events cannot be kept still runs.
|
|
16
|
+
*/
|
|
17
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
18
|
+
import { join } from "node:path";
|
|
19
|
+
import { gitCommonDir } from "./op/run-live.js";
|
|
20
|
+
/** The directory name under `<git-common-dir>/chant/` that holds the files. */
|
|
21
|
+
export const RUN_EVENTS_DIR = "run-events";
|
|
22
|
+
/** The file name a run id is kept under: anything that is not a plain file-name character becomes `_`. */
|
|
23
|
+
export function runEventFileName(runId) {
|
|
24
|
+
return `${runId.replace(/[^A-Za-z0-9._@-]/g, "_")}.jsonl`;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The environment variable that names the directory run events are kept in,
|
|
28
|
+
* in place of the checkout's. The test suite sets it to a per-run temp
|
|
29
|
+
* directory, so no test writes to the real repository's store (worktrees
|
|
30
|
+
* share one git directory).
|
|
31
|
+
*/
|
|
32
|
+
export const RUN_EVENTS_DIR_ENV = "CHANT_RUN_EVENTS_DIR";
|
|
33
|
+
/** The directory the checkout at `cwd` keeps run events in (`CHANT_RUN_EVENTS_DIR` when set), or null outside a checkout. */
|
|
34
|
+
export async function runEventsDir(cwd) {
|
|
35
|
+
const override = process.env[RUN_EVENTS_DIR_ENV];
|
|
36
|
+
if (override)
|
|
37
|
+
return override;
|
|
38
|
+
const common = await gitCommonDir(cwd);
|
|
39
|
+
return common ? join(common, "chant", RUN_EVENTS_DIR) : null;
|
|
40
|
+
}
|
|
41
|
+
/** Open the file for `runId`, or undefined outside a checkout or where it cannot be created. */
|
|
42
|
+
export async function openRunEventStore(cwd, runId) {
|
|
43
|
+
let dir;
|
|
44
|
+
try {
|
|
45
|
+
dir = await runEventsDir(cwd);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
if (!dir)
|
|
51
|
+
return undefined;
|
|
52
|
+
const path = join(dir, runEventFileName(runId));
|
|
53
|
+
try {
|
|
54
|
+
mkdirSync(dir, { recursive: true });
|
|
55
|
+
// A run id used again (a re-run of the same CI run) replaces the earlier stream.
|
|
56
|
+
writeFileSync(path, "");
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
path,
|
|
63
|
+
write(line) {
|
|
64
|
+
try {
|
|
65
|
+
appendFileSync(path, line);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// The directory is gone or unwritable: the line is dropped.
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/** A write function that hands each line to every function given, or undefined when none is. */
|
|
74
|
+
export function teeLines(...writes) {
|
|
75
|
+
const live = writes.filter((w) => w !== undefined);
|
|
76
|
+
if (live.length === 0)
|
|
77
|
+
return undefined;
|
|
78
|
+
if (live.length === 1)
|
|
79
|
+
return live[0];
|
|
80
|
+
return (line) => {
|
|
81
|
+
for (const w of live)
|
|
82
|
+
w(line);
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/** The events in `text`, one per whole line. Returns what is left of an unfinished last line. */
|
|
86
|
+
export function parseRunEventLines(text) {
|
|
87
|
+
const events = [];
|
|
88
|
+
const parts = text.split("\n");
|
|
89
|
+
const rest = parts.pop() ?? "";
|
|
90
|
+
for (const part of parts) {
|
|
91
|
+
if (part.trim() === "")
|
|
92
|
+
continue;
|
|
93
|
+
try {
|
|
94
|
+
events.push(JSON.parse(part));
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// A line that is not JSON is not an event: skipped.
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return { events, rest };
|
|
101
|
+
}
|
|
102
|
+
/** The runs stored for the checkout at `cwd`, newest first. */
|
|
103
|
+
export async function listStoredRuns(cwd) {
|
|
104
|
+
const dir = await runEventsDir(cwd);
|
|
105
|
+
if (!dir || !existsSync(dir))
|
|
106
|
+
return [];
|
|
107
|
+
const runs = [];
|
|
108
|
+
for (const entry of readdirSync(dir)) {
|
|
109
|
+
if (!entry.endsWith(".jsonl"))
|
|
110
|
+
continue;
|
|
111
|
+
const file = join(dir, entry);
|
|
112
|
+
try {
|
|
113
|
+
const first = readFileSync(file, "utf8").split("\n", 1)[0] ?? "";
|
|
114
|
+
if (first === "")
|
|
115
|
+
continue;
|
|
116
|
+
const head = JSON.parse(first);
|
|
117
|
+
if (typeof head.runId !== "string")
|
|
118
|
+
continue;
|
|
119
|
+
runs.push({ runId: head.runId, name: String(head.name ?? ""), file, mtimeMs: statSync(file).mtimeMs });
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// Unreadable or not an event file: not listed.
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return runs.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The file for `ref`: a run id, else the name of an Op or a component
|
|
129
|
+
* selection, for which the newest stored run of that name stands. Null when
|
|
130
|
+
* nothing matches (a run that has not written its first line yet included).
|
|
131
|
+
*/
|
|
132
|
+
export async function findStoredRun(cwd, ref) {
|
|
133
|
+
const dir = await runEventsDir(cwd);
|
|
134
|
+
if (!dir)
|
|
135
|
+
return null;
|
|
136
|
+
const direct = join(dir, runEventFileName(ref));
|
|
137
|
+
if (existsSync(direct)) {
|
|
138
|
+
const byId = (await listStoredRuns(cwd)).find((r) => r.file === direct);
|
|
139
|
+
return byId ?? { runId: ref, name: "", file: direct, mtimeMs: statSync(direct).mtimeMs };
|
|
140
|
+
}
|
|
141
|
+
return (await listStoredRuns(cwd)).find((r) => r.name === ref) ?? null;
|
|
142
|
+
}
|
|
143
|
+
/** Whether `event` ends a stream. */
|
|
144
|
+
export const isRunSettle = (event) => event.type === "run-settle";
|
|
145
|
+
/**
|
|
146
|
+
* Read `file` from the start and hand each event to `onEvent` (with its raw
|
|
147
|
+
* line). Without `follow` it stops at the end of the file. With it, it keeps
|
|
148
|
+
* reading what is appended, by polling every `pollMs`, until `run-settle` is
|
|
149
|
+
* read, `signal` aborts, or `idleMs` passes with nothing new (when given).
|
|
150
|
+
* Resolves with the `run-settle` event, or undefined when the stream had
|
|
151
|
+
* none (a replay of a run still going, or a follow that was cut short).
|
|
152
|
+
*/
|
|
153
|
+
export async function readRunEvents(file, onEvent, opts = {}) {
|
|
154
|
+
const pollMs = opts.pollMs ?? 100;
|
|
155
|
+
let offset = 0;
|
|
156
|
+
let rest = "";
|
|
157
|
+
let lastGrowth = Date.now();
|
|
158
|
+
for (;;) {
|
|
159
|
+
let size = 0;
|
|
160
|
+
try {
|
|
161
|
+
size = statSync(file).size;
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
// Not there yet (a follow started before the run opened its file).
|
|
165
|
+
}
|
|
166
|
+
if (size > offset) {
|
|
167
|
+
const buf = readFileSync(file);
|
|
168
|
+
const chunk = buf.subarray(offset, size).toString("utf8");
|
|
169
|
+
offset = size;
|
|
170
|
+
lastGrowth = Date.now();
|
|
171
|
+
const text = rest + chunk;
|
|
172
|
+
const parts = text.split("\n");
|
|
173
|
+
rest = parts.pop() ?? "";
|
|
174
|
+
for (const part of parts) {
|
|
175
|
+
if (part.trim() === "")
|
|
176
|
+
continue;
|
|
177
|
+
let event;
|
|
178
|
+
try {
|
|
179
|
+
event = JSON.parse(part);
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
onEvent(event, `${part}\n`);
|
|
185
|
+
if (isRunSettle(event))
|
|
186
|
+
return event;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
else if (!opts.follow) {
|
|
190
|
+
return undefined;
|
|
191
|
+
}
|
|
192
|
+
else if (opts.signal?.aborted) {
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
else if (opts.idleMs !== undefined && Date.now() - lastGrowth > opts.idleMs) {
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
await new Promise((resolve) => {
|
|
200
|
+
const timer = setTimeout(resolve, pollMs);
|
|
201
|
+
opts.signal?.addEventListener("abort", () => { clearTimeout(timer); resolve(); }, { once: true });
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Which run event files the policy lets go (#4036): every file older than
|
|
208
|
+
* `days` by its last write, apart from the newest `keep`. A run still going
|
|
209
|
+
* writes its file as it goes, so it is never older than the window. Reads
|
|
210
|
+
* only; {@link pruneRunEvents} deletes.
|
|
211
|
+
*/
|
|
212
|
+
export async function planRunEventPrune(cwd, policy, now) {
|
|
213
|
+
const dir = await runEventsDir(cwd);
|
|
214
|
+
if (!dir || !existsSync(dir))
|
|
215
|
+
return { dir, remove: [], keep: [] };
|
|
216
|
+
const files = [];
|
|
217
|
+
for (const entry of readdirSync(dir)) {
|
|
218
|
+
if (!entry.endsWith(".jsonl"))
|
|
219
|
+
continue;
|
|
220
|
+
const file = join(dir, entry);
|
|
221
|
+
try {
|
|
222
|
+
const st = statSync(file);
|
|
223
|
+
if (!st.isFile())
|
|
224
|
+
continue;
|
|
225
|
+
files.push({ file, bytes: st.size, modified: new Date(st.mtimeMs).toISOString(), ms: st.mtimeMs });
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
// Gone between the listing and the stat.
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
files.sort((a, b) => b.ms - a.ms || (a.file < b.file ? -1 : 1));
|
|
232
|
+
const cutoff = now.getTime() - policy.days * 86400000;
|
|
233
|
+
const remove = [];
|
|
234
|
+
const keep = [];
|
|
235
|
+
files.forEach(({ ms, ...f }, i) => (i >= policy.keep && ms < cutoff ? remove : keep).push(f));
|
|
236
|
+
return { dir, remove, keep };
|
|
237
|
+
}
|
|
238
|
+
/** Delete the files a plan lets go. Returns how many were deleted; a file already gone is not counted. */
|
|
239
|
+
export function pruneRunEvents(plan) {
|
|
240
|
+
let n = 0;
|
|
241
|
+
for (const f of plan.remove) {
|
|
242
|
+
try {
|
|
243
|
+
rmSync(f.file);
|
|
244
|
+
n++;
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
// Already gone.
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return n;
|
|
251
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The emitters' side of the run-event contract (#4041): what a runtime or a
|
|
3
|
+
* command needs to print a run's stream through the one writer in
|
|
4
|
+
* `./run-event.ts`.
|
|
5
|
+
*
|
|
6
|
+
* Every emitter hands bodies to a {@link RunEventSink}. The CLI opens a
|
|
7
|
+
* {@link RunEventStream} over a run's identity, which stamps each body
|
|
8
|
+
* through `createRunEventWriter` and makes sure the stream opens with
|
|
9
|
+
* `run-start` and ends with one `run-settle`, even when the run threw before
|
|
10
|
+
* it said so itself. The components driver emits bodies only, and
|
|
11
|
+
* {@link progressOfRunEvent} turns them back into the older
|
|
12
|
+
* `RunProgressEvent` lines that `--progress-json` still prints.
|
|
13
|
+
*
|
|
14
|
+
* Kept apart from `./run-event.ts`, which a level-0 import loads: this
|
|
15
|
+
* module reads git and the CI environment.
|
|
16
|
+
*/
|
|
17
|
+
import type { RunProgressEvent } from "./components/run-progress.js";
|
|
18
|
+
import type { GateCheck } from "./op/gate.js";
|
|
19
|
+
import { type RunOrigin } from "./lifecycle/release-ledger.js";
|
|
20
|
+
import { type RunEventBody, type RunEventKind, type RunEventRun, type RunEventRuntime, type RunEventSettleStatus } from "./run-event.js";
|
|
21
|
+
/** Where an emitter hands a run's events, before the writer stamps them. */
|
|
22
|
+
export type RunEventSink = (body: RunEventBody) => void;
|
|
23
|
+
/** One sink that hands each body to every sink given, or undefined when none is. */
|
|
24
|
+
export declare function joinRunEventSinks(...sinks: Array<RunEventSink | undefined>): RunEventSink | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* A run-event body as the older `RunProgressEvent`, or undefined when that
|
|
27
|
+
* stream had no such event. It never printed a gate step, a skipped step,
|
|
28
|
+
* a phase outside a component, a gate's decision or a component the run did
|
|
29
|
+
* not start (`blocked`, `already-applied`, #4007), so those map to nothing
|
|
30
|
+
* and `--progress-json` prints what it printed before #4041.
|
|
31
|
+
*/
|
|
32
|
+
export declare function progressOfRunEvent(body: RunEventBody): RunProgressEvent | undefined;
|
|
33
|
+
/** A `RunProgressEvent` callback as a sink of run-event bodies, through {@link progressOfRunEvent}. */
|
|
34
|
+
export declare function progressSinkOf(onProgress: ((event: RunProgressEvent) => void) | undefined): RunEventSink | undefined;
|
|
35
|
+
/** The CI run the environment names, as `resolveCiRun` gives it. */
|
|
36
|
+
type CiRun = {
|
|
37
|
+
runId: string;
|
|
38
|
+
runOrigin: RunOrigin;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* A run's identity from what the emitter already knows. The runtime is `ci`
|
|
42
|
+
* inside a CI job, `steward` in a steward's turn and `local` otherwise; the
|
|
43
|
+
* origin is the CI run's, `op` for a steward's run, and `local` otherwise. An
|
|
44
|
+
* Op run keeps its own run id in CI, as its run record does (#4020).
|
|
45
|
+
*/
|
|
46
|
+
export declare function runEventRunOf(input: {
|
|
47
|
+
kind: RunEventKind;
|
|
48
|
+
name: string;
|
|
49
|
+
runId: string;
|
|
50
|
+
gitSha?: string;
|
|
51
|
+
ci?: CiRun;
|
|
52
|
+
steward?: boolean;
|
|
53
|
+
runtime?: RunEventRuntime;
|
|
54
|
+
runOrigin?: RunOrigin;
|
|
55
|
+
}): RunEventRun;
|
|
56
|
+
/**
|
|
57
|
+
* A run's identity, resolved: the commit from `resolveCommitSha` and the CI
|
|
58
|
+
* run from `resolveCiRun` (#4020). Without `runId`, a CI run is named by its
|
|
59
|
+
* CI run id and any other by a locally minted `local-<ms>` id, the spelling
|
|
60
|
+
* `resolveRunId` uses for a release record.
|
|
61
|
+
*/
|
|
62
|
+
export declare function resolveRunEventRun(input: {
|
|
63
|
+
kind: RunEventKind;
|
|
64
|
+
name: string;
|
|
65
|
+
runId?: string;
|
|
66
|
+
cwd?: string;
|
|
67
|
+
env?: NodeJS.ProcessEnv;
|
|
68
|
+
}): Promise<RunEventRun>;
|
|
69
|
+
/** One run's stream: the writer, held to the shape the contract promises. */
|
|
70
|
+
export interface RunEventStream {
|
|
71
|
+
/** The run every event names. */
|
|
72
|
+
readonly run: RunEventRun;
|
|
73
|
+
/** Write a body. */
|
|
74
|
+
emit: RunEventSink;
|
|
75
|
+
/**
|
|
76
|
+
* A sink for a part of the run that frames itself as a whole run, such as
|
|
77
|
+
* the fan-out a pull request's apply runs: its `run-start` and
|
|
78
|
+
* `run-settle` are dropped, and the caller settles the run.
|
|
79
|
+
*/
|
|
80
|
+
nested: RunEventSink;
|
|
81
|
+
/** End the stream with `run-settle`, unless it has ended. */
|
|
82
|
+
settle(status: RunEventSettleStatus, error?: string): void;
|
|
83
|
+
/** Whether `run-settle` has been written. */
|
|
84
|
+
readonly settled: boolean;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Open a run's stream over `write`. The first event is always `run-start`
|
|
88
|
+
* (one with `waves: null` is written first when the emitter starts with
|
|
89
|
+
* something else), a second `run-start` is dropped, `run-settle` gets the
|
|
90
|
+
* time since `run-start` when the emitter did not time it, and nothing is
|
|
91
|
+
* written after `run-settle`.
|
|
92
|
+
*/
|
|
93
|
+
export declare function openRunEventStream(run: RunEventRun, write: (line: string) => void, opts?: {
|
|
94
|
+
now?: () => Date;
|
|
95
|
+
chant?: string;
|
|
96
|
+
}): RunEventStream;
|
|
97
|
+
/** Where a gate step sits, for {@link gateEventsOf}. */
|
|
98
|
+
export interface GateStepAt {
|
|
99
|
+
component: string | null;
|
|
100
|
+
phase: string;
|
|
101
|
+
/** `gate:<name>`. */
|
|
102
|
+
step: string;
|
|
103
|
+
index?: number;
|
|
104
|
+
/** The op the gate is recorded under. */
|
|
105
|
+
op: string;
|
|
106
|
+
gate: string;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* A decided gate as events: `gate-resolved` and an `ok` settle when an
|
|
110
|
+
* approval stands, `gate-waiting` and a `gated` settle when none does.
|
|
111
|
+
* `message` says why it did not pass, for a person.
|
|
112
|
+
*/
|
|
113
|
+
export declare function gateEventsOf(check: GateCheck, at: GateStepAt, opts: {
|
|
114
|
+
durationMs: number | null;
|
|
115
|
+
message?: string;
|
|
116
|
+
}): RunEventBody[];
|
|
117
|
+
/** The phase a gate outside any component is the one step of: a fan-out's, a wave's or a pull request's. */
|
|
118
|
+
export declare const GATE_PHASE = "gate";
|
|
119
|
+
/**
|
|
120
|
+
* Decide a gate that stands outside any component, and emit it as the one
|
|
121
|
+
* step of a {@link GATE_PHASE} phase: `phase-start`, `step-start`, the
|
|
122
|
+
* decision through {@link gateEventsOf}, the settle and `phase-settle`. A
|
|
123
|
+
* decision that throws settles the step `failed` and is rethrown. `message`
|
|
124
|
+
* says, for a person, why a gate that did not pass did not.
|
|
125
|
+
*/
|
|
126
|
+
export declare function emitGateStep(emit: RunEventSink | undefined, at: {
|
|
127
|
+
op: string;
|
|
128
|
+
gate: string;
|
|
129
|
+
}, decide: () => Promise<GateCheck>, message?: (check: Extract<GateCheck, {
|
|
130
|
+
satisfied: false;
|
|
131
|
+
}>) => string | undefined): Promise<GateCheck>;
|
|
132
|
+
export {};
|
|
133
|
+
//# sourceMappingURL=run-event-stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-event-stream.d.ts","sourceRoot":"","sources":["../src/run-event-stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EAC1B,MAAM,aAAa,CAAC;AAErB,4EAA4E;AAC5E,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;AAExD,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,YAAY,GAAG,SAAS,CAAC,GAAG,YAAY,GAAG,SAAS,CAOrG;AAID;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,YAAY,GAAG,gBAAgB,GAAG,SAAS,CAyCnF;AAED,uGAAuG;AACvG,wBAAgB,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,CAMpH;AAED,oEAAoE;AACpE,KAAK,KAAK,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAAE,CAAC;AAErD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,KAAK,CAAC;IACX,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,GAAG,WAAW,CASd;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE;IAC9C,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,GAAG,OAAO,CAAC,WAAW,CAAC,CAgBvB;AAED,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B,iCAAiC;IACjC,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;IAC1B,oBAAoB;IACpB,IAAI,EAAE,YAAY,CAAC;IACnB;;;;OAIG;IACH,MAAM,EAAE,YAAY,CAAC;IACrB,6DAA6D;IAC7D,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3D,6CAA6C;IAC7C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAC7B,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,cAAc,CAqChB;AAED,wDAAwD;AACxD,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,EAAE,CAsBpI;AAED,4GAA4G;AAC5G,eAAO,MAAM,UAAU,SAAS,CAAC;AAEjC;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,YAAY,GAAG,SAAS,EAC9B,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAChC,MAAM,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,EAChC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE;IAAE,SAAS,EAAE,KAAK,CAAA;CAAE,CAAC,KAAK,MAAM,GAAG,SAAS,GAChF,OAAO,CAAC,SAAS,CAAC,CAqBpB"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The emitters' side of the run-event contract (#4041): what a runtime or a
|
|
3
|
+
* command needs to print a run's stream through the one writer in
|
|
4
|
+
* `./run-event.ts`.
|
|
5
|
+
*
|
|
6
|
+
* Every emitter hands bodies to a {@link RunEventSink}. The CLI opens a
|
|
7
|
+
* {@link RunEventStream} over a run's identity, which stamps each body
|
|
8
|
+
* through `createRunEventWriter` and makes sure the stream opens with
|
|
9
|
+
* `run-start` and ends with one `run-settle`, even when the run threw before
|
|
10
|
+
* it said so itself. The components driver emits bodies only, and
|
|
11
|
+
* {@link progressOfRunEvent} turns them back into the older
|
|
12
|
+
* `RunProgressEvent` lines that `--progress-json` still prints.
|
|
13
|
+
*
|
|
14
|
+
* Kept apart from `./run-event.ts`, which a level-0 import loads: this
|
|
15
|
+
* module reads git and the CI environment.
|
|
16
|
+
*/
|
|
17
|
+
import { resolveCommitSha } from "./lifecycle/commit-sha.js";
|
|
18
|
+
import { resolveCiRun } from "./lifecycle/release-ledger.js";
|
|
19
|
+
import { createRunEventWriter, } from "./run-event.js";
|
|
20
|
+
/** One sink that hands each body to every sink given, or undefined when none is. */
|
|
21
|
+
export function joinRunEventSinks(...sinks) {
|
|
22
|
+
const live = sinks.filter((s) => s !== undefined);
|
|
23
|
+
if (live.length === 0)
|
|
24
|
+
return undefined;
|
|
25
|
+
if (live.length === 1)
|
|
26
|
+
return live[0];
|
|
27
|
+
return (body) => {
|
|
28
|
+
for (const sink of live)
|
|
29
|
+
sink(body);
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const GATE_PREFIX = "gate:";
|
|
33
|
+
/**
|
|
34
|
+
* A run-event body as the older `RunProgressEvent`, or undefined when that
|
|
35
|
+
* stream had no such event. It never printed a gate step, a skipped step,
|
|
36
|
+
* a phase outside a component, a gate's decision or a component the run did
|
|
37
|
+
* not start (`blocked`, `already-applied`, #4007), so those map to nothing
|
|
38
|
+
* and `--progress-json` prints what it printed before #4041.
|
|
39
|
+
*/
|
|
40
|
+
export function progressOfRunEvent(body) {
|
|
41
|
+
const progressStatus = (s) => (s === "waiting" ? "gated" : s);
|
|
42
|
+
switch (body.type) {
|
|
43
|
+
case "run-start":
|
|
44
|
+
return { type: "run-start", waves: body.waves ?? [] };
|
|
45
|
+
case "wave-start":
|
|
46
|
+
return { type: "wave-start", wave: body.wave, components: body.components };
|
|
47
|
+
case "component-start":
|
|
48
|
+
return { type: "component-start", wave: body.wave, component: body.component };
|
|
49
|
+
case "phase-start":
|
|
50
|
+
return body.component === null ? undefined : { type: "phase-start", component: body.component, phase: body.phase };
|
|
51
|
+
case "step-start":
|
|
52
|
+
if (body.component === null || body.step.startsWith(GATE_PREFIX))
|
|
53
|
+
return undefined;
|
|
54
|
+
return { type: "step", component: body.component, phase: body.phase, step: body.step, status: "running" };
|
|
55
|
+
case "step-settle":
|
|
56
|
+
if (body.component === null || body.step.startsWith(GATE_PREFIX))
|
|
57
|
+
return undefined;
|
|
58
|
+
if (body.status !== "ok" && body.status !== "failed")
|
|
59
|
+
return undefined;
|
|
60
|
+
return {
|
|
61
|
+
type: "step",
|
|
62
|
+
component: body.component,
|
|
63
|
+
phase: body.phase,
|
|
64
|
+
step: body.step,
|
|
65
|
+
status: body.status,
|
|
66
|
+
...(body.error !== undefined ? { error: body.error } : {}),
|
|
67
|
+
};
|
|
68
|
+
case "phase-settle":
|
|
69
|
+
return body.component === null
|
|
70
|
+
? undefined
|
|
71
|
+
: { type: "phase-done", component: body.component, phase: body.phase, status: progressStatus(body.status) };
|
|
72
|
+
case "component-settle":
|
|
73
|
+
// A component the run did not start (#4007) was never in the older stream.
|
|
74
|
+
if (body.status === "blocked" || body.status === "already-applied")
|
|
75
|
+
return undefined;
|
|
76
|
+
return { type: "component-done", wave: body.wave, component: body.component, status: progressStatus(body.status) };
|
|
77
|
+
case "wave-settle":
|
|
78
|
+
return { type: "wave-done", wave: body.wave, status: progressStatus(body.status) };
|
|
79
|
+
case "run-settle":
|
|
80
|
+
return { type: "run-done", status: progressStatus(body.status) };
|
|
81
|
+
case "gate-waiting":
|
|
82
|
+
case "gate-resolved":
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** A `RunProgressEvent` callback as a sink of run-event bodies, through {@link progressOfRunEvent}. */
|
|
87
|
+
export function progressSinkOf(onProgress) {
|
|
88
|
+
if (!onProgress)
|
|
89
|
+
return undefined;
|
|
90
|
+
return (body) => {
|
|
91
|
+
const event = progressOfRunEvent(body);
|
|
92
|
+
if (event)
|
|
93
|
+
onProgress(event);
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* A run's identity from what the emitter already knows. The runtime is `ci`
|
|
98
|
+
* inside a CI job, `steward` in a steward's turn and `local` otherwise; the
|
|
99
|
+
* origin is the CI run's, `op` for a steward's run, and `local` otherwise. An
|
|
100
|
+
* Op run keeps its own run id in CI, as its run record does (#4020).
|
|
101
|
+
*/
|
|
102
|
+
export function runEventRunOf(input) {
|
|
103
|
+
return {
|
|
104
|
+
runId: input.runId,
|
|
105
|
+
kind: input.kind,
|
|
106
|
+
name: input.name,
|
|
107
|
+
gitSha: input.gitSha ?? null,
|
|
108
|
+
runtime: input.runtime ?? (input.ci ? "ci" : input.steward ? "steward" : "local"),
|
|
109
|
+
runOrigin: input.runOrigin ?? input.ci?.runOrigin ?? (input.steward ? { forge: "op" } : { forge: "local" }),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* A run's identity, resolved: the commit from `resolveCommitSha` and the CI
|
|
114
|
+
* run from `resolveCiRun` (#4020). Without `runId`, a CI run is named by its
|
|
115
|
+
* CI run id and any other by a locally minted `local-<ms>` id, the spelling
|
|
116
|
+
* `resolveRunId` uses for a release record.
|
|
117
|
+
*/
|
|
118
|
+
export async function resolveRunEventRun(input) {
|
|
119
|
+
const env = input.env ?? process.env;
|
|
120
|
+
const ci = resolveCiRun(env);
|
|
121
|
+
const gitSha = await resolveCommitSha({ ...(input.cwd ? { cwd: input.cwd } : {}), env });
|
|
122
|
+
const runId = input.runId ?? ci?.runId ?? `local-${Date.now()}`;
|
|
123
|
+
// An explicit id that is not the CI run's is one the caller minted, so the
|
|
124
|
+
// origin says local, as `resolveRunId` records it on a release.
|
|
125
|
+
const inCiSpace = ci !== undefined && runId === ci.runId;
|
|
126
|
+
return runEventRunOf({
|
|
127
|
+
kind: input.kind,
|
|
128
|
+
name: input.name,
|
|
129
|
+
runId,
|
|
130
|
+
...(gitSha ? { gitSha } : {}),
|
|
131
|
+
...(ci ? { ci } : {}),
|
|
132
|
+
...(ci && !inCiSpace ? { runOrigin: { forge: "local" } } : {}),
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Open a run's stream over `write`. The first event is always `run-start`
|
|
137
|
+
* (one with `waves: null` is written first when the emitter starts with
|
|
138
|
+
* something else), a second `run-start` is dropped, `run-settle` gets the
|
|
139
|
+
* time since `run-start` when the emitter did not time it, and nothing is
|
|
140
|
+
* written after `run-settle`.
|
|
141
|
+
*/
|
|
142
|
+
export function openRunEventStream(run, write, opts = {}) {
|
|
143
|
+
const now = opts.now ?? (() => new Date());
|
|
144
|
+
const writer = createRunEventWriter({ run, write, now, ...(opts.chant ? { chant: opts.chant } : {}) });
|
|
145
|
+
let startedAt;
|
|
146
|
+
let settled = false;
|
|
147
|
+
const emit = (body) => {
|
|
148
|
+
if (settled)
|
|
149
|
+
return;
|
|
150
|
+
if (body.type === "run-start") {
|
|
151
|
+
if (startedAt !== undefined)
|
|
152
|
+
return;
|
|
153
|
+
startedAt = now().getTime();
|
|
154
|
+
writer.emit(body);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (startedAt === undefined)
|
|
158
|
+
emit({ type: "run-start", waves: null });
|
|
159
|
+
if (body.type === "run-settle") {
|
|
160
|
+
settled = true;
|
|
161
|
+
writer.emit(body.durationMs === null ? { ...body, durationMs: Math.max(0, now().getTime() - startedAt) } : body);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
writer.emit(body);
|
|
165
|
+
};
|
|
166
|
+
return {
|
|
167
|
+
run,
|
|
168
|
+
emit,
|
|
169
|
+
nested: (body) => {
|
|
170
|
+
if (body.type !== "run-start" && body.type !== "run-settle")
|
|
171
|
+
emit(body);
|
|
172
|
+
},
|
|
173
|
+
settle(status, error) {
|
|
174
|
+
if (settled)
|
|
175
|
+
return;
|
|
176
|
+
emit({ type: "run-settle", status, durationMs: null, ...(error !== undefined ? { error } : {}) });
|
|
177
|
+
},
|
|
178
|
+
get settled() {
|
|
179
|
+
return settled;
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* A decided gate as events: `gate-resolved` and an `ok` settle when an
|
|
185
|
+
* approval stands, `gate-waiting` and a `gated` settle when none does.
|
|
186
|
+
* `message` says why it did not pass, for a person.
|
|
187
|
+
*/
|
|
188
|
+
export function gateEventsOf(check, at, opts) {
|
|
189
|
+
const where = { component: at.component, phase: at.phase, step: at.step, ...(at.index !== undefined ? { index: at.index } : {}) };
|
|
190
|
+
const message = opts.message !== undefined ? { message: opts.message } : {};
|
|
191
|
+
if (check.satisfied) {
|
|
192
|
+
return [
|
|
193
|
+
{
|
|
194
|
+
type: "gate-resolved",
|
|
195
|
+
...where,
|
|
196
|
+
op: at.op,
|
|
197
|
+
gate: at.gate,
|
|
198
|
+
resolvedBy: check.resolution.resolvedBy,
|
|
199
|
+
resolvedAt: check.resolution.timestamp,
|
|
200
|
+
via: check.via ?? null,
|
|
201
|
+
...(check.resolution.url ? { url: check.resolution.url } : {}),
|
|
202
|
+
},
|
|
203
|
+
{ type: "step-settle", ...where, status: "ok", durationMs: opts.durationMs },
|
|
204
|
+
];
|
|
205
|
+
}
|
|
206
|
+
return [
|
|
207
|
+
{ type: "gate-waiting", ...where, op: check.pending.op, gate: at.gate, point: null, ...message },
|
|
208
|
+
{ type: "step-settle", ...where, status: "gated", durationMs: opts.durationMs, ...message },
|
|
209
|
+
];
|
|
210
|
+
}
|
|
211
|
+
/** The phase a gate outside any component is the one step of: a fan-out's, a wave's or a pull request's. */
|
|
212
|
+
export const GATE_PHASE = "gate";
|
|
213
|
+
/**
|
|
214
|
+
* Decide a gate that stands outside any component, and emit it as the one
|
|
215
|
+
* step of a {@link GATE_PHASE} phase: `phase-start`, `step-start`, the
|
|
216
|
+
* decision through {@link gateEventsOf}, the settle and `phase-settle`. A
|
|
217
|
+
* decision that throws settles the step `failed` and is rethrown. `message`
|
|
218
|
+
* says, for a person, why a gate that did not pass did not.
|
|
219
|
+
*/
|
|
220
|
+
export async function emitGateStep(emit, at, decide, message) {
|
|
221
|
+
const where = { component: null, phase: GATE_PHASE, step: `gate:${at.gate}` };
|
|
222
|
+
emit?.({ type: "phase-start", component: null, phase: GATE_PHASE });
|
|
223
|
+
emit?.({ type: "step-start", ...where });
|
|
224
|
+
const start = Date.now();
|
|
225
|
+
let check;
|
|
226
|
+
try {
|
|
227
|
+
check = await decide();
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
emit?.({ type: "step-settle", ...where, status: "failed", durationMs: Date.now() - start, error: err instanceof Error ? err.message : String(err) });
|
|
231
|
+
emit?.({ type: "phase-settle", component: null, phase: GATE_PHASE, status: "failed" });
|
|
232
|
+
throw err;
|
|
233
|
+
}
|
|
234
|
+
const why = check.satisfied
|
|
235
|
+
? undefined
|
|
236
|
+
: (message?.(check) ?? (check.mismatch ? "an approval stands for this gate, but for another plan" : undefined));
|
|
237
|
+
for (const body of gateEventsOf(check, { ...where, op: at.op, gate: at.gate }, { durationMs: Date.now() - start, ...(why !== undefined ? { message: why } : {}) })) {
|
|
238
|
+
emit?.(body);
|
|
239
|
+
}
|
|
240
|
+
emit?.({ type: "phase-settle", component: null, phase: GATE_PHASE, status: check.satisfied ? "ok" : "gated" });
|
|
241
|
+
return check;
|
|
242
|
+
}
|