@intentius/sql-yodeler 0.3.0 → 0.5.0

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.
Files changed (220) hide show
  1. package/README.md +2 -2
  2. package/dist/apply-steps/index.d.ts +65 -0
  3. package/dist/apply-steps/index.js +106 -0
  4. package/dist/apply-steps/index.js.map +1 -0
  5. package/dist/approval-mode/index.d.ts +78 -0
  6. package/dist/approval-mode/index.js +105 -0
  7. package/dist/approval-mode/index.js.map +1 -0
  8. package/dist/chant/access.d.ts +84 -0
  9. package/dist/chant/access.js +155 -0
  10. package/dist/chant/access.js.map +1 -0
  11. package/dist/chant/drift.d.ts +17 -1
  12. package/dist/chant/drift.js +55 -2
  13. package/dist/chant/drift.js.map +1 -1
  14. package/dist/chant/plan.d.ts +18 -2
  15. package/dist/chant/plan.js +21 -3
  16. package/dist/chant/plan.js.map +1 -1
  17. package/dist/ci/login.d.ts +78 -0
  18. package/dist/ci/login.js +199 -0
  19. package/dist/ci/login.js.map +1 -0
  20. package/dist/ci/render.d.ts +64 -10
  21. package/dist/ci/render.js +385 -88
  22. package/dist/ci/render.js.map +1 -1
  23. package/dist/cleanup/index.d.ts +92 -0
  24. package/dist/cleanup/index.js +213 -0
  25. package/dist/cleanup/index.js.map +1 -0
  26. package/dist/commands/apply.js +178 -20
  27. package/dist/commands/apply.js.map +1 -1
  28. package/dist/commands/approve.d.ts +13 -0
  29. package/dist/commands/approve.js +206 -24
  30. package/dist/commands/approve.js.map +1 -1
  31. package/dist/commands/ci.js +12 -0
  32. package/dist/commands/ci.js.map +1 -1
  33. package/dist/commands/cleanup.d.ts +13 -0
  34. package/dist/commands/cleanup.js +158 -0
  35. package/dist/commands/cleanup.js.map +1 -0
  36. package/dist/commands/config.d.ts +3 -0
  37. package/dist/commands/config.js +136 -0
  38. package/dist/commands/config.js.map +1 -0
  39. package/dist/commands/drift.js +33 -3
  40. package/dist/commands/drift.js.map +1 -1
  41. package/dist/commands/index.js +6 -0
  42. package/dist/commands/index.js.map +1 -1
  43. package/dist/commands/init.d.ts +11 -0
  44. package/dist/commands/init.js +98 -10
  45. package/dist/commands/init.js.map +1 -1
  46. package/dist/commands/lint.js +67 -10
  47. package/dist/commands/lint.js.map +1 -1
  48. package/dist/commands/new.js +135 -54
  49. package/dist/commands/new.js.map +1 -1
  50. package/dist/commands/plan.js +39 -5
  51. package/dist/commands/plan.js.map +1 -1
  52. package/dist/commands/test.d.ts +3 -0
  53. package/dist/commands/test.js +164 -0
  54. package/dist/commands/test.js.map +1 -0
  55. package/dist/config/define.d.ts +175 -2
  56. package/dist/config/define.js +2 -0
  57. package/dist/config/define.js.map +1 -1
  58. package/dist/config/load.js +78 -10
  59. package/dist/config/load.js.map +1 -1
  60. package/dist/config/settings.d.ts +20 -0
  61. package/dist/config/settings.js +28 -0
  62. package/dist/config/settings.js.map +1 -1
  63. package/dist/credentials.d.ts +119 -0
  64. package/dist/credentials.js +119 -0
  65. package/dist/credentials.js.map +1 -0
  66. package/dist/exit.js +1 -1
  67. package/dist/exit.js.map +1 -1
  68. package/dist/index.d.ts +5 -1
  69. package/dist/index.js +2 -0
  70. package/dist/index.js.map +1 -1
  71. package/dist/init/adopt.js +1 -1
  72. package/dist/init/adopt.js.map +1 -1
  73. package/dist/init/clickhouse-access.d.ts +64 -0
  74. package/dist/init/clickhouse-access.js +211 -0
  75. package/dist/init/clickhouse-access.js.map +1 -0
  76. package/dist/init/index.d.ts +2 -0
  77. package/dist/init/index.js +2 -0
  78. package/dist/init/index.js.map +1 -1
  79. package/dist/init/live.d.ts +4 -0
  80. package/dist/init/live.js +16 -0
  81. package/dist/init/live.js.map +1 -1
  82. package/dist/init/second.d.ts +70 -0
  83. package/dist/init/second.js +149 -0
  84. package/dist/init/second.js.map +1 -0
  85. package/dist/lint/access.d.ts +18 -0
  86. package/dist/lint/access.js +34 -0
  87. package/dist/lint/access.js.map +1 -0
  88. package/dist/lint/annotations.d.ts +49 -0
  89. package/dist/lint/annotations.js +82 -0
  90. package/dist/lint/annotations.js.map +1 -0
  91. package/dist/lint/check.js +25 -7
  92. package/dist/lint/check.js.map +1 -1
  93. package/dist/lint/config.d.ts +7 -1
  94. package/dist/lint/config.js +11 -5
  95. package/dist/lint/config.js.map +1 -1
  96. package/dist/lint/index.d.ts +4 -0
  97. package/dist/lint/index.js +4 -0
  98. package/dist/lint/index.js.map +1 -1
  99. package/dist/lint/naming.d.ts +62 -0
  100. package/dist/lint/naming.js +138 -0
  101. package/dist/lint/naming.js.map +1 -0
  102. package/dist/lint/rules.d.ts +37 -4
  103. package/dist/lint/rules.js +16 -4
  104. package/dist/lint/rules.js.map +1 -1
  105. package/dist/lint/schema-checks.d.ts +63 -0
  106. package/dist/lint/schema-checks.js +128 -0
  107. package/dist/lint/schema-checks.js.map +1 -0
  108. package/dist/lint/statements.d.ts +22 -1
  109. package/dist/lint/statements.js +40 -1
  110. package/dist/lint/statements.js.map +1 -1
  111. package/dist/mcp/tools.d.ts +1 -1
  112. package/dist/mcp/tools.js +1 -1
  113. package/dist/mcp/tools.js.map +1 -1
  114. package/dist/migrations/checkpoint.js +0 -2
  115. package/dist/migrations/checkpoint.js.map +1 -1
  116. package/dist/migrations/checks.d.ts +19 -1
  117. package/dist/migrations/checks.js +15 -0
  118. package/dist/migrations/checks.js.map +1 -1
  119. package/dist/migrations/create.d.ts +13 -4
  120. package/dist/migrations/create.js +24 -9
  121. package/dist/migrations/create.js.map +1 -1
  122. package/dist/migrations/routines.d.ts +5 -15
  123. package/dist/migrations/routines.js +5 -30
  124. package/dist/migrations/routines.js.map +1 -1
  125. package/dist/pr/model.d.ts +4 -1
  126. package/dist/pr/model.js +13 -5
  127. package/dist/pr/model.js.map +1 -1
  128. package/dist/pr/render.d.ts +4 -1
  129. package/dist/pr/render.js +22 -8
  130. package/dist/pr/render.js.map +1 -1
  131. package/dist/pr/tenants.d.ts +37 -0
  132. package/dist/pr/tenants.js +138 -0
  133. package/dist/pr/tenants.js.map +1 -0
  134. package/dist/probe.d.ts +27 -0
  135. package/dist/probe.js +106 -0
  136. package/dist/probe.js.map +1 -0
  137. package/dist/project.d.ts +16 -0
  138. package/dist/project.js +29 -1
  139. package/dist/project.js.map +1 -1
  140. package/dist/replay/clickhouse.d.ts +31 -0
  141. package/dist/replay/clickhouse.js +103 -6
  142. package/dist/replay/clickhouse.js.map +1 -1
  143. package/dist/replay/replay.d.ts +5 -2
  144. package/dist/replay/replay.js.map +1 -1
  145. package/dist/report/audit.d.ts +1 -1
  146. package/dist/report/audit.js +20 -3
  147. package/dist/report/audit.js.map +1 -1
  148. package/dist/schemas.d.ts +3 -1
  149. package/dist/schemas.js +2 -0
  150. package/dist/schemas.js.map +1 -1
  151. package/dist/sources/ddl.d.ts +15 -20
  152. package/dist/sources/ddl.js +34 -328
  153. package/dist/sources/ddl.js.map +1 -1
  154. package/dist/sources/index.js +2 -2
  155. package/dist/sources/index.js.map +1 -1
  156. package/dist/steps/backfill.d.ts +40 -5
  157. package/dist/steps/backfill.js +128 -8
  158. package/dist/steps/backfill.js.map +1 -1
  159. package/dist/steps/index.d.ts +19 -1
  160. package/dist/steps/index.js +34 -7
  161. package/dist/steps/index.js.map +1 -1
  162. package/dist/steps/kinds.d.ts +42 -4
  163. package/dist/steps/kinds.js +88 -14
  164. package/dist/steps/kinds.js.map +1 -1
  165. package/dist/steps/postgres-migration.d.ts +3 -0
  166. package/dist/steps/postgres-migration.js +7 -3
  167. package/dist/steps/postgres-migration.js.map +1 -1
  168. package/dist/steps/rebuild.d.ts +15 -6
  169. package/dist/steps/rebuild.js +12 -9
  170. package/dist/steps/rebuild.js.map +1 -1
  171. package/dist/tenants/index.d.ts +2 -1
  172. package/dist/tenants/index.js +3 -4
  173. package/dist/tenants/index.js.map +1 -1
  174. package/dist/tenants/wave.d.ts +128 -0
  175. package/dist/tenants/wave.js +254 -0
  176. package/dist/tenants/wave.js.map +1 -0
  177. package/dist/testing/define.d.ts +62 -0
  178. package/dist/testing/define.js +32 -0
  179. package/dist/testing/define.js.map +1 -0
  180. package/dist/testing/files.d.ts +5 -0
  181. package/dist/testing/files.js +18 -0
  182. package/dist/testing/files.js.map +1 -0
  183. package/dist/testing/report.d.ts +14 -0
  184. package/dist/testing/report.js +83 -0
  185. package/dist/testing/report.js.map +1 -0
  186. package/dist/testing/run.d.ts +104 -0
  187. package/dist/testing/run.js +328 -0
  188. package/dist/testing/run.js.map +1 -0
  189. package/dist/versioned/approval.d.ts +6 -0
  190. package/dist/versioned/approval.js +11 -5
  191. package/dist/versioned/approval.js.map +1 -1
  192. package/dist/versioned/checks.d.ts +8 -2
  193. package/dist/versioned/checks.js +34 -13
  194. package/dist/versioned/checks.js.map +1 -1
  195. package/dist/versioned/driver.d.ts +2 -2
  196. package/dist/versioned/engine.d.ts +10 -0
  197. package/dist/versioned/engine.js +8 -4
  198. package/dist/versioned/engine.js.map +1 -1
  199. package/dist/versioned/explain.d.ts +2 -0
  200. package/dist/versioned/explain.js +3 -1
  201. package/dist/versioned/explain.js.map +1 -1
  202. package/dist/versioned/op.d.ts +4 -0
  203. package/dist/versioned/op.js +5 -2
  204. package/dist/versioned/op.js.map +1 -1
  205. package/dist/versioned/state.js +1 -1
  206. package/dist/versioned/state.js.map +1 -1
  207. package/dist/waves/index.d.ts +58 -13
  208. package/dist/waves/index.js +109 -24
  209. package/dist/waves/index.js.map +1 -1
  210. package/dist/waves/record.d.ts +10 -0
  211. package/dist/waves/record.js.map +1 -1
  212. package/package.json +8 -7
  213. package/schemas/apply.schema.json +1 -1
  214. package/schemas/cleanup.schema.json +40 -0
  215. package/schemas/init.schema.json +51 -22
  216. package/schemas/lint-rules.schema.json +4 -0
  217. package/schemas/new.schema.json +41 -3
  218. package/schemas/plan.schema.json +39 -0
  219. package/schemas/report.schema.json +1 -1
  220. package/schemas/test.schema.json +41 -0
