@stim-cli/ci 1.37.0 → 1.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
CHANGED
|
@@ -109,13 +109,20 @@ run options other than those that build.
|
|
|
109
109
|
Everything after `--` is an argument vector. No shell is inferred. To use shell
|
|
110
110
|
syntax, pass a shell explicitly: `-- bash -e -o pipefail -c 'pnpm test:e2e'`.
|
|
111
111
|
|
|
112
|
+
Without `--`, `run` installs and launches the app, writes `run.json`, then stops the
|
|
113
|
+
workspace as after a passing test, with `test: null` and exit code 0. Use it when a
|
|
114
|
+
later step drives a Release app on the device `run.json` names; boot a simulator again
|
|
115
|
+
by its UDID, since cleanup shuts it down. Cleanup also stops Metro, so a Debug app has
|
|
116
|
+
no bundler in that later step. An explicit `--` with no command after it is
|
|
117
|
+
refused. The library's `runCI` behaves the same when `command` is omitted.
|
|
118
|
+
|
|
112
119
|
The test process runs in the project directory. It receives the caller's
|
|
113
120
|
environment plus these values:
|
|
114
121
|
|
|
115
122
|
| Variable | Value |
|
|
116
123
|
| ----------------------- | ------------------------------------------------------------------------- |
|
|
117
124
|
| `STIM_CI_PLATFORM` | Selected platform |
|
|
118
|
-
| `STIM_CI_DEVICE_ID` |
|
|
125
|
+
| `STIM_CI_DEVICE_ID` | Local simulator UDID or emulator serial; empty when unavailable |
|
|
119
126
|
| `STIM_CI_APP_ID` | App bundle/package identifier when available |
|
|
120
127
|
| `STIM_CI_METRO_PORT` | Metro port when available |
|
|
121
128
|
| `STIM_CI_ARTIFACTS_DIR` | Absolute results directory; empty without `--artifacts` |
|
|
@@ -142,7 +149,7 @@ the `test` result, optional `failure`, `diagnostics`, and `cleanup`.
|
|
|
142
149
|
If a progress callback or writing `result.json` fails, the result includes
|
|
143
150
|
`reportingError`. Reporter failures cannot interrupt cleanup or replace an earlier
|
|
144
151
|
test failure; after a passing test, they return 1.
|
|
145
|
-
Setup failure leaves `run` and `test` null. Diagnostics include the last 1000
|
|
152
|
+
Setup failure leaves `run` and `test` null; a run without a command leaves `test` null. Diagnostics include the last 1000
|
|
146
153
|
structured records and their original directory. After cleanup, regular `.log`
|
|
147
154
|
and `.ndjson` files (including `.1` rotated copies) directly inside that directory
|
|
148
155
|
are copied into `logs/` and listed in `diagnostics.files`. This retains raw
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { n as buildCI, t as runCI } from "./src-
|
|
1
|
+
import { n as buildCI, t as runCI } from "./src-geNYW1_0.mjs";
|
|
2
2
|
import { parseArgs } from "node:util";
|
|
3
3
|
//#region src/cli.ts
|
|
4
4
|
const HELP = `Usage: stim-ci build --platform <ios|android|macos> [options]
|
|
5
|
-
stim-ci run --platform <ios|android|macos|web> [options] -- <command> [args...]
|
|
5
|
+
stim-ci run --platform <ios|android|macos|web> [options] [-- <command> [args...]]
|
|
6
6
|
|
|
7
7
|
Build is the only step that compiles. It records the app for this checkout, platform and
|
|
8
8
|
selectors, and exports it only with --export.
|
|
9
|
-
Run installs and launches the app the last matching build recorded, runs
|
|
10
|
-
stops the app. It never builds; with no recorded build it refuses
|
|
9
|
+
Run installs and launches the app the last matching build recorded, runs the test command
|
|
10
|
+
given after --, if any, and stops the app. It never builds; with no recorded build it refuses
|
|
11
|
+
and names the build to run.
|
|
11
12
|
The final result is JSON on stdout; progress and test output go to stderr. No result, test or
|
|
12
13
|
diagnostic file is written unless --artifacts is given.
|
|
13
14
|
|
|
@@ -110,8 +111,7 @@ function parse(argv) {
|
|
|
110
111
|
}
|
|
111
112
|
};
|
|
112
113
|
}
|
|
113
|
-
if (separator
|
|
114
|
-
if (!command[0]) throw new Error("A test command is required after --.");
|
|
114
|
+
if (separator >= 0 && !command[0]) throw new Error("A test command is required after --.");
|
|
115
115
|
const run = platform === "ios" ? {
|
|
116
116
|
platform,
|
|
117
117
|
scheme: values.scheme,
|
|
@@ -125,13 +125,13 @@ function parse(argv) {
|
|
|
125
125
|
options: {
|
|
126
126
|
...common,
|
|
127
127
|
run,
|
|
128
|
-
command
|
|
128
|
+
...separator >= 0 ? { command } : {}
|
|
129
129
|
}
|
|
130
130
|
};
|
|
131
131
|
}
|
|
132
132
|
async function main(argv = process.argv.slice(2)) {
|
|
133
133
|
if (argv.length === 1 && argv[0] === "--version") {
|
|
134
|
-
process.stdout.write(`1.
|
|
134
|
+
process.stdout.write(`1.39.0\n`);
|
|
135
135
|
return;
|
|
136
136
|
}
|
|
137
137
|
if (argv.length === 0 || argv[0] === "--help" || (argv[0] === "run" || argv[0] === "build") && argv[1] === "--help") {
|
package/dist/index.d.mts
CHANGED
|
@@ -58,7 +58,8 @@ type WithoutKeys<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : ne
|
|
|
58
58
|
interface CIOptions extends CIContextOptions {
|
|
59
59
|
/** Selectors of the recorded build to run. `run` never builds, so build-time options such as `easProfile` belong to `buildCI`. */
|
|
60
60
|
run: WithoutKeys<StimRunOptions, "signal" | "recordedBuild" | "cleanAppState" | "easProfile">;
|
|
61
|
-
command
|
|
61
|
+
/** Test command argv. Without it, `runCI` installs and launches the app, then stops it as after a passing test. */
|
|
62
|
+
command?: readonly [string, ...string[]];
|
|
62
63
|
}
|
|
63
64
|
interface CIFailure {
|
|
64
65
|
code: string;
|
|
@@ -89,7 +90,7 @@ interface CIResult {
|
|
|
89
90
|
error?: CIFailure;
|
|
90
91
|
};
|
|
91
92
|
}
|
|
92
|
-
/** Runs an app and argv-based test command, stops its workspace or explicit slot, and retains diagnostics. */
|
|
93
|
+
/** Runs an app and an optional argv-based test command, stops its workspace or explicit slot, and retains diagnostics. */
|
|
93
94
|
declare function runCI(options: CIOptions): Promise<CIResult>;
|
|
94
95
|
//#endregion
|
|
95
96
|
export { type CIBuildOptions, type CIBuildResult, CIFailure, CIOptions, CIResult, type CommandResult, buildCI, runCI };
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as buildCI, t as runCI } from "./src-
|
|
1
|
+
import { n as buildCI, t as runCI } from "./src-geNYW1_0.mjs";
|
|
2
2
|
export { buildCI, runCI };
|
|
@@ -290,17 +290,17 @@ function commandEnvironment(result, options) {
|
|
|
290
290
|
...options.home ? { STIM_HOME: resolve(options.home) } : {},
|
|
291
291
|
...options.buildCache ? { STIM_BUILD_CACHE: resolve(options.buildCache) } : {},
|
|
292
292
|
STIM_CI_PLATFORM: result.platform,
|
|
293
|
-
STIM_CI_DEVICE_ID: String("udid" in facts ? facts.udid : "serial" in facts ? facts.serial ?? "" : ""),
|
|
293
|
+
STIM_CI_DEVICE_ID: String("udid" in facts ? facts.udid ?? "" : "serial" in facts ? facts.serial ?? "" : ""),
|
|
294
294
|
STIM_CI_APP_ID: String("bundleId" in facts ? facts.bundleId ?? "" : ""),
|
|
295
295
|
STIM_CI_METRO_PORT: String("metroPort" in facts ? facts.metroPort ?? "" : ""),
|
|
296
296
|
STIM_CI_ARTIFACTS_DIR: result.artifactsDir ?? "",
|
|
297
297
|
STIM_CI_RUN_RESULT: result.runPath ?? ""
|
|
298
298
|
};
|
|
299
299
|
}
|
|
300
|
-
/** Runs an app and argv-based test command, stops its workspace or explicit slot, and retains diagnostics. */
|
|
300
|
+
/** Runs an app and an optional argv-based test command, stops its workspace or explicit slot, and retains diagnostics. */
|
|
301
301
|
async function runCI(options) {
|
|
302
|
-
if (!options.command[0]) throw new Error("A non-empty test command is required.");
|
|
303
|
-
for (const argument of options.command) if (typeof argument !== "string" || argument.includes("\0")) throw new Error("Test command arguments must be strings without null bytes.");
|
|
302
|
+
if (options.command && !options.command[0]) throw new Error("A non-empty test command is required.");
|
|
303
|
+
for (const argument of options.command ?? []) if (typeof argument !== "string" || argument.includes("\0")) throw new Error("Test command arguments must be strings without null bytes.");
|
|
304
304
|
const prepared = prepareCI(options);
|
|
305
305
|
options = prepared.options;
|
|
306
306
|
const { projectRoot, artifactsDir, timeout, signal } = prepared;
|
|
@@ -347,22 +347,25 @@ async function runCI(options) {
|
|
|
347
347
|
});
|
|
348
348
|
signal?.throwIfAborted();
|
|
349
349
|
if (result.runPath) writeJson(result.runPath, result.run);
|
|
350
|
-
result.
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
350
|
+
if (!options.command) result.exitCode = 0;
|
|
351
|
+
else {
|
|
352
|
+
result.test = await runCommand({
|
|
353
|
+
command: options.command,
|
|
354
|
+
cwd: projectRoot,
|
|
355
|
+
env: commandEnvironment(result, options),
|
|
356
|
+
artifactsDir,
|
|
357
|
+
signal,
|
|
358
|
+
onOutput: onProgress
|
|
359
|
+
});
|
|
360
|
+
result.exitCode = result.test.exitCode ?? 1;
|
|
361
|
+
if (result.exitCode < 0 || result.exitCode === 0 && result.test.error) result.exitCode = 1;
|
|
362
|
+
if (result.exitCode !== 0) result.failure = {
|
|
363
|
+
code: "STIM_CI_TEST_FAILED",
|
|
364
|
+
message: result.test.error ?? `Test command ${result.test.signal ? `was terminated by ${result.test.signal}` : `exited with ${result.exitCode}`}.`
|
|
365
|
+
};
|
|
366
|
+
}
|
|
364
367
|
} catch (error) {
|
|
365
|
-
result.failure = failure(error, result.run ? "STIM_CI_TEST_FAILED" : "STIM_CI_SETUP_FAILED");
|
|
368
|
+
result.failure = failure(error, result.run && options.command ? "STIM_CI_TEST_FAILED" : "STIM_CI_SETUP_FAILED");
|
|
366
369
|
if (result.failure.code === "STIM_NO_RECORDED_BUILD") result.failure.remedy = `Run ${buildCommand(options, projectRoot)} first.`;
|
|
367
370
|
} finally {
|
|
368
371
|
cleaningUp = true;
|
package/dist/stim-ci.mjs
CHANGED
|
@@ -6,6 +6,6 @@ const minor = parts[1] ?? 0;
|
|
|
6
6
|
if (major < 22 || major === 22 && minor < 12) {
|
|
7
7
|
process.stderr.write(`stim-ci requires Node.js 22.12.0 or later; this is ${process.versions.node}.\n`);
|
|
8
8
|
process.exitCode = 1;
|
|
9
|
-
} else import("./cli-
|
|
9
|
+
} else import("./cli-C0gUue7A.mjs").then(({ main }) => main());
|
|
10
10
|
//#endregion
|
|
11
11
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stim-cli/ci",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.39.0",
|
|
4
4
|
"description": "Build Stim app artifacts or run Stim apps and test commands in CI with diagnostics and scoped cleanup.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"cross-spawn": "^7.0.6",
|
|
36
|
-
"stim": "1.
|
|
36
|
+
"stim": "1.39.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/cross-spawn": "^6.0.6"
|