@intentius/chant 0.124.28 → 0.124.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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 +8 -1
- package/dist/change-set-graph.d.ts.map +1 -1
- package/dist/change-set-graph.js +4 -2
- package/dist/change-set.d.ts +10 -0
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +4 -3
- 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.map +1 -1
- package/dist/cli/commands/build.js +6 -3
- package/dist/cli/handlers/approve.d.ts.map +1 -1
- package/dist/cli/handlers/approve.js +45 -0
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.js +18 -4
- package/dist/cli/handlers/fan-out.d.ts +9 -0
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.js +67 -8
- 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 +11 -3
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +134 -26
- 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 +210 -33
- package/dist/cli/handlers/release.d.ts +62 -5
- package/dist/cli/handlers/release.d.ts.map +1 -1
- package/dist/cli/handlers/release.js +414 -28
- package/dist/cli/handlers/run.d.ts +11 -1
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/handlers/run.js +67 -6
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +91 -10
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +73 -2
- package/dist/cli/registry.d.ts +32 -4
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/cli/run-events.d.ts +3 -2
- package/dist/cli/run-events.d.ts.map +1 -1
- package/dist/cli/run-events.js +5 -3
- package/dist/components/auto-release.d.ts +2 -0
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/auto-release.js +1 -0
- package/dist/components/capability.d.ts +9 -0
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/driver.d.ts +8 -0
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/driver.js +35 -0
- 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.map +1 -1
- package/dist/components/fan-out-run.js +50 -0
- 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 +49 -0
- package/dist/components/pr-pipeline.d.ts.map +1 -1
- package/dist/components/pr-pipeline.js +38 -4
- package/dist/components/pr-run.d.ts +20 -2
- package/dist/components/pr-run.d.ts.map +1 -1
- package/dist/components/pr-run.js +26 -13
- package/dist/components/promote.d.ts +23 -0
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/promote.js +60 -2
- package/dist/components/release-compile.d.ts +9 -0
- package/dist/components/release-compile.d.ts.map +1 -1
- package/dist/components/release-compile.js +9 -3
- package/dist/components/release-gate.d.ts +11 -1
- package/dist/components/release-gate.d.ts.map +1 -1
- package/dist/components/release-gate.js +10 -4
- package/dist/components/wave-plan.d.ts +16 -0
- package/dist/components/wave-plan.d.ts.map +1 -1
- package/dist/components/wave-plan.js +36 -2
- package/dist/config.d.ts +38 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -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/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 +2 -1
- package/dist/lifecycle/change-set-store.d.ts.map +1 -1
- package/dist/lifecycle/change-set-store.js +2 -1
- 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 +10 -1
- package/dist/lifecycle/gate-change-set.d.ts.map +1 -1
- package/dist/lifecycle/gate-change-set.js +35 -3
- package/dist/lifecycle/gate-ledger.d.ts +2 -3
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- 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 +48 -1
- package/dist/lifecycle/release-cut.d.ts.map +1 -1
- package/dist/lifecycle/release-cut.js +116 -23
- 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 +8 -3
- package/dist/lifecycle/release-ledger.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.js +2 -0
- 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 +12 -2
- package/dist/lifecycle/release-store.d.ts.map +1 -1
- package/dist/lifecycle/release-store.js +4 -2
- 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 +1 -1
- package/dist/lifecycle/run-ledger.d.ts.map +1 -1
- package/dist/lifecycle/run-ledger.js +9 -0
- package/dist/op/activities/activity-contracts.d.ts +1 -0
- package/dist/op/activities/activity-contracts.d.ts.map +1 -1
- package/dist/op/activities/activity-contracts.js +1 -0
- package/dist/op/activities/shell.d.ts +6 -0
- package/dist/op/activities/shell.d.ts.map +1 -1
- package/dist/op/activities/shell.js +1 -1
- package/dist/op/local-executor.d.ts +23 -1
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-executor.js +9 -3
- package/dist/op/runtime.d.ts +27 -0
- package/dist/op/runtime.d.ts.map +1 -1
- package/dist/op/runtime.js +20 -0
- package/dist/plan-summary.d.ts.map +1 -1
- package/dist/plan-summary.js +8 -2
- package/dist/pr-forge.d.ts +23 -0
- package/dist/pr-forge.d.ts.map +1 -1
- package/dist/pr-forge.js +44 -0
- package/dist/pr-loop.d.ts +17 -0
- package/dist/pr-loop.d.ts.map +1 -1
- package/dist/pr-loop.js +30 -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 +29 -2
- package/dist/run-event-store.d.ts.map +1 -1
- package/dist/run-event-store.js +50 -3
- package/dist/run-event-stream.d.ts +4 -3
- package/dist/run-event-stream.d.ts.map +1 -1
- package/dist/run-event-stream.js +7 -3
- package/dist/run-event.d.ts +34 -1
- package/dist/run-event.d.ts.map +1 -1
- package/dist/run-event.js +4 -0
- package/dist/wave-runtime.mjs +260 -229
- 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/change-set.schema.json +5 -1
- 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-forge.d.ts +2 -0
- package/dist/workspace/ci-green-forge.d.ts.map +1 -1
- package/dist/workspace/ci-green.d.ts +10 -0
- package/dist/workspace/ci-green.d.ts.map +1 -1
- package/dist/workspace/ci-green.js +14 -5
- package/dist/workspace/ci-run.d.ts +222 -0
- package/dist/workspace/ci-run.d.ts.map +1 -0
- package/dist/workspace/ci-run.js +464 -0
- package/dist/workspace/ci-serve.d.ts +214 -0
- package/dist/workspace/ci-serve.d.ts.map +1 -0
- package/dist/workspace/ci-serve.js +412 -0
- package/dist/workspace/declaration.d.ts +16 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.js +26 -0
- package/dist/workspace/declaration.schema.json +64 -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/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 +30 -6
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/intent.js +141 -21
- package/dist/workspace/intent.schema.json +702 -6
- 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/pr-report.schema.json +5 -0
- package/dist/workspace/reason-codes.d.ts +2 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +3 -0
- 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 +9 -0
- package/dist/workspace/releases.d.ts.map +1 -1
- package/dist/workspace/releases.js +9 -0
- package/dist/workspace/releases.schema.json +123 -1
- package/dist/workspace/run-event.schema.json +24 -6
- package/dist/workspace/status-gates.d.ts +8 -0
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status-stewards.d.ts +2 -0
- package/dist/workspace/status-stewards.d.ts.map +1 -1
- package/dist/workspace/status-stewards.js +1 -0
- package/dist/workspace/status.d.ts +78 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/status.js +170 -3
- package/dist/workspace/status.schema.json +210 -2
- package/dist/workspace/wip.d.ts.map +1 -1
- package/dist/workspace/wip.js +11 -3
- package/package.json +1 -1
- package/src/build-params.test.ts +46 -0
- package/src/build-params.ts +55 -1
- package/src/change-set-graph.ts +10 -2
- package/src/change-set.ts +14 -3
- package/src/cli/build-params-cli.ts +22 -9
- package/src/cli/commands/build.ts +6 -3
- package/src/cli/handlers/approve-release.test.ts +5 -1
- package/src/cli/handlers/approve-revoked.test.ts +155 -0
- package/src/cli/handlers/approve.ts +47 -0
- package/src/cli/handlers/build.test.ts +30 -0
- package/src/cli/handlers/build.ts +20 -4
- package/src/cli/handlers/fan-out.test.ts +262 -1
- package/src/cli/handlers/fan-out.ts +72 -8
- 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/pr.test.ts +148 -1
- package/src/cli/handlers/pr.ts +144 -28
- package/src/cli/handlers/promote.test.ts +280 -2
- package/src/cli/handlers/promote.ts +210 -34
- package/src/cli/handlers/release-implicit.e2e.test.ts +12 -4
- 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 +146 -32
- package/src/cli/handlers/release.ts +415 -28
- package/src/cli/handlers/run-auto-release.test.ts +9 -0
- package/src/cli/handlers/run-release.test.ts +55 -0
- package/src/cli/handlers/run.ts +69 -5
- package/src/cli/main.test.ts +1 -0
- package/src/cli/main.ts +91 -10
- package/src/cli/parse-args.ts +54 -2
- package/src/cli/registry.ts +32 -4
- package/src/cli/run-events.ts +5 -2
- package/src/components/auto-release.test.ts +9 -0
- package/src/components/auto-release.ts +3 -0
- package/src/components/capability.ts +9 -0
- package/src/components/driver.test.ts +24 -0
- package/src/components/driver.ts +36 -0
- 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 +48 -0
- package/src/components/fan-out.ts +4 -0
- package/src/components/pr-pipeline.ts +67 -4
- package/src/components/pr-run.test.ts +127 -0
- package/src/components/pr-run.ts +32 -12
- package/src/components/promote.ts +68 -2
- package/src/components/release-compile.ts +17 -3
- package/src/components/release-gate.ts +18 -4
- package/src/components/wave-plan.ts +45 -2
- package/src/config.ts +8 -0
- package/src/flag-params.test.ts +144 -0
- package/src/flag-params.ts +134 -0
- package/src/lifecycle/__fixtures__/publish-fakes.ts +351 -0
- package/src/lifecycle/change-set-store.ts +2 -1
- package/src/lifecycle/delivery-metrics.ts +263 -0
- package/src/lifecycle/deploy-outcome.ts +147 -0
- package/src/lifecycle/gate-change-set.ts +37 -6
- package/src/lifecycle/gate-ledger.ts +2 -2
- 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.test.ts +74 -2
- package/src/lifecycle/release-cut.ts +158 -22
- 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.ts +9 -3
- 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 +15 -4
- 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.ts +7 -1
- package/src/op/activities/activity-contracts.ts +1 -0
- package/src/op/activities/shell.ts +7 -1
- package/src/op/local-executor.ts +27 -4
- package/src/op/runtime.ts +42 -0
- package/src/plan-summary.test.ts +20 -0
- package/src/plan-summary.ts +8 -1
- package/src/pr-forge.test.ts +25 -0
- package/src/pr-forge.ts +62 -0
- package/src/pr-loop.test.ts +13 -1
- package/src/pr-loop.ts +41 -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.ts +63 -3
- package/src/run-event-stream.ts +8 -4
- package/src/run-event.ts +38 -1
- 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/change-set.schema.json +5 -1
- 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-forge.ts +2 -0
- package/src/workspace/ci-green.ts +20 -5
- package/src/workspace/ci-run.test.ts +416 -0
- package/src/workspace/ci-run.ts +571 -0
- package/src/workspace/ci-serve.test.ts +268 -0
- package/src/workspace/ci-serve.ts +521 -0
- package/src/workspace/declaration.schema.json +64 -0
- package/src/workspace/declaration.test.ts +28 -0
- package/src/workspace/declaration.ts +38 -0
- 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/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 +148 -25
- 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/pr-report.schema.json +5 -0
- package/src/workspace/read-contract.e2e.test.ts +2 -1
- package/src/workspace/reason-codes.test.ts +5 -0
- package/src/workspace/reason-codes.ts +3 -0
- 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 +123 -1
- package/src/workspace/releases.ts +11 -0
- package/src/workspace/run-event.schema.json +24 -6
- package/src/workspace/status-contract.test.ts +29 -0
- package/src/workspace/status-gates.ts +8 -0
- package/src/workspace/status-mixed.test.ts +152 -0
- package/src/workspace/status-revoked.test.ts +153 -0
- package/src/workspace/status-stewards.ts +3 -0
- package/src/workspace/status.schema.json +210 -2
- package/src/workspace/status.ts +254 -3
- package/src/workspace/wip.ts +11 -2
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The publish targets (#4047): a member's `release.publish` declarations
|
|
3
|
+
* (./publish-declaration.ts) made into {@link PublishTarget}s, and what the
|
|
4
|
+
* targets share.
|
|
5
|
+
*
|
|
6
|
+
* - `npm` (./publish-npm.ts): `npm publish` per package, in order, with
|
|
7
|
+
* `--provenance` when the run has an OIDC token.
|
|
8
|
+
* - `oci` (./publish-oci.ts): an OCI image layout pushed to a registry such
|
|
9
|
+
* as GHCR or Docker Hub over the registry HTTP API, by digest, then tagged.
|
|
10
|
+
* - `forge` (./publish-forge.ts): files attached to the GitHub, GitLab or
|
|
11
|
+
* Forgejo release named by the release's tag.
|
|
12
|
+
*
|
|
13
|
+
* A file a target reads that the release records as an artifact at the same
|
|
14
|
+
* path is checked against the release's digest, and a file that differs is
|
|
15
|
+
* refused (`publish-artifact-digest-mismatch`). Other files are the commit's
|
|
16
|
+
* by the checkout check (`checkCheckoutIsRelease` in ./release-publish.ts).
|
|
17
|
+
*/
|
|
18
|
+
import { createHash } from "node:crypto";
|
|
19
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
20
|
+
import { isAbsolute, normalize, relative, resolve } from "node:path";
|
|
21
|
+
import { PublishTargetError } from "./release-publish.js";
|
|
22
|
+
import { sortedJsonReplacer } from "../utils.js";
|
|
23
|
+
/** Make each declaration a target, in the order declared. */
|
|
24
|
+
export async function createPublishTargets(decls, deps = {}) {
|
|
25
|
+
const out = [];
|
|
26
|
+
for (const d of decls) {
|
|
27
|
+
switch (d.type) {
|
|
28
|
+
case "npm":
|
|
29
|
+
out.push((await import("./publish-npm.js")).npmTarget(d, deps));
|
|
30
|
+
break;
|
|
31
|
+
case "oci":
|
|
32
|
+
out.push((await import("./publish-oci.js")).ociTarget(d, deps));
|
|
33
|
+
break;
|
|
34
|
+
case "forge":
|
|
35
|
+
out.push((await import("./publish-forge.js")).forgeTarget(d, deps));
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The key of a target made from `decl` (#4048): its kind and the first 16 hex
|
|
43
|
+
* digits of the SHA-256 of its sorted JSON. A declaration holds variable
|
|
44
|
+
* names, never a credential, so the key holds none either.
|
|
45
|
+
*/
|
|
46
|
+
export function publishTargetKey(decl) {
|
|
47
|
+
return `${decl.type}:${createHash("sha256").update(JSON.stringify(decl, sortedJsonReplacer)).digest("hex").slice(0, 16)}`;
|
|
48
|
+
}
|
|
49
|
+
/** `path` resolved in the member at `cwd`, refused when it is not there. */
|
|
50
|
+
export function memberFile(cwd, path) {
|
|
51
|
+
const abs = isAbsolute(path) ? path : resolve(cwd, path);
|
|
52
|
+
if (!existsSync(abs)) {
|
|
53
|
+
throw new PublishTargetError("publish-file-missing", `${path} does not exist in ${cwd}`, "Build it before publishing: a publish uploads what is there and never builds.");
|
|
54
|
+
}
|
|
55
|
+
return abs;
|
|
56
|
+
}
|
|
57
|
+
/** `sha256:<hex>` of a file's bytes. */
|
|
58
|
+
export function fileDigest(abs) {
|
|
59
|
+
return `sha256:${createHash("sha256").update(readFileSync(abs)).digest("hex")}`;
|
|
60
|
+
}
|
|
61
|
+
/** `sha256:<hex>` of bytes. */
|
|
62
|
+
export function bytesDigest(bytes) {
|
|
63
|
+
return `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
|
|
64
|
+
}
|
|
65
|
+
/** True when `abs` is a directory. */
|
|
66
|
+
export function isDir(abs) {
|
|
67
|
+
return statSync(abs).isDirectory();
|
|
68
|
+
}
|
|
69
|
+
const normal = (p) => normalize(p).replace(/\\/g, "/").replace(/^\.\//, "");
|
|
70
|
+
/** The release's artifact of `kind` at `path` (relative to the member at `cwd`), if it records one. */
|
|
71
|
+
export function releaseArtifactAt(release, kind, cwd, path) {
|
|
72
|
+
const rel = normal(isAbsolute(path) ? relative(cwd, path) : path);
|
|
73
|
+
return release.artifactDigests.find((a) => a.kind === kind && normal(a.path) === rel);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Refuse a file the release records at `path` whose digest is none of
|
|
77
|
+
* `digests`, the identities the target can compute for it (the file's bytes,
|
|
78
|
+
* and for an image its manifest and config digests).
|
|
79
|
+
*/
|
|
80
|
+
export function checkReleaseDigest(release, kind, cwd, path, digests) {
|
|
81
|
+
const recorded = releaseArtifactAt(release, kind, cwd, path);
|
|
82
|
+
if (!recorded || digests.includes(recorded.digest))
|
|
83
|
+
return;
|
|
84
|
+
throw new PublishTargetError("publish-artifact-digest-mismatch", `${path} is not the ${kind} release ${release.releaseDigest} built: the release records ${recorded.digest}, and the file here is ${digests[0]}`, "Publish the files the cut built. A publish never builds, so restore them from the cut's build, or cut a new release.");
|
|
85
|
+
}
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
* `ci.green.signedSince` declared, a green tag counts only with a valid
|
|
33
33
|
* statement (`../workspace/ci-green.ts`), so a hand-pushed tag cuts nothing.
|
|
34
34
|
*/
|
|
35
|
-
import { type Release, type ReleaseCut } from "./release-store.js";
|
|
35
|
+
import { type Release, type ReleaseCut, type ReleaseTarget } from "./release-store.js";
|
|
36
36
|
import type { CompiledTarget, TargetCompiler } from "../components/release-compile.js";
|
|
37
37
|
/** The stable codes a cut refuses with. */
|
|
38
38
|
export type ReleaseCutCode = "not-a-git-repository" | "release-commit-not-green" | "release-commit-revoked" | "release-worktree-dirty" | "release-no-environments" | "release-no-components" | "release-build-inputs-differ" | "release-unsigned" | "release-signer-refused" | "declaration-invalid";
|
|
@@ -95,6 +95,49 @@ export declare function differingBuildSteps(targets: readonly CompiledTarget[]):
|
|
|
95
95
|
component: string;
|
|
96
96
|
envs: string[];
|
|
97
97
|
}>;
|
|
98
|
+
/** What a dry run of the cut found (#4027): what the cut would do, with nothing built, signed or written. */
|
|
99
|
+
export interface CutPlan {
|
|
100
|
+
commit: string;
|
|
101
|
+
member: string | null;
|
|
102
|
+
label: string | null;
|
|
103
|
+
/** The release's digest when no artifact needs building, so it is known now; null when a build decides it. */
|
|
104
|
+
releaseDigest: string | null;
|
|
105
|
+
/** The digest already cut under `label`, or this digest when it is already cut: the cut would then write no new release. */
|
|
106
|
+
alreadyCut: string | null;
|
|
107
|
+
/** Each environment's target: its params, and its templates by component and path. */
|
|
108
|
+
targets: Array<{
|
|
109
|
+
env: string;
|
|
110
|
+
params: ReleaseTarget["params"];
|
|
111
|
+
templates: Array<{
|
|
112
|
+
component: string | null;
|
|
113
|
+
path: string;
|
|
114
|
+
}>;
|
|
115
|
+
}>;
|
|
116
|
+
/** The components whose artifacts would be built, and the environment each is built in. */
|
|
117
|
+
build: Array<{
|
|
118
|
+
component: string;
|
|
119
|
+
env: string;
|
|
120
|
+
}>;
|
|
121
|
+
/** The components whose artifacts would be carried from an earlier release. */
|
|
122
|
+
reused: CutResult["reused"];
|
|
123
|
+
/** Each component's publish steps, with the environments whose deploy runs them. */
|
|
124
|
+
publishSteps: Array<{
|
|
125
|
+
component: string;
|
|
126
|
+
kind: string;
|
|
127
|
+
to: string | null;
|
|
128
|
+
envs: string[];
|
|
129
|
+
}>;
|
|
130
|
+
/** Whether the release gate in identity.gates requires a signed cut. */
|
|
131
|
+
signatureRequired: boolean;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* The dry run of {@link cutRelease} (#4027): the same checks and compile,
|
|
135
|
+
* then what the cut would build, carry and record, without building an
|
|
136
|
+
* artifact, signing, or writing anything. Throws what the cut throws before
|
|
137
|
+
* it builds, and `ReleaseLabelError` when the label is invalid or names a
|
|
138
|
+
* release of another commit.
|
|
139
|
+
*/
|
|
140
|
+
export declare function planRelease(req: CutRequest): Promise<CutPlan>;
|
|
98
141
|
/**
|
|
99
142
|
* Cut a release of the member at `req.cwd` from its checkout's `HEAD`. Writes
|
|
100
143
|
* the release and the cut to the local `chant/lifecycle` branch and does not
|
|
@@ -102,6 +145,10 @@ export declare function differingBuildSteps(targets: readonly CompiledTarget[]):
|
|
|
102
145
|
* commit isn't green, the tree is dirty, or an environment can't be compiled
|
|
103
146
|
* to the same artifacts, and `ReleaseLabelError` (./release-store.ts) when the
|
|
104
147
|
* label is taken or the release already carries another one.
|
|
148
|
+
*
|
|
149
|
+
* The cut line names its run (#4027): the CI run's id and origin in CI, and
|
|
150
|
+
* outside CI an id minted from the cut's time, `local-<epoch ms>`, with the
|
|
151
|
+
* origin `{ forge: "local" }`.
|
|
105
152
|
*/
|
|
106
153
|
export declare function cutRelease(req: CutRequest): Promise<CutResult>;
|
|
107
154
|
//# sourceMappingURL=release-cut.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release-cut.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-cut.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAUH,OAAO,
|
|
1
|
+
{"version":3,"file":"release-cut.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-cut.ts"],"names":[],"mappings":"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"}
|
|
@@ -40,7 +40,7 @@ import { contentDigest } from "../content-digest.js";
|
|
|
40
40
|
import { getHeadCommit } from "./git.js";
|
|
41
41
|
import { resolveMemberLedger } from "./member-ledger.js";
|
|
42
42
|
import { resolveCiRun } from "./release-ledger.js";
|
|
43
|
-
import { appendCut, makeRelease, persistRelease, readAllReleases, readCuts, } from "./release-store.js";
|
|
43
|
+
import { appendCut, invalidLabel, labelsByDigest, makeRelease, persistRelease, readAllReleases, readCuts, readRelease, ReleaseLabelError, } from "./release-store.js";
|
|
44
44
|
export class ReleaseCutError extends Error {
|
|
45
45
|
constructor(code, message, fix) {
|
|
46
46
|
super(message);
|
|
@@ -68,15 +68,10 @@ function tryGit(top, args) {
|
|
|
68
68
|
* every tag counts.
|
|
69
69
|
*/
|
|
70
70
|
export async function greenState(top, sha, green = null) {
|
|
71
|
-
const {
|
|
72
|
-
const base = green
|
|
73
|
-
? (tryGit(top, ["rev-parse", "--verify", "--quiet", `refs/remotes/origin/${green.branch}^{commit}`]) ??
|
|
74
|
-
tryGit(top, ["rev-parse", "--verify", "--quiet", `refs/heads/${green.branch}^{commit}`]) ??
|
|
75
|
-
tryGit(top, ["rev-parse", "HEAD"]))
|
|
76
|
-
: null;
|
|
71
|
+
const { judgedCiTags } = await import("./release-revocation.js");
|
|
77
72
|
let tags;
|
|
78
73
|
try {
|
|
79
|
-
tags =
|
|
74
|
+
tags = await judgedCiTags(top, green);
|
|
80
75
|
}
|
|
81
76
|
catch (err) {
|
|
82
77
|
const { WorkspaceReadError } = await import("../workspace/declaration.js");
|
|
@@ -123,14 +118,12 @@ async function previousRelease(top, commit, cwd) {
|
|
|
123
118
|
return candidates[0]?.r;
|
|
124
119
|
}
|
|
125
120
|
/**
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
* to the same artifacts, and `ReleaseLabelError` (./release-store.ts) when the
|
|
131
|
-
* label is taken or the release already carries another one.
|
|
121
|
+
* The checks and the compile a cut makes before it builds or writes: the
|
|
122
|
+
* commit is green and not revoked, the cut is signed when the release gate
|
|
123
|
+
* asks, the tree is clean, every environment compiles with the same build
|
|
124
|
+
* steps, and which artifacts are carried from an earlier release.
|
|
132
125
|
*/
|
|
133
|
-
|
|
126
|
+
async function prepare(req) {
|
|
134
127
|
const cwd = resolve(req.cwd);
|
|
135
128
|
const top = tryGit(cwd, ["rev-parse", "--show-toplevel"]);
|
|
136
129
|
if (!top)
|
|
@@ -207,11 +200,21 @@ export async function cutRelease(req) {
|
|
|
207
200
|
}
|
|
208
201
|
toBuild.set(target.env, [...(toBuild.get(target.env) ?? []), component]);
|
|
209
202
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
203
|
+
const ledger = await resolveMemberLedger(cwd);
|
|
204
|
+
return {
|
|
205
|
+
cwd,
|
|
206
|
+
commit,
|
|
207
|
+
envs,
|
|
208
|
+
compiled,
|
|
209
|
+
releaseRule,
|
|
210
|
+
toBuild,
|
|
211
|
+
carried: artifacts,
|
|
212
|
+
reused,
|
|
213
|
+
member: ledger.members.length > 0 ? ledger.members.join("/") : null,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
/** The targets and template bytes of a compile, each template by its content digest. */
|
|
217
|
+
function targetsOf(compiled) {
|
|
215
218
|
const templates = [];
|
|
216
219
|
const targets = compiled.map((t) => ({
|
|
217
220
|
env: t.env,
|
|
@@ -222,8 +225,97 @@ export async function cutRelease(req) {
|
|
|
222
225
|
return { component: tpl.component, path: tpl.path, digest };
|
|
223
226
|
}),
|
|
224
227
|
}));
|
|
225
|
-
|
|
226
|
-
|
|
228
|
+
return { targets, templates };
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* The dry run of {@link cutRelease} (#4027): the same checks and compile,
|
|
232
|
+
* then what the cut would build, carry and record, without building an
|
|
233
|
+
* artifact, signing, or writing anything. Throws what the cut throws before
|
|
234
|
+
* it builds, and `ReleaseLabelError` when the label is invalid or names a
|
|
235
|
+
* release of another commit.
|
|
236
|
+
*/
|
|
237
|
+
export async function planRelease(req) {
|
|
238
|
+
const p = await prepare(req);
|
|
239
|
+
const { targets } = targetsOf(p.compiled);
|
|
240
|
+
const build = [];
|
|
241
|
+
for (const env of p.envs)
|
|
242
|
+
for (const component of p.toBuild.get(env) ?? [])
|
|
243
|
+
build.push({ component, env });
|
|
244
|
+
const releaseDigest = build.length === 0 ? makeRelease({ member: p.member, commit: p.commit, artifactDigests: p.carried, targets }).releaseDigest : null;
|
|
245
|
+
const { cuts } = await readCuts({ cwd: p.cwd });
|
|
246
|
+
const labels = labelsByDigest(cuts);
|
|
247
|
+
let alreadyCut = null;
|
|
248
|
+
if (req.label !== null) {
|
|
249
|
+
const why = invalidLabel(req.label);
|
|
250
|
+
if (why)
|
|
251
|
+
throw new ReleaseLabelError("release-label-invalid", why);
|
|
252
|
+
const named = [...labels].find(([, l]) => l === req.label)?.[0];
|
|
253
|
+
if (named !== undefined) {
|
|
254
|
+
const other = await readRelease(named, { cwd: p.cwd });
|
|
255
|
+
const sameCommit = other?.commit === p.commit;
|
|
256
|
+
if (!sameCommit || (releaseDigest !== null && named !== releaseDigest)) {
|
|
257
|
+
throw new ReleaseLabelError("release-label-taken", `the label "${req.label}" already names release ${named}${other && !sameCommit ? `, cut from commit ${other.commit.slice(0, 12)}` : ""}`);
|
|
258
|
+
}
|
|
259
|
+
alreadyCut = named;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (releaseDigest !== null && alreadyCut === null && cuts.some((c) => c.releaseDigest === releaseDigest)) {
|
|
263
|
+
const own = labels.get(releaseDigest);
|
|
264
|
+
if (own !== undefined && req.label !== null && own !== req.label) {
|
|
265
|
+
throw new ReleaseLabelError("release-already-labelled", `release ${releaseDigest} is already labelled "${own}", and a release takes one label`);
|
|
266
|
+
}
|
|
267
|
+
alreadyCut = releaseDigest;
|
|
268
|
+
}
|
|
269
|
+
const steps = new Map();
|
|
270
|
+
for (const t of p.compiled) {
|
|
271
|
+
for (const [component, list] of Object.entries(t.publishSteps ?? {})) {
|
|
272
|
+
for (const step of list) {
|
|
273
|
+
const kind = typeof step.kind === "string" ? step.kind : "publish";
|
|
274
|
+
const to = typeof step.to === "string" ? step.to : null;
|
|
275
|
+
const key = JSON.stringify([component, kind, to]);
|
|
276
|
+
const entry = steps.get(key) ?? { component, kind, to, envs: [] };
|
|
277
|
+
if (!entry.envs.includes(t.env))
|
|
278
|
+
entry.envs.push(t.env);
|
|
279
|
+
steps.set(key, entry);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
commit: p.commit,
|
|
285
|
+
member: p.member,
|
|
286
|
+
label: req.label,
|
|
287
|
+
releaseDigest,
|
|
288
|
+
alreadyCut,
|
|
289
|
+
targets: targets.map((t) => ({ env: t.env, params: t.params, templates: t.templates.map(({ component, path }) => ({ component, path })) })),
|
|
290
|
+
build,
|
|
291
|
+
reused: p.reused,
|
|
292
|
+
publishSteps: [...steps.values()],
|
|
293
|
+
signatureRequired: p.releaseRule.requirement !== null,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Cut a release of the member at `req.cwd` from its checkout's `HEAD`. Writes
|
|
298
|
+
* the release and the cut to the local `chant/lifecycle` branch and does not
|
|
299
|
+
* push. Throws {@link ReleaseCutError} before anything is written when the
|
|
300
|
+
* commit isn't green, the tree is dirty, or an environment can't be compiled
|
|
301
|
+
* to the same artifacts, and `ReleaseLabelError` (./release-store.ts) when the
|
|
302
|
+
* label is taken or the release already carries another one.
|
|
303
|
+
*
|
|
304
|
+
* The cut line names its run (#4027): the CI run's id and origin in CI, and
|
|
305
|
+
* outside CI an id minted from the cut's time, `local-<epoch ms>`, with the
|
|
306
|
+
* origin `{ forge: "local" }`.
|
|
307
|
+
*/
|
|
308
|
+
export async function cutRelease(req) {
|
|
309
|
+
const p = await prepare(req);
|
|
310
|
+
const { cwd, commit, compiled, releaseRule, reused } = p;
|
|
311
|
+
const artifacts = [...p.carried];
|
|
312
|
+
for (const env of p.envs) {
|
|
313
|
+
const names = p.toBuild.get(env);
|
|
314
|
+
if (names)
|
|
315
|
+
artifacts.push(...(await req.compiler.buildArtifacts(env, names)));
|
|
316
|
+
}
|
|
317
|
+
const { targets, templates } = targetsOf(compiled);
|
|
318
|
+
const release = makeRelease({ member: p.member, commit, artifactDigests: artifacts, targets });
|
|
227
319
|
const timestamp = (req.now ?? (() => new Date()))().toISOString();
|
|
228
320
|
const signed = { releaseDigest: release.releaseDigest, label: req.label, actor: req.actor, timestamp };
|
|
229
321
|
let signature = null;
|
|
@@ -260,7 +352,8 @@ export async function cutRelease(req) {
|
|
|
260
352
|
label: req.label,
|
|
261
353
|
actor: req.actor,
|
|
262
354
|
timestamp,
|
|
263
|
-
|
|
355
|
+
runId: ci?.runId ?? `local-${Date.parse(timestamp)}`,
|
|
356
|
+
runOrigin: ci?.runOrigin ?? { forge: "local" },
|
|
264
357
|
signature,
|
|
265
358
|
}, { cwd });
|
|
266
359
|
return {
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Join a commit, a release, its gates and its deploy records through the
|
|
3
|
+
* release digest (#4043, ws-104).
|
|
4
|
+
*
|
|
5
|
+
* The records already name one another. A release file holds its `commit`; a
|
|
6
|
+
* release gate's pending fact and resolution hold the `releaseDigest`; a deploy
|
|
7
|
+
* record holds the `releaseDigest` when the deploy was made from a release.
|
|
8
|
+
* From any one of the four, the others are one lookup away:
|
|
9
|
+
*
|
|
10
|
+
* commit to releases `_releases/*.json` `commit`
|
|
11
|
+
* release to gates `releaseDigest` on the records of `_gates/release.jsonl`
|
|
12
|
+
* release to deploys `releaseDigest` on the records of every `<env>/releases.jsonl`
|
|
13
|
+
*
|
|
14
|
+
* This is the one place that does it, for the readers that need the chain
|
|
15
|
+
* (the why chain of #4023, behold). Release plus a deploy record's `env`
|
|
16
|
+
* names the release target.
|
|
17
|
+
*
|
|
18
|
+
* Read-only. Reads the local `chant/lifecycle` branch; fetch it first for the
|
|
19
|
+
* remote's records. A release digest or commit that nothing recorded joins to
|
|
20
|
+
* an empty list rather than an error.
|
|
21
|
+
*/
|
|
22
|
+
import { type GateResolutionRecord, type PendingGateRecord } from "./gate-ledger.js";
|
|
23
|
+
import { type ReleaseRecord } from "./release-ledger.js";
|
|
24
|
+
import { type Release, type ReleaseCut } from "./release-store.js";
|
|
25
|
+
import type { LedgerLocation } from "./git.js";
|
|
26
|
+
/** Where a join starts. Each names the others one lookup away. */
|
|
27
|
+
export type ReleaseJoinStart =
|
|
28
|
+
/** A full commit sha, or a prefix of at least 7 characters. Joins to every release cut from it. */
|
|
29
|
+
{
|
|
30
|
+
commit: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Several full commit shas, or prefixes of at least 7 characters. Joins to
|
|
34
|
+
* every release cut from any of them, reading the ledgers once (#4023).
|
|
35
|
+
*/
|
|
36
|
+
| {
|
|
37
|
+
commits: readonly string[];
|
|
38
|
+
}
|
|
39
|
+
/** A release's label or its `releaseDigest`. */
|
|
40
|
+
| {
|
|
41
|
+
release: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A deploy record. It joins through its `releaseDigest`; a record with none
|
|
45
|
+
* but an admission by the release gate joins through the resolution that
|
|
46
|
+
* admission names.
|
|
47
|
+
*/
|
|
48
|
+
| {
|
|
49
|
+
deploy: Pick<ReleaseRecord, "releaseDigest" | "admission">;
|
|
50
|
+
}
|
|
51
|
+
/** A release gate's pending fact or resolution. */
|
|
52
|
+
| {
|
|
53
|
+
gate: Pick<PendingGateRecord | GateResolutionRecord, "releaseDigest">;
|
|
54
|
+
};
|
|
55
|
+
/** One release with everything the digest joins to it. */
|
|
56
|
+
export interface JoinedRelease {
|
|
57
|
+
releaseDigest: string;
|
|
58
|
+
/** The label of the release, or null when it was cut with none. */
|
|
59
|
+
label: string | null;
|
|
60
|
+
/** The green commit the release was cut from. */
|
|
61
|
+
commit: string;
|
|
62
|
+
release: Release;
|
|
63
|
+
/** Every cut of the release, oldest first. */
|
|
64
|
+
cuts: ReleaseCut[];
|
|
65
|
+
/** The release gate's facts for this release (`_gates/release.jsonl`), oldest first. */
|
|
66
|
+
gates: {
|
|
67
|
+
pending: PendingGateRecord[];
|
|
68
|
+
resolutions: GateResolutionRecord[];
|
|
69
|
+
};
|
|
70
|
+
/** Every deploy record that names the release, across environments, oldest first: by its `releaseDigest`, or, without one, by the release gate resolution its admission names. Each record's `env` with the release names the target. */
|
|
71
|
+
deploys: ReleaseRecord[];
|
|
72
|
+
}
|
|
73
|
+
/** What {@link joinRelease} returns. */
|
|
74
|
+
export interface ReleaseJoin {
|
|
75
|
+
/** The releases the starting point joins to: one for a release, a gate or a deploy, any number for a commit. */
|
|
76
|
+
releases: JoinedRelease[];
|
|
77
|
+
/** Why `releases` is empty, when the starting point could not be followed. Absent otherwise. */
|
|
78
|
+
reason?: string;
|
|
79
|
+
}
|
|
80
|
+
/** The version of the shape above, for a reader that stores it. Chant 0.124.29 and newer. */
|
|
81
|
+
export declare const RELEASE_JOIN_VERSION = 1;
|
|
82
|
+
/**
|
|
83
|
+
* Follow one record to the rest of its chain. Never throws for an unknown
|
|
84
|
+
* starting point; a ledger that can't be read does throw, as those readers do.
|
|
85
|
+
*/
|
|
86
|
+
export declare function joinRelease(from: ReleaseJoinStart, loc?: LedgerLocation): Promise<ReleaseJoin>;
|
|
87
|
+
/**
|
|
88
|
+
* The release a deploy record names, over the release gate's resolutions
|
|
89
|
+
* already read: its own `releaseDigest`, else the one on the resolution its
|
|
90
|
+
* admission names. Undefined when it was not made from a release. The rule
|
|
91
|
+
* {@link joinRelease} follows, for a reader that holds the ledgers already,
|
|
92
|
+
* such as retention's garbage collection (#4036).
|
|
93
|
+
*/
|
|
94
|
+
export declare function releaseOfDeploy(record: Pick<ReleaseRecord, "releaseDigest" | "admission">, releaseGateResolutions: readonly Pick<GateResolutionRecord, "gate" | "timestamp" | "releaseDigest">[]): string | undefined;
|
|
95
|
+
//# sourceMappingURL=release-join.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-join.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-join.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAkB,KAAK,oBAAoB,EAAE,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClG,OAAO,EAA8C,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAClG,OAAO,EAA6C,KAAK,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC3G,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAE5C,kEAAkE;AAClE,MAAM,MAAM,gBAAgB;AAC1B,mGAAmG;AACjG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE;AACpB;;;GAGG;GACD;IAAE,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE;AAChC,gDAAgD;GAC9C;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE;AACrB;;;;GAIG;GACD;IAAE,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,eAAe,GAAG,WAAW,CAAC,CAAA;CAAE;AAChE,mDAAmD;GACjD;IAAE,IAAI,EAAE,IAAI,CAAC,iBAAiB,GAAG,oBAAoB,EAAE,eAAe,CAAC,CAAA;CAAE,CAAC;AAE9E,0DAA0D;AAC1D,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,8CAA8C;IAC9C,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,wFAAwF;IACxF,KAAK,EAAE;QAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC;QAAC,WAAW,EAAE,oBAAoB,EAAE,CAAA;KAAE,CAAC;IAC7E,yOAAyO;IACzO,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,wCAAwC;AACxC,MAAM,WAAW,WAAW;IAC1B,gHAAgH;IAChH,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,gGAAgG;IAChG,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,6FAA6F;AAC7F,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAItC;;;GAGG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,GAAE,cAAmB,GAAG,OAAO,CAAC,WAAW,CAAC,CAwExG;AAaD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,eAAe,GAAG,WAAW,CAAC,EAC1D,sBAAsB,EAAE,SAAS,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,WAAW,GAAG,eAAe,CAAC,EAAE,GACpG,MAAM,GAAG,SAAS,CAKpB"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Join a commit, a release, its gates and its deploy records through the
|
|
3
|
+
* release digest (#4043, ws-104).
|
|
4
|
+
*
|
|
5
|
+
* The records already name one another. A release file holds its `commit`; a
|
|
6
|
+
* release gate's pending fact and resolution hold the `releaseDigest`; a deploy
|
|
7
|
+
* record holds the `releaseDigest` when the deploy was made from a release.
|
|
8
|
+
* From any one of the four, the others are one lookup away:
|
|
9
|
+
*
|
|
10
|
+
* commit to releases `_releases/*.json` `commit`
|
|
11
|
+
* release to gates `releaseDigest` on the records of `_gates/release.jsonl`
|
|
12
|
+
* release to deploys `releaseDigest` on the records of every `<env>/releases.jsonl`
|
|
13
|
+
*
|
|
14
|
+
* This is the one place that does it, for the readers that need the chain
|
|
15
|
+
* (the why chain of #4023, behold). Release plus a deploy record's `env`
|
|
16
|
+
* names the release target.
|
|
17
|
+
*
|
|
18
|
+
* Read-only. Reads the local `chant/lifecycle` branch; fetch it first for the
|
|
19
|
+
* remote's records. A release digest or commit that nothing recorded joins to
|
|
20
|
+
* an empty list rather than an error.
|
|
21
|
+
*/
|
|
22
|
+
import { RELEASE_GATE_OP } from "../op/gate-name.js";
|
|
23
|
+
import { readGateLedger } from "./gate-ledger.js";
|
|
24
|
+
import { listReleaseEnvironments, readReleaseLedger } from "./release-ledger.js";
|
|
25
|
+
import { labelsByDigest, readAllReleases, readCuts } from "./release-store.js";
|
|
26
|
+
/** The version of the shape above, for a reader that stores it. Chant 0.124.29 and newer. */
|
|
27
|
+
export const RELEASE_JOIN_VERSION = 1;
|
|
28
|
+
const MIN_COMMIT_PREFIX = 7;
|
|
29
|
+
/**
|
|
30
|
+
* Follow one record to the rest of its chain. Never throws for an unknown
|
|
31
|
+
* starting point; a ledger that can't be read does throw, as those readers do.
|
|
32
|
+
*/
|
|
33
|
+
export async function joinRelease(from, loc = {}) {
|
|
34
|
+
const { releases } = await readAllReleases(loc);
|
|
35
|
+
const { cuts } = await readCuts(loc);
|
|
36
|
+
const labels = labelsByDigest(cuts);
|
|
37
|
+
let digests;
|
|
38
|
+
let reason;
|
|
39
|
+
if ("commit" in from) {
|
|
40
|
+
const sha = from.commit.toLowerCase();
|
|
41
|
+
if (sha.length < MIN_COMMIT_PREFIX) {
|
|
42
|
+
return { releases: [], reason: `a commit needs at least ${MIN_COMMIT_PREFIX} characters to join on` };
|
|
43
|
+
}
|
|
44
|
+
digests = releases.filter((r) => r.commit.toLowerCase().startsWith(sha)).map((r) => r.releaseDigest);
|
|
45
|
+
if (digests.length === 0)
|
|
46
|
+
reason = `no release was cut from commit ${from.commit}`;
|
|
47
|
+
}
|
|
48
|
+
else if ("commits" in from) {
|
|
49
|
+
const shas = from.commits.map((c) => c.toLowerCase());
|
|
50
|
+
if (shas.some((sha) => sha.length < MIN_COMMIT_PREFIX)) {
|
|
51
|
+
return { releases: [], reason: `a commit needs at least ${MIN_COMMIT_PREFIX} characters to join on` };
|
|
52
|
+
}
|
|
53
|
+
digests = releases.filter((r) => shas.some((sha) => r.commit.toLowerCase().startsWith(sha))).map((r) => r.releaseDigest);
|
|
54
|
+
if (digests.length === 0)
|
|
55
|
+
reason = shas.length === 0 ? "no commit was given to join on" : `no release was cut from ${shas.length === 1 ? `commit ${from.commits[0]}` : `any of ${shas.length} commits`}`;
|
|
56
|
+
}
|
|
57
|
+
else if ("release" in from) {
|
|
58
|
+
const ref = from.release;
|
|
59
|
+
const byDigest = releases.find((r) => r.releaseDigest === ref);
|
|
60
|
+
const byLabel = [...labels].find(([, label]) => label === ref)?.[0];
|
|
61
|
+
const found = byDigest?.releaseDigest ?? byLabel;
|
|
62
|
+
digests = found ? [found] : [];
|
|
63
|
+
if (digests.length === 0)
|
|
64
|
+
reason = `no release is labelled or digested "${ref}"`;
|
|
65
|
+
}
|
|
66
|
+
else if ("deploy" in from) {
|
|
67
|
+
const digest = from.deploy.releaseDigest ?? (await releaseOfAdmission(from.deploy.admission, loc));
|
|
68
|
+
digests = digest ? [digest] : [];
|
|
69
|
+
if (digests.length === 0)
|
|
70
|
+
reason = "the deploy record names no release: it was not made from one";
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
const digest = from.gate.releaseDigest;
|
|
74
|
+
digests = digest ? [digest] : [];
|
|
75
|
+
if (digests.length === 0)
|
|
76
|
+
reason = "the gate binds no release: it is not a release gate";
|
|
77
|
+
}
|
|
78
|
+
const known = new Map(releases.map((r) => [r.releaseDigest, r]));
|
|
79
|
+
const wanted = [...new Set(digests)].filter((d) => known.has(d));
|
|
80
|
+
if (digests.length > 0 && wanted.length === 0)
|
|
81
|
+
reason = `release ${digests[0]} is named but its file is not on this checkout's chant/lifecycle`;
|
|
82
|
+
if (wanted.length === 0)
|
|
83
|
+
return { releases: [], ...(reason ? { reason } : {}) };
|
|
84
|
+
const gateLedger = await readGateLedger(RELEASE_GATE_OP, loc);
|
|
85
|
+
// A record names its release by `releaseDigest`, or, with none, through the
|
|
86
|
+
// release gate resolution its admission names (#4045), as releaseOfDeploy reads it.
|
|
87
|
+
const records = [];
|
|
88
|
+
for (const env of await listReleaseEnvironments(loc)) {
|
|
89
|
+
for (const record of (await readReleaseLedger(env, loc)).records) {
|
|
90
|
+
const digest = releaseOfDeploy(record, gateLedger.resolutions);
|
|
91
|
+
if (digest !== undefined && wanted.includes(digest))
|
|
92
|
+
records.push({ record, digest });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const byTime = (a, b) => (a.timestamp < b.timestamp ? -1 : a.timestamp > b.timestamp ? 1 : 0);
|
|
96
|
+
return {
|
|
97
|
+
releases: wanted.map((digest) => {
|
|
98
|
+
const release = known.get(digest);
|
|
99
|
+
return {
|
|
100
|
+
releaseDigest: digest,
|
|
101
|
+
label: labels.get(digest) ?? null,
|
|
102
|
+
commit: release.commit,
|
|
103
|
+
release,
|
|
104
|
+
cuts: cuts.filter((c) => c.releaseDigest === digest),
|
|
105
|
+
gates: {
|
|
106
|
+
pending: gateLedger.pending.filter((p) => p.releaseDigest === digest),
|
|
107
|
+
resolutions: gateLedger.resolutions.filter((r) => r.releaseDigest === digest),
|
|
108
|
+
},
|
|
109
|
+
deploys: records.filter((r) => r.digest === digest).map((r) => r.record).sort(byTime),
|
|
110
|
+
};
|
|
111
|
+
}),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* The release a deploy record's admission names, when the record itself has no
|
|
116
|
+
* `releaseDigest`: the resolution it points at, in the release gate's ledger,
|
|
117
|
+
* carries one (#4045).
|
|
118
|
+
*/
|
|
119
|
+
async function releaseOfAdmission(admission, loc) {
|
|
120
|
+
if (!admission || admission.op !== RELEASE_GATE_OP)
|
|
121
|
+
return undefined;
|
|
122
|
+
const { resolutions } = await readGateLedger(RELEASE_GATE_OP, loc);
|
|
123
|
+
return releaseOfDeploy({ admission }, resolutions);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* The release a deploy record names, over the release gate's resolutions
|
|
127
|
+
* already read: its own `releaseDigest`, else the one on the resolution its
|
|
128
|
+
* admission names. Undefined when it was not made from a release. The rule
|
|
129
|
+
* {@link joinRelease} follows, for a reader that holds the ledgers already,
|
|
130
|
+
* such as retention's garbage collection (#4036).
|
|
131
|
+
*/
|
|
132
|
+
export function releaseOfDeploy(record, releaseGateResolutions) {
|
|
133
|
+
if (record.releaseDigest !== undefined)
|
|
134
|
+
return record.releaseDigest;
|
|
135
|
+
const admission = record.admission;
|
|
136
|
+
if (!admission || admission.op !== RELEASE_GATE_OP)
|
|
137
|
+
return undefined;
|
|
138
|
+
return releaseGateResolutions.find((r) => r.gate === admission.gate && r.timestamp === admission.resolvedAt && r.releaseDigest !== undefined)?.releaseDigest;
|
|
139
|
+
}
|
|
@@ -41,15 +41,20 @@ export interface RunOrigin {
|
|
|
41
41
|
* Which id space minted `runId`: `github` (a GitHub Actions run id — also
|
|
42
42
|
* the spelling Forgejo Actions uses, since it implements the same env
|
|
43
43
|
* contract; `url` disambiguates the actual host), `gitlab` (a CI pipeline
|
|
44
|
-
* id), `op` (an orchestrator/Op run id),
|
|
45
|
-
* that ran the deploy, resolvable nowhere)
|
|
44
|
+
* id), `op` (an orchestrator/Op run id), `local` (minted on the machine
|
|
45
|
+
* that ran the deploy, resolvable nowhere), or `chant` (a job the chant
|
|
46
|
+
* runner ran, `chant ci run`, #4094, named by its Op run id). `chant` was
|
|
47
|
+
* added within contract 1 by {@link RUN_ORIGIN_CHANT_FLOOR}, so a reader
|
|
48
|
+
* that switches on `forge` keeps a case for a value it does not know.
|
|
46
49
|
*/
|
|
47
|
-
forge: "github" | "gitlab" | "op" | "local";
|
|
50
|
+
forge: "github" | "gitlab" | "op" | "local" | "chant";
|
|
48
51
|
/** Repo/project slug on the forge (`GITHUB_REPOSITORY` / `CI_PROJECT_PATH`), when the environment named one. */
|
|
49
52
|
repo?: string;
|
|
50
53
|
/** Resolved link to the run, when the environment provided enough to build one. */
|
|
51
54
|
url?: string;
|
|
52
55
|
}
|
|
56
|
+
/** The first chant that writes `runOrigin.forge: "chant"`, for a job `chant ci run` ran (#4094). */
|
|
57
|
+
export declare const RUN_ORIGIN_CHANT_FLOOR = "0.124.30";
|
|
53
58
|
/**
|
|
54
59
|
* The gate resolution that admitted a deploy (#4020): the gate's address in the
|
|
55
60
|
* gate ledger (`_gates/<op>.jsonl`, `op` and `gate`) and when the resolution
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release-ledger.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-ledger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,EAAyC,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EAAwG,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAElJ,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAG1D,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC9I,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB
|
|
1
|
+
{"version":3,"file":"release-ledger.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-ledger.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,6 +33,8 @@ import { appendReleaseRecordLine, readReleaseLedgerLines, listLedgerEnvironments
|
|
|
33
33
|
import { parseReleaseLedger, validateReleaseRecord } from "./release-read.js";
|
|
34
34
|
// The pure readers live apart, so a bundle can import them without git (#3865).
|
|
35
35
|
export { validateReleaseRecord, parseReleaseLedger, releaseLedgerLines, readReleaseRecords, listReleaseEnvironmentsOn } from "./release-read.js";
|
|
36
|
+
/** The first chant that writes `runOrigin.forge: "chant"`, for a job `chant ci run` ran (#4094). */
|
|
37
|
+
export const RUN_ORIGIN_CHANT_FLOOR = "0.124.30";
|
|
36
38
|
/**
|
|
37
39
|
* The approver and admission a release records for the resolutions of its gate
|
|
38
40
|
* (#4020): those of `gate` on `op` bound to `planDigest`. The approver is the
|