@intentius/chant 0.124.39 → 0.124.41
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/__fixtures__/oidc-emulator.d.ts +49 -0
- package/dist/__fixtures__/oidc-emulator.d.ts.map +1 -0
- package/dist/__fixtures__/oidc-emulator.js +89 -0
- package/dist/ci-handover.d.ts +117 -0
- package/dist/ci-handover.d.ts.map +1 -0
- package/dist/ci-handover.js +217 -0
- package/dist/ci-identity.d.ts +190 -0
- package/dist/ci-identity.d.ts.map +1 -0
- package/dist/ci-identity.js +219 -0
- package/dist/cli/component-endpoint.d.ts +20 -0
- package/dist/cli/component-endpoint.d.ts.map +1 -0
- package/dist/cli/component-endpoint.js +36 -0
- package/dist/cli/handlers/approve.d.ts +2 -1
- package/dist/cli/handlers/approve.d.ts.map +1 -1
- package/dist/cli/handlers/approve.js +20 -6
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.js +15 -1
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.js +26 -4
- package/dist/cli/handlers/gate-resume.d.ts +3 -0
- package/dist/cli/handlers/gate-resume.d.ts.map +1 -1
- package/dist/cli/handlers/gate-resume.js +15 -2
- package/dist/cli/handlers/lock.d.ts +8 -0
- package/dist/cli/handlers/lock.d.ts.map +1 -0
- package/dist/cli/handlers/lock.js +197 -0
- package/dist/cli/handlers/pr-env.d.ts +34 -0
- package/dist/cli/handlers/pr-env.d.ts.map +1 -0
- package/dist/cli/handlers/pr-env.js +436 -0
- package/dist/cli/handlers/pr.d.ts +74 -0
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +514 -58
- package/dist/cli/handlers/promote.d.ts.map +1 -1
- package/dist/cli/handlers/promote.js +16 -2
- package/dist/cli/handlers/query.d.ts +6 -0
- package/dist/cli/handlers/query.d.ts.map +1 -0
- package/dist/cli/handlers/query.js +80 -0
- package/dist/cli/handlers/run.d.ts +4 -1
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/handlers/run.js +17 -6
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +41 -2
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +31 -2
- package/dist/cli/registry.d.ts +12 -2
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/components/auto-release.d.ts +35 -3
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/auto-release.js +29 -2
- package/dist/components/cli-support.d.ts +2 -0
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/cli-support.js +2 -0
- package/dist/components/deploy-units.d.ts.map +1 -1
- package/dist/components/deploy-units.js +5 -0
- package/dist/components/fan-out-run.d.ts +28 -0
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-run.js +27 -3
- package/dist/components/pr-environment.d.ts +298 -0
- package/dist/components/pr-environment.d.ts.map +1 -0
- package/dist/components/pr-environment.js +406 -0
- package/dist/components/pr-hooks.d.ts +66 -0
- package/dist/components/pr-hooks.d.ts.map +1 -0
- package/dist/components/pr-hooks.js +119 -0
- package/dist/components/pr-pipeline.d.ts +72 -2
- package/dist/components/pr-pipeline.d.ts.map +1 -1
- package/dist/components/pr-pipeline.js +96 -5
- package/dist/components/pr-policy.d.ts +109 -0
- package/dist/components/pr-policy.d.ts.map +1 -0
- package/dist/components/pr-policy.js +150 -0
- package/dist/components/pr-run.d.ts.map +1 -1
- package/dist/components/pr-run.js +5 -3
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/promote.js +39 -16
- package/dist/gate-decision.d.ts +15 -2
- package/dist/gate-decision.d.ts.map +1 -1
- package/dist/gate-decision.js +17 -2
- package/dist/gate-policy.d.ts +140 -0
- package/dist/gate-policy.d.ts.map +1 -0
- package/dist/gate-policy.js +242 -0
- package/dist/lifecycle/__fixtures__/publish-fakes.d.ts.map +1 -1
- package/dist/lifecycle/__fixtures__/publish-fakes.js +6 -1
- package/dist/lifecycle/gate-checkpoint.d.ts +1 -1
- package/dist/lifecycle/gate-checkpoint.js +1 -1
- package/dist/{workspace/trust → lifecycle}/gate-seal.d.ts +1 -1
- package/dist/lifecycle/gate-seal.d.ts.map +1 -0
- package/dist/lifecycle/publish-declaration.d.ts.map +1 -1
- package/dist/lifecycle/publish-declaration.js +4 -3
- package/dist/lifecycle/publish-npm.d.ts +2 -2
- package/dist/lifecycle/publish-npm.d.ts.map +1 -1
- package/dist/lifecycle/publish-npm.js +31 -8
- package/dist/lifecycle/query.d.ts +68 -0
- package/dist/lifecycle/query.d.ts.map +1 -0
- package/dist/lifecycle/query.js +246 -0
- package/dist/lifecycle/release-ledger.d.ts +31 -0
- package/dist/lifecycle/release-ledger.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.js +19 -1
- package/dist/lifecycle/run-ledger.d.ts +13 -0
- package/dist/lifecycle/run-ledger.d.ts.map +1 -1
- package/dist/lifecycle/run-ledger.js +16 -0
- package/dist/lifecycle/status.d.ts +5 -1
- package/dist/lifecycle/status.d.ts.map +1 -1
- package/dist/lifecycle/status.js +10 -5
- package/dist/lifecycle/target-lock.d.ts +97 -0
- package/dist/lifecycle/target-lock.d.ts.map +1 -0
- package/dist/lifecycle/target-lock.js +286 -0
- package/dist/live-endpoint.d.ts +18 -0
- package/dist/live-endpoint.d.ts.map +1 -1
- package/dist/live-endpoint.js +27 -0
- package/dist/op/activities/activity-contracts.d.ts +30 -0
- package/dist/op/activities/activity-contracts.d.ts.map +1 -1
- package/dist/op/activities/activity-contracts.js +26 -0
- package/dist/op/activities/index.d.ts +2 -0
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/index.js +4 -0
- package/dist/op/activities/review-agent.d.ts +137 -0
- package/dist/op/activities/review-agent.d.ts.map +1 -0
- package/dist/op/activities/review-agent.js +266 -0
- package/dist/op/builders.d.ts +9 -0
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/builders.js +11 -0
- package/dist/op/cron.d.ts +8 -0
- package/dist/op/cron.d.ts.map +1 -1
- package/dist/op/cron.js +51 -0
- package/dist/op/gate-approval.d.ts +20 -13
- package/dist/op/gate-approval.d.ts.map +1 -1
- package/dist/op/gate-approval.js +13 -18
- package/dist/op/gate-quorum.d.ts +131 -0
- package/dist/op/gate-quorum.d.ts.map +1 -0
- package/dist/op/gate-quorum.js +183 -0
- package/dist/op/gate-resume.d.ts +4 -2
- package/dist/op/gate-resume.d.ts.map +1 -1
- package/dist/op/gate-resume.js +5 -4
- package/dist/op/gate-review.js +1 -1
- package/dist/op/gate.d.ts +32 -4
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/gate.js +40 -24
- package/dist/op/index.d.ts +6 -4
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/index.js +4 -3
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-executor.js +9 -3
- package/dist/op/op-waves-run.d.ts +62 -1
- package/dist/op/op-waves-run.d.ts.map +1 -1
- package/dist/op/op-waves-run.js +190 -11
- package/dist/op/op-waves.d.ts +55 -3
- package/dist/op/op-waves.d.ts.map +1 -1
- package/dist/op/op-waves.js +63 -8
- package/dist/op/schedule-overdue.d.ts +57 -0
- package/dist/op/schedule-overdue.d.ts.map +1 -0
- package/dist/op/schedule-overdue.js +138 -0
- package/dist/override-gate.d.ts +2 -2
- package/dist/override-gate.d.ts.map +1 -1
- package/dist/override-gate.js +1 -1
- package/dist/pr-forge.d.ts +36 -0
- package/dist/pr-forge.d.ts.map +1 -1
- package/dist/pr-forge.js +82 -0
- package/dist/pr-loop.d.ts +90 -1
- package/dist/pr-loop.d.ts.map +1 -1
- package/dist/pr-loop.js +77 -3
- package/dist/pr-post.d.ts +72 -0
- package/dist/pr-post.d.ts.map +1 -0
- package/dist/pr-post.js +134 -0
- package/dist/wave-blocked.d.ts +79 -0
- package/dist/wave-blocked.d.ts.map +1 -0
- package/dist/wave-blocked.js +245 -0
- package/dist/wave-engine.d.ts +6 -0
- package/dist/wave-engine.d.ts.map +1 -1
- package/dist/wave-engine.js +2 -0
- package/dist/wave-runtime.mjs +239 -239
- package/dist/workspace/__fixtures__/two-member-workspace.d.ts +1 -0
- package/dist/workspace/__fixtures__/two-member-workspace.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/two-member-workspace.js +1 -1
- package/dist/workspace/ci-branches.d.ts +51 -0
- package/dist/workspace/ci-branches.d.ts.map +1 -0
- package/dist/workspace/ci-branches.js +69 -0
- package/dist/workspace/ci-cloud-identity.d.ts +11 -0
- package/dist/workspace/ci-cloud-identity.d.ts.map +1 -0
- package/dist/workspace/ci-cloud-identity.js +24 -0
- package/dist/workspace/ci-locks.d.ts +12 -0
- package/dist/workspace/ci-locks.d.ts.map +1 -0
- package/dist/workspace/ci-locks.js +6 -0
- package/dist/workspace/ci-run.d.ts +24 -1
- package/dist/workspace/ci-run.d.ts.map +1 -1
- package/dist/workspace/ci-run.js +85 -6
- package/dist/workspace/declaration.d.ts +63 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.js +72 -1
- package/dist/workspace/declaration.schema.json +147 -0
- package/dist/workspace/identity-gate-rule.d.ts +1 -1
- package/dist/workspace/identity-gate-rule.d.ts.map +1 -1
- package/dist/workspace/identity-gate-rule.js +1 -1
- package/dist/workspace/identity.d.ts +1 -1
- package/dist/workspace/identity.d.ts.map +1 -1
- package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
- package/dist/workspace/lineage-upgrade.js +8 -5
- 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 +23 -0
- package/dist/workspace/pr-report.schema.json +73 -2
- package/dist/workspace/security.d.ts.map +1 -1
- package/dist/workspace/security.js +4 -0
- package/dist/workspace/status-gates.d.ts +3 -2
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status-gates.js +8 -7
- package/dist/workspace/status.d.ts +3 -1
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/status.js +7 -3
- package/dist/workspace/status.schema.json +1 -0
- package/dist/workspace/trust/seal.d.ts +2 -2
- package/dist/workspace/trust/seal.d.ts.map +1 -1
- package/dist/workspace/trust/seal.js +2 -2
- package/package.json +1 -1
- package/src/__fixtures__/oidc-emulator.ts +118 -0
- package/src/ci-handover.test.ts +209 -0
- package/src/ci-handover.ts +237 -0
- package/src/ci-identity.test.ts +201 -0
- package/src/ci-identity.ts +310 -0
- package/src/cli/component-endpoint.ts +43 -0
- package/src/cli/handlers/approve.ts +18 -5
- package/src/cli/handlers/build.ts +15 -1
- package/src/cli/handlers/fan-out.test.ts +10 -0
- package/src/cli/handlers/fan-out.ts +29 -4
- package/src/cli/handlers/gate-resume.ts +16 -2
- package/src/cli/handlers/lock.test.ts +98 -0
- package/src/cli/handlers/lock.ts +202 -0
- package/src/cli/handlers/operator.test.ts +3 -1
- package/src/cli/handlers/pr-endpoint.test.ts +169 -0
- package/src/cli/handlers/pr-env.ts +462 -0
- package/src/cli/handlers/pr-waves-blocked.test.ts +247 -0
- package/src/cli/handlers/pr.test.ts +184 -0
- package/src/cli/handlers/pr.ts +508 -64
- package/src/cli/handlers/promote.ts +25 -2
- package/src/cli/handlers/query.ts +78 -0
- package/src/cli/handlers/run.test.ts +2 -1
- package/src/cli/handlers/run.ts +16 -5
- package/src/cli/main.ts +41 -2
- package/src/cli/parse-args.ts +23 -2
- package/src/cli/registry.ts +12 -2
- package/src/components/auto-release-infra.test.ts +131 -0
- package/src/components/auto-release.test.ts +40 -1
- package/src/components/auto-release.ts +50 -4
- package/src/components/cli-support.ts +4 -0
- package/src/components/deploy-units.ts +5 -0
- package/src/components/fan-out-run.ts +39 -2
- package/src/components/fan-out-waves.test.ts +45 -1
- package/src/components/pr-environment.test.ts +249 -0
- package/src/components/pr-environment.ts +538 -0
- package/src/components/pr-hooks.test.ts +118 -0
- package/src/components/pr-hooks.ts +157 -0
- package/src/components/pr-pipeline.ts +130 -5
- package/src/components/pr-policy.test.ts +145 -0
- package/src/components/pr-policy.ts +211 -0
- package/src/components/pr-run.ts +5 -2
- package/src/components/promote.test.ts +39 -0
- package/src/components/promote.ts +38 -14
- package/src/gate-decision-bundle.test.ts +4 -3
- package/src/gate-decision.ts +39 -2
- package/src/gate-policy-bundle.test.ts +28 -0
- package/src/gate-policy.test.ts +162 -0
- package/src/gate-policy.ts +298 -0
- package/src/lifecycle/__fixtures__/publish-fakes.ts +6 -1
- package/src/lifecycle/gate-checkpoint.ts +1 -1
- package/src/{workspace/trust → lifecycle}/gate-seal.ts +1 -1
- package/src/lifecycle/publish-declaration.ts +4 -3
- package/src/lifecycle/publish-npm.ts +33 -8
- package/src/lifecycle/publish-targets.test.ts +36 -3
- package/src/lifecycle/query.test.ts +91 -0
- package/src/lifecycle/query.ts +315 -0
- package/src/lifecycle/release-ledger.ts +42 -1
- package/src/lifecycle/run-ledger.ts +18 -0
- package/src/lifecycle/status.test.ts +19 -0
- package/src/lifecycle/status.ts +14 -6
- package/src/lifecycle/target-lock.test.ts +195 -0
- package/src/lifecycle/target-lock.ts +347 -0
- package/src/live-endpoint.ts +31 -0
- package/src/op/activities/activity-contracts.ts +31 -0
- package/src/op/activities/index.ts +6 -0
- package/src/op/activities/review-agent.test.ts +240 -0
- package/src/op/activities/review-agent.ts +355 -0
- package/src/op/builders.ts +13 -0
- package/src/op/cron.ts +44 -0
- package/src/op/gate-alias.test.ts +2 -2
- package/src/op/gate-approval.test.ts +30 -9
- package/src/op/gate-approval.ts +23 -26
- package/src/op/gate-quorum.test.ts +139 -0
- package/src/op/gate-quorum.ts +248 -0
- package/src/op/gate-resume.ts +6 -3
- package/src/op/gate-review.ts +1 -1
- package/src/op/gate.ts +64 -23
- package/src/op/index.ts +13 -1
- package/src/op/local-executor.ts +9 -2
- package/src/op/op-waves-hook-targets.test.ts +126 -0
- package/src/op/op-waves-policy-hold.test.ts +66 -0
- package/src/op/op-waves-quorum.test.ts +101 -0
- package/src/op/op-waves-run.ts +233 -11
- package/src/op/op-waves.ts +83 -10
- package/src/op/schedule-overdue.test.ts +220 -0
- package/src/op/schedule-overdue.ts +161 -0
- package/src/override-gate-bundle.test.ts +1 -1
- package/src/override-gate.ts +2 -2
- package/src/pr-forge-bundle.test.ts +2 -2
- package/src/pr-forge.test.ts +33 -0
- package/src/pr-forge.ts +114 -0
- package/src/pr-loop-bundle.test.ts +2 -2
- package/src/pr-loop.test.ts +58 -0
- package/src/pr-loop.ts +146 -4
- package/src/pr-post.test.ts +141 -0
- package/src/pr-post.ts +159 -0
- package/src/wave-blocked-bundle.test.ts +25 -0
- package/src/wave-blocked.test.ts +146 -0
- package/src/wave-blocked.ts +271 -0
- package/src/wave-engine.ts +8 -0
- package/src/workspace/__fixtures__/two-member-workspace.ts +2 -2
- package/src/workspace/ci-branches.test.ts +62 -0
- package/src/workspace/ci-branches.ts +79 -0
- package/src/workspace/ci-cloud-identity.test.ts +53 -0
- package/src/workspace/ci-cloud-identity.ts +23 -0
- package/src/workspace/ci-locks.ts +16 -0
- package/src/workspace/ci-run-index.test.ts +2 -1
- package/src/workspace/ci-run.test.ts +133 -8
- package/src/workspace/ci-run.ts +92 -7
- package/src/workspace/declaration.schema.json +147 -0
- package/src/workspace/declaration.test.ts +76 -0
- package/src/workspace/declaration.ts +134 -2
- package/src/workspace/identity-gate-rule.ts +1 -1
- package/src/workspace/identity.ts +1 -1
- package/src/workspace/lineage-upgrade.ts +11 -8
- package/src/workspace/member-pipeline.test.ts +29 -0
- package/src/workspace/member-pipeline.ts +30 -0
- package/src/workspace/pr-report.schema.json +73 -2
- package/src/workspace/security.ts +4 -0
- package/src/workspace/status-gates.ts +9 -6
- package/src/workspace/status.schema.json +1 -0
- package/src/workspace/status.ts +11 -4
- package/src/workspace/trust/gate-seal.test.ts +1 -1
- package/src/workspace/trust/seal.ts +2 -2
- package/dist/workspace/trust/gate-seal.d.ts.map +0 -1
- /package/dist/{workspace/trust → lifecycle}/gate-seal.js +0 -0
|
@@ -179,7 +179,12 @@ if (args[0] === "publish") {
|
|
|
179
179
|
const [name, version] = split(args[1]);
|
|
180
180
|
const p = reg.packages[name];
|
|
181
181
|
if (!p) { console.error("npm error 404 Not Found - " + name); process.exit(1); }
|
|
182
|
-
if (
|
|
182
|
+
if (process.env.FAKE_NPM_VIEW_ERROR && name.includes(process.env.FAKE_NPM_VIEW_ERROR) && p.versions.includes(version)) { console.error("npm error code E500"); console.error("npm error 500 Internal Server Error - GET https://registry.example/" + name); process.exit(1); }
|
|
183
|
+
if (p.lag && p.lag[version] > 0) {
|
|
184
|
+
p.lag[version] -= 1; save();
|
|
185
|
+
// A new package npm does not serve yet answers 404, as the real registry does.
|
|
186
|
+
if (process.env.FAKE_NPM_LAG_404) { console.error("npm error code E404"); console.error("npm error 404 No match found for version " + version); process.exit(1); }
|
|
187
|
+
}
|
|
183
188
|
else if (p.versions.includes(version)) console.log(version);
|
|
184
189
|
} else if (args[0] === "dist-tag" && args[1] === "add") {
|
|
185
190
|
const [name, version] = split(args[2]);
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* The run writes the file just before it appends the pending fact, and puts
|
|
7
7
|
* the file's digest on that fact as `checkpointDigest`. `chant approve`
|
|
8
8
|
* copies the digest onto the approval, the way it copies the plan digest, and
|
|
9
|
-
* a seal covers it (
|
|
9
|
+
* a seal covers it (`./gate-seal.ts`). A later run that
|
|
10
10
|
* resumes at the gate reads the file back and checks it against the digest
|
|
11
11
|
* the approver saw, so a value pushed onto the branch after the approval is
|
|
12
12
|
* refused rather than carried into the steps after the gate.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* The run writes the file just before it appends the pending fact, and puts
|
|
7
7
|
* the file's digest on that fact as `checkpointDigest`. `chant approve`
|
|
8
8
|
* copies the digest onto the approval, the way it copies the plan digest, and
|
|
9
|
-
* a seal covers it (
|
|
9
|
+
* a seal covers it (`./gate-seal.ts`). A later run that
|
|
10
10
|
* resumes at the gate reads the file back and checks it against the digest
|
|
11
11
|
* the approver saw, so a value pushed onto the branch after the approval is
|
|
12
12
|
* refused rather than carried into the steps after the gate.
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* signers line with no `no-touch-required` option (which the signers parser
|
|
18
18
|
* does not accept). An RSA signature over SHA-1 does not verify.
|
|
19
19
|
*/
|
|
20
|
-
import type { Signer } from "
|
|
20
|
+
import type { Signer } from "../workspace/trust/trust-files.js";
|
|
21
21
|
/**
|
|
22
22
|
* The ssh signature namespace of a gate approval's seal (#3163, ws-080), so a
|
|
23
23
|
* verdict, record or commit signature can't stand in for one.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-seal.d.ts","sourceRoot":"","sources":["../../src/lifecycle/gate-seal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AAE7D;;;GAGG;AACH,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAEhD,kIAAkI;AAClI,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,uFAAuF;IACvF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iGAAiG;IACjG,WAAW,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzF,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,kBAAkB,GAAG,kBAAkB,CAWxE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAGtG;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,CAKpE;AA8BD,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAmCD,iDAAiD;AACjD,MAAM,MAAM,iBAAiB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1F;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,iBAAiB,CA0CtI;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAU9D;AAID;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,uGAAuG;IACvG,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,yFAAyF;IACzF,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAID,kJAAkJ;AAClJ,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAYrF;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,kBAAkB,GAAG,MAAM,GAAG,IAAI,CAmB1F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish-declaration.d.ts","sourceRoot":"","sources":["../../src/lifecycle/publish-declaration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"publish-declaration.d.ts","sourceRoot":"","sources":["../../src/lifecycle/publish-declaration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB;;;;;;;;;;;;kBAqClB,CAAC;AAEZ,8FAA8F;AAC9F,eAAO,MAAM,gBAAgB;;;;;;;;kBAgBlB,CAAC;AAEZ,wFAAwF;AACxF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;kBAiBpB,CAAC;AAEZ,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAAyF,CAAC;AAE/H,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACrE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACrE,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACzE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
|
|
@@ -57,9 +57,10 @@ export const NpmPublishSchema = z
|
|
|
57
57
|
*/
|
|
58
58
|
tokenEnv: envName.optional(),
|
|
59
59
|
/**
|
|
60
|
-
*
|
|
61
|
-
* published before installing them to audit (#4244). A
|
|
62
|
-
* publish before it serves it.
|
|
60
|
+
* A cap, in seconds, on the reveal's wait for the registry to serve every
|
|
61
|
+
* version it published before installing them to audit (#4244). A
|
|
62
|
+
* registry accepts a publish before it serves it. Unset, the wait ends
|
|
63
|
+
* only when every version is served or the registry fails (#4271).
|
|
63
64
|
*/
|
|
64
65
|
registryWait: z.number().int().min(0).optional(),
|
|
65
66
|
})
|
|
@@ -61,9 +61,9 @@ export declare function npmDistTagArgs(decl: Pick<NpmPublishDeclaration, "regist
|
|
|
61
61
|
export declare function npmAuditInstallArgs(decl: Pick<NpmPublishDeclaration, "registry">): string[];
|
|
62
62
|
/** The arguments of `npm audit signatures`. */
|
|
63
63
|
export declare function npmAuditSignaturesArgs(decl: Pick<NpmPublishDeclaration, "registry">): string[];
|
|
64
|
-
/** Seconds the reveal waits for the registry to serve what it published, by default (#4244). */
|
|
65
|
-
export declare const NPM_REGISTRY_WAIT_SECONDS = 600;
|
|
66
64
|
/** Between polls of the registry while it waits. */
|
|
67
65
|
export declare const NPM_REGISTRY_POLL_MS = 10000;
|
|
66
|
+
/** Between progress lines while the reveal waits for the registry (#4271). */
|
|
67
|
+
export declare const NPM_REGISTRY_PROGRESS_MS = 60000;
|
|
68
68
|
export declare function npmTarget(decl: NpmPublishDeclaration, deps: PublishDeps): PublishTarget;
|
|
69
69
|
//# sourceMappingURL=publish-npm.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish-npm.d.ts","sourceRoot":"","sources":["../../src/lifecycle/publish-npm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAOH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,EAAqC,KAAK,cAAc,EAAE,KAAK,WAAW,EAAoB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAoDnJ,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,GAAG,QAAQ,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,EAAE,GAAG,GAAE,MAAsB,GAAG,MAAM,EAAE,CAUpL;AAED,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAElI;AAED,iIAAiI;AACjI,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,GAAG,MAAM,EAAE,CAE3F;AAED,+CAA+C;AAC/C,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,GAAG,MAAM,EAAE,CAE9F;AAuBD,
|
|
1
|
+
{"version":3,"file":"publish-npm.d.ts","sourceRoot":"","sources":["../../src/lifecycle/publish-npm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAOH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,EAAqC,KAAK,cAAc,EAAE,KAAK,WAAW,EAAoB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAoDnJ,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,GAAG,QAAQ,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,EAAE,GAAG,GAAE,MAAsB,GAAG,MAAM,EAAE,CAUpL;AAED,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAElI;AAED,iIAAiI;AACjI,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,GAAG,MAAM,EAAE,CAE3F;AAED,+CAA+C;AAC/C,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,GAAG,MAAM,EAAE,CAE9F;AAuBD,oDAAoD;AACpD,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAC3C,8EAA8E;AAC9E,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAM/C,wBAAgB,SAAS,CAAC,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,WAAW,GAAG,aAAa,CAuMvF"}
|
|
@@ -148,10 +148,12 @@ function run(bin, args, ctx, cwd = ctx.cwd, env = ctx.env) {
|
|
|
148
148
|
});
|
|
149
149
|
});
|
|
150
150
|
}
|
|
151
|
-
/** Seconds the reveal waits for the registry to serve what it published, by default (#4244). */
|
|
152
|
-
export const NPM_REGISTRY_WAIT_SECONDS = 600;
|
|
153
151
|
/** Between polls of the registry while it waits. */
|
|
154
152
|
export const NPM_REGISTRY_POLL_MS = 10000;
|
|
153
|
+
/** Between progress lines while the reveal waits for the registry (#4271). */
|
|
154
|
+
export const NPM_REGISTRY_PROGRESS_MS = 60000;
|
|
155
|
+
/** `npm view`'s answers for a version the registry does not serve yet; any other failure is the registry's error. */
|
|
156
|
+
const NPM_VIEW_NOT_YET = /\bE404\b|\b404 Not Found\b|is not in (this|the npm) registry|No match found for version|\b(ETARGET|notarget)\b/;
|
|
155
157
|
/** npm's errors for a version the registry does not serve yet. */
|
|
156
158
|
const NPM_NOT_SERVED = /\b(ETARGET|ERESOLVE|notarget)\b|No matching version found/;
|
|
157
159
|
export function npmTarget(decl, deps) {
|
|
@@ -216,28 +218,49 @@ export function npmTarget(decl, deps) {
|
|
|
216
218
|
* `npm audit signatures` there (#4049), which checks each package's
|
|
217
219
|
* registry signature and provenance attestation.
|
|
218
220
|
*/
|
|
221
|
+
/**
|
|
222
|
+
* Whether the registry serves the version yet, while the reveal waits for
|
|
223
|
+
* it (#4271). A 404, or an answer without the version, is not yet; any other
|
|
224
|
+
* failure of `npm view` is the registry's error and ends the wait.
|
|
225
|
+
*/
|
|
226
|
+
const probe = async (ctx, pkg) => {
|
|
227
|
+
const r = await npm(ctx, ["view", `${pkg.name}@${pkg.version}`, "version", ...(decl.registry ? ["--registry", decl.registry] : [])]);
|
|
228
|
+
if (r.code === 0)
|
|
229
|
+
return r.output.some((l) => l.trim() === pkg.version || l.trim() === JSON.stringify(pkg.version));
|
|
230
|
+
if (r.output.some((l) => NPM_VIEW_NOT_YET.test(l)))
|
|
231
|
+
return false;
|
|
232
|
+
const said = r.output.filter((l) => /^npm (error|ERR!)/.test(l)).at(-1) ?? r.output.at(-1) ?? "npm printed nothing";
|
|
233
|
+
throw new PublishTargetError("publish-npm-registry-failed", `npm view ${pkg.name}@${pkg.version} exited ${r.code} while the reveal waited for the registry to serve it, so nothing was audited: ${said}`, "Each package was published. Once the registry answers, run the publish again: it publishes nothing twice and audits again.");
|
|
234
|
+
};
|
|
219
235
|
/**
|
|
220
236
|
* Wait until the registry serves every version (#4244): npm accepts a
|
|
221
237
|
* publish minutes before `npm view` and `npm install` find it, so an
|
|
222
|
-
* install straight after fails with ETARGET or ERESOLVE.
|
|
238
|
+
* install straight after fails with ETARGET or ERESOLVE. The wait ends when
|
|
239
|
+
* every version is served or the registry fails (#4271), with a progress
|
|
240
|
+
* line about once a minute. `registryWait` caps it only when declared.
|
|
223
241
|
*/
|
|
224
242
|
const served = async (ctx, pkgs) => {
|
|
225
|
-
const
|
|
243
|
+
const cap = decl.registryWait === undefined ? undefined : decl.registryWait * 1000;
|
|
226
244
|
const start = now();
|
|
245
|
+
let logged;
|
|
227
246
|
let missing = pkgs;
|
|
228
247
|
for (;;) {
|
|
229
248
|
const still = [];
|
|
230
249
|
for (const pkg of missing)
|
|
231
|
-
if (!(await
|
|
250
|
+
if (!(await probe(ctx, pkg)))
|
|
232
251
|
still.push(pkg);
|
|
233
252
|
missing = still;
|
|
234
253
|
if (missing.length === 0)
|
|
235
254
|
return;
|
|
236
255
|
const names = missing.map((p) => `${p.name}@${p.version}`).join(", ");
|
|
237
|
-
|
|
238
|
-
|
|
256
|
+
const waited = now() - start;
|
|
257
|
+
if (cap !== undefined && waited >= cap) {
|
|
258
|
+
throw new PublishTargetError("publish-npm-not-served", `the registry did not serve ${names} within ${Math.round(cap / 1000)}s of the publish, so nothing was audited`, "Each package was published. Once npm serves them, run the publish again: it publishes nothing twice and audits again. `registryWait` sets the wait.");
|
|
259
|
+
}
|
|
260
|
+
if (logged === undefined || now() - logged >= NPM_REGISTRY_PROGRESS_MS) {
|
|
261
|
+
ctx.log(`waiting for the registry to serve ${names}${waited > 0 ? ` (${Math.round(waited / 1000)}s so far)` : ""}`);
|
|
262
|
+
logged = now();
|
|
239
263
|
}
|
|
240
|
-
ctx.log(`waiting for the registry to serve ${names}`);
|
|
241
264
|
await sleep(NPM_REGISTRY_POLL_MS);
|
|
242
265
|
}
|
|
243
266
|
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { LedgerReadPort } from "./ledger-port.js";
|
|
2
|
+
/** The version of the table schema below. */
|
|
3
|
+
export declare const QUERY_SCHEMA_VERSION = 1;
|
|
4
|
+
/**
|
|
5
|
+
* Each table's columns, in order, with their SQLite type. A column named in
|
|
6
|
+
* the doc as JSON holds a JSON text, for `json_extract`. Every table starts
|
|
7
|
+
* with `member`: the workspace member whose ledger the row came from, or NULL
|
|
8
|
+
* for a project outside a workspace.
|
|
9
|
+
*/
|
|
10
|
+
export declare const QUERY_TABLES: {
|
|
11
|
+
/** One row per resource in each environment's newest snapshot. `attributes` is JSON. */
|
|
12
|
+
readonly resources: readonly [readonly ["member", "TEXT"], readonly ["env", "TEXT"], readonly ["stack", "TEXT"], readonly ["lexicon", "TEXT"], readonly ["name", "TEXT"], readonly ["type", "TEXT"], readonly ["physical_id", "TEXT"], readonly ["status", "TEXT"], readonly ["last_updated", "TEXT"], readonly ["ownership", "TEXT"], readonly ["attributes", "TEXT"], readonly ["git_sha", "TEXT"], readonly ["observed_at", "TEXT"]];
|
|
13
|
+
/** One row per snapshot file: what was observed, when, and how many resources it holds. */
|
|
14
|
+
readonly snapshots: readonly [readonly ["member", "TEXT"], readonly ["env", "TEXT"], readonly ["stack", "TEXT"], readonly ["lexicon", "TEXT"], readonly ["git_sha", "TEXT"], readonly ["observed_at", "TEXT"], readonly ["depth", "TEXT"], readonly ["resources", "INTEGER"], readonly ["unobserved", "INTEGER"]];
|
|
15
|
+
/** One row per Op run record. `labels` and `outcomes` are JSON. */
|
|
16
|
+
readonly runs: readonly [readonly ["member", "TEXT"], readonly ["id", "TEXT"], readonly ["op", "TEXT"], readonly ["env", "TEXT"], readonly ["started", "TEXT"], readonly ["ended", "TEXT"], readonly ["status", "TEXT"], readonly ["git_sha", "TEXT"], readonly ["forge", "TEXT"], readonly ["run_url", "TEXT"], readonly ["failure_code", "TEXT"], readonly ["failure_reason", "TEXT"], readonly ["failed_phase", "TEXT"], readonly ["gate", "TEXT"], readonly ["steward", "TEXT"], readonly ["labels", "TEXT"], readonly ["outcomes", "TEXT"]];
|
|
17
|
+
/** One row per gate ledger line: `kind` is `pending` or `resolution`. `signed` is 1 for a sealed approval. */
|
|
18
|
+
readonly gates: readonly [readonly ["member", "TEXT"], readonly ["op", "TEXT"], readonly ["gate", "TEXT"], readonly ["kind", "TEXT"], readonly ["timestamp", "TEXT"], readonly ["resolved_by", "TEXT"], readonly ["relayed_by", "TEXT"], readonly ["approver_kind", "TEXT"], readonly ["plan_digest", "TEXT"], readonly ["environment", "TEXT"], readonly ["release_digest", "TEXT"], readonly ["git_sha", "TEXT"], readonly ["run_id", "TEXT"], readonly ["url", "TEXT"], readonly ["note", "TEXT"], readonly ["expires_at", "TEXT"], readonly ["origin", "TEXT"], readonly ["empty", "INTEGER"], readonly ["signed", "INTEGER"]];
|
|
19
|
+
/** One row per deploy record in `<env>/releases.jsonl`. `promoted_from`, `restores` and `redeploys` are JSON. */
|
|
20
|
+
readonly deploys: readonly [readonly ["member", "TEXT"], readonly ["env", "TEXT"], readonly ["component", "TEXT"], readonly ["digest", "TEXT"], readonly ["git_sha", "TEXT"], readonly ["run_id", "TEXT"], readonly ["forge", "TEXT"], readonly ["run_url", "TEXT"], readonly ["timestamp", "TEXT"], readonly ["actor", "TEXT"], readonly ["approver", "TEXT"], readonly ["release_digest", "TEXT"], readonly ["digest_kind", "TEXT"], readonly ["promoted_from", "TEXT"], readonly ["restores", "TEXT"], readonly ["redeploys", "TEXT"]];
|
|
21
|
+
/** One row per release file whose content hashes to its digest. `envs` joins its targets' environments with commas; `artifacts` is JSON. */
|
|
22
|
+
readonly releases: readonly [readonly ["member", "TEXT"], readonly ["release_digest", "TEXT"], readonly ["release_member", "TEXT"], readonly ["git_sha", "TEXT"], readonly ["envs", "TEXT"], readonly ["artifacts", "TEXT"]];
|
|
23
|
+
/** One row per line of `_releases/cuts.jsonl`. `signed` is 1 for a signed cut. */
|
|
24
|
+
readonly cuts: readonly [readonly ["member", "TEXT"], readonly ["release_digest", "TEXT"], readonly ["label", "TEXT"], readonly ["actor", "TEXT"], readonly ["timestamp", "TEXT"], readonly ["run_id", "TEXT"], readonly ["forge", "TEXT"], readonly ["channel", "TEXT"], readonly ["signed", "INTEGER"], readonly ["composed_base", "TEXT"]];
|
|
25
|
+
};
|
|
26
|
+
export type QueryTable = keyof typeof QUERY_TABLES;
|
|
27
|
+
/** The table that describes the others: one row per column, with the schema version. */
|
|
28
|
+
export declare const SCHEMA_TABLE = "chant_schema";
|
|
29
|
+
type Value = string | number | null;
|
|
30
|
+
export type QueryRow = Record<string, Value>;
|
|
31
|
+
/** The rows of each table, as loaded. */
|
|
32
|
+
export type QueryData = Record<QueryTable, QueryRow[]>;
|
|
33
|
+
/** One ledger to read: a member's, or the project's own with `member` null. */
|
|
34
|
+
export interface QueryLedger {
|
|
35
|
+
member: string | null;
|
|
36
|
+
port: LedgerReadPort;
|
|
37
|
+
}
|
|
38
|
+
export interface QueryLoad {
|
|
39
|
+
data: QueryData;
|
|
40
|
+
/** Lines and files that could not be read as their kind, per table. Left out of the rows. */
|
|
41
|
+
malformed: Record<QueryTable, number>;
|
|
42
|
+
}
|
|
43
|
+
export interface QueryResult {
|
|
44
|
+
schemaVersion: number;
|
|
45
|
+
columns: string[];
|
|
46
|
+
rows: QueryRow[];
|
|
47
|
+
/** How many rows each table held. */
|
|
48
|
+
tables: Record<QueryTable, number>;
|
|
49
|
+
malformed: Record<QueryTable, number>;
|
|
50
|
+
}
|
|
51
|
+
/** A statement that can't run, or a Node.js with no SQLite. The message is for a person. */
|
|
52
|
+
export declare class QueryError extends Error {
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Read every table's rows from the ledgers, in the order given. A ledger
|
|
56
|
+
* whose branch is absent reads as no rows. A line or file that is not its
|
|
57
|
+
* kind is counted in `malformed` and left out, as each ledger's own reader
|
|
58
|
+
* does.
|
|
59
|
+
*/
|
|
60
|
+
export declare function loadQueryData(ledgers: readonly QueryLedger[]): Promise<QueryLoad>;
|
|
61
|
+
/** The first word of a statement, past whitespace and comments. */
|
|
62
|
+
export declare function firstWord(sql: string): string;
|
|
63
|
+
/** Run one read-only statement over the tables. */
|
|
64
|
+
export declare function runQuery(sql: string, load: QueryLoad): Promise<QueryResult>;
|
|
65
|
+
/** The rows as an aligned table, a header and a count. */
|
|
66
|
+
export declare function formatQueryResult(r: QueryResult): string;
|
|
67
|
+
export {};
|
|
68
|
+
//# sourceMappingURL=query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/lifecycle/query.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAMpD,6CAA6C;AAC7C,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAItC;;;;;GAKG;AACH,eAAO,MAAM,YAAY;IACvB,wFAAwF;;IAExF,2FAA2F;;IAE3F,mEAAmE;;IAEnE,8GAA8G;;IAE9G,iHAAiH;;IAEjH,4IAA4I;;IAE5I,kFAAkF;;CAEH,CAAC;AAElF,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,YAAY,CAAC;AAEnD,wFAAwF;AACxF,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C,KAAK,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AACpC,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE7C,yCAAyC;AACzC,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;AAEvD,+EAA+E;AAC/E,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,cAAc,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,6FAA6F;IAC7F,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;CACvC;AAED,4FAA4F;AAC5F,qBAAa,UAAW,SAAQ,KAAK;CAAG;AAsDxC;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAyEvF;AA6BD,mEAAmE;AACnE,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED,mDAAmD;AACnD,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAoCjF;AAID,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,CAMxD"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { parseGateLedger, GATES_DIR } from "./gate-ledger.js";
|
|
2
|
+
import { parseReleaseLedger, releaseLedgerLines } from "./release-read.js";
|
|
3
|
+
import { CUTS_FILE, parseCuts, parseRelease, RELEASES_DIR, verifyReleaseDigest } from "./release-store.js";
|
|
4
|
+
import { opOfRunLedgerFile, parseRunLedger } from "./run-ledger.js";
|
|
5
|
+
/** The version of the table schema below. */
|
|
6
|
+
export const QUERY_SCHEMA_VERSION = 1;
|
|
7
|
+
/**
|
|
8
|
+
* Each table's columns, in order, with their SQLite type. A column named in
|
|
9
|
+
* the doc as JSON holds a JSON text, for `json_extract`. Every table starts
|
|
10
|
+
* with `member`: the workspace member whose ledger the row came from, or NULL
|
|
11
|
+
* for a project outside a workspace.
|
|
12
|
+
*/
|
|
13
|
+
export const QUERY_TABLES = {
|
|
14
|
+
/** One row per resource in each environment's newest snapshot. `attributes` is JSON. */
|
|
15
|
+
resources: [["member", "TEXT"], ["env", "TEXT"], ["stack", "TEXT"], ["lexicon", "TEXT"], ["name", "TEXT"], ["type", "TEXT"], ["physical_id", "TEXT"], ["status", "TEXT"], ["last_updated", "TEXT"], ["ownership", "TEXT"], ["attributes", "TEXT"], ["git_sha", "TEXT"], ["observed_at", "TEXT"]],
|
|
16
|
+
/** One row per snapshot file: what was observed, when, and how many resources it holds. */
|
|
17
|
+
snapshots: [["member", "TEXT"], ["env", "TEXT"], ["stack", "TEXT"], ["lexicon", "TEXT"], ["git_sha", "TEXT"], ["observed_at", "TEXT"], ["depth", "TEXT"], ["resources", "INTEGER"], ["unobserved", "INTEGER"]],
|
|
18
|
+
/** One row per Op run record. `labels` and `outcomes` are JSON. */
|
|
19
|
+
runs: [["member", "TEXT"], ["id", "TEXT"], ["op", "TEXT"], ["env", "TEXT"], ["started", "TEXT"], ["ended", "TEXT"], ["status", "TEXT"], ["git_sha", "TEXT"], ["forge", "TEXT"], ["run_url", "TEXT"], ["failure_code", "TEXT"], ["failure_reason", "TEXT"], ["failed_phase", "TEXT"], ["gate", "TEXT"], ["steward", "TEXT"], ["labels", "TEXT"], ["outcomes", "TEXT"]],
|
|
20
|
+
/** One row per gate ledger line: `kind` is `pending` or `resolution`. `signed` is 1 for a sealed approval. */
|
|
21
|
+
gates: [["member", "TEXT"], ["op", "TEXT"], ["gate", "TEXT"], ["kind", "TEXT"], ["timestamp", "TEXT"], ["resolved_by", "TEXT"], ["relayed_by", "TEXT"], ["approver_kind", "TEXT"], ["plan_digest", "TEXT"], ["environment", "TEXT"], ["release_digest", "TEXT"], ["git_sha", "TEXT"], ["run_id", "TEXT"], ["url", "TEXT"], ["note", "TEXT"], ["expires_at", "TEXT"], ["origin", "TEXT"], ["empty", "INTEGER"], ["signed", "INTEGER"]],
|
|
22
|
+
/** One row per deploy record in `<env>/releases.jsonl`. `promoted_from`, `restores` and `redeploys` are JSON. */
|
|
23
|
+
deploys: [["member", "TEXT"], ["env", "TEXT"], ["component", "TEXT"], ["digest", "TEXT"], ["git_sha", "TEXT"], ["run_id", "TEXT"], ["forge", "TEXT"], ["run_url", "TEXT"], ["timestamp", "TEXT"], ["actor", "TEXT"], ["approver", "TEXT"], ["release_digest", "TEXT"], ["digest_kind", "TEXT"], ["promoted_from", "TEXT"], ["restores", "TEXT"], ["redeploys", "TEXT"]],
|
|
24
|
+
/** One row per release file whose content hashes to its digest. `envs` joins its targets' environments with commas; `artifacts` is JSON. */
|
|
25
|
+
releases: [["member", "TEXT"], ["release_digest", "TEXT"], ["release_member", "TEXT"], ["git_sha", "TEXT"], ["envs", "TEXT"], ["artifacts", "TEXT"]],
|
|
26
|
+
/** One row per line of `_releases/cuts.jsonl`. `signed` is 1 for a signed cut. */
|
|
27
|
+
cuts: [["member", "TEXT"], ["release_digest", "TEXT"], ["label", "TEXT"], ["actor", "TEXT"], ["timestamp", "TEXT"], ["run_id", "TEXT"], ["forge", "TEXT"], ["channel", "TEXT"], ["signed", "INTEGER"], ["composed_base", "TEXT"]],
|
|
28
|
+
};
|
|
29
|
+
/** The table that describes the others: one row per column, with the schema version. */
|
|
30
|
+
export const SCHEMA_TABLE = "chant_schema";
|
|
31
|
+
/** A statement that can't run, or a Node.js with no SQLite. The message is for a person. */
|
|
32
|
+
export class QueryError extends Error {
|
|
33
|
+
}
|
|
34
|
+
const TABLE_NAMES = Object.keys(QUERY_TABLES);
|
|
35
|
+
const empty = (v) => Object.fromEntries(TABLE_NAMES.map((t) => [t, v()]));
|
|
36
|
+
const json = (v) => (v === undefined || v === null ? null : JSON.stringify(v));
|
|
37
|
+
const str = (v) => (typeof v === "string" ? v : null);
|
|
38
|
+
const bit = (v) => (v ? 1 : 0);
|
|
39
|
+
/** Whether a parsed `.json` file under an environment is a snapshot (an observation baseline or another file is not). */
|
|
40
|
+
function isSnapshot(v) {
|
|
41
|
+
if (!v || typeof v !== "object")
|
|
42
|
+
return false;
|
|
43
|
+
const s = v;
|
|
44
|
+
return typeof s.lexicon === "string" && typeof s.environment === "string" && typeof s.commit === "string" && typeof s.timestamp === "string" && !!s.resources && typeof s.resources === "object" && !Array.isArray(s.resources);
|
|
45
|
+
}
|
|
46
|
+
function snapshotRows(member, env, file, s, data) {
|
|
47
|
+
// The file name folds the stack in as `<stack>__<lexicon>` (git.ts snapshotStorageKey); the record names it too.
|
|
48
|
+
const key = file.slice(0, -".json".length);
|
|
49
|
+
const stack = s.stack ?? (key.includes("__") ? key.slice(0, key.lastIndexOf("__")) : null);
|
|
50
|
+
const at = { git_sha: s.commit, observed_at: s.timestamp };
|
|
51
|
+
const resources = Object.entries(s.resources);
|
|
52
|
+
data.snapshots.push({ member, env, stack, lexicon: s.lexicon, ...at, depth: s.depth ?? "identity", resources: resources.length, unobserved: Object.keys(s.unobserved ?? {}).length });
|
|
53
|
+
for (const [name, r] of resources) {
|
|
54
|
+
data.resources.push({ member, env, stack, lexicon: s.lexicon, name, type: str(r?.type), physical_id: str(r?.physicalId), status: str(r?.status), last_updated: str(r?.lastUpdated), ownership: str(r?.ownership), attributes: json(r?.attributes), ...at });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function gateRow(member, r) {
|
|
58
|
+
const pending = r.kind === "pending";
|
|
59
|
+
const res = pending ? undefined : r;
|
|
60
|
+
const origin = r.origin;
|
|
61
|
+
return {
|
|
62
|
+
member,
|
|
63
|
+
op: r.op,
|
|
64
|
+
gate: r.gate,
|
|
65
|
+
kind: pending ? "pending" : "resolution",
|
|
66
|
+
timestamp: r.timestamp,
|
|
67
|
+
resolved_by: res?.resolvedBy ?? null,
|
|
68
|
+
relayed_by: str(res?.relayedBy),
|
|
69
|
+
approver_kind: str(res?.approver?.kind),
|
|
70
|
+
plan_digest: str(r.planDigest),
|
|
71
|
+
environment: str(r.environment),
|
|
72
|
+
release_digest: str(r.releaseDigest),
|
|
73
|
+
git_sha: str(r.gitSha),
|
|
74
|
+
run_id: str(r.runId),
|
|
75
|
+
url: str(res?.url),
|
|
76
|
+
note: str(res?.note),
|
|
77
|
+
expires_at: pending ? str(r.expiresAt) : null,
|
|
78
|
+
origin: str(origin),
|
|
79
|
+
empty: bit(res?.empty === true),
|
|
80
|
+
signed: bit(res?.seal !== undefined),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Read every table's rows from the ledgers, in the order given. A ledger
|
|
85
|
+
* whose branch is absent reads as no rows. A line or file that is not its
|
|
86
|
+
* kind is counted in `malformed` and left out, as each ledger's own reader
|
|
87
|
+
* does.
|
|
88
|
+
*/
|
|
89
|
+
export async function loadQueryData(ledgers) {
|
|
90
|
+
const data = empty(() => []);
|
|
91
|
+
const malformed = empty(() => 0);
|
|
92
|
+
for (const { member, port } of ledgers) {
|
|
93
|
+
const trees = (await port.trees()).sort();
|
|
94
|
+
for (const env of trees.filter((t) => !t.startsWith("_"))) {
|
|
95
|
+
for (const file of (await port.list(env)).sort()) {
|
|
96
|
+
if (file.endsWith(".json")) {
|
|
97
|
+
const text = await port.read(env, file);
|
|
98
|
+
let parsed;
|
|
99
|
+
try {
|
|
100
|
+
parsed = text === null ? null : JSON.parse(text);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
parsed = null;
|
|
104
|
+
}
|
|
105
|
+
// Other JSON files live beside the snapshots (the observation baseline); only a snapshot-shaped one is read.
|
|
106
|
+
if (isSnapshot(parsed))
|
|
107
|
+
snapshotRows(member, env, file, parsed, data);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (file === "releases.jsonl") {
|
|
111
|
+
const { records, malformed: bad } = parseReleaseLedger(releaseLedgerLines(await port.read(env, file)));
|
|
112
|
+
malformed.deploys += bad;
|
|
113
|
+
for (const d of records) {
|
|
114
|
+
data.deploys.push({ member, env: d.env, component: d.component, digest: d.digest, git_sha: d.gitSha, run_id: d.runId, forge: str(d.runOrigin?.forge), run_url: str(d.runOrigin?.url), timestamp: d.timestamp, actor: d.actor, approver: str(d.approver), release_digest: str(d.releaseDigest), digest_kind: str(d.digestKind), promoted_from: json(d.promotedFrom), restores: json(d.restores), redeploys: json(d.redeploys) });
|
|
115
|
+
}
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (opOfRunLedgerFile(file) !== null) {
|
|
119
|
+
const text = await port.read(env, file);
|
|
120
|
+
if (text === null)
|
|
121
|
+
continue;
|
|
122
|
+
const { records, malformed: bad } = parseRunLedger(text);
|
|
123
|
+
malformed.runs += bad;
|
|
124
|
+
for (const r of records) {
|
|
125
|
+
data.runs.push({ member, id: r.id, op: r.op, env: r.env, started: r.started, ended: r.ended, status: r.status, git_sha: str(r.gitSha), forge: str(r.runOrigin?.forge), run_url: str(r.runOrigin?.url), failure_code: str(r.failure?.code), failure_reason: str(r.failure?.reason), failed_phase: str(r.failure?.phase), gate: str(r.gate?.name), steward: str(r.steward), labels: json(r.labels ?? {}), outcomes: json(r.outcomes ?? {}) });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (trees.includes(GATES_DIR)) {
|
|
131
|
+
for (const file of (await port.list(GATES_DIR)).sort()) {
|
|
132
|
+
if (!file.endsWith(".jsonl"))
|
|
133
|
+
continue;
|
|
134
|
+
const text = await port.read(GATES_DIR, file);
|
|
135
|
+
if (text === null)
|
|
136
|
+
continue;
|
|
137
|
+
const { resolutions, pending, malformed: bad } = parseGateLedger(text);
|
|
138
|
+
malformed.gates += bad;
|
|
139
|
+
// Both kinds share the file; ledger order is time order, so they are merged back by timestamp.
|
|
140
|
+
const lines = [...pending, ...resolutions].sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
141
|
+
for (const r of lines)
|
|
142
|
+
data.gates.push(gateRow(member, r));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (trees.includes(RELEASES_DIR)) {
|
|
146
|
+
for (const file of (await port.list(RELEASES_DIR)).sort()) {
|
|
147
|
+
if (file === CUTS_FILE) {
|
|
148
|
+
const { cuts, malformed: bad } = parseCuts(await port.read(RELEASES_DIR, file));
|
|
149
|
+
malformed.cuts += bad;
|
|
150
|
+
for (const c of cuts) {
|
|
151
|
+
data.cuts.push({ member, release_digest: c.releaseDigest, label: c.label, actor: c.actor, timestamp: c.timestamp, run_id: c.runId, forge: str(c.runOrigin?.forge), channel: str(c.channel), signed: bit(c.signature !== null), composed_base: str(c.composed?.base) });
|
|
152
|
+
}
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
if (!file.endsWith(".json"))
|
|
156
|
+
continue;
|
|
157
|
+
const text = await port.read(RELEASES_DIR, file);
|
|
158
|
+
const release = text === null ? null : parseRelease(text);
|
|
159
|
+
// `readAllReleases` (release-store.ts) counts a file whose content does not hash to its digest as malformed; so does this.
|
|
160
|
+
if (!release || release.releaseDigest.replace(/:/g, "_") !== file.slice(0, -".json".length) || !verifyReleaseDigest(release)) {
|
|
161
|
+
malformed.releases++;
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
data.releases.push({ member, release_digest: release.releaseDigest, release_member: release.member, git_sha: release.commit, envs: release.targets.map((t) => t.env).join(","), artifacts: json(release.artifactDigests) });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return { data, malformed };
|
|
169
|
+
}
|
|
170
|
+
/** node:sqlite, without the experimental warning some Node.js versions print when it loads. */
|
|
171
|
+
async function sqlite() {
|
|
172
|
+
const emit = process.emitWarning;
|
|
173
|
+
process.emitWarning = ((warning, ...rest) => {
|
|
174
|
+
if (/SQLite/.test(typeof warning === "string" ? warning : warning.message))
|
|
175
|
+
return;
|
|
176
|
+
return emit.call(process, warning, ...rest);
|
|
177
|
+
});
|
|
178
|
+
try {
|
|
179
|
+
const name = "node:sqlite";
|
|
180
|
+
return (await import(name));
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
throw new QueryError(`chant query runs on the SQLite built into Node.js 22.13 or later; this is Node.js ${process.versions.node}`);
|
|
184
|
+
}
|
|
185
|
+
finally {
|
|
186
|
+
process.emitWarning = emit;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/** The first word of a statement, past whitespace and comments. */
|
|
190
|
+
export function firstWord(sql) {
|
|
191
|
+
const s = sql.replace(/^(\s+|--[^\n]*(\n|$)|\/\*[\s\S]*?\*\/)*/, "");
|
|
192
|
+
return (/^[A-Za-z]+/.exec(s)?.[0] ?? "").toLowerCase();
|
|
193
|
+
}
|
|
194
|
+
/** Run one read-only statement over the tables. */
|
|
195
|
+
export async function runQuery(sql, load) {
|
|
196
|
+
if (sql.trim() === "")
|
|
197
|
+
throw new QueryError('chant query needs a statement: chant query "SELECT * FROM resources"');
|
|
198
|
+
if (!["select", "with", "values"].includes(firstWord(sql)))
|
|
199
|
+
throw new QueryError("chant query runs one SELECT (or WITH, or VALUES) statement; it changes nothing");
|
|
200
|
+
const { DatabaseSync } = await sqlite();
|
|
201
|
+
const db = new DatabaseSync(":memory:");
|
|
202
|
+
try {
|
|
203
|
+
db.exec(`CREATE TABLE ${SCHEMA_TABLE} ("version" INTEGER, "table_name" TEXT, "column_name" TEXT, "type" TEXT, "position" INTEGER)`);
|
|
204
|
+
const describe = db.prepare(`INSERT INTO ${SCHEMA_TABLE} VALUES (?, ?, ?, ?, ?)`);
|
|
205
|
+
for (const table of TABLE_NAMES) {
|
|
206
|
+
const cols = QUERY_TABLES[table];
|
|
207
|
+
db.exec(`CREATE TABLE ${table} (${cols.map(([c, t]) => `"${c}" ${t}`).join(", ")})`);
|
|
208
|
+
cols.forEach(([c, t], i) => describe.run(QUERY_SCHEMA_VERSION, table, c, t, i + 1));
|
|
209
|
+
const insert = db.prepare(`INSERT INTO ${table} VALUES (${cols.map(() => "?").join(", ")})`);
|
|
210
|
+
db.exec("BEGIN");
|
|
211
|
+
for (const row of load.data[table])
|
|
212
|
+
insert.run(...cols.map(([c]) => row[c] ?? null));
|
|
213
|
+
db.exec("COMMIT");
|
|
214
|
+
}
|
|
215
|
+
db.exec("PRAGMA query_only = ON");
|
|
216
|
+
let stmt;
|
|
217
|
+
try {
|
|
218
|
+
stmt = db.prepare(sql);
|
|
219
|
+
}
|
|
220
|
+
catch (e) {
|
|
221
|
+
throw new QueryError(`the query does not run: ${e.message}`);
|
|
222
|
+
}
|
|
223
|
+
let rows;
|
|
224
|
+
try {
|
|
225
|
+
rows = stmt.all();
|
|
226
|
+
}
|
|
227
|
+
catch (e) {
|
|
228
|
+
throw new QueryError(`the query does not run: ${e.message}`);
|
|
229
|
+
}
|
|
230
|
+
const columns = typeof stmt.columns === "function" ? stmt.columns().map((c) => c.name) : Object.keys(rows[0] ?? {});
|
|
231
|
+
const tables = Object.fromEntries(TABLE_NAMES.map((t) => [t, load.data[t].length]));
|
|
232
|
+
return { schemaVersion: QUERY_SCHEMA_VERSION, columns, rows: rows.map((r) => ({ ...r })), tables, malformed: load.malformed };
|
|
233
|
+
}
|
|
234
|
+
finally {
|
|
235
|
+
db.close();
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
const cell = (v) => (v === null || v === undefined ? "" : String(v));
|
|
239
|
+
/** The rows as an aligned table, a header and a count. */
|
|
240
|
+
export function formatQueryResult(r) {
|
|
241
|
+
const widths = r.columns.map((c) => Math.max(c.length, ...r.rows.map((row) => cell(row[c]).length)));
|
|
242
|
+
const line = (vals) => vals.map((v, i) => v.padEnd(widths[i])).join(" ").trimEnd();
|
|
243
|
+
const out = [line(r.columns), line(widths.map((w) => "-".repeat(w))), ...r.rows.map((row) => line(r.columns.map((c) => cell(row[c]))))];
|
|
244
|
+
out.push(`(${r.rows.length} ${r.rows.length === 1 ? "row" : "rows"})`);
|
|
245
|
+
return out.join("\n");
|
|
246
|
+
}
|
|
@@ -227,7 +227,32 @@ export interface ReleaseRecord {
|
|
|
227
227
|
* deploy that was not made from a release.
|
|
228
228
|
*/
|
|
229
229
|
releaseDigest?: string;
|
|
230
|
+
/**
|
|
231
|
+
* Optional: what `digest` names when it is not an artifact digest (#4274).
|
|
232
|
+
* Absent on a record whose digest is the artifact the deploy promoted, and on
|
|
233
|
+
* every record written before 0.124.35.
|
|
234
|
+
*
|
|
235
|
+
* - `plan`: the component published nothing, and the digest is its plan
|
|
236
|
+
* digest, the one its approval bound (`pr-apply`).
|
|
237
|
+
* - `deploy-input`: the component published nothing and planned nothing, and
|
|
238
|
+
* the digest is its deploy-input digest (`componentInputDigests`,
|
|
239
|
+
* ../components/fan-out-inputs.ts).
|
|
240
|
+
* - `templates`: the digest of the templates the release records for the
|
|
241
|
+
* component (#4222, `releaseTemplatesDigest`).
|
|
242
|
+
*
|
|
243
|
+
* A `plan` or `deploy-input` record says the component applied; it names no
|
|
244
|
+
* artifact, so promote, rollback and redeploy never deploy it
|
|
245
|
+
* ({@link isApplyRecord}).
|
|
246
|
+
*/
|
|
247
|
+
digestKind?: ReleaseDigestKind;
|
|
230
248
|
}
|
|
249
|
+
/** What a release record's `digest` names when it is not an artifact digest (#4274). */
|
|
250
|
+
export type ReleaseDigestKind = "plan" | "deploy-input" | "templates";
|
|
251
|
+
/**
|
|
252
|
+
* Whether `record` only says its component applied (#4274): its digest is a
|
|
253
|
+
* plan or deploy-input digest, not one anything can be deployed from again.
|
|
254
|
+
*/
|
|
255
|
+
export declare function isApplyRecord(record: Pick<ReleaseRecord, "digestKind">): boolean;
|
|
231
256
|
/** Thrown by `appendReleaseRecord` when the record is missing a required field — a release record can never be recorded partially, since it is never editable afterward. */
|
|
232
257
|
export declare class InvalidReleaseRecordError extends Error {
|
|
233
258
|
readonly missing: string[];
|
|
@@ -270,6 +295,12 @@ export declare function resolveCiRun(env?: NodeJS.ProcessEnv): {
|
|
|
270
295
|
runId: string;
|
|
271
296
|
runOrigin: RunOrigin;
|
|
272
297
|
} | undefined;
|
|
298
|
+
/** The run id `chant ci run` hands each step of a job it runs (#4275), the id its run index lists. */
|
|
299
|
+
export declare const CHANT_CI_RUN_ID_ENV = "CHANT_CI_RUN_ID";
|
|
300
|
+
/** The run's origin `chant ci run` hands each step with {@link CHANT_CI_RUN_ID_ENV}: always `chant`. */
|
|
301
|
+
export declare const CHANT_CI_RUN_FORGE_ENV = "CHANT_CI_RUN_FORGE";
|
|
302
|
+
/** The forge's run variables, which a step of a job the chant runner ran never gets (#4275). */
|
|
303
|
+
export declare const FORGE_RUN_ENV: readonly ["GITHUB_RUN_ID", "GITHUB_RUN_ATTEMPT", "GITHUB_JOB", "CI_PIPELINE_ID", "CI_PIPELINE_URL", "CI_JOB_ID"];
|
|
273
304
|
/**
|
|
274
305
|
* The CI run the environment names, as {@link resolveCiRun} has it, with the
|
|
275
306
|
* job within the run and the run's attempt when the forge gives them
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release-ledger.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-ledger.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"release-ledger.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-ledger.ts"],"names":[],"mappings":"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"}
|
|
@@ -53,6 +53,13 @@ export function admissionOf(resolutions, at) {
|
|
|
53
53
|
admission: { op: at.op, gate: at.gate, resolvedAt: bound.map((r) => r.timestamp).sort().at(-1) },
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Whether `record` only says its component applied (#4274): its digest is a
|
|
58
|
+
* plan or deploy-input digest, not one anything can be deployed from again.
|
|
59
|
+
*/
|
|
60
|
+
export function isApplyRecord(record) {
|
|
61
|
+
return record.digestKind === "plan" || record.digestKind === "deploy-input";
|
|
62
|
+
}
|
|
56
63
|
/** Thrown by `appendReleaseRecord` when the record is missing a required field — a release record can never be recorded partially, since it is never editable afterward. */
|
|
57
64
|
export class InvalidReleaseRecordError extends Error {
|
|
58
65
|
constructor(missing) {
|
|
@@ -123,8 +130,19 @@ export function resolveCiRun(env = process.env) {
|
|
|
123
130
|
},
|
|
124
131
|
};
|
|
125
132
|
}
|
|
133
|
+
// #4275: a step of a job the chant runner ran. The forge branches come first, and the runner
|
|
134
|
+
// strips the forge's run variables from its steps, so neither kind of job is taken for the other.
|
|
135
|
+
if (env[CHANT_CI_RUN_ID_ENV] && env[CHANT_CI_RUN_FORGE_ENV] === "chant") {
|
|
136
|
+
return { runId: env[CHANT_CI_RUN_ID_ENV], runOrigin: { forge: "chant" } };
|
|
137
|
+
}
|
|
126
138
|
return undefined;
|
|
127
139
|
}
|
|
140
|
+
/** The run id `chant ci run` hands each step of a job it runs (#4275), the id its run index lists. */
|
|
141
|
+
export const CHANT_CI_RUN_ID_ENV = "CHANT_CI_RUN_ID";
|
|
142
|
+
/** The run's origin `chant ci run` hands each step with {@link CHANT_CI_RUN_ID_ENV}: always `chant`. */
|
|
143
|
+
export const CHANT_CI_RUN_FORGE_ENV = "CHANT_CI_RUN_FORGE";
|
|
144
|
+
/** The forge's run variables, which a step of a job the chant runner ran never gets (#4275). */
|
|
145
|
+
export const FORGE_RUN_ENV = ["GITHUB_RUN_ID", "GITHUB_RUN_ATTEMPT", "GITHUB_JOB", "CI_PIPELINE_ID", "CI_PIPELINE_URL", "CI_JOB_ID"];
|
|
128
146
|
/**
|
|
129
147
|
* The CI run the environment names, as {@link resolveCiRun} has it, with the
|
|
130
148
|
* job within the run and the run's attempt when the forge gives them
|
|
@@ -136,7 +154,7 @@ export function resolveCiJob(env = process.env) {
|
|
|
136
154
|
if (!ci)
|
|
137
155
|
return undefined;
|
|
138
156
|
const github = ci.runOrigin.forge === "github";
|
|
139
|
-
const jobId = github ? env.GITHUB_JOB : env.CI_JOB_ID;
|
|
157
|
+
const jobId = github ? env.GITHUB_JOB : ci.runOrigin.forge === "gitlab" ? env.CI_JOB_ID : undefined;
|
|
140
158
|
const attempt = github ? Number(env.GITHUB_RUN_ATTEMPT) : NaN;
|
|
141
159
|
return {
|
|
142
160
|
runId: ci.runId,
|
|
@@ -60,4 +60,17 @@ export declare function readRunLedger(environment: string, op: string, opts?: {
|
|
|
60
60
|
records: OpRunRecord[];
|
|
61
61
|
malformed: number;
|
|
62
62
|
}>;
|
|
63
|
+
/** The run ledger file name for `op` under `<env>/`, `runs__<op>.jsonl`. */
|
|
64
|
+
export declare function runLedgerFile(op: string): string;
|
|
65
|
+
/** The op a run ledger file name holds, or null when `file` is not one. */
|
|
66
|
+
export declare function opOfRunLedgerFile(file: string): string | null;
|
|
67
|
+
/**
|
|
68
|
+
* Parse the text of one run ledger file the way {@link readRunLedger} reads
|
|
69
|
+
* it (#4297): a reader that fetches the file itself, such as `chant query`,
|
|
70
|
+
* gets the same records and the same malformed count.
|
|
71
|
+
*/
|
|
72
|
+
export declare function parseRunLedger(content: string): {
|
|
73
|
+
records: OpRunRecord[];
|
|
74
|
+
malformed: number;
|
|
75
|
+
};
|
|
63
76
|
//# sourceMappingURL=run-ledger.d.ts.map
|