@andrian.yablonskyy/thub-agent 1.0.32 → 1.0.34
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 +5 -5
- package/package.json +2 -2
- package/src/cli.js +29 -7
- package/src/streaming.js +0 -3
package/README.md
CHANGED
|
@@ -29,10 +29,10 @@ thub config set user "Your Name" # optional default --user
|
|
|
29
29
|
|
|
30
30
|
```
|
|
31
31
|
thub run [options] Submit a test job and follow its log
|
|
32
|
-
thub status <jobId> Show status; follow log if running,
|
|
32
|
+
thub status <jobId> Show status; follow log if running, verdict, test counts and artifacts if done
|
|
33
33
|
thub cancel <jobId> Cancel a job
|
|
34
34
|
thub resources List resources and their status
|
|
35
|
-
thub jobs [--mine] [--state <s>] List recent jobs
|
|
35
|
+
thub jobs [--mine] [--state <s>] List recent jobs (a cli token: only its own; a ci token: all, or its own with --mine)
|
|
36
36
|
thub config set <key> <value> Save coordinator URL / token / default group / default user locally
|
|
37
37
|
thub check-update Compare this Agent with the latest published version
|
|
38
38
|
thub self-update [--to <x.y.z>] Update this Agent with npm i -g
|
|
@@ -68,7 +68,7 @@ Key options for `thub run`. **On the Client** names the environment variable the
|
|
|
68
68
|
| `--json` | Machine-readable output. | — (Agent only) |
|
|
69
69
|
|
|
70
70
|
- `thub run` prints the **job ID**, then streams logs until Ctrl-C. Ctrl-C detaches; the job keeps running on the Client.
|
|
71
|
-
- `thub status <jobId>` prints the current state; if active it keeps streaming, if done it prints the verdict and
|
|
71
|
+
- `thub status <jobId>` prints the current state; if active it keeps streaming, if done it prints the verdict, the command's exit code and the JUnit test counts. `--json` prints the job once and never follows it (see [Job status and PASS/FAIL](#job-status-and-passfail)).
|
|
72
72
|
|
|
73
73
|
Exit codes make the Agent usable as a CI step:
|
|
74
74
|
|
|
@@ -222,14 +222,14 @@ thub run --type sw --git-repo git@bitbucket.org:yourorg/tests.git main --depth 1
|
|
|
222
222
|
|
|
223
223
|
## Job status and PASS/FAIL
|
|
224
224
|
|
|
225
|
-
The verdict is `--command`'s exit code: `0` → **PASSED**, anything else → **FAILED**. ERROR, TIMEOUT, LOST and CANCELED mean the job didn't run to a verdict. JUnit XML written to `results/` or `artifacts/` in the work directory is
|
|
225
|
+
The verdict is `--command`'s exit code: `0` → **PASSED**, anything else → **FAILED**. ERROR, TIMEOUT, LOST and CANCELED mean the job didn't run to a verdict. JUnit XML written to `results/` or `artifacts/` in the work directory is summed into the job's `summary` by the Client. Nothing is uploaded: a job's files stay in its workspace on the Client, deleted when it ends — publish anything you need to keep from `--command`, e.g. to Artifactory.
|
|
226
226
|
|
|
227
227
|
**In CI:** `thub run … --wait` exits with the verdict code (table above): `0` PASSED, `1` FAILED, `2` infrastructure, `3` canceled.
|
|
228
228
|
|
|
229
229
|
**Check a job:**
|
|
230
230
|
|
|
231
231
|
```bash
|
|
232
|
-
thub status M-00125 # state; follows the log while active; then "Verdict: …" and
|
|
232
|
+
thub status M-00125 # state; follows the log while active; then "Verdict: …" and test counts; exit = verdict
|
|
233
233
|
thub jobs --mine --state FAILED
|
|
234
234
|
```
|
|
235
235
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andrian.yablonskyy/thub-agent",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.34",
|
|
4
4
|
"description": "TestHub Agent CLI — the single entry point CI/CD and developers use to submit and follow test jobs",
|
|
5
5
|
"bin": {
|
|
6
6
|
"thub": "./src/cli.js"
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"lint:fix": "eslint . --fix"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@andrian.yablonskyy/thub-common": "^1.0.
|
|
15
|
+
"@andrian.yablonskyy/thub-common": "^1.0.33",
|
|
16
16
|
"commander": "^13.1.0"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
package/src/cli.js
CHANGED
|
@@ -207,7 +207,7 @@ program
|
|
|
207
207
|
)
|
|
208
208
|
.option(
|
|
209
209
|
'--dry-run',
|
|
210
|
-
'Exercise the full pipeline (schedule, accept, state transitions, logs,
|
|
210
|
+
'Exercise the full pipeline (schedule, accept, state transitions, logs, result) ' +
|
|
211
211
|
'without the Client flashing/running anything for real',
|
|
212
212
|
false
|
|
213
213
|
)
|
|
@@ -252,7 +252,7 @@ program
|
|
|
252
252
|
|
|
253
253
|
program
|
|
254
254
|
.command('status')
|
|
255
|
-
.description('Show status; follow log if running,
|
|
255
|
+
.description('Show status; follow log if running, verdict, test counts and artifacts if done')
|
|
256
256
|
.argument('<jobId>')
|
|
257
257
|
.option('--json', 'Print the job as JSON once, without following it; exit code: its verdict, or 5 while it\'s still active', false)
|
|
258
258
|
.action(async (jobId, opts) => {
|
|
@@ -274,10 +274,20 @@ program
|
|
|
274
274
|
return process.exit(code);
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
console.log(`
|
|
277
|
+
console.log(`Verdict: ${job.state}${job.exit_code != null ? ` (exit code ${job.exit_code})` : ''}`);
|
|
278
|
+
const s = job.summary;
|
|
279
|
+
if (s && Number.isFinite(s.total) && s.total > 0){
|
|
280
|
+
console.log(`Tests: ${s.total} total, ${s.passed} passed, ${s.failed} failed, ${s.skipped} skipped`);
|
|
281
|
+
}
|
|
282
|
+
if (job.message){
|
|
283
|
+
console.log(`Message: ${job.message}`);
|
|
284
|
+
}
|
|
285
|
+
// What the job published elsewhere and reported (links, not files).
|
|
286
|
+
if (job.artifacts?.length){
|
|
287
|
+
console.log('Artifacts:');
|
|
288
|
+
for (const a of job.artifacts){
|
|
289
|
+
console.log(` ${a.name} ${a.size != null ? formatBytes(a.size) : '—'} ${a.link}`);
|
|
290
|
+
}
|
|
281
291
|
}
|
|
282
292
|
process.exit(exitCodeForJobState(job.state));
|
|
283
293
|
}
|
|
@@ -327,7 +337,7 @@ program
|
|
|
327
337
|
program
|
|
328
338
|
.command('jobs')
|
|
329
339
|
.description('List recent jobs')
|
|
330
|
-
.option('--mine', 'Only jobs submitted by this agent token', false)
|
|
340
|
+
.option('--mine', 'Only jobs submitted by this agent token (always so for a cli token, which sees only its own)', false)
|
|
331
341
|
.option('--state <state>', 'Filter by state')
|
|
332
342
|
.option('--json', 'Machine-readable output', false)
|
|
333
343
|
.action(async (opts) => {
|
|
@@ -349,6 +359,18 @@ program
|
|
|
349
359
|
}
|
|
350
360
|
});
|
|
351
361
|
|
|
362
|
+
// 1233 -> "1.2 KB" (1024-based), for artifact sizes.
|
|
363
|
+
function formatBytes(bytes){
|
|
364
|
+
const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
|
|
365
|
+
let value = bytes,
|
|
366
|
+
unit = 0;
|
|
367
|
+
while (value >= 1024 && unit < units.length - 1){
|
|
368
|
+
value /= 1024;
|
|
369
|
+
unit += 1;
|
|
370
|
+
}
|
|
371
|
+
return unit === 0 ? `${value} B` : `${value < 10 ? value.toFixed(1) : Math.round(value)} ${units[unit]}`;
|
|
372
|
+
}
|
|
373
|
+
|
|
352
374
|
const config = program.command('config').description('Manage local Agent configuration');
|
|
353
375
|
config
|
|
354
376
|
.command('set')
|
package/src/streaming.js
CHANGED
|
@@ -82,9 +82,6 @@ async function followJob(client, jobId, { fromSeq = 0, waitMode = false, print =
|
|
|
82
82
|
}
|
|
83
83
|
else if (event === 'end'){
|
|
84
84
|
print(`\nJob finished: ${data.state}`);
|
|
85
|
-
if (data.artifactsUrl){
|
|
86
|
-
print(`Artifacts: ${data.artifactsUrl}`);
|
|
87
|
-
}
|
|
88
85
|
resolveOnce(exitCodeForJobState(data.state));
|
|
89
86
|
}
|
|
90
87
|
}
|