@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.
- package/README.md +2 -2
- package/dist/apply-steps/index.d.ts +65 -0
- package/dist/apply-steps/index.js +106 -0
- package/dist/apply-steps/index.js.map +1 -0
- package/dist/approval-mode/index.d.ts +78 -0
- package/dist/approval-mode/index.js +105 -0
- package/dist/approval-mode/index.js.map +1 -0
- package/dist/chant/access.d.ts +84 -0
- package/dist/chant/access.js +155 -0
- package/dist/chant/access.js.map +1 -0
- package/dist/chant/drift.d.ts +17 -1
- package/dist/chant/drift.js +55 -2
- package/dist/chant/drift.js.map +1 -1
- package/dist/chant/plan.d.ts +18 -2
- package/dist/chant/plan.js +21 -3
- package/dist/chant/plan.js.map +1 -1
- package/dist/ci/login.d.ts +78 -0
- package/dist/ci/login.js +199 -0
- package/dist/ci/login.js.map +1 -0
- package/dist/ci/render.d.ts +64 -10
- package/dist/ci/render.js +385 -88
- package/dist/ci/render.js.map +1 -1
- package/dist/cleanup/index.d.ts +92 -0
- package/dist/cleanup/index.js +213 -0
- package/dist/cleanup/index.js.map +1 -0
- package/dist/commands/apply.js +178 -20
- package/dist/commands/apply.js.map +1 -1
- package/dist/commands/approve.d.ts +13 -0
- package/dist/commands/approve.js +206 -24
- package/dist/commands/approve.js.map +1 -1
- package/dist/commands/ci.js +12 -0
- package/dist/commands/ci.js.map +1 -1
- package/dist/commands/cleanup.d.ts +13 -0
- package/dist/commands/cleanup.js +158 -0
- package/dist/commands/cleanup.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.js +136 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/drift.js +33 -3
- package/dist/commands/drift.js.map +1 -1
- package/dist/commands/index.js +6 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/init.d.ts +11 -0
- package/dist/commands/init.js +98 -10
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/lint.js +67 -10
- package/dist/commands/lint.js.map +1 -1
- package/dist/commands/new.js +135 -54
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/plan.js +39 -5
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/test.d.ts +3 -0
- package/dist/commands/test.js +164 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/config/define.d.ts +175 -2
- package/dist/config/define.js +2 -0
- package/dist/config/define.js.map +1 -1
- package/dist/config/load.js +78 -10
- package/dist/config/load.js.map +1 -1
- package/dist/config/settings.d.ts +20 -0
- package/dist/config/settings.js +28 -0
- package/dist/config/settings.js.map +1 -1
- package/dist/credentials.d.ts +119 -0
- package/dist/credentials.js +119 -0
- package/dist/credentials.js.map +1 -0
- package/dist/exit.js +1 -1
- package/dist/exit.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/init/adopt.js +1 -1
- package/dist/init/adopt.js.map +1 -1
- package/dist/init/clickhouse-access.d.ts +64 -0
- package/dist/init/clickhouse-access.js +211 -0
- package/dist/init/clickhouse-access.js.map +1 -0
- package/dist/init/index.d.ts +2 -0
- package/dist/init/index.js +2 -0
- package/dist/init/index.js.map +1 -1
- package/dist/init/live.d.ts +4 -0
- package/dist/init/live.js +16 -0
- package/dist/init/live.js.map +1 -1
- package/dist/init/second.d.ts +70 -0
- package/dist/init/second.js +149 -0
- package/dist/init/second.js.map +1 -0
- package/dist/lint/access.d.ts +18 -0
- package/dist/lint/access.js +34 -0
- package/dist/lint/access.js.map +1 -0
- package/dist/lint/annotations.d.ts +49 -0
- package/dist/lint/annotations.js +82 -0
- package/dist/lint/annotations.js.map +1 -0
- package/dist/lint/check.js +25 -7
- package/dist/lint/check.js.map +1 -1
- package/dist/lint/config.d.ts +7 -1
- package/dist/lint/config.js +11 -5
- package/dist/lint/config.js.map +1 -1
- package/dist/lint/index.d.ts +4 -0
- package/dist/lint/index.js +4 -0
- package/dist/lint/index.js.map +1 -1
- package/dist/lint/naming.d.ts +62 -0
- package/dist/lint/naming.js +138 -0
- package/dist/lint/naming.js.map +1 -0
- package/dist/lint/rules.d.ts +37 -4
- package/dist/lint/rules.js +16 -4
- package/dist/lint/rules.js.map +1 -1
- package/dist/lint/schema-checks.d.ts +63 -0
- package/dist/lint/schema-checks.js +128 -0
- package/dist/lint/schema-checks.js.map +1 -0
- package/dist/lint/statements.d.ts +22 -1
- package/dist/lint/statements.js +40 -1
- package/dist/lint/statements.js.map +1 -1
- package/dist/mcp/tools.d.ts +1 -1
- package/dist/mcp/tools.js +1 -1
- package/dist/mcp/tools.js.map +1 -1
- package/dist/migrations/checkpoint.js +0 -2
- package/dist/migrations/checkpoint.js.map +1 -1
- package/dist/migrations/checks.d.ts +19 -1
- package/dist/migrations/checks.js +15 -0
- package/dist/migrations/checks.js.map +1 -1
- package/dist/migrations/create.d.ts +13 -4
- package/dist/migrations/create.js +24 -9
- package/dist/migrations/create.js.map +1 -1
- package/dist/migrations/routines.d.ts +5 -15
- package/dist/migrations/routines.js +5 -30
- package/dist/migrations/routines.js.map +1 -1
- package/dist/pr/model.d.ts +4 -1
- package/dist/pr/model.js +13 -5
- package/dist/pr/model.js.map +1 -1
- package/dist/pr/render.d.ts +4 -1
- package/dist/pr/render.js +22 -8
- package/dist/pr/render.js.map +1 -1
- package/dist/pr/tenants.d.ts +37 -0
- package/dist/pr/tenants.js +138 -0
- package/dist/pr/tenants.js.map +1 -0
- package/dist/probe.d.ts +27 -0
- package/dist/probe.js +106 -0
- package/dist/probe.js.map +1 -0
- package/dist/project.d.ts +16 -0
- package/dist/project.js +29 -1
- package/dist/project.js.map +1 -1
- package/dist/replay/clickhouse.d.ts +31 -0
- package/dist/replay/clickhouse.js +103 -6
- package/dist/replay/clickhouse.js.map +1 -1
- package/dist/replay/replay.d.ts +5 -2
- package/dist/replay/replay.js.map +1 -1
- package/dist/report/audit.d.ts +1 -1
- package/dist/report/audit.js +20 -3
- package/dist/report/audit.js.map +1 -1
- package/dist/schemas.d.ts +3 -1
- package/dist/schemas.js +2 -0
- package/dist/schemas.js.map +1 -1
- package/dist/sources/ddl.d.ts +15 -20
- package/dist/sources/ddl.js +34 -328
- package/dist/sources/ddl.js.map +1 -1
- package/dist/sources/index.js +2 -2
- package/dist/sources/index.js.map +1 -1
- package/dist/steps/backfill.d.ts +40 -5
- package/dist/steps/backfill.js +128 -8
- package/dist/steps/backfill.js.map +1 -1
- package/dist/steps/index.d.ts +19 -1
- package/dist/steps/index.js +34 -7
- package/dist/steps/index.js.map +1 -1
- package/dist/steps/kinds.d.ts +42 -4
- package/dist/steps/kinds.js +88 -14
- package/dist/steps/kinds.js.map +1 -1
- package/dist/steps/postgres-migration.d.ts +3 -0
- package/dist/steps/postgres-migration.js +7 -3
- package/dist/steps/postgres-migration.js.map +1 -1
- package/dist/steps/rebuild.d.ts +15 -6
- package/dist/steps/rebuild.js +12 -9
- package/dist/steps/rebuild.js.map +1 -1
- package/dist/tenants/index.d.ts +2 -1
- package/dist/tenants/index.js +3 -4
- package/dist/tenants/index.js.map +1 -1
- package/dist/tenants/wave.d.ts +128 -0
- package/dist/tenants/wave.js +254 -0
- package/dist/tenants/wave.js.map +1 -0
- package/dist/testing/define.d.ts +62 -0
- package/dist/testing/define.js +32 -0
- package/dist/testing/define.js.map +1 -0
- package/dist/testing/files.d.ts +5 -0
- package/dist/testing/files.js +18 -0
- package/dist/testing/files.js.map +1 -0
- package/dist/testing/report.d.ts +14 -0
- package/dist/testing/report.js +83 -0
- package/dist/testing/report.js.map +1 -0
- package/dist/testing/run.d.ts +104 -0
- package/dist/testing/run.js +328 -0
- package/dist/testing/run.js.map +1 -0
- package/dist/versioned/approval.d.ts +6 -0
- package/dist/versioned/approval.js +11 -5
- package/dist/versioned/approval.js.map +1 -1
- package/dist/versioned/checks.d.ts +8 -2
- package/dist/versioned/checks.js +34 -13
- package/dist/versioned/checks.js.map +1 -1
- package/dist/versioned/driver.d.ts +2 -2
- package/dist/versioned/engine.d.ts +10 -0
- package/dist/versioned/engine.js +8 -4
- package/dist/versioned/engine.js.map +1 -1
- package/dist/versioned/explain.d.ts +2 -0
- package/dist/versioned/explain.js +3 -1
- package/dist/versioned/explain.js.map +1 -1
- package/dist/versioned/op.d.ts +4 -0
- package/dist/versioned/op.js +5 -2
- package/dist/versioned/op.js.map +1 -1
- package/dist/versioned/state.js +1 -1
- package/dist/versioned/state.js.map +1 -1
- package/dist/waves/index.d.ts +58 -13
- package/dist/waves/index.js +109 -24
- package/dist/waves/index.js.map +1 -1
- package/dist/waves/record.d.ts +10 -0
- package/dist/waves/record.js.map +1 -1
- package/package.json +8 -7
- package/schemas/apply.schema.json +1 -1
- package/schemas/cleanup.schema.json +40 -0
- package/schemas/init.schema.json +51 -22
- package/schemas/lint-rules.schema.json +4 -0
- package/schemas/new.schema.json +41 -3
- package/schemas/plan.schema.json +39 -0
- package/schemas/report.schema.json +1 -1
- package/schemas/test.schema.json +41 -0
package/dist/commands/approve.js
CHANGED
|
@@ -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
|
|
18
|
-
approval chant approve gives, bound to the same digest: if
|
|
19
|
-
digest covers changes before the apply, the gate asks again.
|
|
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)
|
|
32
|
-
|
|
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
|
|
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
|
|
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: {
|
|
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
|
-
|
|
74
|
-
|
|
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
|
|
125
|
-
|
|
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
|
|
145
|
-
if (
|
|
146
|
-
|
|
147
|
-
io.
|
|
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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"}
|
package/dist/commands/ci.js
CHANGED
|
@@ -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
|
package/dist/commands/ci.js.map
CHANGED
|
@@ -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
|
|
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":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,UAAU,EAAkC,MAAM,eAAe,CAAC;AAC5G,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAqB,MAAM,uBAAuB,CAAC;AACjJ,OAAO,EAAE,wBAAwB,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACxF,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAiB,MAAM,qBAAqB,CAAC;AAE9I,MAAM,KAAK,GAAG,8EAA8E,CAAC;AAE7F,MAAM,IAAI,GAAG,GAAG,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCpB,CAAC;AAUF,SAAS,gBAAgB,CAAC,IAAc;IACtC,IAAI,MAAoC,CAAC;IACzC,IAAI,CAAC;QACH,MAAM,GAAG,SAAS,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;IACrM,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,UAAU,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC;IAC1C,IAAI,GAAG,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IACtE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;IACxB,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC;AACxK,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,WAAW,CAAC,CAAiK;IAC3L,OAAO;QACL,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACrN,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM;QAC3C,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,OAAO,EAAE,CAAC,CAAC,OAAO;KACnB,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,MAAM,CAAC,MAAM,OAAO,GAAY;IAC9B,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,kEAAkE;IAC3E,WAAW,EAAE,IAAI;IACjB,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAChB,OAAO,CAAC,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,CAAC,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC/C,IAAI,CAAC;YACH,OAAO,MAAM,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACtD,CAAC;gBAAS,CAAC;YACT,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC;CACL,CAAC;AAEF,KAAK,UAAU,WAAW,CAAC,OAAgB,EAAE,GAAgB,EAAE,IAAkB,EAAE,CAAc,EAAE,EAAM;IACvG,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IACtD,MAAM,KAAK,GAAG,CAAC,oBAAoB,GAAG,CAAC,IAAI,iBAAiB,GAAG,IAAI,CAAC,CAAC;IACrE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,KAAK,CAAC,CAAC,CAAC,GAAG,4BAA4B,GAAG,CAAC,IAAI,4DAA4D,CAAC;IACvI,KAAK,MAAM,CAAC,IAAI,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,KAAK,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACjE,MAAM,MAAM,GAAG,CAAC,KAAoE,EAAE,OAAiB,EAAE,EAAE,EAAE;QAC3G,IAAI,CAAC,CAAC,IAAI;YAAE,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;;YAC5H,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrD,CAAC,CAAC;IACF,IAAI,QAAQ,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,kCAAkC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAClG,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IACxD,uFAAuF;IACvF,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;IAC3D,2GAA2G;IAC3G,MAAM,IAAI,GAAG,MAAM,wBAAwB,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/D,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI;QAAE,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9F,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,WAAW,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC7F,IAAI,CAAC;QACH,MAAM,cAAc,CAAC,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,CAAC,CAAC,YAAY,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,KAAK,YAAY;YAAE,MAAM,CAAC,CAAC;QACvE,8FAA8F;QAC9F,MAAM,SAAS,GAAG,sEAAsE,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9G,MAAM,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;YACtC,EAAE;YACF,gBAAgB,MAAM,EAAE;YACxB,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpF,GAAG,MAAM,CAAC,QAAQ,CAAC,4CAA4C,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,uCAAuC,CAAC,CAAC,CAAC,EAAE,oBAAoB;YACxJ,KAAK,OAAO,EAAE;YACd,0BAA0B,GAAG,CAAC,IAAI,SAAS;SAC5C,CAAC,CAAC;QACH,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC;IACxD,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI;QAAE,EAAE,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAC9D,2EAA2E;QAC3E,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC1D,MAAM,EAAE,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;QACjD,IAAI,CAAC,CAAC,CAAC,IAAI;YAAE,EAAE,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,IAAI,QAAQ,GAAG,QAAQ,EAAE,CAAC,UAAU,OAAO,EAAE,CAAC,SAAS,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAC5J,OAAO,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;YAChD,IAAI,CAAC,CAAC,CAAC,IAAI;gBAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,WAAW,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1G,OAAO,CAAC,CAAC;AACX,CAAC"}
|