@geonosis/release 1.4.0 → 2.1.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/dist/chunk-MZWAN6WT.js +2436 -0
- package/dist/index.d.ts +394 -1
- package/dist/index.js +83 -3
- package/dist/release-cli.js +322 -88
- package/package.json +2 -2
- package/dist/chunk-D5IC766I.js +0 -1006
package/dist/release-cli.js
CHANGED
|
@@ -1,99 +1,46 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ADOPTION_NEXT,
|
|
2
3
|
CannotRun,
|
|
4
|
+
DEFAULT_REGISTRY,
|
|
5
|
+
MIGRATIONS_NEXT,
|
|
6
|
+
PUBLISHED_NEXT,
|
|
7
|
+
SCHEMA_NEXT,
|
|
8
|
+
SMOKE_NEXT,
|
|
9
|
+
adoptionEnvelope,
|
|
10
|
+
comparisonsIn,
|
|
11
|
+
formatAdoption,
|
|
12
|
+
formatBaseline,
|
|
3
13
|
formatDeployed,
|
|
4
14
|
formatMigrations,
|
|
5
15
|
formatPlan,
|
|
6
16
|
formatProve,
|
|
17
|
+
formatPublished,
|
|
18
|
+
formatSchema,
|
|
19
|
+
formatSnapshot,
|
|
20
|
+
formatSweep,
|
|
7
21
|
formatVerdict,
|
|
22
|
+
migrationsEnvelope,
|
|
8
23
|
prove,
|
|
9
24
|
proveOver,
|
|
25
|
+
publishedEnvelope,
|
|
26
|
+
readReleaseConfig,
|
|
27
|
+
recordBaseline,
|
|
28
|
+
runAdoption,
|
|
10
29
|
runDeployed,
|
|
11
30
|
runMigrations,
|
|
12
|
-
runPlan
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
import { fileURLToPath } from "url";
|
|
22
|
-
var ENVELOPES_DIR = ".geonosis/envelopes";
|
|
23
|
-
var envelopePath = (root, tool) => join(root, ENVELOPES_DIR, `${tool}.json`);
|
|
24
|
-
var UnbalancedEnvelope = class extends Error {
|
|
25
|
-
constructor(message) {
|
|
26
|
-
super(message);
|
|
27
|
-
this.name = "UnbalancedEnvelope";
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
var isCount = (value) => Number.isSafeInteger(value) && value >= 0;
|
|
31
|
-
var unbalancedMessage = (envelope, next) => `${envelope.tool}: considered ${envelope.considered} but accounts for ${envelope.read + envelope.refused.length + envelope.excused.length} \u2014 ${envelope.read} read + ${envelope.refused.length} refused + ${envelope.excused.length} excused. A run that has lost count of its own inputs cannot say what it measured, so no verdict was rendered and no envelope was written. Next: ${next}`;
|
|
32
|
-
var writeEnvelope = ({
|
|
33
|
-
envelope,
|
|
34
|
-
next,
|
|
35
|
-
root
|
|
36
|
-
}) => {
|
|
37
|
-
if (envelope.tool.trim() === "") {
|
|
38
|
-
throw new UnbalancedEnvelope(
|
|
39
|
-
`an envelope with no tool name cannot be filed or reported against. Next: ${next}`
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
if (envelope.version.trim() === "") {
|
|
43
|
-
throw new UnbalancedEnvelope(
|
|
44
|
-
`${envelope.tool}: an envelope that cannot name the build that wrote it dates nothing, and a stale one reads exactly like a fresh one. Next: ${next}`
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
if (!isCount(envelope.considered) || !isCount(envelope.read)) {
|
|
48
|
-
throw new UnbalancedEnvelope(
|
|
49
|
-
`${envelope.tool}: considered ${envelope.considered} and read ${envelope.read} \u2014 a census is a whole number of things, and arithmetic over anything else balances by accident. Next: ${next}`
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
if (envelope.considered !== envelope.read + envelope.refused.length + envelope.excused.length) {
|
|
53
|
-
throw new UnbalancedEnvelope(unbalancedMessage(envelope, next));
|
|
54
|
-
}
|
|
55
|
-
const at = envelopePath(root, envelope.tool);
|
|
56
|
-
mkdirSync(dirname(at), { recursive: true });
|
|
57
|
-
writeFileSync(at, `${JSON.stringify(envelope, void 0, 2)}
|
|
58
|
-
`);
|
|
59
|
-
return at;
|
|
60
|
-
};
|
|
61
|
-
var UNKNOWN = "unknown";
|
|
62
|
-
var versionIn = (dir) => {
|
|
63
|
-
try {
|
|
64
|
-
const manifest = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
|
|
65
|
-
return typeof manifest.version === "string" ? manifest.version : void 0;
|
|
66
|
-
} catch {
|
|
67
|
-
return void 0;
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
var versionOf = (moduleUrl) => {
|
|
71
|
-
let dir = dirname(fileURLToPath(moduleUrl));
|
|
72
|
-
for (; ; ) {
|
|
73
|
-
const found = versionIn(dir);
|
|
74
|
-
if (found !== void 0) return found;
|
|
75
|
-
const up = dirname(dir);
|
|
76
|
-
if (up === dir) return UNKNOWN;
|
|
77
|
-
dir = up;
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
var MIGRATIONS_TOOL = "release-migrations";
|
|
81
|
-
var MIGRATIONS_NEXT = "geonosis-release migrations --since <ref> --json and compare `files` against `unreadable` \u2014 every added file leaves by exactly one door, and a file in one list and not the other is the accounting bug this refuses over";
|
|
82
|
-
var migrationsEnvelope = (report, durationMs) => ({
|
|
83
|
-
considered: report.files.length,
|
|
84
|
-
durationMs,
|
|
85
|
-
excused: report.files.filter((one) => one.state === "excused").map((one) => ({
|
|
86
|
-
path: one.path,
|
|
87
|
-
reason: "a contract-migration marker this gate could believe"
|
|
88
|
-
})),
|
|
89
|
-
findings: [...report.refusals, ...report.markers, ...report.squawk],
|
|
90
|
-
read: report.files.filter((one) => one.state !== "excused" && one.state !== "unreadable").length,
|
|
91
|
-
refused: report.unreadable.map((one) => ({ path: one.path, reason: one.why })),
|
|
92
|
-
tool: MIGRATIONS_TOOL,
|
|
93
|
-
version: versionOf(import.meta.url)
|
|
94
|
-
});
|
|
31
|
+
runPlan,
|
|
32
|
+
runPublished,
|
|
33
|
+
runSchema,
|
|
34
|
+
runSnapshot,
|
|
35
|
+
schemaEnvelope,
|
|
36
|
+
sweepEnvelope,
|
|
37
|
+
sweepSmoke,
|
|
38
|
+
writeEnvelope
|
|
39
|
+
} from "./chunk-MZWAN6WT.js";
|
|
95
40
|
|
|
96
41
|
// src/release-cli.ts
|
|
42
|
+
import { existsSync } from "fs";
|
|
43
|
+
import { join, resolve } from "path";
|
|
97
44
|
var USAGE = `geonosis-release <command> [options]
|
|
98
45
|
|
|
99
46
|
migrations --since <ref> [--dialect <name>] [--root <dir>] [--json]
|
|
@@ -110,6 +57,17 @@ var USAGE = `geonosis-release <command> [options]
|
|
|
110
57
|
|
|
111
58
|
Exit 0 clean, 1 refusals, 2 the run could not be made.
|
|
112
59
|
|
|
60
|
+
schema [--root <dir>] [--json]
|
|
61
|
+
|
|
62
|
+
The wall no oxlint rule can see. Over every migration under every directory
|
|
63
|
+
geonosis.json \u2192 release.schema.domains declares: a statement naming a table another
|
|
64
|
+
domain declared is a cross-domain dependency the import graph does not show, and a
|
|
65
|
+
current_setting('\u2026') outside release.schema.sessionVariables writes one consumer's
|
|
66
|
+
session vocabulary into a package everyone installs.
|
|
67
|
+
|
|
68
|
+
Options only, empty defaults; the block declared and empty is a refusal naming both.
|
|
69
|
+
Whole-directory, not diff-scoped \u2014 a domain's migrations are applied as a set.
|
|
70
|
+
|
|
113
71
|
plan [--root <dir>] [--i-accept-an-unproven-smoke] [--json]
|
|
114
72
|
|
|
115
73
|
The contract as data \u2014 geonosis.json \u2192 release.steps and release.proof \u2014 validated
|
|
@@ -133,13 +91,88 @@ var USAGE = `geonosis-release <command> [options]
|
|
|
133
91
|
tree declares in the wrangler configs geonosis.json names and release.secrets.
|
|
134
92
|
\`versions upload\` applies no triggers, and a secret can be put outside the gate
|
|
135
93
|
entirely \u2014 so declared and deployed drift apart silently, with a green pipeline.
|
|
94
|
+
|
|
95
|
+
published --group [--registry <url>] [--wait <seconds>] [--root <dir>] [--json]
|
|
96
|
+
|
|
97
|
+
Every workspace's local version against the version the registry answers, with no
|
|
98
|
+
sampling. \`changeset publish\` exiting zero is not the release; the GROUP resolving
|
|
99
|
+
from npm is \u2014 a six-package sample announced a version while the one unchecked entry
|
|
100
|
+
point read one release behind, and the consumer's bump aborted on it and left a
|
|
101
|
+
nested duplicate (#147).
|
|
102
|
+
|
|
103
|
+
The registry is asked over HTTP, never through npm or bun: their manifest CACHE is
|
|
104
|
+
the thing that lied. --wait polls through the few minutes in which a freshly
|
|
105
|
+
published name still 404s.
|
|
106
|
+
|
|
107
|
+
Exit 0 the whole group is there, 1 a gap, 2 the registry could not be asked.
|
|
108
|
+
|
|
109
|
+
adoption [--registry <url>] [--root <dir>] [--json]
|
|
110
|
+
|
|
111
|
+
How far every declared consumer is from the version this workspace holds, read off
|
|
112
|
+
the recordings the smoke keeps and never off a consumer's disk. Per consumer: MATCH,
|
|
113
|
+
BEHIND <name> <declared> \u2192 <current>, INCOHERENT (a group published as one number
|
|
114
|
+
declared at two), FLOOR UNDECLARED (informational \u2014 a floor is opted into).
|
|
115
|
+
|
|
116
|
+
--registry compares against what npm answers instead of against this workspace.
|
|
117
|
+
|
|
118
|
+
Exit 0 always: it is a report, and the release review carries one row per consumer
|
|
119
|
+
from it (D-061).
|
|
120
|
+
|
|
121
|
+
smoke snapshot <name> --from <their tree> [--replace] [--root <dir>] [--json]
|
|
122
|
+
[--typecheck <cmd>] [--lint <cmd>] [--doctor <cmd>]
|
|
123
|
+
|
|
124
|
+
Copy a consumer tree, read-only, into .geonosis/consumer-snapshots/<name>/ \u2014 the
|
|
125
|
+
thing a release must be read against. Installed packages, build output and the git
|
|
126
|
+
history stay behind; the manager comes off the lockfile; the versions every manifest
|
|
127
|
+
declares and the commands the smoke will run are recorded beside the copy.
|
|
128
|
+
|
|
129
|
+
The bytes are a private tree's (D-048), so it refuses to write where git would let
|
|
130
|
+
them be committed.
|
|
131
|
+
|
|
132
|
+
smoke baseline --snapshot <name> [--rc-dir <workspace>] [--install <cmd>] [--json]
|
|
133
|
+
smoke run [--snapshot <name>] [--absent <name>]... [--rc-dir <workspace>] [--install <cmd>]
|
|
134
|
+
[--json]
|
|
135
|
+
|
|
136
|
+
Pack every workspace package of the release candidate (\`pnpm pack\` \u2014 a tarball is
|
|
137
|
+
what a consumer installs, and a release that shipped no declarations shipped them in
|
|
138
|
+
the tree and not in the tarball), point a COPY of the snapshot's manifests at those
|
|
139
|
+
tarballs, install with the snapshot's own manager, and run the snapshot's own
|
|
140
|
+
typecheck, lint and doctor.
|
|
141
|
+
|
|
142
|
+
\`baseline\` records what those three answered at the versions the consumer is on.
|
|
143
|
+
\`run\` compares against it and refuses only what THIS release broke, in their
|
|
144
|
+
compiler's and their doctor's own lines. Exit 0 nothing new, 1 a new failure,
|
|
145
|
+
2 the run could not be made \u2014 including a phase the baseline cannot be compared to.
|
|
146
|
+
|
|
147
|
+
With no --snapshot it sweeps every consumer geonosis.json declares, one block each in
|
|
148
|
+
declaration order. A declared name with no recording whose tree is on this machine \u2014
|
|
149
|
+
named in .geonosis/consumer-trees.local.json, uncommitted \u2014 REFUSES with the snapshot
|
|
150
|
+
command to run; --absent <name> excuses one out loud and keeps it in the count. A
|
|
151
|
+
recording whose source tree has moved since it was taken prints STALE.
|
|
136
152
|
`;
|
|
137
|
-
var VALUED = /* @__PURE__ */ new Set([
|
|
138
|
-
|
|
153
|
+
var VALUED = /* @__PURE__ */ new Set([
|
|
154
|
+
"--absent",
|
|
155
|
+
"--dialect",
|
|
156
|
+
"--doctor",
|
|
157
|
+
"--from",
|
|
158
|
+
"--install",
|
|
159
|
+
"--lint",
|
|
160
|
+
"--rc-dir",
|
|
161
|
+
"--registry",
|
|
162
|
+
"--root",
|
|
163
|
+
"--runner",
|
|
164
|
+
"--since",
|
|
165
|
+
"--snapshot",
|
|
166
|
+
"--typecheck",
|
|
167
|
+
"--wait"
|
|
168
|
+
]);
|
|
169
|
+
var FLAGS = /* @__PURE__ */ new Set(["--check", "--group", "--i-accept-an-unproven-smoke", "--json", "--replace"]);
|
|
139
170
|
var DIALECTS = /* @__PURE__ */ new Set(["mikro-orm-ts", "postgres", "sqlite"]);
|
|
140
171
|
var parseArgs = (argv) => {
|
|
172
|
+
const many = {};
|
|
141
173
|
const read = {};
|
|
142
174
|
const flags = /* @__PURE__ */ new Set();
|
|
175
|
+
const rest = [];
|
|
143
176
|
let json = false;
|
|
144
177
|
for (let index = 1; index < argv.length; index += 1) {
|
|
145
178
|
const flag = argv[index] ?? "";
|
|
@@ -148,13 +181,18 @@ var parseArgs = (argv) => {
|
|
|
148
181
|
flags.add(flag);
|
|
149
182
|
continue;
|
|
150
183
|
}
|
|
184
|
+
if (!flag.startsWith("--")) {
|
|
185
|
+
rest.push(flag);
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
151
188
|
if (!VALUED.has(flag)) throw new CannotRun(`unknown argument "${flag}"`);
|
|
152
189
|
const value = argv[index + 1];
|
|
153
190
|
if (value === void 0 || value.startsWith("--")) throw new CannotRun(`${flag} needs a value`);
|
|
154
191
|
read[flag] = value;
|
|
192
|
+
many[flag] = [...many[flag] ?? [], value];
|
|
155
193
|
index += 1;
|
|
156
194
|
}
|
|
157
|
-
return { command: argv[0] ?? "", flags, json, read };
|
|
195
|
+
return { command: argv[0] ?? "", flags, json, many, read, rest };
|
|
158
196
|
};
|
|
159
197
|
var rootOf = (parsed, cwd) => resolve(cwd, parsed.read["--root"] ?? cwd);
|
|
160
198
|
var migrations = (parsed, cwd) => {
|
|
@@ -185,6 +223,24 @@ var migrations = (parsed, cwd) => {
|
|
|
185
223
|
if (report.unreadable.length > 0) return 2;
|
|
186
224
|
return report.ok ? 0 : 1;
|
|
187
225
|
};
|
|
226
|
+
var schema = (parsed, cwd) => {
|
|
227
|
+
const root = rootOf(parsed, cwd);
|
|
228
|
+
const startedAt = Date.now();
|
|
229
|
+
const report = runSchema({ root });
|
|
230
|
+
process.stdout.write(
|
|
231
|
+
parsed.json ? `${JSON.stringify(report, void 0, 2)}
|
|
232
|
+
` : formatSchema(report)
|
|
233
|
+
);
|
|
234
|
+
const at = writeEnvelope({
|
|
235
|
+
envelope: schemaEnvelope(report, Date.now() - startedAt),
|
|
236
|
+
next: SCHEMA_NEXT,
|
|
237
|
+
root
|
|
238
|
+
});
|
|
239
|
+
if (!parsed.json) process.stdout.write(`envelope: ${at}
|
|
240
|
+
`);
|
|
241
|
+
if (report.unreadable.length > 0) return 2;
|
|
242
|
+
return report.ok ? 0 : 1;
|
|
243
|
+
};
|
|
188
244
|
var plan = (parsed, cwd) => {
|
|
189
245
|
const report = runPlan({
|
|
190
246
|
accept: parsed.flags.has("--i-accept-an-unproven-smoke"),
|
|
@@ -223,6 +279,166 @@ var deployed = (parsed, cwd) => {
|
|
|
223
279
|
);
|
|
224
280
|
return report.ok ? 0 : 1;
|
|
225
281
|
};
|
|
282
|
+
var published = async (parsed, cwd) => {
|
|
283
|
+
if (!parsed.flags.has("--group")) {
|
|
284
|
+
throw new CannotRun("published needs --group \u2014 the whole workspace, or nothing");
|
|
285
|
+
}
|
|
286
|
+
const wait = parsed.read["--wait"];
|
|
287
|
+
if (wait !== void 0 && !/^\d+(?:\.\d+)?$/.test(wait)) {
|
|
288
|
+
throw new CannotRun(`--wait takes a number of seconds, not "${wait}"`);
|
|
289
|
+
}
|
|
290
|
+
const root = rootOf(parsed, cwd);
|
|
291
|
+
const startedAt = Date.now();
|
|
292
|
+
const report = await runPublished({
|
|
293
|
+
registry: parsed.read["--registry"] ?? DEFAULT_REGISTRY,
|
|
294
|
+
root,
|
|
295
|
+
waitSeconds: wait === void 0 ? 0 : Number(wait)
|
|
296
|
+
});
|
|
297
|
+
process.stdout.write(
|
|
298
|
+
parsed.json ? `${JSON.stringify(report, void 0, 2)}
|
|
299
|
+
` : formatPublished(report)
|
|
300
|
+
);
|
|
301
|
+
const at = writeEnvelope({
|
|
302
|
+
envelope: publishedEnvelope(report, Date.now() - startedAt),
|
|
303
|
+
next: PUBLISHED_NEXT,
|
|
304
|
+
root
|
|
305
|
+
});
|
|
306
|
+
if (!parsed.json) process.stdout.write(`envelope: ${at}
|
|
307
|
+
`);
|
|
308
|
+
if (report.unreachable > 0) return 2;
|
|
309
|
+
return report.ok ? 0 : 1;
|
|
310
|
+
};
|
|
311
|
+
var adoption = async (parsed, cwd) => {
|
|
312
|
+
const root = rootOf(parsed, cwd);
|
|
313
|
+
const startedAt = Date.now();
|
|
314
|
+
const registry = parsed.read["--registry"];
|
|
315
|
+
const report = await runAdoption({
|
|
316
|
+
declared: readReleaseConfig(root).smoke?.snapshots ?? [],
|
|
317
|
+
...registry === void 0 ? {} : { registry },
|
|
318
|
+
root
|
|
319
|
+
});
|
|
320
|
+
process.stdout.write(
|
|
321
|
+
parsed.json ? `${JSON.stringify(report, void 0, 2)}
|
|
322
|
+
` : formatAdoption(report)
|
|
323
|
+
);
|
|
324
|
+
const at = writeEnvelope({
|
|
325
|
+
envelope: adoptionEnvelope(report, Date.now() - startedAt),
|
|
326
|
+
next: ADOPTION_NEXT,
|
|
327
|
+
root
|
|
328
|
+
});
|
|
329
|
+
if (!parsed.json) process.stdout.write(`envelope: ${at}
|
|
330
|
+
`);
|
|
331
|
+
return 0;
|
|
332
|
+
};
|
|
333
|
+
var namedCommands = (parsed) => ({
|
|
334
|
+
...parsed.read["--doctor"] === void 0 ? {} : { doctor: parsed.read["--doctor"] },
|
|
335
|
+
...parsed.read["--lint"] === void 0 ? {} : { lint: parsed.read["--lint"] },
|
|
336
|
+
...parsed.read["--typecheck"] === void 0 ? {} : { typecheck: parsed.read["--typecheck"] }
|
|
337
|
+
});
|
|
338
|
+
var snapshot = (parsed, root) => {
|
|
339
|
+
const name = parsed.rest[1];
|
|
340
|
+
if (name === void 0) {
|
|
341
|
+
throw new CannotRun("smoke snapshot needs a name: smoke snapshot <name> --from <their tree>");
|
|
342
|
+
}
|
|
343
|
+
const from = parsed.read["--from"];
|
|
344
|
+
if (from === void 0) {
|
|
345
|
+
throw new CannotRun("smoke snapshot needs --from <the consumer tree to copy>");
|
|
346
|
+
}
|
|
347
|
+
const record = runSnapshot({
|
|
348
|
+
exclude: readReleaseConfig(root).smoke?.exclude ?? [],
|
|
349
|
+
from,
|
|
350
|
+
name,
|
|
351
|
+
named: namedCommands(parsed),
|
|
352
|
+
replace: parsed.flags.has("--replace"),
|
|
353
|
+
root
|
|
354
|
+
});
|
|
355
|
+
process.stdout.write(
|
|
356
|
+
parsed.json ? `${JSON.stringify(record, void 0, 2)}
|
|
357
|
+
` : formatSnapshot(record)
|
|
358
|
+
);
|
|
359
|
+
return 0;
|
|
360
|
+
};
|
|
361
|
+
var wantedSnapshots = (parsed, root) => {
|
|
362
|
+
const configured = readReleaseConfig(root).smoke?.snapshots ?? [];
|
|
363
|
+
const named = parsed.read["--snapshot"];
|
|
364
|
+
const install = parsed.read["--install"];
|
|
365
|
+
const withFlag = (one) => {
|
|
366
|
+
const chosen = install ?? one.install;
|
|
367
|
+
return {
|
|
368
|
+
...one.commands === void 0 ? {} : { commands: one.commands },
|
|
369
|
+
...chosen === void 0 ? {} : { install: chosen },
|
|
370
|
+
name: one.name
|
|
371
|
+
};
|
|
372
|
+
};
|
|
373
|
+
if (named === void 0) return configured.map(withFlag);
|
|
374
|
+
return [withFlag(configured.find((one) => one.name === named) ?? { name: named })];
|
|
375
|
+
};
|
|
376
|
+
var rcOf = (parsed, root, cwd) => {
|
|
377
|
+
const named = parsed.read["--rc-dir"];
|
|
378
|
+
if (named !== void 0) return resolve(cwd, named);
|
|
379
|
+
if (existsSync(join(root, "package.json"))) return root;
|
|
380
|
+
throw new CannotRun(
|
|
381
|
+
"nothing here is a release candidate \u2014 pass --rc-dir <the workspace whose packages this release publishes>, because a smoke with nothing packed compares a tree to itself"
|
|
382
|
+
);
|
|
383
|
+
};
|
|
384
|
+
var baseline = (parsed, root, cwd) => {
|
|
385
|
+
const wanted = wantedSnapshots(parsed, root);
|
|
386
|
+
const one = wanted[0];
|
|
387
|
+
if (parsed.read["--snapshot"] === void 0 || one === void 0) {
|
|
388
|
+
throw new CannotRun("smoke baseline needs --snapshot <name>");
|
|
389
|
+
}
|
|
390
|
+
const rc = parsed.read["--rc-dir"];
|
|
391
|
+
const recorded = recordBaseline({
|
|
392
|
+
...one.commands === void 0 ? {} : { commands: one.commands },
|
|
393
|
+
...one.install === void 0 ? {} : { install: one.install },
|
|
394
|
+
name: one.name,
|
|
395
|
+
...rc === void 0 ? {} : { rc: resolve(cwd, rc) },
|
|
396
|
+
root
|
|
397
|
+
});
|
|
398
|
+
process.stdout.write(
|
|
399
|
+
parsed.json ? `${JSON.stringify(recorded, void 0, 2)}
|
|
400
|
+
` : formatBaseline(one.name, recorded)
|
|
401
|
+
);
|
|
402
|
+
return 0;
|
|
403
|
+
};
|
|
404
|
+
var smokeRun = (parsed, root, cwd) => {
|
|
405
|
+
const startedAt = Date.now();
|
|
406
|
+
const wanted = wantedSnapshots(parsed, root);
|
|
407
|
+
if (wanted.length === 0) {
|
|
408
|
+
throw new CannotRun(
|
|
409
|
+
"nothing here names a consumer to read this release against \u2014 geonosis.json \u2192 release.smoke.snapshots names them, or pass --snapshot <name>. A release check over zero consumers is not a green release check."
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
const swept = sweepSmoke({
|
|
413
|
+
absent: parsed.many["--absent"] ?? [],
|
|
414
|
+
rc: rcOf(parsed, root, cwd),
|
|
415
|
+
root,
|
|
416
|
+
skipMissing: parsed.read["--snapshot"] === void 0,
|
|
417
|
+
wanted
|
|
418
|
+
});
|
|
419
|
+
process.stdout.write(
|
|
420
|
+
parsed.json ? `${JSON.stringify(swept, void 0, 2)}
|
|
421
|
+
` : formatSweep(swept)
|
|
422
|
+
);
|
|
423
|
+
const at = writeEnvelope({
|
|
424
|
+
envelope: sweepEnvelope(swept, Date.now() - startedAt),
|
|
425
|
+
next: SMOKE_NEXT,
|
|
426
|
+
root
|
|
427
|
+
});
|
|
428
|
+
if (!parsed.json) process.stdout.write(`envelope: ${at}
|
|
429
|
+
`);
|
|
430
|
+
const comparisons = comparisonsIn(swept);
|
|
431
|
+
if (comparisons.some((one) => one.refused.length > 0)) return 2;
|
|
432
|
+
return comparisons.every((one) => one.ok) ? 0 : 1;
|
|
433
|
+
};
|
|
434
|
+
var smoke = (parsed, cwd) => {
|
|
435
|
+
const root = rootOf(parsed, cwd);
|
|
436
|
+
const verb = parsed.rest[0];
|
|
437
|
+
if (verb === "snapshot") return snapshot(parsed, root);
|
|
438
|
+
if (verb === "baseline") return baseline(parsed, root, cwd);
|
|
439
|
+
if (verb === "run") return smokeRun(parsed, root, cwd);
|
|
440
|
+
throw new CannotRun(`smoke has snapshot, baseline and run \u2014 "${verb ?? ""}" is none of them`);
|
|
441
|
+
};
|
|
226
442
|
var CONFIG_SHAPE = `geonosis-release reads geonosis.json
|
|
227
443
|
|
|
228
444
|
geonosis.json \u2192 "release" every key optional; a repo that configured nothing gets nothing
|
|
@@ -232,6 +448,15 @@ geonosis.json \u2192 "release" every key optional; a repo that configured n
|
|
|
232
448
|
phases string[]? "up" and/or "down" (default ["up"])
|
|
233
449
|
squawk object? { exclude: string[] } \u2014 the rule ids to leave out
|
|
234
450
|
proof object? { mustAssertVersion: boolean }
|
|
451
|
+
schema object? the walls no oxlint rule can see (#168)
|
|
452
|
+
domains Entry[]? { dir, name, tables } \u2014 whose migrations, and whose tables
|
|
453
|
+
sessionVariables string[]? the session variable names DDL may name
|
|
454
|
+
smoke object? the consumer trees this release is read against
|
|
455
|
+
exclude string[]? what a snapshot leaves behind, beyond the built and the installed
|
|
456
|
+
snapshots Entry[]? { name, install?, commands? } \u2014 the recorded snapshot, the command
|
|
457
|
+
that tree is installed with when the manager's default is not it,
|
|
458
|
+
and { doctor?, lint?, typecheck? } when their gates are not the
|
|
459
|
+
scripts of those names
|
|
235
460
|
secrets string[]? the secret names a deployment carries
|
|
236
461
|
steps string[]? the release steps
|
|
237
462
|
workers string[]? the workers it deploys
|
|
@@ -239,7 +464,10 @@ geonosis.json \u2192 "release" every key optional; a repo that configured n
|
|
|
239
464
|
wranglerEnv string? the named environment block to read out of them
|
|
240
465
|
|
|
241
466
|
A key outside either list is refused BY NAME, with the accepted set. This shape had to be read out
|
|
242
|
-
of a bundled chunk file by a consumer once (#75)
|
|
467
|
+
of a bundled chunk file by a consumer once (#75).
|
|
468
|
+
|
|
469
|
+
published reads no geonosis.json at all: its inputs are every package.json under the root \u2014 "name"
|
|
470
|
+
and "version", and "private" to tell a package a publish is a claim about from one it is not.`;
|
|
243
471
|
var main = async () => {
|
|
244
472
|
const argv = process.argv.slice(2);
|
|
245
473
|
if (argv.includes("--print-config-shape")) {
|
|
@@ -252,12 +480,18 @@ var main = async () => {
|
|
|
252
480
|
return 0;
|
|
253
481
|
}
|
|
254
482
|
const parsed = parseArgs(argv);
|
|
483
|
+
if (parsed.command === "smoke") return smoke(parsed, process.cwd());
|
|
484
|
+
const stray = parsed.rest[0];
|
|
485
|
+
if (stray !== void 0) throw new CannotRun(`unknown argument "${stray}"`);
|
|
255
486
|
if (parsed.command === "migrations") return migrations(parsed, process.cwd());
|
|
256
487
|
if (parsed.command === "plan") return plan(parsed, process.cwd());
|
|
488
|
+
if (parsed.command === "schema") return schema(parsed, process.cwd());
|
|
257
489
|
if (parsed.command === "prove") return proving(parsed, process.cwd());
|
|
258
490
|
if (parsed.command === "deployed") return deployed(parsed, process.cwd());
|
|
491
|
+
if (parsed.command === "published") return published(parsed, process.cwd());
|
|
492
|
+
if (parsed.command === "adoption") return adoption(parsed, process.cwd());
|
|
259
493
|
throw new CannotRun(
|
|
260
|
-
`no command called "${parsed.command}" \u2014 this bin has migrations, plan, prove, deployed`
|
|
494
|
+
`no command called "${parsed.command}" \u2014 this bin has migrations, schema, plan, prove, deployed, published, adoption, smoke`
|
|
261
495
|
);
|
|
262
496
|
};
|
|
263
497
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geonosis/release",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"types": "./dist/index.d.ts",
|
|
5
5
|
"description": "The release contract with its proofs: an expand-only migration gate over three dialects, a smoke that must name the version that answered it, and declared ≠ deployed.",
|
|
6
6
|
"keywords": [
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"squawk-cli": "2.63.0",
|
|
48
|
-
"@geonosis/ratchet": "1.
|
|
48
|
+
"@geonosis/ratchet": "2.1.0"
|
|
49
49
|
},
|
|
50
50
|
"engines": {
|
|
51
51
|
"node": ">=22"
|