@memberjunction/cli 5.37.0 → 5.39.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 +74 -0
- package/dist/baseline/cli-helpers.d.ts +12 -0
- package/dist/baseline/cli-helpers.d.ts.map +1 -0
- package/dist/baseline/cli-helpers.js +40 -0
- package/dist/baseline/cli-helpers.js.map +1 -0
- package/dist/baseline/comparator.d.ts +26 -0
- package/dist/baseline/comparator.d.ts.map +1 -0
- package/dist/baseline/comparator.js +527 -0
- package/dist/baseline/comparator.js.map +1 -0
- package/dist/baseline/connection.d.ts +39 -0
- package/dist/baseline/connection.d.ts.map +1 -0
- package/dist/baseline/connection.js +104 -0
- package/dist/baseline/connection.js.map +1 -0
- package/dist/baseline/data-dumper.d.ts +23 -0
- package/dist/baseline/data-dumper.d.ts.map +1 -0
- package/dist/baseline/data-dumper.js +94 -0
- package/dist/baseline/data-dumper.js.map +1 -0
- package/dist/baseline/emitter.d.ts +36 -0
- package/dist/baseline/emitter.d.ts.map +1 -0
- package/dist/baseline/emitter.js +519 -0
- package/dist/baseline/emitter.js.map +1 -0
- package/dist/baseline/index.d.ts +18 -0
- package/dist/baseline/index.d.ts.map +1 -0
- package/dist/baseline/index.js +14 -0
- package/dist/baseline/index.js.map +1 -0
- package/dist/baseline/introspector-mssql.d.ts +15 -0
- package/dist/baseline/introspector-mssql.d.ts.map +1 -0
- package/dist/baseline/introspector-mssql.js +673 -0
- package/dist/baseline/introspector-mssql.js.map +1 -0
- package/dist/baseline/introspector-postgres.d.ts +14 -0
- package/dist/baseline/introspector-postgres.d.ts.map +1 -0
- package/dist/baseline/introspector-postgres.js +277 -0
- package/dist/baseline/introspector-postgres.js.map +1 -0
- package/dist/baseline/report.d.ts +7 -0
- package/dist/baseline/report.d.ts.map +1 -0
- package/dist/baseline/report.js +105 -0
- package/dist/baseline/report.js.map +1 -0
- package/dist/baseline/types.d.ts +286 -0
- package/dist/baseline/types.d.ts.map +1 -0
- package/dist/baseline/types.js +10 -0
- package/dist/baseline/types.js.map +1 -0
- package/dist/baseline/util.d.ts +112 -0
- package/dist/baseline/util.d.ts.map +1 -0
- package/dist/baseline/util.js +325 -0
- package/dist/baseline/util.js.map +1 -0
- package/dist/commands/baseline/build.d.ts +29 -0
- package/dist/commands/baseline/build.d.ts.map +1 -0
- package/dist/commands/baseline/build.js +188 -0
- package/dist/commands/baseline/build.js.map +1 -0
- package/dist/commands/baseline/compare.d.ts +19 -0
- package/dist/commands/baseline/compare.d.ts.map +1 -0
- package/dist/commands/baseline/compare.js +133 -0
- package/dist/commands/baseline/compare.js.map +1 -0
- package/dist/commands/baseline/roundtrip.d.ts +23 -0
- package/dist/commands/baseline/roundtrip.d.ts.map +1 -0
- package/dist/commands/baseline/roundtrip.js +245 -0
- package/dist/commands/baseline/roundtrip.js.map +1 -0
- package/dist/commands/bundle/index.d.ts +21 -0
- package/dist/commands/bundle/index.d.ts.map +1 -0
- package/dist/commands/bundle/index.js +62 -0
- package/dist/commands/bundle/index.js.map +1 -0
- package/dist/commands/migrate/index.d.ts +29 -0
- package/dist/commands/migrate/index.d.ts.map +1 -1
- package/dist/commands/migrate/index.js +111 -5
- package/dist/commands/migrate/index.js.map +1 -1
- package/dist/commands/test/compare.d.ts +3 -0
- package/dist/commands/test/compare.d.ts.map +1 -1
- package/dist/commands/test/compare.js +23 -3
- package/dist/commands/test/compare.js.map +1 -1
- package/dist/commands/test/regression/build.d.ts +14 -0
- package/dist/commands/test/regression/build.d.ts.map +1 -0
- package/dist/commands/test/regression/build.js +48 -0
- package/dist/commands/test/regression/build.js.map +1 -0
- package/dist/commands/test/regression/compare.d.ts +15 -0
- package/dist/commands/test/regression/compare.d.ts.map +1 -0
- package/dist/commands/test/regression/compare.js +66 -0
- package/dist/commands/test/regression/compare.js.map +1 -0
- package/dist/commands/test/regression/down.d.ts +10 -0
- package/dist/commands/test/regression/down.d.ts.map +1 -0
- package/dist/commands/test/regression/down.js +29 -0
- package/dist/commands/test/regression/down.js.map +1 -0
- package/dist/commands/test/regression/export.d.ts +11 -0
- package/dist/commands/test/regression/export.d.ts.map +1 -0
- package/dist/commands/test/regression/export.js +56 -0
- package/dist/commands/test/regression/export.js.map +1 -0
- package/dist/commands/test/regression/gen-forms.d.ts +7 -0
- package/dist/commands/test/regression/gen-forms.d.ts.map +1 -0
- package/dist/commands/test/regression/gen-forms.js +18 -0
- package/dist/commands/test/regression/gen-forms.js.map +1 -0
- package/dist/commands/test/regression/index.d.ts +7 -0
- package/dist/commands/test/regression/index.d.ts.map +1 -0
- package/dist/commands/test/regression/index.js +33 -0
- package/dist/commands/test/regression/index.js.map +1 -0
- package/dist/commands/test/regression/init.d.ts +21 -0
- package/dist/commands/test/regression/init.d.ts.map +1 -0
- package/dist/commands/test/regression/init.js +111 -0
- package/dist/commands/test/regression/init.js.map +1 -0
- package/dist/commands/test/regression/remote.d.ts +23 -0
- package/dist/commands/test/regression/remote.d.ts.map +1 -0
- package/dist/commands/test/regression/remote.js +140 -0
- package/dist/commands/test/regression/remote.js.map +1 -0
- package/dist/commands/test/regression/up.d.ts +21 -0
- package/dist/commands/test/regression/up.d.ts.map +1 -0
- package/dist/commands/test/regression/up.js +111 -0
- package/dist/commands/test/regression/up.js.map +1 -0
- package/dist/commands/test/run.d.ts +1 -0
- package/dist/commands/test/run.d.ts.map +1 -1
- package/dist/commands/test/run.js +6 -0
- package/dist/commands/test/run.js.map +1 -1
- package/dist/commands/test/suite.d.ts +5 -0
- package/dist/commands/test/suite.d.ts.map +1 -1
- package/dist/commands/test/suite.js +27 -0
- package/dist/commands/test/suite.js.map +1 -1
- package/dist/commands/translate-sql/index.d.ts.map +1 -1
- package/dist/commands/translate-sql/index.js +3 -2
- package/dist/commands/translate-sql/index.js.map +1 -1
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +13 -0
- package/dist/config.js.map +1 -1
- package/dist/init-templates/bring-your-own-app/README.md +74 -0
- package/dist/init-templates/bring-your-own-app/byo-metadata/.mj-sync.json +10 -0
- package/dist/init-templates/bring-your-own-app/byo-metadata/test-suites/.byo-suite.json +51 -0
- package/dist/init-templates/bring-your-own-app/byo-metadata/test-suites/.mj-sync.json +12 -0
- package/dist/init-templates/bring-your-own-app/byo-metadata/tests/.T01-counter-increment.json +63 -0
- package/dist/init-templates/bring-your-own-app/byo-metadata/tests/.T02-contact-form-submit.json +63 -0
- package/dist/init-templates/bring-your-own-app/byo-metadata/tests/.mj-sync.json +12 -0
- package/dist/init-templates/bring-your-own-app/docker-compose.app.yml +76 -0
- package/dist/init-templates/bring-your-own-app/target.json +23 -0
- package/dist/init-templates/generic-web/README.md +115 -0
- package/dist/init-templates/generic-web/metadata/.mj-sync.json +10 -0
- package/dist/init-templates/generic-web/metadata/test-suites/.generic-web-suite.json +48 -0
- package/dist/init-templates/generic-web/metadata/test-suites/.mj-sync.json +12 -0
- package/dist/init-templates/generic-web/metadata/tests/.GW01-home-loads.json +74 -0
- package/dist/init-templates/generic-web/metadata/tests/.GW02-search-array-map.json +82 -0
- package/dist/init-templates/generic-web/metadata/tests/.mj-sync.json +12 -0
- package/dist/init-templates/generic-web/oracles/mdn-oracles.cjs +121 -0
- package/dist/init-templates/generic-web/target.json +25 -0
- package/dist/init-templates/github-actions/README.md +26 -0
- package/dist/init-templates/github-actions/regression.yml +52 -0
- package/dist/init-templates/remote-mj/README.md +95 -0
- package/dist/init-templates/remote-mj/target.json +22 -0
- package/dist/init-templates/static-file-server/Dockerfile +23 -0
- package/dist/init-templates/static-file-server/README.md +88 -0
- package/dist/init-templates/static-file-server/docker-compose.app.yml +44 -0
- package/dist/init-templates/static-file-server/metadata/.mj-sync.json +10 -0
- package/dist/init-templates/static-file-server/metadata/test-suites/.mj-sync.json +12 -0
- package/dist/init-templates/static-file-server/metadata/test-suites/.static-server-suite.json +27 -0
- package/dist/init-templates/static-file-server/metadata/tests/.SS01-home-loads.json +45 -0
- package/dist/init-templates/static-file-server/metadata/tests/.SS02-navigate-about.json +45 -0
- package/dist/init-templates/static-file-server/metadata/tests/.mj-sync.json +12 -0
- package/dist/init-templates/static-file-server/public/about.html +12 -0
- package/dist/init-templates/static-file-server/public/index.html +27 -0
- package/dist/init-templates/static-file-server/target.json +16 -0
- package/dist/lib/db-preflight.d.ts +42 -0
- package/dist/lib/db-preflight.d.ts.map +1 -0
- package/dist/lib/db-preflight.js +113 -0
- package/dist/lib/db-preflight.js.map +1 -0
- package/dist/lib/db-version.d.ts +36 -0
- package/dist/lib/db-version.d.ts.map +1 -0
- package/dist/lib/db-version.js +45 -0
- package/dist/lib/db-version.js.map +1 -0
- package/dist/lib/migration-fetch.d.ts +49 -0
- package/dist/lib/migration-fetch.d.ts.map +1 -0
- package/dist/lib/migration-fetch.js +152 -0
- package/dist/lib/migration-fetch.js.map +1 -0
- package/dist/lib/regression/docker-helpers.d.ts +98 -0
- package/dist/lib/regression/docker-helpers.d.ts.map +1 -0
- package/dist/lib/regression/docker-helpers.js +184 -0
- package/dist/lib/regression/docker-helpers.js.map +1 -0
- package/dist/light-commands.d.ts.map +1 -1
- package/dist/light-commands.js +2 -0
- package/dist/light-commands.js.map +1 -1
- package/oclif.manifest.json +1635 -702
- package/package.json +22 -17
- package/regression-compose/docker-compose.bacpac-standalone.yml +109 -0
- package/regression-compose/docker-compose.standalone.yml +50 -0
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
1
2
|
import { Command, Flags } from '@oclif/core';
|
|
2
3
|
import { Skyway } from '@memberjunction/skyway-core';
|
|
3
4
|
import ora from 'ora-classic';
|
|
4
5
|
import { getValidatedConfig, getSkywayConfig } from '../../config.js';
|
|
6
|
+
import { fetchMigrationSlice, resolveGitRef } from '../../lib/migration-fetch.js';
|
|
7
|
+
import { verifyDatabaseConnection } from '../../lib/db-preflight.js';
|
|
8
|
+
import { readCurrentDbVersion } from '../../lib/db-version.js';
|
|
9
|
+
/** Skyway's default history table — matches `@memberjunction/skyway-core`'s config default. */
|
|
10
|
+
const HISTORY_TABLE = 'flyway_schema_history';
|
|
5
11
|
export default class Migrate extends Command {
|
|
6
12
|
static { this.description = 'Migrate MemberJunction database to latest version'; }
|
|
7
13
|
static { this.examples = [
|
|
@@ -17,12 +23,112 @@ export default class Migrate extends Command {
|
|
|
17
23
|
tag: Flags.string({ char: 't', description: 'Version tag to use for running remote migrations' }),
|
|
18
24
|
schema: Flags.string({ char: 's', description: 'Target schema (overrides coreSchema from config)' }),
|
|
19
25
|
dir: Flags.string({ description: 'Migration source directory (overrides migrationsLocation from config)' }),
|
|
26
|
+
'check-connection': Flags.boolean({
|
|
27
|
+
description: 'Verify the database connection (including TLS) and exit without migrating',
|
|
28
|
+
}),
|
|
20
29
|
}; }
|
|
21
30
|
async run() {
|
|
22
31
|
const { flags } = await this.parse(Migrate);
|
|
23
32
|
const config = getValidatedConfig();
|
|
24
|
-
|
|
25
|
-
|
|
33
|
+
// Connection preflight: a real connect with the configured TLS/auth settings, so a
|
|
34
|
+
// self-signed cert or bad credentials fails fast with an actionable hint instead of a
|
|
35
|
+
// cryptic error mid-migration. `--check-connection` runs only this and exits.
|
|
36
|
+
await this.preflightConnection(config, flags['check-connection']);
|
|
37
|
+
if (flags['check-connection'])
|
|
38
|
+
return;
|
|
39
|
+
// For a remote ref we read the DB's current migration version, then fetch only the
|
|
40
|
+
// slice needed to reach the target — versioned migrations after the current version
|
|
41
|
+
// for an existing DB, or baseline + tail for a fresh one — into a temp dir handed to
|
|
42
|
+
// Skyway. cleanup() runs on every exit path.
|
|
43
|
+
//
|
|
44
|
+
// Explicit --tag wins; otherwise the install-pinned version (mjRepoVersion) drives
|
|
45
|
+
// the fetch so migrate stays consistent with the installed code. An explicit --dir
|
|
46
|
+
// override (without --tag) keeps using the local filesystem and skips fetching, so
|
|
47
|
+
// monorepo developers are unaffected.
|
|
48
|
+
const ref = flags.tag ?? (flags.dir ? undefined : config.mjRepoVersion);
|
|
49
|
+
const fetched = ref ? await this.fetchSliceForRef(config, ref, flags.schema) : null;
|
|
50
|
+
try {
|
|
51
|
+
const sourceDir = this.resolveSourceDir(fetched, flags.dir);
|
|
52
|
+
const skywayConfig = await getSkywayConfig(config, undefined, flags.schema, sourceDir);
|
|
53
|
+
this.logFetchSummary(flags.verbose, fetched);
|
|
54
|
+
await this.executeMigration(config, flags, skywayConfig);
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
if (fetched)
|
|
58
|
+
await fetched.cleanup();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Reads the database's current migration version, logs it, then fetches the minimal
|
|
63
|
+
* slice to reach `ref`: versioned migrations after the current version for an existing
|
|
64
|
+
* database, or baseline + tail for a fresh one.
|
|
65
|
+
*/
|
|
66
|
+
async fetchSliceForRef(config, ref, schema) {
|
|
67
|
+
const currentVersion = await this.readInstalledVersion(config, schema);
|
|
68
|
+
this.logInstalledVersion(currentVersion);
|
|
69
|
+
return fetchMigrationSlice({
|
|
70
|
+
repoUrl: config.mjRepoUrl,
|
|
71
|
+
ref: resolveGitRef(ref),
|
|
72
|
+
dialect: config.dbPlatform,
|
|
73
|
+
currentVersion,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Connects to read the highest migration version already applied (from Skyway's
|
|
78
|
+
* history table). Returns null for a fresh database (no history table yet).
|
|
79
|
+
*/
|
|
80
|
+
async readInstalledVersion(config, schema) {
|
|
81
|
+
// A throwaway config just to obtain a provider — the migration location is irrelevant here.
|
|
82
|
+
const probe = await getSkywayConfig(config, undefined, schema, undefined);
|
|
83
|
+
return readCurrentDbVersion(probe.Provider, probe.Migrations.DefaultSchema, HISTORY_TABLE);
|
|
84
|
+
}
|
|
85
|
+
/** Surfaces the detected installed version so the user sees what's being upgraded from. */
|
|
86
|
+
logInstalledVersion(currentVersion) {
|
|
87
|
+
if (currentVersion === null) {
|
|
88
|
+
this.log('No prior migration history detected — treating as a fresh install (baseline + later migrations).');
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
this.log(`Detected installed migration version: ${currentVersion} — fetching only migrations newer than it.`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Verify the database is reachable with the configured TLS/auth settings before
|
|
96
|
+
* running migrations. On failure, prints a classified message (and an actionable
|
|
97
|
+
* suggestion such as DB_TRUST_SERVER_CERTIFICATE for a self-signed cert) and exits.
|
|
98
|
+
*/
|
|
99
|
+
async preflightConnection(config, checkOnly) {
|
|
100
|
+
const result = await verifyDatabaseConnection(config);
|
|
101
|
+
if (!result.Ok) {
|
|
102
|
+
const suggestion = result.Suggestion ? `\n→ ${result.Suggestion}` : '';
|
|
103
|
+
this.error(`Database connection failed: ${result.Message ?? 'unknown error'}${suggestion}`);
|
|
104
|
+
}
|
|
105
|
+
if (checkOnly) {
|
|
106
|
+
this.log(`Database connection OK (${config.dbHost}:${config.dbPort}, ${config.dbDatabase}).`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Resolves the migration source directory handed to Skyway. With a fetched slice,
|
|
111
|
+
* the temp clone root is used (Skyway scans it recursively); a `--dir` override is
|
|
112
|
+
* applied as a subpath within that clone.
|
|
113
|
+
*/
|
|
114
|
+
resolveSourceDir(fetched, dirFlag) {
|
|
115
|
+
if (!fetched)
|
|
116
|
+
return dirFlag;
|
|
117
|
+
if (!dirFlag)
|
|
118
|
+
return fetched.dir;
|
|
119
|
+
const subPath = dirFlag.replace(/^filesystem:/, '').replace(/^\.\//, '');
|
|
120
|
+
return path.join(fetched.dir, subPath);
|
|
121
|
+
}
|
|
122
|
+
logFetchSummary(verbose, fetched) {
|
|
123
|
+
if (!verbose || !fetched)
|
|
124
|
+
return;
|
|
125
|
+
this.log(fetched.usedFallback
|
|
126
|
+
? 'Fetched full migration history (partial clone unavailable)'
|
|
127
|
+
: `Fetched ${fetched.selected.length} migration file(s) for the target slice`);
|
|
128
|
+
}
|
|
129
|
+
/** Runs Skyway against the prepared config and reports the outcome. */
|
|
130
|
+
async executeMigration(config, flags, skywayConfig) {
|
|
131
|
+
const targetSchema = skywayConfig.Migrations.DefaultSchema;
|
|
26
132
|
const skyway = new Skyway(skywayConfig);
|
|
27
133
|
// Always capture progress for error diagnostics; verbose mode prints it live
|
|
28
134
|
const errorLog = [];
|
|
@@ -87,7 +193,7 @@ export default class Migrate extends Command {
|
|
|
87
193
|
this.logToStderr(`\nMigration failed: ${result.ErrorMessage ?? 'unknown error'}\n`);
|
|
88
194
|
if (result.Details.length > 0) {
|
|
89
195
|
// We have per-migration details — show them
|
|
90
|
-
const succeeded = result.Details.filter(d => d.Success);
|
|
196
|
+
const succeeded = result.Details.filter((d) => d.Success);
|
|
91
197
|
if (succeeded.length > 0) {
|
|
92
198
|
this.logToStderr(` Applied ${succeeded.length} migration(s) before failure:`);
|
|
93
199
|
for (const detail of succeeded) {
|
|
@@ -95,7 +201,7 @@ export default class Migrate extends Command {
|
|
|
95
201
|
}
|
|
96
202
|
this.logToStderr('');
|
|
97
203
|
}
|
|
98
|
-
const failed = result.Details.filter(d => !d.Success);
|
|
204
|
+
const failed = result.Details.filter((d) => !d.Success);
|
|
99
205
|
for (const detail of failed) {
|
|
100
206
|
this.logToStderr(` FAILED: ${detail.Migration.Filename}`);
|
|
101
207
|
this.logToStderr(` Script: ${detail.Migration.FilePath}`);
|
|
@@ -138,7 +244,7 @@ export default class Migrate extends Command {
|
|
|
138
244
|
this.logToStderr(` Version: ${lastMigrationStarted.Version ?? '(repeatable)'}`);
|
|
139
245
|
}
|
|
140
246
|
// Show relevant log messages from Skyway (error/failure lines)
|
|
141
|
-
const relevantLogs = errorLog.filter(msg => msg.toLowerCase().includes('fail') || msg.toLowerCase().includes('error') || msg.toLowerCase().includes('rolled back'));
|
|
247
|
+
const relevantLogs = errorLog.filter((msg) => msg.toLowerCase().includes('fail') || msg.toLowerCase().includes('error') || msg.toLowerCase().includes('rolled back'));
|
|
142
248
|
if (relevantLogs.length > 0) {
|
|
143
249
|
this.logToStderr('');
|
|
144
250
|
this.logToStderr(' Skyway log:');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/migrate/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAErD,OAAO,GAAG,MAAM,aAAa,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/migrate/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,9 +10,12 @@ export default class TestCompare extends Command {
|
|
|
10
10
|
version: import("@oclif/core/lib/interfaces").OptionFlag<string[], import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
11
|
commit: import("@oclif/core/lib/interfaces").OptionFlag<string[], import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
12
|
'diff-only': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
latest: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
'from-json': import("@oclif/core/lib/interfaces").OptionFlag<string[], import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
15
|
format: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
14
16
|
output: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
15
17
|
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
18
|
+
tag: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
16
19
|
};
|
|
17
20
|
run(): Promise<void>;
|
|
18
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../../src/commands/test/compare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,aAAa,CAAC;AAEnD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,OAAO;IAC9C,MAAM,CAAC,WAAW,SAAgD;IAElE,MAAM,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../../src/commands/test/compare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,aAAa,CAAC;AAEnD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,OAAO;IAC9C,MAAM,CAAC,WAAW,SAAgD;IAElE,MAAM,CAAC,QAAQ,WAQb;IAEF,MAAM,CAAC,IAAI;;;MAST;IAEF,MAAM,CAAC,KAAK;;;;;;;;;;MA4CV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAyB3B"}
|
|
@@ -2,10 +2,13 @@ import { Command, Flags, Args } from '@oclif/core';
|
|
|
2
2
|
export default class TestCompare extends Command {
|
|
3
3
|
static { this.description = 'Compare test runs for regression detection'; }
|
|
4
4
|
static { this.examples = [
|
|
5
|
+
'<%= config.bin %> <%= command.id %>',
|
|
6
|
+
'<%= config.bin %> <%= command.id %> --latest',
|
|
5
7
|
'<%= config.bin %> <%= command.id %> <run-id-1> <run-id-2>',
|
|
6
|
-
'<%= config.bin %> <%= command.id %>
|
|
7
|
-
'<%= config.bin %> <%= command.id %>
|
|
8
|
-
'<%= config.bin %> <%= command.id %>
|
|
8
|
+
'<%= config.bin %> <%= command.id %> -v 5.17.0 -v 5.18.0',
|
|
9
|
+
'<%= config.bin %> <%= command.id %> -c abc1234 -c def5678',
|
|
10
|
+
'<%= config.bin %> <%= command.id %> --from-json baseline.json latest.json',
|
|
11
|
+
'<%= config.bin %> <%= command.id %> --latest --format=markdown --output=report.md',
|
|
9
12
|
]; }
|
|
10
13
|
static { this.args = {
|
|
11
14
|
runId1: Args.string({
|
|
@@ -32,6 +35,15 @@ export default class TestCompare extends Command {
|
|
|
32
35
|
description: 'Show only differences',
|
|
33
36
|
default: false,
|
|
34
37
|
}),
|
|
38
|
+
latest: Flags.boolean({
|
|
39
|
+
char: 'l',
|
|
40
|
+
description: 'Compare the two most recent completed suite runs',
|
|
41
|
+
default: false,
|
|
42
|
+
}),
|
|
43
|
+
'from-json': Flags.string({
|
|
44
|
+
description: 'Compare two results.json files directly (no DB). Pass twice: --from-json PREV --from-json CURR',
|
|
45
|
+
multiple: true,
|
|
46
|
+
}),
|
|
35
47
|
format: Flags.string({
|
|
36
48
|
char: 'f',
|
|
37
49
|
description: 'Output format',
|
|
@@ -46,6 +58,11 @@ export default class TestCompare extends Command {
|
|
|
46
58
|
description: 'Show detailed information',
|
|
47
59
|
default: false,
|
|
48
60
|
}),
|
|
61
|
+
tag: Flags.string({
|
|
62
|
+
description: 'Filter suite runs by tag (matches against MJTestSuiteRunEntity.Tags). Useful for ' +
|
|
63
|
+
'isolating runs from a specific source environment in an archive MJ. DB mode only — ' +
|
|
64
|
+
'--from-json ignores this flag.',
|
|
65
|
+
}),
|
|
49
66
|
}; }
|
|
50
67
|
async run() {
|
|
51
68
|
const { CompareCommand } = await import('@memberjunction/testing-cli');
|
|
@@ -58,9 +75,12 @@ export default class TestCompare extends Command {
|
|
|
58
75
|
version: flags.version,
|
|
59
76
|
commit: flags.commit,
|
|
60
77
|
diffOnly: flags['diff-only'],
|
|
78
|
+
latest: flags.latest,
|
|
79
|
+
fromJson: flags['from-json'],
|
|
61
80
|
format: flags.format,
|
|
62
81
|
output: flags.output,
|
|
63
82
|
verbose: flags.verbose,
|
|
83
|
+
tag: flags.tag,
|
|
64
84
|
});
|
|
65
85
|
}
|
|
66
86
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare.js","sourceRoot":"","sources":["../../../src/commands/test/compare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,OAAO;aACvC,gBAAW,GAAG,4CAA4C,CAAC;aAE3D,aAAQ,GAAG;QAChB,2DAA2D;QAC3D,
|
|
1
|
+
{"version":3,"file":"compare.js","sourceRoot":"","sources":["../../../src/commands/test/compare.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class TestRegressionBuild extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static strict: boolean;
|
|
6
|
+
static args: {
|
|
7
|
+
service: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
static flags: {
|
|
10
|
+
'skip-gen-forms': import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../../src/commands/test/regression/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,OAAO,EAAS,MAAM,aAAa,CAAC;AAYnD,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,OAAO;IACtD,MAAM,CAAC,WAAW,SAIc;IAEhC,MAAM,CAAC,QAAQ,WAIb;IAEF,MAAM,CAAC,MAAM,UAAS;IAEtB,MAAM,CAAC,IAAI;;MAKT;IAEF,MAAM,CAAC,KAAK;;MAOV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAoB3B"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Args, Command, Flags } from '@oclif/core';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { dockerComposeArgs, GEN_FORMS_SCRIPT, requireMonorepoRoot, spawnInherit, } from '../../../lib/regression/docker-helpers.js';
|
|
5
|
+
const GENERATED_FORMS_DIR = 'docker/regression/.docker-generated/MJExplorer-forms/Entities';
|
|
6
|
+
export default class TestRegressionBuild extends Command {
|
|
7
|
+
static { this.description = 'Build Docker images for the regression stack. On first run (or whenever ' +
|
|
8
|
+
'.docker-generated/ is empty) this also invokes `gen-forms` to generate ' +
|
|
9
|
+
'Angular entity forms — that step takes ~5 minutes but only happens when ' +
|
|
10
|
+
'the form output is missing.'; }
|
|
11
|
+
static { this.examples = [
|
|
12
|
+
'<%= config.bin %> <%= command.id %>',
|
|
13
|
+
'<%= config.bin %> <%= command.id %> mjexplorer # rebuild a specific service',
|
|
14
|
+
'<%= config.bin %> <%= command.id %> --skip-gen-forms',
|
|
15
|
+
]; }
|
|
16
|
+
static { this.strict = false; }
|
|
17
|
+
static { this.args = {
|
|
18
|
+
service: Args.string({
|
|
19
|
+
description: 'Optional service name(s) to rebuild (e.g. mjexplorer, test-runner).',
|
|
20
|
+
required: false,
|
|
21
|
+
}),
|
|
22
|
+
}; }
|
|
23
|
+
static { this.flags = {
|
|
24
|
+
'skip-gen-forms': Flags.boolean({
|
|
25
|
+
description: 'Skip the gen-forms guard, even when .docker-generated/ is empty. Use when you know ' +
|
|
26
|
+
'the entity forms are already generated.',
|
|
27
|
+
default: false,
|
|
28
|
+
}),
|
|
29
|
+
}; }
|
|
30
|
+
async run() {
|
|
31
|
+
const { argv, flags } = await this.parse(TestRegressionBuild);
|
|
32
|
+
requireMonorepoRoot();
|
|
33
|
+
if (!flags['skip-gen-forms'] && !existsSync(path.resolve(GENERATED_FORMS_DIR))) {
|
|
34
|
+
this.log('▶ .docker-generated/ is empty — running `gen-forms` first (one-time, ~5 min)...');
|
|
35
|
+
const genCode = await spawnInherit('bash', [GEN_FORMS_SCRIPT]);
|
|
36
|
+
if (genCode !== 0)
|
|
37
|
+
this.exit(genCode);
|
|
38
|
+
}
|
|
39
|
+
// Pass-through any positional service names so users can rebuild a
|
|
40
|
+
// single image (e.g. `mj test regression build mjexplorer`).
|
|
41
|
+
const services = argv.filter(Boolean);
|
|
42
|
+
const composeArgs = dockerComposeArgs('full', ['build', ...services]);
|
|
43
|
+
const code = await spawnInherit('docker', composeArgs);
|
|
44
|
+
if (code !== 0)
|
|
45
|
+
this.exit(code);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../../../src/commands/test/regression/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,GACb,MAAM,2CAA2C,CAAC;AAEnD,MAAM,mBAAmB,GAAG,+DAA+D,CAAC;AAE5F,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,OAAO;aAC/C,gBAAW,GAChB,0EAA0E;QAC1E,yEAAyE;QACzE,0EAA0E;QAC1E,6BAA6B,CAAC;aAEzB,aAAQ,GAAG;QAChB,qCAAqC;QACrC,8EAA8E;QAC9E,sDAAsD;KACvD,CAAC;aAEK,WAAM,GAAG,KAAK,CAAC;aAEf,SAAI,GAAG;QACZ,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;YACnB,WAAW,EAAE,qEAAqE;YAClF,QAAQ,EAAE,KAAK;SAChB,CAAC;KACH,CAAC;aAEK,UAAK,GAAG;QACb,gBAAgB,EAAE,KAAK,CAAC,OAAO,CAAC;YAC9B,WAAW,EACT,qFAAqF;gBACrF,yCAAyC;YAC3C,OAAO,EAAE,KAAK;SACf,CAAC;KACH,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC9D,mBAAmB,EAAE,CAAC;QAEtB,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC;YAC/E,IAAI,CAAC,GAAG,CACN,iFAAiF,CAClF,CAAC;YACF,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;YAC/D,IAAI,OAAO,KAAK,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC;QAED,mEAAmE;QACnE,6DAA6D;QAC7D,MAAM,QAAQ,GAAI,IAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;QAEtE,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QACvD,IAAI,IAAI,KAAK,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class TestRegressionCompare extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static strict: boolean;
|
|
6
|
+
static flags: {
|
|
7
|
+
'diff-only': import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
8
|
+
format: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
9
|
+
output: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
10
|
+
verbose: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
11
|
+
tag: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
12
|
+
};
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=compare.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../../../src/commands/test/regression/compare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAM7C,MAAM,CAAC,OAAO,OAAO,qBAAsB,SAAQ,OAAO;IACxD,MAAM,CAAC,WAAW,SAE4D;IAE9E,MAAM,CAAC,QAAQ,WAIb;IAEF,MAAM,CAAC,MAAM,UAAS;IAEtB,MAAM,CAAC,KAAK;;;;;;MAwBV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAwB3B"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import { isInsideMonorepo, spawnInherit } from '../../../lib/regression/docker-helpers.js';
|
|
3
|
+
const REGRESSION_RESULTS_DIR = 'docker/regression/test-results';
|
|
4
|
+
const EXTERNAL_RESULTS_DIR = 'test-results';
|
|
5
|
+
export default class TestRegressionCompare extends Command {
|
|
6
|
+
static { this.description = 'Diff the two most recent regression runs from docker/regression/test-results/. ' +
|
|
7
|
+
'Thin alias for `mj test compare --from-json <dir>` that handles the path.'; }
|
|
8
|
+
static { this.examples = [
|
|
9
|
+
'<%= config.bin %> <%= command.id %>',
|
|
10
|
+
'<%= config.bin %> <%= command.id %> --diff-only',
|
|
11
|
+
'<%= config.bin %> <%= command.id %> --format=markdown --output=delta.md',
|
|
12
|
+
]; }
|
|
13
|
+
static { this.strict = false; }
|
|
14
|
+
static { this.flags = {
|
|
15
|
+
'diff-only': Flags.boolean({
|
|
16
|
+
description: 'Show only differences.',
|
|
17
|
+
default: false,
|
|
18
|
+
}),
|
|
19
|
+
format: Flags.string({
|
|
20
|
+
char: 'f',
|
|
21
|
+
description: 'Output format.',
|
|
22
|
+
options: ['console', 'json', 'markdown'],
|
|
23
|
+
default: 'console',
|
|
24
|
+
}),
|
|
25
|
+
output: Flags.string({
|
|
26
|
+
char: 'o',
|
|
27
|
+
description: 'Output file path.',
|
|
28
|
+
}),
|
|
29
|
+
verbose: Flags.boolean({
|
|
30
|
+
description: 'Show detailed information.',
|
|
31
|
+
default: false,
|
|
32
|
+
}),
|
|
33
|
+
tag: Flags.string({
|
|
34
|
+
description: 'Filter suite runs by tag. Compares the two most recent runs whose Tags array ' +
|
|
35
|
+
'contains the tag — useful when an archive MJ holds runs from multiple environments.',
|
|
36
|
+
}),
|
|
37
|
+
}; }
|
|
38
|
+
async run() {
|
|
39
|
+
const { flags } = await this.parse(TestRegressionCompare);
|
|
40
|
+
// Results live under docker/regression/test-results in the monorepo, or
|
|
41
|
+
// ./test-results when running externally (where remote/up wrote them).
|
|
42
|
+
const resultsDir = isInsideMonorepo() ? REGRESSION_RESULTS_DIR : EXTERNAL_RESULTS_DIR;
|
|
43
|
+
// --tag flips us to DB mode (results.json doesn't carry Tags), so drop
|
|
44
|
+
// --from-json when the user asks for tag filtering.
|
|
45
|
+
const args = ['test', 'compare'];
|
|
46
|
+
if (!flags.tag) {
|
|
47
|
+
args.push('--from-json', resultsDir);
|
|
48
|
+
}
|
|
49
|
+
if (flags.tag)
|
|
50
|
+
args.push('--tag', flags.tag);
|
|
51
|
+
if (flags['diff-only'])
|
|
52
|
+
args.push('--diff-only');
|
|
53
|
+
if (flags.format && flags.format !== 'console')
|
|
54
|
+
args.push('--format', flags.format);
|
|
55
|
+
if (flags.output)
|
|
56
|
+
args.push('--output', flags.output);
|
|
57
|
+
if (flags.verbose)
|
|
58
|
+
args.push('--verbose');
|
|
59
|
+
// Re-invoke the same `mj` binary. argv[1] is the entry script path.
|
|
60
|
+
const mjBin = process.argv[1] ?? 'mj';
|
|
61
|
+
const code = await spawnInherit(process.execPath, [mjBin, ...args]);
|
|
62
|
+
if (code !== 0)
|
|
63
|
+
this.exit(code);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=compare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare.js","sourceRoot":"","sources":["../../../../src/commands/test/regression/compare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AAE3F,MAAM,sBAAsB,GAAG,gCAAgC,CAAC;AAChE,MAAM,oBAAoB,GAAG,cAAc,CAAC;AAE5C,MAAM,CAAC,OAAO,OAAO,qBAAsB,SAAQ,OAAO;aACjD,gBAAW,GAChB,iFAAiF;QACjF,2EAA2E,CAAC;aAEvE,aAAQ,GAAG;QAChB,qCAAqC;QACrC,iDAAiD;QACjD,yEAAyE;KAC1E,CAAC;aAEK,WAAM,GAAG,KAAK,CAAC;aAEf,UAAK,GAAG;QACb,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC;YACzB,WAAW,EAAE,wBAAwB;YACrC,OAAO,EAAE,KAAK;SACf,CAAC;QACF,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;YACnB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,gBAAgB;YAC7B,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC;YACxC,OAAO,EAAE,SAAS;SACnB,CAAC;QACF,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;YACnB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,mBAAmB;SACjC,CAAC;QACF,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;YACrB,WAAW,EAAE,4BAA4B;YACzC,OAAO,EAAE,KAAK;SACf,CAAC;QACF,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC;YAChB,WAAW,EACT,+EAA+E;gBAC/E,qFAAqF;SACxF,CAAC;KACH,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAE1D,wEAAwE;QACxE,uEAAuE;QACvE,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,oBAAoB,CAAC;QAEtF,uEAAuE;QACvE,oDAAoD;QACpD,MAAM,IAAI,GAAa,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC3C,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YACf,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;QACvC,CAAC;QACD,IAAI,KAAK,CAAC,GAAG;YAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7C,IAAI,KAAK,CAAC,WAAW,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACjD,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;YAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACpF,IAAI,KAAK,CAAC,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACtD,IAAI,KAAK,CAAC,OAAO;YAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAE1C,oEAAoE;QACpE,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QACtC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;QACpE,IAAI,IAAI,KAAK,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class TestRegressionDown extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
'keep-volumes': import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
7
|
+
};
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=down.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"down.d.ts","sourceRoot":"","sources":["../../../../src/commands/test/regression/down.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAO7C,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,OAAO;IACrD,MAAM,CAAC,WAAW,SAC0D;IAE5E,MAAM,CAAC,QAAQ,WAGb;IAEF,MAAM,CAAC,KAAK;;MAKV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAa3B"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import { dockerComposeArgs, requireMonorepoRoot, spawnInherit, } from '../../../lib/regression/docker-helpers.js';
|
|
3
|
+
export default class TestRegressionDown extends Command {
|
|
4
|
+
static { this.description = 'Stop the regression stack and wipe DB volumes (docker compose down -v).'; }
|
|
5
|
+
static { this.examples = [
|
|
6
|
+
'<%= config.bin %> <%= command.id %>',
|
|
7
|
+
'<%= config.bin %> <%= command.id %> --keep-volumes',
|
|
8
|
+
]; }
|
|
9
|
+
static { this.flags = {
|
|
10
|
+
'keep-volumes': Flags.boolean({
|
|
11
|
+
description: 'Skip the `-v` flag — preserves the ephemeral DB volume.',
|
|
12
|
+
default: false,
|
|
13
|
+
}),
|
|
14
|
+
}; }
|
|
15
|
+
async run() {
|
|
16
|
+
const { flags } = await this.parse(TestRegressionDown);
|
|
17
|
+
requireMonorepoRoot();
|
|
18
|
+
// Use `--profile *` so compose tears down services in every profile,
|
|
19
|
+
// not just the active one. Otherwise `down` leaves orphan containers
|
|
20
|
+
// from a profile we haven't named.
|
|
21
|
+
const composeArgs = dockerComposeArgs(undefined, ['--profile', '*', 'down']);
|
|
22
|
+
if (!flags['keep-volumes'])
|
|
23
|
+
composeArgs.push('-v');
|
|
24
|
+
const code = await spawnInherit('docker', composeArgs);
|
|
25
|
+
if (code !== 0)
|
|
26
|
+
this.exit(code);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=down.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"down.js","sourceRoot":"","sources":["../../../../src/commands/test/regression/down.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,GACb,MAAM,2CAA2C,CAAC;AAEnD,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,OAAO;aAC9C,gBAAW,GAChB,yEAAyE,CAAC;aAErE,aAAQ,GAAG;QAChB,qCAAqC;QACrC,oDAAoD;KACrD,CAAC;aAEK,UAAK,GAAG;QACb,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC;YAC5B,WAAW,EAAE,yDAAyD;YACtE,OAAO,EAAE,KAAK;SACf,CAAC;KACH,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACvD,mBAAmB,EAAE,CAAC;QAEtB,qEAAqE;QACrE,qEAAqE;QACrE,mCAAmC;QACnC,MAAM,WAAW,GAAG,iBAAiB,CAAC,SAAS,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;QAC7E,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC;YAAE,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEnD,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QACvD,IAAI,IAAI,KAAK,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class TestRegressionExport extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
run: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
7
|
+
image: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
8
|
+
};
|
|
9
|
+
run(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../../src/commands/test/regression/export.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAY7C,MAAM,CAAC,OAAO,OAAO,oBAAqB,SAAQ,OAAO;IACvD,MAAM,CAAC,WAAW,SAGsC;IAExD,MAAM,CAAC,QAAQ,WAIb;IAEF,MAAM,CAAC,KAAK;;;MAUV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAiC3B"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { AGENTIC_TEST_RUNNER_IMAGE, dockerRunArgs, INLINE_REPORT_SCRIPT, isInsideMonorepo, RESULTS_DIR, spawnInherit, } from '../../../lib/regression/docker-helpers.js';
|
|
5
|
+
export default class TestRegressionExport extends Command {
|
|
6
|
+
static { this.description = 'Export a regression run\'s HTML report as a single self-contained file ' +
|
|
7
|
+
'(screenshots inlined as base64), producing report.standalone.html. ' +
|
|
8
|
+
'Portable for sharing or attaching as a CI artifact.'; }
|
|
9
|
+
static { this.examples = [
|
|
10
|
+
'<%= config.bin %> <%= command.id %>',
|
|
11
|
+
'<%= config.bin %> <%= command.id %> --run=run-20260526T220118Z',
|
|
12
|
+
'<%= config.bin %> <%= command.id %> --run=./some/other/run-dir',
|
|
13
|
+
]; }
|
|
14
|
+
static { this.flags = {
|
|
15
|
+
run: Flags.string({
|
|
16
|
+
char: 'r',
|
|
17
|
+
description: 'Which run to export. A folder name (under test-results/) or a path. Defaults to the latest run.',
|
|
18
|
+
}),
|
|
19
|
+
image: Flags.string({
|
|
20
|
+
description: '(external) Published image used to inline reports. Default: ' + AGENTIC_TEST_RUNNER_IMAGE + '.',
|
|
21
|
+
}),
|
|
22
|
+
}; }
|
|
23
|
+
async run() {
|
|
24
|
+
const { flags } = await this.parse(TestRegressionExport);
|
|
25
|
+
if (isInsideMonorepo()) {
|
|
26
|
+
// On-disk inline-report.cjs against docker/regression/test-results.
|
|
27
|
+
if (!existsSync(INLINE_REPORT_SCRIPT))
|
|
28
|
+
this.error(`✗ Exporter missing: ${INLINE_REPORT_SCRIPT}`);
|
|
29
|
+
const args = [INLINE_REPORT_SCRIPT];
|
|
30
|
+
if (flags.run) {
|
|
31
|
+
const runDir = flags.run.includes('/') || path.isAbsolute(flags.run)
|
|
32
|
+
? path.resolve(flags.run)
|
|
33
|
+
: path.resolve(RESULTS_DIR, flags.run);
|
|
34
|
+
if (!existsSync(runDir))
|
|
35
|
+
this.error(`✗ Run directory not found: ${runDir}`);
|
|
36
|
+
args.push(runDir);
|
|
37
|
+
}
|
|
38
|
+
const code = await spawnInherit(process.execPath, args);
|
|
39
|
+
if (code !== 0)
|
|
40
|
+
this.exit(code);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
// External: run the image's `export` subcommand against the mounted run dir.
|
|
44
|
+
// Results live under ./test-results; mount it and resolve the run inside the container.
|
|
45
|
+
const image = flags.image ?? AGENTIC_TEST_RUNNER_IMAGE;
|
|
46
|
+
const resultsDir = path.resolve('test-results');
|
|
47
|
+
if (!existsSync(resultsDir))
|
|
48
|
+
this.error(`✗ No ./test-results directory found to export from.`);
|
|
49
|
+
const runArg = flags.run ? `/app/test-results/${path.basename(flags.run)}` : '/app/test-results/latest';
|
|
50
|
+
this.log(`▶ docker run ${image} export ${runArg}`);
|
|
51
|
+
const code = await spawnInherit('docker', dockerRunArgs(image, ['export', runArg], { mounts: [[resultsDir, '/app/test-results']] }));
|
|
52
|
+
if (code !== 0)
|
|
53
|
+
this.exit(code);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../../../src/commands/test/regression/export.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gen-forms.d.ts","sourceRoot":"","sources":["../../../../src/commands/test/regression/gen-forms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAQtC,MAAM,CAAC,OAAO,OAAO,sBAAuB,SAAQ,OAAO;IACzD,MAAM,CAAC,WAAW,SAEiD;IAEnE,MAAM,CAAC,QAAQ,WAA2C;IAEpD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAS3B"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { GEN_FORMS_SCRIPT, requireMonorepoRoot, spawnInherit, } from '../../../lib/regression/docker-helpers.js';
|
|
4
|
+
export default class TestRegressionGenForms extends Command {
|
|
5
|
+
static { this.description = 'Regenerate Angular entity forms used by the regression MJExplorer image. ' +
|
|
6
|
+
'Slow (~5 min) — only required after schema or codegen changes.'; }
|
|
7
|
+
static { this.examples = ['<%= config.bin %> <%= command.id %>']; }
|
|
8
|
+
async run() {
|
|
9
|
+
requireMonorepoRoot();
|
|
10
|
+
if (!existsSync(GEN_FORMS_SCRIPT)) {
|
|
11
|
+
this.error(`✗ ${GEN_FORMS_SCRIPT} not found. Verify the docker/regression/ directory is intact.`);
|
|
12
|
+
}
|
|
13
|
+
const code = await spawnInherit('bash', [GEN_FORMS_SCRIPT]);
|
|
14
|
+
if (code !== 0)
|
|
15
|
+
this.exit(code);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=gen-forms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gen-forms.js","sourceRoot":"","sources":["../../../../src/commands/test/regression/gen-forms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,GACb,MAAM,2CAA2C,CAAC;AAEnD,MAAM,CAAC,OAAO,OAAO,sBAAuB,SAAQ,OAAO;aAClD,gBAAW,GAChB,2EAA2E;QAC3E,gEAAgE,CAAC;aAE5D,aAAQ,GAAG,CAAC,qCAAqC,CAAC,CAAC;IAE1D,KAAK,CAAC,GAAG;QACP,mBAAmB,EAAE,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,KAAK,CAAC,KAAK,gBAAgB,gEAAgE,CAAC,CAAC;QACpG,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAC5D,IAAI,IAAI,KAAK,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC"}
|