@intentius/chant 0.124.40 → 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/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.js +16 -3
- 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 +503 -53
- package/dist/cli/handlers/promote.d.ts.map +1 -1
- package/dist/cli/handlers/promote.js +9 -0
- 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/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/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/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/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/query.d.ts +68 -0
- package/dist/lifecycle/query.d.ts.map +1 -0
- package/dist/lifecycle/query.js +246 -0
- 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/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/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 +242 -242
- 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 +17 -1
- package/dist/workspace/ci-run.d.ts.map +1 -1
- package/dist/workspace/ci-run.js +64 -3
- 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.map +1 -1
- package/dist/workspace/status.js +4 -1
- 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/handlers/approve.ts +18 -5
- package/src/cli/handlers/build.ts +15 -1
- package/src/cli/handlers/fan-out.ts +17 -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-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 +496 -59
- package/src/cli/handlers/promote.ts +9 -0
- package/src/cli/handlers/query.ts +78 -0
- 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/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/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/gate-checkpoint.ts +1 -1
- package/src/{workspace/trust → lifecycle}/gate-seal.ts +1 -1
- package/src/lifecycle/query.test.ts +91 -0
- package/src/lifecycle/query.ts +315 -0
- package/src/lifecycle/run-ledger.ts +18 -0
- package/src/lifecycle/target-lock.test.ts +195 -0
- package/src/lifecycle/target-lock.ts +347 -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 +107 -8
- package/src/workspace/ci-run.ts +72 -4
- 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.ts +4 -1
- 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
|
@@ -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
|
+
}
|
|
@@ -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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-ledger.d.ts","sourceRoot":"","sources":["../../src/lifecycle/run-ledger.ts"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAkB,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAA+C,MAAM,eAAe,CAAC;AASrI,0EAA0E;AAC1E,eAAO,MAAM,eAAe,UAAU,CAAC;AAMvC,8FAA8F;AAC9F,wBAAgB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,MAAM,CAEjE;AAQD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC,EACzC,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,KAAK,EAAE;IACL,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACjC,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IACrC,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC,GACA,gBAAgB,CAkDlB;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,gBAAgB,EACvB,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,CAAC,CAsBlD;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,EACV,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtB,OAAO,CAAC;IAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"run-ledger.d.ts","sourceRoot":"","sources":["../../src/lifecycle/run-ledger.ts"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAkB,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAA+C,MAAM,eAAe,CAAC;AASrI,0EAA0E;AAC1E,eAAO,MAAM,eAAe,UAAU,CAAC;AAMvC,8FAA8F;AAC9F,wBAAgB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,MAAM,CAEjE;AAQD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC,EACzC,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,KAAK,EAAE;IACL,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACjC,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IACrC,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC,GACA,gBAAgB,CAkDlB;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,gBAAgB,EACvB,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,CAAC,CAsBlD;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,EACV,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtB,OAAO,CAAC;IAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAIxD;AAED,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CA+B7F"}
|
|
@@ -163,6 +163,22 @@ export async function readRunLedger(environment, op, opts) {
|
|
|
163
163
|
const content = await readBlobFromPath(environment, fileFor(op), opts);
|
|
164
164
|
if (!content)
|
|
165
165
|
return { records: [], malformed: 0 };
|
|
166
|
+
return parseRunLedger(content);
|
|
167
|
+
}
|
|
168
|
+
/** The run ledger file name for `op` under `<env>/`, `runs__<op>.jsonl`. */
|
|
169
|
+
export function runLedgerFile(op) {
|
|
170
|
+
return fileFor(op);
|
|
171
|
+
}
|
|
172
|
+
/** The op a run ledger file name holds, or null when `file` is not one. */
|
|
173
|
+
export function opOfRunLedgerFile(file) {
|
|
174
|
+
return file.startsWith(PREFIX) && file.endsWith(".jsonl") && file.length > PREFIX.length + ".jsonl".length ? file.slice(PREFIX.length, -".jsonl".length) : null;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Parse the text of one run ledger file the way {@link readRunLedger} reads
|
|
178
|
+
* it (#4297): a reader that fetches the file itself, such as `chant query`,
|
|
179
|
+
* gets the same records and the same malformed count.
|
|
180
|
+
*/
|
|
181
|
+
export function parseRunLedger(content) {
|
|
166
182
|
const lines = content.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
167
183
|
const records = [];
|
|
168
184
|
let malformed = 0;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/** The directory on `chant/lifecycle` that holds the lock files. */
|
|
2
|
+
export declare const LOCKS_DIR = "_locks";
|
|
3
|
+
/**
|
|
4
|
+
* How a lock was taken. `plan`: the pull request's plan took it (`ci.locks:
|
|
5
|
+
* plan`). `apply`: its apply took it. `lock`: someone ran `chant lock`.
|
|
6
|
+
*/
|
|
7
|
+
export type TargetLockStage = "plan" | "apply" | "lock";
|
|
8
|
+
export declare const TARGET_LOCK_STAGES: readonly ["plan", "apply", "lock"];
|
|
9
|
+
/** One target's lock: the pull request that holds it, who took it, when, how, and the head it took it at. */
|
|
10
|
+
export interface TargetLock {
|
|
11
|
+
pr: number;
|
|
12
|
+
by: string;
|
|
13
|
+
at: string;
|
|
14
|
+
stage: TargetLockStage;
|
|
15
|
+
/** The pull request's head commit when the lock was taken. Absent when the caller did not say. */
|
|
16
|
+
head?: string;
|
|
17
|
+
}
|
|
18
|
+
/** `_locks/<gate>.json`. */
|
|
19
|
+
export interface TargetLockFile {
|
|
20
|
+
version: 1;
|
|
21
|
+
locks: Record<string, TargetLock>;
|
|
22
|
+
}
|
|
23
|
+
/** A lock another open pull request holds on a target the caller needs. */
|
|
24
|
+
export interface HeldTargetLock extends TargetLock {
|
|
25
|
+
target: string;
|
|
26
|
+
}
|
|
27
|
+
/** Says whether pull request `pr` is still open. */
|
|
28
|
+
export type PullRequestOpen = (pr: number) => Promise<boolean>;
|
|
29
|
+
export interface TargetLockOptions {
|
|
30
|
+
cwd?: string;
|
|
31
|
+
/** Whether a holder is still open. Absent: every holder counts as open. */
|
|
32
|
+
isOpen?: PullRequestOpen;
|
|
33
|
+
}
|
|
34
|
+
export type TakeTargetLocksResult = {
|
|
35
|
+
ok: true;
|
|
36
|
+
/** The targets now locked, sorted. */
|
|
37
|
+
taken: string[];
|
|
38
|
+
/** Plan locks of the same pull request on targets it no longer reaches, released (`releaseStalePlan`). */
|
|
39
|
+
released: string[];
|
|
40
|
+
/** Locks of merged or closed pull requests that this write dropped. */
|
|
41
|
+
expired: string[];
|
|
42
|
+
/** Whether the remote has the write. False with no remote, or when recording is off. */
|
|
43
|
+
pushed: boolean;
|
|
44
|
+
} | {
|
|
45
|
+
ok: false;
|
|
46
|
+
held: HeldTargetLock[];
|
|
47
|
+
};
|
|
48
|
+
/** The path of `gate`'s lock file on `chant/lifecycle`, under a member's prefix when it has one. */
|
|
49
|
+
export declare function targetLockPath(gate: string, memberPrefix?: string): string;
|
|
50
|
+
/** A gate name that is safe as a file name. */
|
|
51
|
+
export declare function targetLockGateProblem(gate: string): string | null;
|
|
52
|
+
/** Parse a lock file. Anything that is not a version 1 file with a map of locks reads as no locks; a malformed entry is dropped. */
|
|
53
|
+
export declare function parseTargetLocks(text: string | null): TargetLockFile;
|
|
54
|
+
/** The file's text: targets sorted, so two writes of the same locks are the same blob. */
|
|
55
|
+
export declare function renderTargetLocks(file: TargetLockFile): string;
|
|
56
|
+
/** The locks of `gate` as the remote holds them now, fetched first. */
|
|
57
|
+
export declare function readTargetLocks(gate: string, opts?: {
|
|
58
|
+
cwd?: string;
|
|
59
|
+
}): Promise<TargetLockFile>;
|
|
60
|
+
/**
|
|
61
|
+
* The locks on `targets` that an open pull request other than `pr` holds.
|
|
62
|
+
* Reads only: an apply calls this to refuse a target another pull request
|
|
63
|
+
* holds. `pr` null (an apply of a green commit) counts every open holder.
|
|
64
|
+
*/
|
|
65
|
+
export declare function heldTargetLocks(gate: string, targets: readonly string[], pr: number | null, opts?: TargetLockOptions): Promise<HeldTargetLock[]>;
|
|
66
|
+
/**
|
|
67
|
+
* Lock `targets` for pull request `holder.pr`. A target locked by another
|
|
68
|
+
* pull request that is still open is held, and nothing is locked. A target
|
|
69
|
+
* locked by one that merged or closed is taken over, and its lock dropped.
|
|
70
|
+
* Targets this pull request already holds stay its own, with the new head.
|
|
71
|
+
* An apply or a `chant lock` takes over the pull request's own plan locks;
|
|
72
|
+
* a plan keeps its own apply and `chant lock` locks as they are. With
|
|
73
|
+
* `releaseStalePlan`, the pull request's plan locks on targets it no longer
|
|
74
|
+
* reaches are released.
|
|
75
|
+
*/
|
|
76
|
+
export declare function takeTargetLocks(gate: string, targets: readonly string[], holder: TargetLock, opts?: TargetLockOptions & {
|
|
77
|
+
releaseStalePlan?: boolean;
|
|
78
|
+
}): Promise<TakeTargetLocksResult>;
|
|
79
|
+
/**
|
|
80
|
+
* Release the locks pull request `pr` holds on `gate`: every one, or only
|
|
81
|
+
* those on `targets`. Returns the targets released, sorted.
|
|
82
|
+
*/
|
|
83
|
+
export declare function releaseTargetLocks(gate: string, pr: number, opts?: {
|
|
84
|
+
cwd?: string;
|
|
85
|
+
targets?: readonly string[];
|
|
86
|
+
}): Promise<{
|
|
87
|
+
released: string[];
|
|
88
|
+
pushed: boolean;
|
|
89
|
+
}>;
|
|
90
|
+
/** The lock file's path for the project at `cwd`, for messages. */
|
|
91
|
+
export declare function targetLockPathAt(gate: string, cwd?: string): Promise<string>;
|
|
92
|
+
/**
|
|
93
|
+
* One line naming the targets others hold, for a refusal or a note.
|
|
94
|
+
* `name` says how the forge names a holder (GitLab: `merge request !7`).
|
|
95
|
+
*/
|
|
96
|
+
export declare function describeHeldTargetLocks(held: readonly HeldTargetLock[], name?: (pr: number) => string): string;
|
|
97
|
+
//# sourceMappingURL=target-lock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"target-lock.d.ts","sourceRoot":"","sources":["../../src/lifecycle/target-lock.ts"],"names":[],"mappings":"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"}
|