@@ -5,18 +5,33 @@ import { readMigrations } from "../migrations/index.js";
5
5
  import { runChant } from "../chant/process.js";
6
6
  import { runnable } from "../chant/runnable.js";
7
7
  import { describeWave, WAVES_PIPELINE, waveView } from "../waves/index.js";
8
+ import { EXIT_OUTSTANDING } from "../exit.js";
9
+ import { gitLedger } from "../versioned/approval.js";
10
+ import { migrationsApprovalAtBase } from "../approval-mode/index.js";
8
11
  import { closeVersioned, findMigrateOp, hasMigrations, migrationsDir, openVersioned, renderStatus, statusReport, ALLOW_OUT_OF_ORDER_ENV } from "../versioned/index.js";
12
+ import { tenantSetOf } from "../tenants/index.js";
13
+ import { describeTenantSetWave, groupTenants, someNames, viewTenantSetWave, viewTenants } from "../tenants/wave.js";
9
14
  /** Exit code: nothing was approved (no one to ask, a wrong answer, a plan apply would refuse, a plan that moved). */
10
15
  export const NOT_APPROVED = 4;
11
- const usage = "usage: yodel approve <env> [--dir <project>] [--op <name>] [--allow-out-of-order]";
16
+ const usage = "usage: yodel approve <env> [--plan <digest>] [--sign [--key <file>]] [--actor <name>] [--no-resume] [--dir <project>] [--op <name>] [--allow-out-of-order]";
12
17
  const help = `${usage}
13
18
 
14
19
  For a person at a terminal. Approves the plan yodel apply <env> would run,
15
20
  without the Op and gate names or the digest: shows the pending migrations
16
21
  and the plan digest, asks you to type the environment's name, then records
17
- the approval with chant approve <op> <gate> --plan <digest>. It is the same
18
- approval chant approve gives, bound to the same digest: if anything the
19
- digest covers changes before the apply, the gate asks again. Then run
22
+ the approval with chant approve <op> <gate> --plan <digest> --resume. It is
23
+ the same approval chant approve gives, bound to the same digest: if
24
+ anything the digest covers changes before the apply, the gate asks again.
25
+
26
+ chant pushes the approval to chant/lifecycle and starts the CI job that
27
+ waits at the gate again through the forge's API (GitHub re-runs the failed
28
+ jobs, GitLab retries the job, Forgejo dispatches the workflow), so the
29
+ apply goes on without a new push. The token comes from CHANT_FORGE_TOKEN,
30
+ else GITHUB_TOKEN or GH_TOKEN (GitHub, Forgejo) or GITLAB_TOKEN (GitLab):
31
+ GitHub needs actions: write, GitLab the api scope with the Developer role,
32
+ Forgejo write:repository. --no-resume records the approval and starts
33
+ nothing; so does a repository with no remote. When no CI job waits (the
34
+ gate was reached on a machine, not in CI), there is nothing to resume: run
20
35
  yodel apply <env>.
21
36
 
22
37
  It never approves on its own. With no terminal to ask (a script, CI, an
@@ -28,23 +43,103 @@ When yodel.config.ts waves names <env>, the apply pipeline's wave waits on
28
43
  its own gate, so that is what is approved: chant approve ${WAVES_PIPELINE}
29
44
  ${WAVES_PIPELINE}-wave-<k> --plan <digest>, bound to the wave's set digest
30
45
  (the plan, the gate policy at the base commit, and what the environments
31
- before it applied). Then push chant/lifecycle and run the wave's job again.
32
- A wave whose policy needs no approval for this plan has nothing to approve.
46
+ before it applied), and the wave's job is the one resumed. A wave whose
47
+ policy needs no approval for this plan has nothing to approve.
48
+
49
+ A gate whose approval mode is sealed (yodel.config.ts waves[].approval, or
50
+ environments.<env>.approval for the migrations Op, read at the base commit)
51
+ counts only an approval sealed with an ssh key that the signers file,
52
+ .chant/allowed_signers at the repository's root, lists at the base commit
53
+ for the approver: --sign seals it (chant approve --sign), with git's
54
+ user.signingkey or --key <file>, and is added on its own under sealed. The
55
+ approver is --actor, else the user chant names (GITHUB_ACTOR,
56
+ GITLAB_USER_LOGIN or USER); it must be the principal the signers file gives
57
+ the key. A key the change being applied adds to that file does not count
58
+ for it.
59
+
60
+ An environment with a tenant set (yodel.config.ts environments.<env>.tenants)
61
+ is approved once for every tenant: yodel approve <env> plans each tenant as
62
+ the wave's deciding job does, shows what is pending on each, and approves
63
+ the wave's set digest over all of them. <env>/<tenant> approves one tenant
64
+ for yodel apply <env>/<tenant>, outside the pipeline.
33
65
 
34
66
  Options:
67
+ --plan <digest> the digest you mean to approve (from the pull request
68
+ comment or the waiting job); refused, naming the one
69
+ that waits, when it is not the plan's
70
+ --sign seal the approval with an ssh key (on its own when the
71
+ gate's approval mode is sealed)
72
+ --key <file> the private key --sign seals with (default: git's
73
+ user.signingkey, with gpg.format ssh)
74
+ --actor <name> the approver chant records, the principal the signers
75
+ file names for the key
76
+ --no-resume record the approval only; start no job
35
77
  --op <name> the migrations Op, when more than one applies <env>
36
78
  --allow-out-of-order approve the plan yodel apply --allow-out-of-order runs
37
79
  -C, --dir <dir> the project directory (default: the working directory)
38
80
 
39
81
  Exit codes:
40
- 0 approved, or nothing is pending
82
+ 0 approved (and the waiting job resumed, or none waits), or nothing is
83
+ pending
84
+ 3 approved, but the waiting job was not resumed (no token, a token the
85
+ forge refused, a push that did not land): chant says why; push
86
+ chant/lifecycle and run chant run resume --op <op>, or run the job again
41
87
  4 nothing approved: no terminal to ask, an answer that was not the
42
- environment's name, a plan apply would refuse, or a plan that moved
43
- while you were asked
88
+ environment's name, a --plan that is not the plan's, a plan apply would
89
+ refuse, or a plan that moved while you were asked
44
90
  2 a pending migration has a step yodel apply does not run
45
91
  1 anything else: a bad config, a server that does not answer, chant
46
92
  approve failed
47
93
  `;
