@geonosis/release 2.0.0 → 2.2.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-KQIWTXQP.js → chunk-IPCIF5DO.js} +1275 -926
- package/dist/index.d.ts +169 -64
- package/dist/index.js +17 -1
- package/dist/release-cli.js +73 -12
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,133 @@
|
|
|
1
1
|
import { ReportEnvelope } from '@geonosis/ratchet';
|
|
2
2
|
|
|
3
|
+
/** What a phase runs: a script of theirs, a binary their install put there, or nothing at all. */
|
|
4
|
+
type Command = {
|
|
5
|
+
exec: string;
|
|
6
|
+
} | {
|
|
7
|
+
run: string;
|
|
8
|
+
} | {
|
|
9
|
+
why: string;
|
|
10
|
+
};
|
|
11
|
+
type SmokePhase = 'doctor' | 'lint' | 'test' | 'typecheck';
|
|
12
|
+
/**
|
|
13
|
+
* The gates a release is read against, in the order they run.
|
|
14
|
+
*
|
|
15
|
+
* Its own module because the runner and the config reader both need it and each imports the other:
|
|
16
|
+
* read through `smoke.ts`, `PHASES` was still undefined when `config.ts` initialised, and the
|
|
17
|
+
* config refused every `geonosis.json` with `Cannot read properties of undefined`.
|
|
18
|
+
*
|
|
19
|
+
* #272: `test` is here because a floor change can keep a consumer's types and their linter green
|
|
20
|
+
* and still redden their suites — the one thing only their own tests can say. A recording taken
|
|
21
|
+
* before it existed has no baseline for the phase, and a phase with nothing to compare against is
|
|
22
|
+
* reported as uncomparable rather than as a pass.
|
|
23
|
+
*/
|
|
24
|
+
declare const PHASES: SmokePhase[];
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Where a consumer's bytes live while the release is being read against them.
|
|
28
|
+
*
|
|
29
|
+
* D-048: a consumer tree is private, and a copy of one that reaches a commit cannot be taken back.
|
|
30
|
+
* The directory is under `.geonosis/`, which every repo in this kit's orbit already ignores, and
|
|
31
|
+
* `smoke snapshot` asks git — in the tree it is about to write into — whether that is still true
|
|
32
|
+
* before it copies a single file.
|
|
33
|
+
*/
|
|
34
|
+
declare const SNAPSHOTS_DIR = ".geonosis/consumer-snapshots";
|
|
35
|
+
/** The managers a snapshot can be installed with here, each measured on this machine. */
|
|
36
|
+
type Manager = 'bun' | 'pnpm';
|
|
37
|
+
/**
|
|
38
|
+
* Directories a consumer builds or installs into. They are excluded by name at every depth: the
|
|
39
|
+
* snapshot is the SOURCE of a tree, and the install the smoke runs is the thing under test.
|
|
40
|
+
*/
|
|
41
|
+
declare const EXCLUDED_DIRS: string[];
|
|
42
|
+
/** Where the source tree stood, or the sentence saying why nothing here could say. */
|
|
43
|
+
type RecordedCommit = {
|
|
44
|
+
sha: string;
|
|
45
|
+
} | {
|
|
46
|
+
why: string;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* The seam a consumer declared, measured on the bytes this recording holds (#280).
|
|
50
|
+
*
|
|
51
|
+
* The user's rule for a floor: it is adopted the day it deletes more than it adds. The sweep can
|
|
52
|
+
* only say so about trees it has recorded, so the number is taken WHERE the tree is read — a
|
|
53
|
+
* `.geonosis/` of theirs never reaches a snapshot (it is an excluded directory), so their own bump
|
|
54
|
+
* report is not available here and this is the figure that is.
|
|
55
|
+
*/
|
|
56
|
+
type RecordedSeams = {
|
|
57
|
+
globs: string[];
|
|
58
|
+
lines: number;
|
|
59
|
+
};
|
|
60
|
+
type SnapshotRecord = {
|
|
61
|
+
at: string;
|
|
62
|
+
bytes: number;
|
|
63
|
+
/** Absent in a recording taken before this was recorded at all. */
|
|
64
|
+
commit?: RecordedCommit;
|
|
65
|
+
commands: Record<SmokePhase, Command>;
|
|
66
|
+
excluded: string[];
|
|
67
|
+
files: number;
|
|
68
|
+
from: string;
|
|
69
|
+
lockfile: string;
|
|
70
|
+
manager: Manager;
|
|
71
|
+
manifests: {
|
|
72
|
+
path: string;
|
|
73
|
+
versions: Record<string, string>;
|
|
74
|
+
}[];
|
|
75
|
+
name: string;
|
|
76
|
+
/** Absent when this consumer declares no `adoption.seams`, or the recording predates the block. */
|
|
77
|
+
seams?: RecordedSeams;
|
|
78
|
+
};
|
|
79
|
+
/** git asked in THEIR tree, and only ever asked: law 5 forbids this tool writing a byte there. */
|
|
80
|
+
declare const headOf: (from: string) => RecordedCommit;
|
|
81
|
+
declare const snapshotDir: (root: string, name: string) => string;
|
|
82
|
+
declare const readSnapshot: (root: string, name: string) => SnapshotRecord;
|
|
83
|
+
type SnapshotInput = {
|
|
84
|
+
exclude?: string[];
|
|
85
|
+
from: string;
|
|
86
|
+
name: string;
|
|
87
|
+
named: Partial<Record<SmokePhase, string>>;
|
|
88
|
+
replace: boolean;
|
|
89
|
+
root: string;
|
|
90
|
+
};
|
|
91
|
+
declare const runSnapshot: (input: SnapshotInput) => SnapshotRecord;
|
|
92
|
+
declare const formatSnapshot: (record: SnapshotRecord) => string;
|
|
93
|
+
|
|
94
|
+
type AdoptionVerdict = 'BEHIND' | 'FLOOR UNDECLARED' | 'INCOHERENT' | 'UNJUDGED';
|
|
95
|
+
type AdoptionFinding = {
|
|
96
|
+
consumer: string;
|
|
97
|
+
detail: string;
|
|
98
|
+
name: string;
|
|
99
|
+
verdict: AdoptionVerdict;
|
|
100
|
+
};
|
|
101
|
+
type AdoptionConsumer = {
|
|
102
|
+
/** How many specs naming a package of this workspace that consumer's manifests declare. */
|
|
103
|
+
declared: number;
|
|
104
|
+
findings: AdoptionFinding[];
|
|
105
|
+
name: string;
|
|
106
|
+
seams?: RecordedSeams;
|
|
107
|
+
};
|
|
108
|
+
type AdoptionReport = {
|
|
109
|
+
considered: number;
|
|
110
|
+
consumers: AdoptionConsumer[];
|
|
111
|
+
excused: {
|
|
112
|
+
path: string;
|
|
113
|
+
reason: string;
|
|
114
|
+
}[];
|
|
115
|
+
/** The registry the current numbers came from, or undefined when they came off this workspace. */
|
|
116
|
+
registry: string | undefined;
|
|
117
|
+
versions: Record<string, string>;
|
|
118
|
+
};
|
|
119
|
+
declare const runAdoption: ({ declared, registry, root, }: {
|
|
120
|
+
declared: {
|
|
121
|
+
name: string;
|
|
122
|
+
}[];
|
|
123
|
+
registry?: string;
|
|
124
|
+
root: string;
|
|
125
|
+
}) => Promise<AdoptionReport>;
|
|
126
|
+
declare const formatAdoption: (report: AdoptionReport) => string;
|
|
127
|
+
declare const ADOPTION_TOOL = "release-adoption";
|
|
128
|
+
declare const ADOPTION_NEXT = "geonosis-release adoption --json and read `consumers` \u2014 every declared consumer leaves by exactly one door, read or excused, and a release review carries one row per consumer from it (D-061)";
|
|
129
|
+
declare const adoptionEnvelope: (report: AdoptionReport, durationMs: number) => ReportEnvelope;
|
|
130
|
+
|
|
3
131
|
/** The dialects the gate can route to. A dialect is never sniffed: it is what the repo declared. */
|
|
4
132
|
type Dialect = 'mikro-orm-ts' | 'postgres' | 'sqlite';
|
|
5
133
|
type Phase = 'down' | 'up';
|
|
@@ -40,8 +168,12 @@ type SchemaReport = {
|
|
|
40
168
|
why: string;
|
|
41
169
|
}[];
|
|
42
170
|
};
|
|
43
|
-
/**
|
|
171
|
+
/**
|
|
172
|
+
* One consumer tree a release must be read against, how that one is installed, and the commands
|
|
173
|
+
* that are ITS gates when the three script names are not what that tree calls them.
|
|
174
|
+
*/
|
|
44
175
|
type SmokeSnapshotConfig = {
|
|
176
|
+
commands?: Partial<Record<'doctor' | 'lint' | 'typecheck', string>>;
|
|
45
177
|
install?: string;
|
|
46
178
|
name: string;
|
|
47
179
|
};
|
|
@@ -372,60 +504,6 @@ declare class Runner {
|
|
|
372
504
|
close(): void;
|
|
373
505
|
}
|
|
374
506
|
|
|
375
|
-
/**
|
|
376
|
-
* Where a consumer's bytes live while the release is being read against them.
|
|
377
|
-
*
|
|
378
|
-
* D-048: a consumer tree is private, and a copy of one that reaches a commit cannot be taken back.
|
|
379
|
-
* The directory is under `.geonosis/`, which every repo in this kit's orbit already ignores, and
|
|
380
|
-
* `smoke snapshot` asks git — in the tree it is about to write into — whether that is still true
|
|
381
|
-
* before it copies a single file.
|
|
382
|
-
*/
|
|
383
|
-
declare const SNAPSHOTS_DIR = ".geonosis/consumer-snapshots";
|
|
384
|
-
/** The managers a snapshot can be installed with here, each measured on this machine. */
|
|
385
|
-
type Manager = 'bun' | 'pnpm';
|
|
386
|
-
/**
|
|
387
|
-
* Directories a consumer builds or installs into. They are excluded by name at every depth: the
|
|
388
|
-
* snapshot is the SOURCE of a tree, and the install the smoke runs is the thing under test.
|
|
389
|
-
*/
|
|
390
|
-
declare const EXCLUDED_DIRS: string[];
|
|
391
|
-
/** What a phase runs: a script of theirs, a binary their install put there, or nothing at all. */
|
|
392
|
-
type Command = {
|
|
393
|
-
exec: string;
|
|
394
|
-
} | {
|
|
395
|
-
run: string;
|
|
396
|
-
} | {
|
|
397
|
-
why: string;
|
|
398
|
-
};
|
|
399
|
-
type SmokePhase = 'doctor' | 'lint' | 'typecheck';
|
|
400
|
-
declare const PHASES: SmokePhase[];
|
|
401
|
-
type SnapshotRecord = {
|
|
402
|
-
at: string;
|
|
403
|
-
bytes: number;
|
|
404
|
-
commands: Record<SmokePhase, Command>;
|
|
405
|
-
excluded: string[];
|
|
406
|
-
files: number;
|
|
407
|
-
from: string;
|
|
408
|
-
lockfile: string;
|
|
409
|
-
manager: Manager;
|
|
410
|
-
manifests: {
|
|
411
|
-
path: string;
|
|
412
|
-
versions: Record<string, string>;
|
|
413
|
-
}[];
|
|
414
|
-
name: string;
|
|
415
|
-
};
|
|
416
|
-
declare const snapshotDir: (root: string, name: string) => string;
|
|
417
|
-
declare const readSnapshot: (root: string, name: string) => SnapshotRecord;
|
|
418
|
-
type SnapshotInput = {
|
|
419
|
-
exclude?: string[];
|
|
420
|
-
from: string;
|
|
421
|
-
name: string;
|
|
422
|
-
named: Partial<Record<SmokePhase, string>>;
|
|
423
|
-
replace: boolean;
|
|
424
|
-
root: string;
|
|
425
|
-
};
|
|
426
|
-
declare const runSnapshot: (input: SnapshotInput) => SnapshotRecord;
|
|
427
|
-
declare const formatSnapshot: (record: SnapshotRecord) => string;
|
|
428
|
-
|
|
429
507
|
/** What a phase did, or the sentence saying there was nothing of theirs to do it with. */
|
|
430
508
|
type PhaseOutcome = {
|
|
431
509
|
code: number;
|
|
@@ -490,6 +568,7 @@ declare const rewriteManifests: (tree: string, manifests: string[], packed: Pack
|
|
|
490
568
|
path: string;
|
|
491
569
|
}[];
|
|
492
570
|
type RunInput = {
|
|
571
|
+
commands?: Partial<Record<SmokePhase, string>>;
|
|
493
572
|
install?: string;
|
|
494
573
|
name: string;
|
|
495
574
|
rc?: string;
|
|
@@ -499,16 +578,42 @@ declare const recordBaseline: (input: RunInput) => SmokeBaseline;
|
|
|
499
578
|
declare const readBaseline: (root: string, name: string) => SmokeBaseline;
|
|
500
579
|
declare const compareToBaseline: (name: string, baseline: SmokeBaseline, outcomes: PhaseOutcome[], findings: string[]) => SmokeComparison;
|
|
501
580
|
declare const runSmoke: (input: RunInput) => SmokeComparison;
|
|
502
|
-
|
|
581
|
+
/**
|
|
582
|
+
* What the sweep can say about WHEN a recording was taken: that its source has moved on, or that
|
|
583
|
+
* the question cannot be asked of it at all.
|
|
584
|
+
*/
|
|
585
|
+
type SweepNote = {
|
|
586
|
+
stale: string;
|
|
587
|
+
} | {
|
|
588
|
+
undated: string;
|
|
589
|
+
};
|
|
590
|
+
/** One declared consumer's turn in the sweep, in the order the repo declared it. */
|
|
591
|
+
type SweepEntry = {
|
|
592
|
+
comparison: SmokeComparison;
|
|
593
|
+
name: string;
|
|
594
|
+
note?: SweepNote;
|
|
595
|
+
} | {
|
|
503
596
|
name: string;
|
|
504
597
|
why: string;
|
|
505
598
|
};
|
|
506
599
|
type SmokeSweep = {
|
|
507
|
-
|
|
508
|
-
|
|
600
|
+
entries: SweepEntry[];
|
|
601
|
+
};
|
|
602
|
+
type WantedSnapshot = {
|
|
603
|
+
commands?: Partial<Record<SmokePhase, string>>;
|
|
604
|
+
install?: string;
|
|
605
|
+
name: string;
|
|
509
606
|
};
|
|
510
607
|
/**
|
|
511
|
-
*
|
|
608
|
+
* Where a consumer tree that has never been recorded lives on THIS machine.
|
|
609
|
+
*
|
|
610
|
+
* A never-recorded name has no `from` to look at, so the paths are declared here — uncommitted,
|
|
611
|
+
* under the directory D-048 already keeps out of git, because a machine's checkout layout is one
|
|
612
|
+
* developer's and not the repo's.
|
|
613
|
+
*/
|
|
614
|
+
declare const CONSUMER_TREES_FILE = ".geonosis/consumer-trees.local.json";
|
|
615
|
+
/**
|
|
616
|
+
* Every snapshot the release expects, read in turn, in the order the repo declared them.
|
|
512
617
|
*
|
|
513
618
|
* A tree that is not on this machine is SKIPPED with the sentence saying so — a laptop without the
|
|
514
619
|
* consumer trees must not fail, it must say what it could not ask. The skip is not free: its three
|
|
@@ -516,6 +621,8 @@ type SmokeSweep = {
|
|
|
516
621
|
* read as a sweep that asked everything.
|
|
517
622
|
*/
|
|
518
623
|
declare const sweepSmoke: (input: {
|
|
624
|
+
/** Declared names this run is excused from reading, each said out loud on the command line. */
|
|
625
|
+
absent?: string[];
|
|
519
626
|
rc?: string;
|
|
520
627
|
root: string;
|
|
521
628
|
/**
|
|
@@ -524,11 +631,9 @@ declare const sweepSmoke: (input: {
|
|
|
524
631
|
* has to be answered, not stepped around.
|
|
525
632
|
*/
|
|
526
633
|
skipMissing: boolean;
|
|
527
|
-
wanted:
|
|
528
|
-
install?: string;
|
|
529
|
-
name: string;
|
|
530
|
-
}[];
|
|
634
|
+
wanted: WantedSnapshot[];
|
|
531
635
|
}) => SmokeSweep;
|
|
636
|
+
declare const comparisonsIn: (sweep: SmokeSweep) => SmokeComparison[];
|
|
532
637
|
declare const formatSweep: (sweep: SmokeSweep) => string;
|
|
533
638
|
declare const sweepEnvelope: (sweep: SmokeSweep, durationMs: number) => ReportEnvelope;
|
|
534
639
|
declare const formatSmoke: (comparison: SmokeComparison) => string;
|
|
@@ -579,4 +684,4 @@ declare const statementsOf: (sql: string) => string;
|
|
|
579
684
|
/** One refusal per verb per file, at the line of that verb's first occurrence. */
|
|
580
685
|
declare const refusalsIn: (path: string, body: string, firstLine?: number) => Refusal[];
|
|
581
686
|
|
|
582
|
-
export { BASELINE_FILE, type Command, DEFAULT_REGISTRY, DEPLOYED_FILE, type Declared, type Deployed, type DeployedReport, type Dialect, type Drift, EXCLUDED_DIRS, EXISTS_BUT, type Manager, type MigrationDir, type MigrationsReport, NARROWING, NOTHING_SAYS, PHASES, PLANTS, type Packed, type Phase, type PhaseOutcome, type PlanReport, type ProveOutcome, type PublishedLine, type PublishedReport, type PublishedVerdict, type Refusal, type RegistryAnswer, type ReleaseConfig, Runner, SMOKE_NEXT, SMOKE_TOOL, SNAPSHOTS_DIR, STEPS, type SchemaConfig, type SchemaDomain, type SchemaFinding, type SchemaReport, type SmokeBaseline, type SmokeComparison, type SmokePhase, type
|
|
687
|
+
export { ADOPTION_NEXT, ADOPTION_TOOL, type AdoptionConsumer, type AdoptionFinding, type AdoptionReport, type AdoptionVerdict, BASELINE_FILE, CONSUMER_TREES_FILE, type Command, DEFAULT_REGISTRY, DEPLOYED_FILE, type Declared, type Deployed, type DeployedReport, type Dialect, type Drift, EXCLUDED_DIRS, EXISTS_BUT, type Manager, type MigrationDir, type MigrationsReport, NARROWING, NOTHING_SAYS, PHASES, PLANTS, type Packed, type Phase, type PhaseOutcome, type PlanReport, type ProveOutcome, type PublishedLine, type PublishedReport, type PublishedVerdict, type RecordedCommit, type RecordedSeams, type Refusal, type RegistryAnswer, type ReleaseConfig, Runner, SMOKE_NEXT, SMOKE_TOOL, SNAPSHOTS_DIR, STEPS, type SchemaConfig, type SchemaDomain, type SchemaFinding, type SchemaReport, type SmokeBaseline, type SmokeComparison, type SmokePhase, type SmokeSweep, type SnapshotRecord, type SweepEntry, type SweepNote, type Verdict, WHY_VERSION_IDENTITY, type WantedSnapshot, addSqlIn, adoptionEnvelope, askRegistry, censusOf, compareToBaseline, comparisonsIn, declaredIn, driftBetween, formatAdoption, formatBaseline, formatDeployed, formatMigrations, formatPlan, formatProve, formatPublished, formatSchema, formatSmoke, formatSnapshot, formatSweep, formatVerdict, headOf, markersIn, packRc, parseJsonc, parseReleaseConfig, parseToml, promisedButNotPacked, prove, proveOver, readBaseline, readDeployed, readReleaseConfig, readSnapshot, readWrangler, recordBaseline, refusalsIn, registryPathOf, rewriteManifests, runAdoption, runDeployed, runMigrations, runPlan, runPublished, runSchema, runSmoke, runSnapshot, smokeEnvelope, snapshotDir, statementsOf, sweepEnvelope, sweepSmoke };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ADOPTION_NEXT,
|
|
3
|
+
ADOPTION_TOOL,
|
|
2
4
|
BASELINE_FILE,
|
|
5
|
+
CONSUMER_TREES_FILE,
|
|
3
6
|
DEFAULT_REGISTRY,
|
|
4
7
|
DEPLOYED_FILE,
|
|
5
8
|
EXCLUDED_DIRS,
|
|
@@ -15,11 +18,14 @@ import {
|
|
|
15
18
|
STEPS,
|
|
16
19
|
WHY_VERSION_IDENTITY,
|
|
17
20
|
addSqlIn,
|
|
21
|
+
adoptionEnvelope,
|
|
18
22
|
askRegistry,
|
|
19
23
|
censusOf,
|
|
20
24
|
compareToBaseline,
|
|
25
|
+
comparisonsIn,
|
|
21
26
|
declaredIn,
|
|
22
27
|
driftBetween,
|
|
28
|
+
formatAdoption,
|
|
23
29
|
formatBaseline,
|
|
24
30
|
formatDeployed,
|
|
25
31
|
formatMigrations,
|
|
@@ -31,6 +37,7 @@ import {
|
|
|
31
37
|
formatSnapshot,
|
|
32
38
|
formatSweep,
|
|
33
39
|
formatVerdict,
|
|
40
|
+
headOf,
|
|
34
41
|
markersIn,
|
|
35
42
|
packRc,
|
|
36
43
|
parseJsonc,
|
|
@@ -48,6 +55,7 @@ import {
|
|
|
48
55
|
refusalsIn,
|
|
49
56
|
registryPathOf,
|
|
50
57
|
rewriteManifests,
|
|
58
|
+
runAdoption,
|
|
51
59
|
runDeployed,
|
|
52
60
|
runMigrations,
|
|
53
61
|
runPlan,
|
|
@@ -60,9 +68,12 @@ import {
|
|
|
60
68
|
statementsOf,
|
|
61
69
|
sweepEnvelope,
|
|
62
70
|
sweepSmoke
|
|
63
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-IPCIF5DO.js";
|
|
64
72
|
export {
|
|
73
|
+
ADOPTION_NEXT,
|
|
74
|
+
ADOPTION_TOOL,
|
|
65
75
|
BASELINE_FILE,
|
|
76
|
+
CONSUMER_TREES_FILE,
|
|
66
77
|
DEFAULT_REGISTRY,
|
|
67
78
|
DEPLOYED_FILE,
|
|
68
79
|
EXCLUDED_DIRS,
|
|
@@ -78,11 +89,14 @@ export {
|
|
|
78
89
|
STEPS,
|
|
79
90
|
WHY_VERSION_IDENTITY,
|
|
80
91
|
addSqlIn,
|
|
92
|
+
adoptionEnvelope,
|
|
81
93
|
askRegistry,
|
|
82
94
|
censusOf,
|
|
83
95
|
compareToBaseline,
|
|
96
|
+
comparisonsIn,
|
|
84
97
|
declaredIn,
|
|
85
98
|
driftBetween,
|
|
99
|
+
formatAdoption,
|
|
86
100
|
formatBaseline,
|
|
87
101
|
formatDeployed,
|
|
88
102
|
formatMigrations,
|
|
@@ -94,6 +108,7 @@ export {
|
|
|
94
108
|
formatSnapshot,
|
|
95
109
|
formatSweep,
|
|
96
110
|
formatVerdict,
|
|
111
|
+
headOf,
|
|
97
112
|
markersIn,
|
|
98
113
|
packRc,
|
|
99
114
|
parseJsonc,
|
|
@@ -111,6 +126,7 @@ export {
|
|
|
111
126
|
refusalsIn,
|
|
112
127
|
registryPathOf,
|
|
113
128
|
rewriteManifests,
|
|
129
|
+
runAdoption,
|
|
114
130
|
runDeployed,
|
|
115
131
|
runMigrations,
|
|
116
132
|
runPlan,
|
package/dist/release-cli.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ADOPTION_NEXT,
|
|
2
3
|
CannotRun,
|
|
3
4
|
DEFAULT_REGISTRY,
|
|
4
5
|
MIGRATIONS_NEXT,
|
|
5
6
|
PUBLISHED_NEXT,
|
|
6
7
|
SCHEMA_NEXT,
|
|
7
8
|
SMOKE_NEXT,
|
|
9
|
+
adoptionEnvelope,
|
|
10
|
+
comparisonsIn,
|
|
11
|
+
formatAdoption,
|
|
8
12
|
formatBaseline,
|
|
9
13
|
formatDeployed,
|
|
10
14
|
formatMigrations,
|
|
@@ -21,6 +25,7 @@ import {
|
|
|
21
25
|
publishedEnvelope,
|
|
22
26
|
readReleaseConfig,
|
|
23
27
|
recordBaseline,
|
|
28
|
+
runAdoption,
|
|
24
29
|
runDeployed,
|
|
25
30
|
runMigrations,
|
|
26
31
|
runPlan,
|
|
@@ -31,7 +36,7 @@ import {
|
|
|
31
36
|
sweepEnvelope,
|
|
32
37
|
sweepSmoke,
|
|
33
38
|
writeEnvelope
|
|
34
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-IPCIF5DO.js";
|
|
35
40
|
|
|
36
41
|
// src/release-cli.ts
|
|
37
42
|
import { existsSync } from "fs";
|
|
@@ -101,8 +106,20 @@ var USAGE = `geonosis-release <command> [options]
|
|
|
101
106
|
|
|
102
107
|
Exit 0 the whole group is there, 1 a gap, 2 the registry could not be asked.
|
|
103
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
|
+
|
|
104
121
|
smoke snapshot <name> --from <their tree> [--replace] [--root <dir>] [--json]
|
|
105
|
-
[--typecheck <cmd>] [--lint <cmd>] [--doctor <cmd>]
|
|
122
|
+
[--typecheck <cmd>] [--lint <cmd>] [--test <cmd>] [--doctor <cmd>]
|
|
106
123
|
|
|
107
124
|
Copy a consumer tree, read-only, into .geonosis/consumer-snapshots/<name>/ \u2014 the
|
|
108
125
|
thing a release must be read against. Installed packages, build output and the git
|
|
@@ -113,20 +130,28 @@ var USAGE = `geonosis-release <command> [options]
|
|
|
113
130
|
them be committed.
|
|
114
131
|
|
|
115
132
|
smoke baseline --snapshot <name> [--rc-dir <workspace>] [--install <cmd>] [--json]
|
|
116
|
-
smoke run --snapshot <name> [--rc-dir <workspace>] [--install <cmd>]
|
|
133
|
+
smoke run [--snapshot <name>] [--absent <name>]... [--rc-dir <workspace>] [--install <cmd>]
|
|
134
|
+
[--json]
|
|
117
135
|
|
|
118
136
|
Pack every workspace package of the release candidate (\`pnpm pack\` \u2014 a tarball is
|
|
119
137
|
what a consumer installs, and a release that shipped no declarations shipped them in
|
|
120
138
|
the tree and not in the tarball), point a COPY of the snapshot's manifests at those
|
|
121
139
|
tarballs, install with the snapshot's own manager, and run the snapshot's own
|
|
122
|
-
typecheck, lint and doctor.
|
|
140
|
+
typecheck, lint, tests and doctor.
|
|
123
141
|
|
|
124
|
-
\`baseline\` records what those
|
|
142
|
+
\`baseline\` records what those four answered at the versions the consumer is on.
|
|
125
143
|
\`run\` compares against it and refuses only what THIS release broke, in their
|
|
126
144
|
compiler's and their doctor's own lines. Exit 0 nothing new, 1 a new failure,
|
|
127
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.
|
|
128
152
|
`;
|
|
129
153
|
var VALUED = /* @__PURE__ */ new Set([
|
|
154
|
+
"--absent",
|
|
130
155
|
"--dialect",
|
|
131
156
|
"--doctor",
|
|
132
157
|
"--from",
|
|
@@ -138,12 +163,14 @@ var VALUED = /* @__PURE__ */ new Set([
|
|
|
138
163
|
"--runner",
|
|
139
164
|
"--since",
|
|
140
165
|
"--snapshot",
|
|
166
|
+
"--test",
|
|
141
167
|
"--typecheck",
|
|
142
168
|
"--wait"
|
|
143
169
|
]);
|
|
144
170
|
var FLAGS = /* @__PURE__ */ new Set(["--check", "--group", "--i-accept-an-unproven-smoke", "--json", "--replace"]);
|
|
145
171
|
var DIALECTS = /* @__PURE__ */ new Set(["mikro-orm-ts", "postgres", "sqlite"]);
|
|
146
172
|
var parseArgs = (argv) => {
|
|
173
|
+
const many = {};
|
|
147
174
|
const read = {};
|
|
148
175
|
const flags = /* @__PURE__ */ new Set();
|
|
149
176
|
const rest = [];
|
|
@@ -163,9 +190,10 @@ var parseArgs = (argv) => {
|
|
|
163
190
|
const value = argv[index + 1];
|
|
164
191
|
if (value === void 0 || value.startsWith("--")) throw new CannotRun(`${flag} needs a value`);
|
|
165
192
|
read[flag] = value;
|
|
193
|
+
many[flag] = [...many[flag] ?? [], value];
|
|
166
194
|
index += 1;
|
|
167
195
|
}
|
|
168
|
-
return { command: argv[0] ?? "", flags, json, read, rest };
|
|
196
|
+
return { command: argv[0] ?? "", flags, json, many, read, rest };
|
|
169
197
|
};
|
|
170
198
|
var rootOf = (parsed, cwd) => resolve(cwd, parsed.read["--root"] ?? cwd);
|
|
171
199
|
var migrations = (parsed, cwd) => {
|
|
@@ -281,9 +309,32 @@ var published = async (parsed, cwd) => {
|
|
|
281
309
|
if (report.unreachable > 0) return 2;
|
|
282
310
|
return report.ok ? 0 : 1;
|
|
283
311
|
};
|
|
312
|
+
var adoption = async (parsed, cwd) => {
|
|
313
|
+
const root = rootOf(parsed, cwd);
|
|
314
|
+
const startedAt = Date.now();
|
|
315
|
+
const registry = parsed.read["--registry"];
|
|
316
|
+
const report = await runAdoption({
|
|
317
|
+
declared: readReleaseConfig(root).smoke?.snapshots ?? [],
|
|
318
|
+
...registry === void 0 ? {} : { registry },
|
|
319
|
+
root
|
|
320
|
+
});
|
|
321
|
+
process.stdout.write(
|
|
322
|
+
parsed.json ? `${JSON.stringify(report, void 0, 2)}
|
|
323
|
+
` : formatAdoption(report)
|
|
324
|
+
);
|
|
325
|
+
const at = writeEnvelope({
|
|
326
|
+
envelope: adoptionEnvelope(report, Date.now() - startedAt),
|
|
327
|
+
next: ADOPTION_NEXT,
|
|
328
|
+
root
|
|
329
|
+
});
|
|
330
|
+
if (!parsed.json) process.stdout.write(`envelope: ${at}
|
|
331
|
+
`);
|
|
332
|
+
return 0;
|
|
333
|
+
};
|
|
284
334
|
var namedCommands = (parsed) => ({
|
|
285
335
|
...parsed.read["--doctor"] === void 0 ? {} : { doctor: parsed.read["--doctor"] },
|
|
286
336
|
...parsed.read["--lint"] === void 0 ? {} : { lint: parsed.read["--lint"] },
|
|
337
|
+
...parsed.read["--test"] === void 0 ? {} : { test: parsed.read["--test"] },
|
|
287
338
|
...parsed.read["--typecheck"] === void 0 ? {} : { typecheck: parsed.read["--typecheck"] }
|
|
288
339
|
});
|
|
289
340
|
var snapshot = (parsed, root) => {
|
|
@@ -315,7 +366,11 @@ var wantedSnapshots = (parsed, root) => {
|
|
|
315
366
|
const install = parsed.read["--install"];
|
|
316
367
|
const withFlag = (one) => {
|
|
317
368
|
const chosen = install ?? one.install;
|
|
318
|
-
return {
|
|
369
|
+
return {
|
|
370
|
+
...one.commands === void 0 ? {} : { commands: one.commands },
|
|
371
|
+
...chosen === void 0 ? {} : { install: chosen },
|
|
372
|
+
name: one.name
|
|
373
|
+
};
|
|
319
374
|
};
|
|
320
375
|
if (named === void 0) return configured.map(withFlag);
|
|
321
376
|
return [withFlag(configured.find((one) => one.name === named) ?? { name: named })];
|
|
@@ -336,6 +391,7 @@ var baseline = (parsed, root, cwd) => {
|
|
|
336
391
|
}
|
|
337
392
|
const rc = parsed.read["--rc-dir"];
|
|
338
393
|
const recorded = recordBaseline({
|
|
394
|
+
...one.commands === void 0 ? {} : { commands: one.commands },
|
|
339
395
|
...one.install === void 0 ? {} : { install: one.install },
|
|
340
396
|
name: one.name,
|
|
341
397
|
...rc === void 0 ? {} : { rc: resolve(cwd, rc) },
|
|
@@ -356,6 +412,7 @@ var smokeRun = (parsed, root, cwd) => {
|
|
|
356
412
|
);
|
|
357
413
|
}
|
|
358
414
|
const swept = sweepSmoke({
|
|
415
|
+
absent: parsed.many["--absent"] ?? [],
|
|
359
416
|
rc: rcOf(parsed, root, cwd),
|
|
360
417
|
root,
|
|
361
418
|
skipMissing: parsed.read["--snapshot"] === void 0,
|
|
@@ -372,8 +429,9 @@ var smokeRun = (parsed, root, cwd) => {
|
|
|
372
429
|
});
|
|
373
430
|
if (!parsed.json) process.stdout.write(`envelope: ${at}
|
|
374
431
|
`);
|
|
375
|
-
|
|
376
|
-
|
|
432
|
+
const comparisons = comparisonsIn(swept);
|
|
433
|
+
if (comparisons.some((one) => one.refused.length > 0)) return 2;
|
|
434
|
+
return comparisons.every((one) => one.ok) ? 0 : 1;
|
|
377
435
|
};
|
|
378
436
|
var smoke = (parsed, cwd) => {
|
|
379
437
|
const root = rootOf(parsed, cwd);
|
|
@@ -397,8 +455,10 @@ geonosis.json \u2192 "release" every key optional; a repo that configured n
|
|
|
397
455
|
sessionVariables string[]? the session variable names DDL may name
|
|
398
456
|
smoke object? the consumer trees this release is read against
|
|
399
457
|
exclude string[]? what a snapshot leaves behind, beyond the built and the installed
|
|
400
|
-
snapshots Entry[]? { name, install? } \u2014 the recorded snapshot,
|
|
401
|
-
tree is installed with when the manager's default is not it
|
|
458
|
+
snapshots Entry[]? { name, install?, commands? } \u2014 the recorded snapshot, the command
|
|
459
|
+
that tree is installed with when the manager's default is not it,
|
|
460
|
+
and { doctor?, lint?, typecheck? } when their gates are not the
|
|
461
|
+
scripts of those names
|
|
402
462
|
secrets string[]? the secret names a deployment carries
|
|
403
463
|
steps string[]? the release steps
|
|
404
464
|
workers string[]? the workers it deploys
|
|
@@ -431,8 +491,9 @@ var main = async () => {
|
|
|
431
491
|
if (parsed.command === "prove") return proving(parsed, process.cwd());
|
|
432
492
|
if (parsed.command === "deployed") return deployed(parsed, process.cwd());
|
|
433
493
|
if (parsed.command === "published") return published(parsed, process.cwd());
|
|
494
|
+
if (parsed.command === "adoption") return adoption(parsed, process.cwd());
|
|
434
495
|
throw new CannotRun(
|
|
435
|
-
`no command called "${parsed.command}" \u2014 this bin has migrations, plan, prove, deployed, published`
|
|
496
|
+
`no command called "${parsed.command}" \u2014 this bin has migrations, schema, plan, prove, deployed, published, adoption, smoke`
|
|
436
497
|
);
|
|
437
498
|
};
|
|
438
499
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geonosis/release",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.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": "2.
|
|
48
|
+
"@geonosis/ratchet": "2.2.0"
|
|
49
49
|
},
|
|
50
50
|
"engines": {
|
|
51
51
|
"node": ">=22"
|