94
+ /**
95
+ * The chant command that records an approval of `gate` on `op` for `digest`
96
+ * and, with `resume`, pushes it and starts the job waiting at the gate
97
+ * again. Which forge API that calls, and with which token, chant reads from
98
+ * the job's pending fact on chant/lifecycle (#47).
99
+ */
100
+ export function chantApproveArgs(op, gate, digest, resume, signing = {}) {
101
+ return [
102
+ "approve", op, gate, "--plan", digest,
103
+ ...(signing.actor !== undefined ? ["--actor", signing.actor] : []),
104
+ ...(signing.sign === true ? ["--sign", ...(signing.key !== undefined ? [signing.key] : [])] : []),
105
+ ...(resume ? ["--resume"] : []),
106
+ ];
107
+ }
108
+ /** Whether the project's git repository has a remote: without one there is nothing to push to and no CI job to resume. */
109
+ async function hasRemote(dir) {
110
+ const { execFile } = await import("node:child_process");
111
+ return new Promise((done) => {
112
+ execFile("git", ["remote"], { cwd: dir }, (err, stdout) => {
113
+ done(!err && stdout.trim() !== "");
114
+ });
115
+ });
116
+ }
117
+ /** Whether chant's gate ledger now holds an approval of `gate` on `op` for `digest`, recorded at or after `since`. */
118
+ async function approvalRecorded(dir, op, gate, digest, since) {
119
+ const { latestResolutionForPlan } = await import("@intentius/chant/lifecycle/gate-ledger");
120
+ const ledger = await (await gitLedger(dir)).read(op);
121
+ const found = latestResolutionForPlan(ledger.resolutions, gate, new Date(0).toISOString(), digest).resolution;
122
+ return found !== undefined && found.timestamp >= since;
123
+ }
124
+ /**
125
+ * Runs chant approve for the gate, resuming its waiting job unless told not
126
+ * to; the exit code is `help`'s. `next` is what to do when nothing was
127
+ * resumed, `afterResume` what to add when it was.
128
+ */
129
+ async function record(io, dir, op, gate, digest, resume, next, afterResume = "", signing = {}) {
130
+ const since = new Date(Date.now() - 1000).toISOString();
131
+ const ran = await runChant(chantApproveArgs(op, gate, digest, resume, signing), { cwd: dir, onStdout: io.err, onStderr: io.err });
132
+ if (ran.code !== 0) {
133
+ if (resume && (await approvalRecorded(dir, op, gate, digest, since).catch(() => false))) {
134
+ io.err(`\nApproved ${digest} for ${op} / ${gate}, but the waiting job was not resumed (chant says why above). ` +
135
+ `Push chant/lifecycle and run ${runnable(`chant run resume --op ${op}`, dir)}, or run the job again.\n`);
136
+ return EXIT_OUTSTANDING;
137
+ }
138
+ throw new YodelError(`chant approve ${op} ${gate} failed (exit ${String(ran.code)}); nothing was approved`);
139
+ }
140
+ io.out(`\nApproved ${digest} for ${op} / ${gate}. ${resume ? `chant pushed it, and started again the CI job waiting at the gate if one waits (above).${afterResume}` : `Nothing was resumed. ${next}`}\n`);
141
+ return 0;
142
+ }
48
143
  /** `yodel approve <env>`; the exit codes are in `help`. */
49
144
  export const approve = {
50
145
  name: "approve",
@@ -57,7 +152,16 @@ export const approve = {
57
152
  args,
58
153
  allowPositionals: true,
59
154
  strict: true,
60
- options: { dir: { type: "string", short: "C" }, op: { type: "string" }, "allow-out-of-order": { type: "boolean" } },
155
+ options: {
156
+ dir: { type: "string", short: "C" },
157
+ op: { type: "string" },
158
+ plan: { type: "string" },
159
+ "no-resume": { type: "boolean" },
160
+ sign: { type: "boolean" },
161
+ key: { type: "string" },
162
+ actor: { type: "string" },
163
+ "allow-out-of-order": { type: "boolean" },
164
+ },
61
165
  });
62
166
  }
63
167
  catch (e) {
@@ -68,12 +172,29 @@ export const approve = {
68
172
  if (name === undefined || rest.length > 0)
69
173
  throw new YodelError(usage);
70
174
  const allowOutOfOrder = values["allow-out-of-order"] === true || process.env[ALLOW_OUT_OF_ORDER_ENV] === "1";
175
+ const expected = typeof values.plan === "string" ? values.plan : undefined;
176
+ if (values.key !== undefined && values.sign !== true)
177
+ throw new YodelError(`--key is the key --sign seals with; add --sign\n${usage}`);
178
+ /** --sign, or a sealed gate (#48), seals the approval. */
179
+ const signing = (mode) => {
180
+ const sign = values.sign === true || mode === "sealed";
181
+ if (sign && values.sign !== true)
182
+ io.err(`The gate's approval mode is sealed: the approval is sealed (chant approve --sign)${typeof values.key === "string" ? "" : " with git's user.signingkey"}.\n`);
183
+ return { ...(sign ? { sign } : {}), ...(typeof values.key === "string" ? { key: values.key } : {}), ...(typeof values.actor === "string" ? { actor: values.actor } : {}) };
184
+ };
185
+ /** --no-resume, or a repository with no remote, records the approval only. */
186
+ const resuming = async (dir) => {
187
+ if (values["no-resume"] === true)
188
+ return false;
189
+ if (await hasRemote(dir))
190
+ return true;
191
+ io.err("This repository has no remote, so no CI job can be waiting: the approval is recorded here and nothing is resumed.\n");
192
+ return false;
193
+ };
71
194
  const project = await loadProject(typeof values.dir === "string" ? values.dir : process.cwd());
72
195
  const env = resolveEnvironment(project, name);
73
- const set = env.tenant?.env ?? (project.yodel?.config.environments?.[env.name]?.tenants ? env.name : undefined);
74
- if (set !== undefined) {
75
- throw new YodelError(`${set} is a tenant set: its wave is approved once for every tenant, with the chant approve command its deciding job printed (yodel apply <tenant> --wave-plan prints it too); nothing was approved`);
76
- }
196
+ // A tenant set (#56): its wave, once for every tenant. One tenant is approved as an environment of its own.
197
+ const set = !env.tenant && tenantSetOf(project, env.name) ? env.name : undefined;
77
198
  // Asked before anything is read: no terminal is no one to ask, whatever the plan.
78
199
  const ask = io.ask;
79
200
  if (!ask) {
@@ -85,6 +206,8 @@ export const approve = {
85
206
  throw new YodelError(`${project.dir} has no migrations/ directory with a migration; yodel approve is for versioned migrations. For a declarative project, run yodel apply ${env.name}: it prints the chant approve command`);
86
207
  }
87
208
  const ordered = readMigrations(migrationsDir(project));
209
+ if (set !== undefined)
210
+ return await approveTenantSet(project, set, ordered, { allowOutOfOrder, expected, ask, io, resuming, signing });
88
211
  const venv = await openVersioned(project, env);
89
212
  try {
90
213
  const report = await statusReport(venv, ordered, { allowOutOfOrder });
@@ -108,6 +231,10 @@ export const approve = {
108
231
  io.out(`${describeWave(view)}\n`);
109
232
  if (!view.waits)
110
233
  return 0;
234
+ if (expected !== undefined && expected !== view.digest) {
235
+ io.err(`yodel approve: --plan ${expected} is not the plan waiting for ${env.name}, which is ${view.digest}. Nothing was approved.\n`);
236
+ return NOT_APPROVED;
237
+ }
111
238
  const answer = (await ask(`\nApprove wave ${String(view.wave)} for ${env.name}, ${view.digest}? Type ${env.name} to approve: `)).trim();
112
239
  if (answer !== env.name) {
113
240
  io.err(`Not approved: the answer was not ${env.name}.\n`);
@@ -121,15 +248,16 @@ export const approve = {
121
248
  }
122
249
  const { waveGateName } = await import("@intentius/chant/gated-waves");
123
250
  const gate = waveGateName(WAVES_PIPELINE, view.wave);
124
- const ran = await runChant(["approve", WAVES_PIPELINE, gate, "--plan", view.digest], { cwd: project.dir, onStdout: io.err, onStderr: io.err });
125
- if (ran.code !== 0)
126
- throw new YodelError(`chant approve ${WAVES_PIPELINE} ${gate} failed (exit ${String(ran.code)}); nothing was approved`);
127
- io.out(`\nApproved ${view.digest} for ${WAVES_PIPELINE} / ${gate}. Push chant/lifecycle, then run wave ${String(view.wave)}'s job again.\n`);
128
- return 0;
251
+ const resume = await resuming(project.dir);
252
+ return await record(io, project.dir, WAVES_PIPELINE, gate, view.digest, resume, `Run wave ${String(view.wave)}'s job again (push chant/lifecycle first if chant did not).`, "", signing(view.approval));
129
253
  }
130
254
  }
131
255
  const op = await findMigrateOp(project, env, typeof values.op === "string" ? values.op : undefined);
132
256
  io.out(renderStatus(report));
257
+ if (expected !== undefined && expected !== report.digest) {
258
+ io.err(`yodel approve: --plan ${expected} is not the plan waiting for ${env.name}, which is ${report.digest}. Nothing was approved.\n`);
259
+ return NOT_APPROVED;
260
+ }
133
261
  const answer = (await ask(`\nApprove this plan for ${env.name}, ${report.digest}? Type ${env.name} to approve: `)).trim();
134
262
  if (answer !== env.name) {
135
263
  io.err(`Not approved: the answer was not ${env.name}.\n`);
@@ -141,15 +269,69 @@ export const approve = {
141
269
  io.err(`Not approved: the plan moved while you were asked (now ${again.digest ?? "nothing to apply"}); run yodel approve ${env.name} again.\n`);
142
270
  return NOT_APPROVED;
143
271
  }
144
- const ran = await runChant(["approve", op.name, op.gate, "--plan", report.digest], { cwd: project.dir, onStdout: io.err, onStderr: io.err });
145
- if (ran.code !== 0)
146
- throw new YodelError(`chant approve ${op.name} ${op.gate} failed (exit ${String(ran.code)}); nothing was approved`);
147
- io.out(`\nApproved ${report.digest} for ${op.name} / ${op.gate}. Apply it with:\n ${runnable(`yodel apply ${env.name}`, project.dir)}\n`);
148
- return 0;
272
+ const mode = await migrationsApprovalAtBase(project, env.name);
273
+ if (mode.note)
274
+ io.err(`${mode.note}\n`);
275
+ return await record(io, project.dir, op.name, op.gate, report.digest, await resuming(project.dir), `Apply it with:\n ${runnable(`yodel apply ${env.name}`, project.dir)}`, ` Where none waits, apply it with:\n ${runnable(`yodel apply ${env.name}`, project.dir)}`, signing(mode.mode));
149
276
  }
150
277
  finally {
151
278
  await closeVersioned(venv);
152
279
  }
153
280
  }),
154
281
  };
282
+ /** `yodel approve <set>` (#56): the tenant set's wave, one approval of its set digest over every tenant's plan. */
283
+ async function approveTenantSet(project, set, ordered, o) {
284
+ const { io } = o;
285
+ const read = async () => {
286
+ const tenants = await viewTenants(project, set, ordered, { allowOutOfOrder: o.allowOutOfOrder });
287
+ return { tenants, view: await viewTenantSetWave(project, set, tenants) };
288
+ };
289
+ const { tenants, view } = await read();
290
+ if (!view) {
291
+ throw new YodelError(`${set} is a tenant set, and yodel.config.ts waves does not name it, so no wave applies it: approve a tenant with yodel approve ${set}/<tenant>, for yodel apply ${set}/<tenant>; nothing was approved`);
292
+ }
293
+ for (const t of tenants.filter((x) => x.report.refusal))
294
+ io.err(`yodel approve: ${t.target}: ${t.report.refusal?.message ?? ""}\n`);
295
+ if (view.refused.length > 0) {
296
+ io.err(`${describeTenantSetWave(view, tenants.length)}\nNothing was approved.\n`);
297
+ return NOT_APPROVED;
298
+ }
299
+ if (tenants.every((t) => t.plan?.empty)) {
300
+ io.out(`Every tenant of ${set} (${String(tenants.length)}) is up to date: there is nothing to approve.\n`);
301
+ return 0;
302
+ }
303
+ io.out(`Tenant set ${set}, ${String(tenants.length)} tenant${tenants.length === 1 ? "" : "s"}:\n`);
304
+ for (const g of groupTenants(tenants, (t) => (t.plan?.pending ?? []).join(" "))) {
305
+ const pending = g.members[0]?.plan?.pending ?? [];
306
+ io.out(` ${pending.length === 0 ? "up to date" : `${String(pending.length)} pending (${pending.join(", ")})`}: ${someNames(g.members.map((m) => m.target))}\n`);
307
+ const destructive = g.members[0]?.plan?.destructiveSteps ?? [];
308
+ if (destructive.length > 0)
309
+ io.out(` destructive: ${destructive.map((d) => `${d.migration} step ${String(d.step)} (${d.why})`).join(", ")}\n`);
310
+ }
311
+ io.out(`${describeTenantSetWave(view, tenants.length)}\n`);
312
+ if (view.blocked.length > 0) {
313
+ io.err("Nothing was approved.\n");
314
+ return NOT_APPROVED;
315
+ }
316
+ if (!view.waits || !view.digest)
317
+ return 0;
318
+ if (o.expected !== undefined && o.expected !== view.digest) {
319
+ io.err(`yodel approve: --plan ${o.expected} is not the plan waiting for ${set}, which is ${view.digest}. Nothing was approved.\n`);
320
+ return NOT_APPROVED;
321
+ }
322
+ const answer = (await o.ask(`\nApprove wave ${String(view.wave)} for every tenant of ${set}, ${view.digest}? Type ${set} to approve: `)).trim();
323
+ if (answer !== set) {
324
+ io.err(`Not approved: the answer was not ${set}.\n`);
325
+ return NOT_APPROVED;
326
+ }
327
+ // Every tenant is read again: what is approved is what the person saw.
328
+ const again = await read();
329
+ if (again.view?.digest !== view.digest) {
330
+ io.err(`Not approved: the plan moved while you were asked (now ${again.view?.digest ?? "nothing to approve"}); run yodel approve ${set} again.\n`);
331
+ return NOT_APPROVED;
332
+ }
333
+ const { waveGateName } = await import("@intentius/chant/gated-waves");
334
+ const gate = waveGateName(WAVES_PIPELINE, view.wave);
335
+ return record(io, project.dir, WAVES_PIPELINE, gate, view.digest, await o.resuming(project.dir), `Run wave ${String(view.wave)}'s deciding job again (push chant/lifecycle first if chant did not).`, "", o.signing(view.approval));
336
+ }
155
337
  //# sourceMappingURL=approve.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"approve.js","sourceRoot":"","sources":["../../src/commands/approve.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"approve.js","sourceRoot":"","sources":["../../src/commands/approve.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,11 @@ Ops), each declared with chant's lexicons:
14
14
  check into a throwaway server, and the plan comment per
15
15
  environment
16
16
  yodel-apply on a push to main: one job per wave (yodel-waves.json)
17
+ yodel-apply-plans
18
+ on a pull request, when a wave's approval is pr-review:
19
+ chant run wave --record-plans records the plan each wave
20
+ makes at the head, for the review to approve (on GitLab, the
21
+ merge request job yodel-apply-record-plans)
17
22
  watch-<env> each environment's drift watch, on its schedule
18
23
 
19
24
  The pipelines come from the installed yodel, so upgrading yodel and running
@@ -26,6 +31,13 @@ yodel.config.ts ci:
26
31
  declared with chant: actions (github lexicon Jobs, for GitHub and
27
32
  Forgejo) and gitlab (gitlab lexicon Jobs). They are added to the
28
33
  pull request pipeline after yodel's jobs, on every render.
34
+ image the CI image every job runs in, pinned by its digest
35
+ resume { schedule: "<cron>" }: a scheduled yodel-apply-resume job that
36
+ starts again an apply wave whose approval has arrived (chant run
37
+ resume); it approves nothing. GitHub uses the job's token
38
+ (actions: write), Forgejo the CHANT_FORGE_TOKEN secret
39
+ (write:repository), GitLab a pipeline schedule you create, with
40
+ GITLAB_TOKEN (api scope, Developer)
29
41
 
30
42
  Options:
31
43
  --check write nothing; exit 1 naming each file that differs from
@@ -1 +1 @@
1
- {"version":3,"file":"ci.js","sourceRoot":"","sources":["../../src/commands/ci.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAExD,MAAM,KAAK,GAAG,mHAAmH,CAAC;AAElI,MAAM,IAAI,GAAG,GAAG,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCpB,CAAC;AASF,SAAS,WAAW,CAAC,IAAuB;IAC1C,MAAM,GAAG,GAAW,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IAClF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACf,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC7B,MAAM;QACR,CAAC;QACD,IAAI,CAAC,KAAK,SAAS;YAAE,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC;aACjC,IAAI,CAAC,KAAK,UAAU;YAAE,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC;aACxC,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACrC,MAAM,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACpB,IAAI,CAAC,KAAK,SAAS;gBAAE,MAAM,IAAI,UAAU,CAAC,GAAG,CAAC,uBAAuB,KAAK,EAAE,CAAC,CAAC;YAC9E,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;QACd,CAAC;aAAM,IAAI,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC;YAAE,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;;YAClE,MAAM,IAAI,UAAU,CAAC,oBAAoB,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,MAAM;QAAE,MAAM,IAAI,UAAU,CAAC,kDAAkD,KAAK,EAAE,CAAC,CAAC;IAC7G,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM;QAAE,MAAM,IAAI,UAAU,CAAC,sCAAsC,KAAK,EAAE,CAAC,CAAC;IAC5G,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gDAAgD;AAChD,MAAM,CAAC,MAAM,EAAE,GAAY;IACzB,IAAI,EAAE,IAAI;IACV,OAAO,EAAE,6DAA6D;IACtE,WAAW,EAAE,IAAI;IACjB,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAChB,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAC5B,yFAAyF;QACzF,MAAM,GAAG,GAAG,CAAC,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACpD,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;YAC1D,OAAO,aAAa,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;QACD,8DAA8D;QAC9D,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;QACnD,IAAI,KAAK,CAAC;QACV,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,UAAU,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACnE,CAAC;QACD,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YACjC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACxE,IAAI,OAAO,KAAK,IAAI,CAAC,OAAO;gBAAE,SAAS;YACvC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;gBACZ,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtB,SAAS;YACX,CAAC;YACD,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7C,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YACjC,EAAE,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;QACjC,CAAC;QACD,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,EAAE,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,CAAC,CAAC,KAAK;YAAE,EAAE,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC;QACzE,OAAO,CAAC,CAAC;IACX,CAAC,CAAC;CACL,CAAC"}
1
+ {"version":3,"file":"ci.js","sourceRoot":"","sources":["../../src/commands/ci.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Command } from "../command.js";
2
+ import { type Retained } from "../cleanup/index.js";
3
+ /** `yodel cleanup --json` (schemas/cleanup.schema.json). */
4
+ export declare function cleanupJson(r: {
5
+ environment: string;
6
+ now: string;
7
+ retained: readonly Retained[];
8
+ planDigest?: string | undefined;
9
+ approve?: string | undefined;
10
+ dropped: readonly string[];
11
+ }): Record<string, unknown>;
12
+ /** `yodel cleanup <env>`; the exit codes are in `help`. */
13
+ export declare const cleanup: Command;
@@ -0,0 +1,158 @@
1
+ import { parseArgs } from "node:util";
2
+ import { guarded } from "../env-args.js";
3
+ import { loadProject, resolveEnvironment, YodelError } from "../project.js";
4
+ import { appliedBy, withLock } from "../history/index.js";
5
+ import { closeVersioned, findMigrateOp, gitLedger, NOT_APPROVED, openVersioned, verifyApproval } from "../versioned/index.js";
6
+ import { migrationsApprovalAtBase, portFor, signFlag } from "../approval-mode/index.js";
7
+ import { cleanupDigest, cleanupGate, describeRetained, dropRetained, findRetained, retainedServer } from "../cleanup/index.js";
8
+ const usage = "usage: yodel cleanup <env> [--list] [--op <name>] [--json] [--dir <project>]";
9
+ const help = `${usage}
10
+
11
+ Lists what steps kept in <env> on purpose, and drops what is past its
12
+ retention date, behind the environment's approval:
13
+
14
+ - a ClickHouse rebuild's old table, <table>__chant_old, kept after the swap
15
+ (7 days, or the step's retain);
16
+ - a Postgres rename's or type change's old column, kept after the switch
17
+ when the step set retain (yodel new --retain), with the trigger and
18
+ function that keep a renamed column written.
19
+
20
+ Each one's date is in its own comment, and the server's clock decides
21
+ whether it has passed. Nothing is dropped before its date.
22
+
23
+ When something is due, the drop is a plan like an apply's: its digest
24
+ covers each due object (a table by its UUID, a column by its table and
25
+ attribute number) and its date. Without an approval for that digest on
26
+ the migrations Op's cleanup gate (its gate's name with -cleanup, e.g.
27
+ approve-migrate-prod-cleanup, apart from the apply's approvals), yodel
28
+ cleanup lists what it would drop, prints the digest and the chant approve
29
+ command, and drops nothing (exit 3). Approve it, run yodel cleanup <env> again, and it drops them under the
30
+ apply lock, after reading them again: if anything due changed, the digest
31
+ differs and the approval does not count. The environment's approval mode
32
+ counts as it does for yodel apply: under sealed (environments.<env>.approval,
33
+ read at the base commit), only an approval sealed with chant approve --sign
34
+ by a key .chant/allowed_signers lists for its approver.
35
+
36
+ Options:
37
+ --list list only; never drop, even with an approval
38
+ --op <name> the migrations Op, when more than one applies <env>
39
+ --json print the list (and what was dropped) as JSON
40
+ -C, --dir <dir> the project directory (default: the working directory)
41
+
42
+ Exit codes:
43
+ 0 nothing is due (and nothing was dropped), the due objects were dropped,
44
+ or --list
45
+ 3 something is due and waits for an approval; nothing was dropped
46
+ 5 another apply holds the lock
47
+ 1 an error: a bad config, an unknown environment, a server it cannot read
48
+ `;
49
+ function parseCleanupArgs(args) {
50
+ let parsed;
51
+ try {
52
+ parsed = parseArgs({ args, allowPositionals: true, strict: true, options: { list: { type: "boolean" }, op: { type: "string" }, json: { type: "boolean" }, dir: { type: "string", short: "C" } } });
53
+ }
54
+ catch (e) {
55
+ throw new YodelError(`${e instanceof Error ? e.message : String(e)}\n${usage}`);
56
+ }
57
+ const [env, ...rest] = parsed.positionals;
58
+ if (env === undefined || rest.length > 0)
59
+ throw new YodelError(usage);
60
+ const v = parsed.values;
61
+ return { env, list: v.list === true, op: typeof v.op === "string" ? v.op : undefined, json: v.json === true, dir: typeof v.dir === "string" ? v.dir : process.cwd() };
62
+ }
63
+ /** `yodel cleanup --json` (schemas/cleanup.schema.json). */
64
+ export function cleanupJson(r) {
65
+ return {
66
+ environment: r.environment,
67
+ now: r.now,
68
+ retained: r.retained.map((x) => ({ kind: x.kind, name: x.name, of: x.of, ...(x.retainUntil ? { retainUntil: x.retainUntil } : {}), due: x.due, identity: x.identity, ...(x.trigger ? { trigger: x.trigger } : {}) })),
69
+ due: r.retained.filter((x) => x.due).length,
70
+ ...(r.planDigest ? { planDigest: r.planDigest } : {}),
71
+ ...(r.approve ? { approve: r.approve } : {}),
72
+ dropped: r.dropped,
73
+ };
74
+ }
75
+ /** `yodel cleanup <env>`; the exit codes are in `help`. */
76
+ export const cleanup = {
77
+ name: "cleanup",
78
+ summary: "drop the old tables and columns steps kept, once past their date",
79
+ implemented: true,
80
+ run: (args, io) => guarded("cleanup", io, args, help, async () => {
81
+ const a = parseCleanupArgs(args);
82
+ const project = await loadProject(a.dir);
83
+ const env = resolveEnvironment(project, a.env);
84
+ const venv = await openVersioned(project, env);
85
+ try {
86
+ return await cleanupWith(project, env, venv, a, io);
87
+ }
88
+ finally {
89
+ await closeVersioned(venv);
90
+ }
91
+ }),
92
+ };
93
+ async function cleanupWith(project, env, venv, a, io) {
94
+ const server = retainedServer(venv);
95
+ const { now, retained } = await findRetained(server);
96
+ const dueCount = retained.filter((r) => r.due).length;
97
+ const lines = [`Kept by steps in ${env.name} (server time ${now}):`];
98
+ if (retained.length === 0)
99
+ lines[0] = `Nothing kept by steps in ${env.name}: no old table or old column waits for its retention date.`;
100
+ for (const r of retained)
101
+ lines.push(` ${describeRetained(r)}`);
102
+ const report = (extra, tail = []) => {
103
+ if (a.json)
104
+ io.out(`${JSON.stringify(cleanupJson({ environment: env.name, now, retained, dropped: [], ...extra }), null, 2)}\n`);
105
+ else
106
+ io.out(`${[...lines, ...tail].join("\n")}\n`);
107
+ };
108
+ if (dueCount === 0 || a.list) {
109
+ report({}, retained.length > 0 && dueCount === 0 ? ["", "Nothing is due: nothing dropped."] : []);
110
+ return 0;
111
+ }
112
+ const digest = await cleanupDigest(env.name, retained);
113
+ const migrate = await findMigrateOp(project, env, a.op);
114
+ // Its own gate on the migrations Op, so an apply's approval is never confused with it.
115
+ const op = { ...migrate, gate: cleanupGate(migrate.gate) };
116
+ // The environment's approval mode, as an apply's (#48, #130): under sealed, only a sealed approval counts.
117
+ const mode = await migrationsApprovalAtBase(project, env.name);
118
+ if (mode.note && !a.json)
119
+ io.err(`${mode.note}\n`);
120
+ const ledger = await portFor(await gitLedger(project.dir), mode.mode, project.dir, mode.base);
121
+ const approve = `chant approve ${op.name} ${op.gate} --plan ${digest}${signFlag(mode.mode)}`;
122
+ try {
123
+ await verifyApproval(ledger, op, digest);
124
+ }
125
+ catch (e) {
126
+ if (!(e instanceof YodelError) || e.exitCode !== NOT_APPROVED)
127
+ throw e;
128
+ // An approval of this digest the mode does not count (an unsigned one under sealed), and why.
129
+ const uncounted = /\((the approval by .* does not count: .*)\)\. Nothing was applied\./s.exec(e.message)?.[1];
130
+ report({ planDigest: digest, approve }, [
131
+ "",
132
+ `Plan digest: ${digest}`,
133
+ ...(uncounted ? [`${uncounted[0]?.toUpperCase() ?? ""}${uncounted.slice(1)}.`] : []),
134
+ `${String(dueCount)} due; nothing dropped without an approval${mode.mode === "sealed" ? " sealed by a signer (approval sealed)" : ""}. Approve it with:`,
135
+ ` ${approve}`,
136
+ `then run yodel cleanup ${env.name} again.`,
137
+ ]);
138
+ return NOT_APPROVED;
139
+ }
140
+ const lock = await venv.driver.acquireLock(appliedBy());
141
+ if (lock.notice && !a.json)
142
+ io.err(`lock: ${lock.notice}\n`);
143
+ const dropped = await withLock(lock, venv.lockTtlMs, async () => {
144
+ // Read again under the lock: the approval counts only for what is due now.
145
+ const again = await findRetained(server);
146
+ const now = await cleanupDigest(env.name, again.retained);
147
+ const by = await verifyApproval(ledger, op, now);
148
+ if (!a.json)
149
+ io.err(`approval: ${op.name} / ${op.gate} for ${now}, by ${by.resolvedBy} at ${by.timestamp}${by.signer ? `, sealed by ${by.signer}` : ""}\n`);
150
+ return dropRetained(server, again.retained, (l) => {
151
+ if (!a.json)
152
+ io.err(`${l}\n`);
153
+ });
154
+ });
155
+ report({ planDigest: digest, dropped }, ["", `Dropped ${String(dropped.length)}: ${dropped.join(", ")}`]);
156
+ return 0;
157
+ }
158
+ //# sourceMappingURL=cleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../../src/commands/cleanup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from "../command.js";
2
+ /** `yodel config check`; the exit codes are in `help`. */
3
+ export declare const config: Command;