@osfactory/har 0.61.2 → 0.62.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/index.js +102 -40
- package/dist/templates/har-boilerplate/agent-slot.sh +23 -0
- package/dist/templates/har-boilerplate/provision-toolchain.sh +258 -19
- package/dist/templates/har-boilerplate/verify.sh +6 -19
- package/dist/templates/har-boilerplate-cli/agent-slot.sh +23 -0
- package/dist/templates/har-boilerplate-cli/provision-toolchain.sh +258 -19
- package/dist/templates/har-boilerplate-cli/verify.sh +4 -10
- package/dist/templates/har-boilerplate-ios/agent-slot.sh +23 -0
- package/dist/templates/har-boilerplate-ios/provision-toolchain.sh +258 -19
- package/dist/templates/har-boilerplate-ios/verify.sh +4 -10
- package/dist/templates/runtime-bundles/shared-kernel/provision-toolchain.sh +258 -19
- package/package.json +1 -1
|
@@ -758,6 +758,29 @@ escape_step_output() {
|
|
|
758
758
|
printf '%s' "$1" | node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const s=d.trim().split('\n').slice(0,50).join('\n');process.stdout.write(JSON.stringify(s))})" 2>/dev/null || echo '""'
|
|
759
759
|
}
|
|
760
760
|
|
|
761
|
+
# Append one verify.sh step to RESULTS_JSON (caller global).
|
|
762
|
+
# Passing steps omit output — it already appeared as ✓ on stderr.
|
|
763
|
+
record_step_result() {
|
|
764
|
+
local name="$1"
|
|
765
|
+
local pass_bool="$2"
|
|
766
|
+
local elapsed="$3"
|
|
767
|
+
local output="${4:-}"
|
|
768
|
+
local step_json
|
|
769
|
+
if [ "$pass_bool" = "true" ]; then
|
|
770
|
+
step_json=$(NAME="$name" MS="$elapsed" node -e 'process.stdout.write(JSON.stringify({name:process.env.NAME,pass:true,ms:Number(process.env.MS)}))' 2>/dev/null) || return 0
|
|
771
|
+
else
|
|
772
|
+
local escaped
|
|
773
|
+
escaped=$(escape_step_output "$output")
|
|
774
|
+
step_json=$(NAME="$name" MS="$elapsed" node -e "process.stdout.write(JSON.stringify({name:process.env.NAME,pass:false,ms:Number(process.env.MS),output:$escaped}))" 2>/dev/null) || return 0
|
|
775
|
+
fi
|
|
776
|
+
RESULTS_JSON=$(echo "$RESULTS_JSON" | node -e "
|
|
777
|
+
const fs = require('fs');
|
|
778
|
+
const arr = JSON.parse(fs.readFileSync('/dev/stdin','utf8'));
|
|
779
|
+
arr.push($step_json);
|
|
780
|
+
process.stdout.write(JSON.stringify(arr));
|
|
781
|
+
" 2>/dev/null || echo "$RESULTS_JSON")
|
|
782
|
+
}
|
|
783
|
+
|
|
761
784
|
# Emit "<id>\t<command>" for each registered stage listed in stages.json
|
|
762
785
|
# verificationStages (used by verify --full). Ids without a matching registered
|
|
763
786
|
# stage are inline verify.sh steps and skipped here; lifecycle stages
|
|
@@ -228,52 +228,291 @@ provision_node() {
|
|
|
228
228
|
append_path_prefix "$dir/node_modules/.bin"
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
+
# ── Python interpreter helpers ────────────────────────────────────────────────
|
|
232
|
+
# Resolve the project Python (requires-python, .python-version, uv) instead of
|
|
233
|
+
# blindly using PATH python3.
|
|
234
|
+
|
|
235
|
+
har_python_version_from_bin() {
|
|
236
|
+
local bin="$1"
|
|
237
|
+
"$bin" -c 'import sys; print(".".join(map(str, sys.version_info[:3])))' 2>/dev/null \
|
|
238
|
+
| tr -d '[:space:]'
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
har_python_version_to_sortable() {
|
|
242
|
+
local v="${1#python}"
|
|
243
|
+
v="${v#v}"
|
|
244
|
+
local major=0 minor=0 patch=0
|
|
245
|
+
IFS='.' read -r major minor patch _ <<< "$v"
|
|
246
|
+
major=${major:-0}
|
|
247
|
+
minor=${minor:-0}
|
|
248
|
+
patch=${patch:-0}
|
|
249
|
+
printf '%03d%03d%03d' "$major" "$minor" "$patch"
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
har_python_version_ge() {
|
|
253
|
+
local a b
|
|
254
|
+
a="$(har_python_version_to_sortable "$1")"
|
|
255
|
+
b="$(har_python_version_to_sortable "$2")"
|
|
256
|
+
[ "$a" -ge "$b" ]
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
har_python_requires_minimum() {
|
|
260
|
+
local spec="$1"
|
|
261
|
+
local ver=""
|
|
262
|
+
|
|
263
|
+
[ -n "$spec" ] || return 1
|
|
264
|
+
|
|
265
|
+
ver="$(printf '%s' "$spec" | sed -n \
|
|
266
|
+
-e 's/.*>=\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/p' \
|
|
267
|
+
-e 's/.*~=\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/p' \
|
|
268
|
+
-e 's/.*==\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/p' \
|
|
269
|
+
| head -1)"
|
|
270
|
+
|
|
271
|
+
if [ -z "$ver" ]; then
|
|
272
|
+
ver="$(printf '%s' "$spec" | sed -n 's/^\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/p')"
|
|
273
|
+
fi
|
|
274
|
+
|
|
275
|
+
[ -n "$ver" ] && echo "$ver"
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
har_python_read_dot_version() {
|
|
279
|
+
local dir="$1"
|
|
280
|
+
[ -f "$dir/.python-version" ] || return 1
|
|
281
|
+
head -1 "$dir/.python-version" | tr -d '[:space:]'
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
har_python_read_requires_spec() {
|
|
285
|
+
local dir="$1"
|
|
286
|
+
local spec=""
|
|
287
|
+
|
|
288
|
+
if [ -f "$dir/pyproject.toml" ]; then
|
|
289
|
+
spec="$(sed -n 's/^[[:space:]]*requires-python[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/p' \
|
|
290
|
+
"$dir/pyproject.toml" | head -1)"
|
|
291
|
+
fi
|
|
292
|
+
if [ -z "$spec" ] && [ -f "$dir/setup.cfg" ]; then
|
|
293
|
+
spec="$(sed -n '/^\[options\]/,/^\[/ s/^python_requires[[:space:]]*=[[:space:]]*\(.*\)/\1/p' \
|
|
294
|
+
"$dir/setup.cfg" | head -1 | tr -d ' "')"
|
|
295
|
+
fi
|
|
296
|
+
[ -n "$spec" ] && echo "$spec"
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
har_python_project_minimum() {
|
|
300
|
+
local dir="$1"
|
|
301
|
+
local req_min="" dot_ver="" higher=""
|
|
302
|
+
|
|
303
|
+
req_min="$(har_python_requires_minimum "$(har_python_read_requires_spec "$dir" || true)" || true)"
|
|
304
|
+
dot_ver="$(har_python_read_dot_version "$dir" || true)"
|
|
305
|
+
if [ -n "$dot_ver" ]; then
|
|
306
|
+
dot_ver="$(printf '%s' "$dot_ver" | sed 's/^v//; s/^\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/')"
|
|
307
|
+
fi
|
|
308
|
+
|
|
309
|
+
if [ -n "$req_min" ] && [ -n "$dot_ver" ]; then
|
|
310
|
+
if har_python_version_ge "$dot_ver" "$req_min"; then
|
|
311
|
+
higher="$dot_ver"
|
|
312
|
+
else
|
|
313
|
+
higher="$req_min"
|
|
314
|
+
fi
|
|
315
|
+
elif [ -n "$req_min" ]; then
|
|
316
|
+
higher="$req_min"
|
|
317
|
+
elif [ -n "$dot_ver" ]; then
|
|
318
|
+
higher="$dot_ver"
|
|
319
|
+
fi
|
|
320
|
+
|
|
321
|
+
[ -n "$higher" ] && echo "$higher"
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
har_python_is_uv_project() {
|
|
325
|
+
local dir="$1"
|
|
326
|
+
[ -f "$dir/uv.lock" ] && return 0
|
|
327
|
+
[ -f "$dir/pyproject.toml" ] && grep -q '^\[tool\.uv\]' "$dir/pyproject.toml" 2>/dev/null
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
har_python_uv_find() {
|
|
331
|
+
local dir="$1"
|
|
332
|
+
local request="${2:-}"
|
|
333
|
+
|
|
334
|
+
command -v uv >/dev/null 2>&1 || return 1
|
|
335
|
+
if [ -n "$request" ]; then
|
|
336
|
+
(cd "$dir" && uv python find "$request" 2>/dev/null)
|
|
337
|
+
else
|
|
338
|
+
(cd "$dir" && uv python find 2>/dev/null)
|
|
339
|
+
fi
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
har_python_resolve_interpreter() {
|
|
343
|
+
local dir="$1"
|
|
344
|
+
local minimum="${2:-}"
|
|
345
|
+
local found=""
|
|
346
|
+
|
|
347
|
+
if har_python_is_uv_project "$dir"; then
|
|
348
|
+
found="$(har_python_uv_find "$dir" "$minimum" || true)"
|
|
349
|
+
if [ -n "$found" ] && [ -x "$found" ]; then
|
|
350
|
+
echo "$found"
|
|
351
|
+
return 0
|
|
352
|
+
fi
|
|
353
|
+
fi
|
|
354
|
+
|
|
355
|
+
if [ -f "$dir/.python-version" ]; then
|
|
356
|
+
found="$(har_python_uv_find "$dir" "$(har_python_read_dot_version "$dir")" || true)"
|
|
357
|
+
if [ -n "$found" ] && [ -x "$found" ]; then
|
|
358
|
+
echo "$found"
|
|
359
|
+
return 0
|
|
360
|
+
fi
|
|
361
|
+
if command -v pyenv >/dev/null 2>&1; then
|
|
362
|
+
found="$(cd "$dir" && pyenv which python 2>/dev/null || true)"
|
|
363
|
+
if [ -n "$found" ] && [ -x "$found" ]; then
|
|
364
|
+
echo "$found"
|
|
365
|
+
return 0
|
|
366
|
+
fi
|
|
367
|
+
fi
|
|
368
|
+
fi
|
|
369
|
+
|
|
370
|
+
if [ -n "$minimum" ]; then
|
|
371
|
+
found="$(har_python_uv_find "$dir" "$minimum" || true)"
|
|
372
|
+
if [ -n "$found" ] && [ -x "$found" ]; then
|
|
373
|
+
echo "$found"
|
|
374
|
+
return 0
|
|
375
|
+
fi
|
|
376
|
+
fi
|
|
377
|
+
|
|
378
|
+
if command -v python3 >/dev/null 2>&1; then
|
|
379
|
+
local sys_py sys_ver=""
|
|
380
|
+
sys_py="$(command -v python3)"
|
|
381
|
+
if [ -z "$minimum" ]; then
|
|
382
|
+
echo "$sys_py"
|
|
383
|
+
return 0
|
|
384
|
+
fi
|
|
385
|
+
sys_ver="$(har_python_version_from_bin "$sys_py")"
|
|
386
|
+
if [ -n "$sys_ver" ] && har_python_version_ge "$sys_ver" "$minimum"; then
|
|
387
|
+
echo "$sys_py"
|
|
388
|
+
return 0
|
|
389
|
+
fi
|
|
390
|
+
echo "$sys_py"
|
|
391
|
+
return 0
|
|
392
|
+
fi
|
|
393
|
+
|
|
394
|
+
return 1
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
har_python_warn_if_below_minimum() {
|
|
398
|
+
local bin="$1"
|
|
399
|
+
local minimum="$2"
|
|
400
|
+
local actual=""
|
|
401
|
+
|
|
402
|
+
[ -n "$minimum" ] || return 0
|
|
403
|
+
actual="$(har_python_version_from_bin "$bin")"
|
|
404
|
+
[ -n "$actual" ] || return 0
|
|
405
|
+
if ! har_python_version_ge "$actual" "$minimum"; then
|
|
406
|
+
pt_log "WARNING: resolved Python ${actual} is older than required ${minimum} (requires-python / .python-version)"
|
|
407
|
+
fi
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
har_python_create_venv() {
|
|
411
|
+
local dir="$1"
|
|
412
|
+
local venv_dir="$2"
|
|
413
|
+
local interpreter="$3"
|
|
414
|
+
local venv_rel="${venv_dir#"$dir"/}"
|
|
415
|
+
|
|
416
|
+
if har_python_is_uv_project "$dir" && command -v uv >/dev/null 2>&1; then
|
|
417
|
+
pt_log "Creating Python venv with uv at ${venv_rel}..."
|
|
418
|
+
if (cd "$dir" && uv venv --python "$interpreter" "$venv_dir" 2>/dev/null) \
|
|
419
|
+
|| (cd "$dir" && uv venv "$venv_dir" 2>/dev/null); then
|
|
420
|
+
return 0
|
|
421
|
+
fi
|
|
422
|
+
pt_log "uv venv failed — falling back to ${interpreter} -m venv"
|
|
423
|
+
fi
|
|
424
|
+
|
|
425
|
+
pt_log "Creating Python venv at ${venv_rel}..."
|
|
426
|
+
"$interpreter" -m venv "$venv_dir"
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
har_python_install_deps() {
|
|
430
|
+
local dir="$1"
|
|
431
|
+
local venv_dir="$2"
|
|
432
|
+
|
|
433
|
+
if har_python_is_uv_project "$dir" && command -v uv >/dev/null 2>&1; then
|
|
434
|
+
pt_log "Syncing Python dependencies with uv..."
|
|
435
|
+
if (cd "$dir" && UV_PROJECT_ENVIRONMENT="$venv_dir" uv sync --quiet 2>/dev/null); then
|
|
436
|
+
return 0
|
|
437
|
+
fi
|
|
438
|
+
if (cd "$dir" && uv sync --quiet 2>/dev/null); then
|
|
439
|
+
return 0
|
|
440
|
+
fi
|
|
441
|
+
pt_log "uv sync failed — falling back to pip"
|
|
442
|
+
return 1
|
|
443
|
+
fi
|
|
444
|
+
return 1
|
|
445
|
+
}
|
|
446
|
+
|
|
231
447
|
provision_python() {
|
|
232
448
|
local dir="$1"
|
|
233
449
|
local venv_rel="${HARNESS_PYTHON_VENV_DIR:-.har/venv}"
|
|
234
450
|
local venv_dir="$dir/$venv_rel"
|
|
235
|
-
local python_bin="
|
|
451
|
+
local python_bin=""
|
|
452
|
+
local interpreter=""
|
|
453
|
+
local project_min=""
|
|
454
|
+
|
|
455
|
+
project_min="$(har_python_project_minimum "$dir" || true)"
|
|
456
|
+
interpreter="$(har_python_resolve_interpreter "$dir" "$project_min" || true)"
|
|
236
457
|
|
|
237
|
-
if ! command -v
|
|
238
|
-
pt_log "
|
|
458
|
+
if [ -z "$interpreter" ] || ! command -v "$interpreter" >/dev/null 2>&1; then
|
|
459
|
+
pt_log "No suitable Python interpreter found — skipping venv provisioning"
|
|
239
460
|
append_env "HARNESS_ECOSYSTEM" "python"
|
|
240
461
|
append_env "PYTHON_BIN" "${PYTHON_BIN:-python3}"
|
|
241
462
|
return
|
|
242
463
|
fi
|
|
243
464
|
|
|
465
|
+
if [ -n "$project_min" ]; then
|
|
466
|
+
har_python_warn_if_below_minimum "$interpreter" "$project_min"
|
|
467
|
+
fi
|
|
468
|
+
|
|
469
|
+
if [ -d "$venv_dir" ] && [ -x "$venv_dir/bin/python" ] && [ -n "$project_min" ]; then
|
|
470
|
+
local venv_ver=""
|
|
471
|
+
venv_ver="$(har_python_version_from_bin "$venv_dir/bin/python")"
|
|
472
|
+
if [ -n "$venv_ver" ] && ! har_python_version_ge "$venv_ver" "$project_min"; then
|
|
473
|
+
pt_log "Existing venv Python ${venv_ver} is older than required ${project_min} — recreating..."
|
|
474
|
+
rm -rf "$venv_dir"
|
|
475
|
+
fi
|
|
476
|
+
fi
|
|
477
|
+
|
|
244
478
|
if [ ! -d "$venv_dir" ]; then
|
|
245
|
-
|
|
246
|
-
if ! python3 -m venv "$venv_dir"; then
|
|
479
|
+
if ! har_python_create_venv "$dir" "$venv_dir" "$interpreter"; then
|
|
247
480
|
rm -rf "$venv_dir"
|
|
248
|
-
pt_log "
|
|
481
|
+
pt_log "venv creation failed (on Debian/Ubuntu install python3-venv) — using resolved interpreter"
|
|
249
482
|
append_env "HARNESS_ECOSYSTEM" "python"
|
|
250
|
-
append_env "PYTHON_BIN" "$
|
|
483
|
+
append_env "PYTHON_BIN" "$interpreter"
|
|
251
484
|
return
|
|
252
485
|
fi
|
|
253
486
|
fi
|
|
254
487
|
|
|
255
488
|
if [ ! -x "$venv_dir/bin/python" ]; then
|
|
256
|
-
pt_log "Python venv at $venv_rel is missing or broken — using
|
|
489
|
+
pt_log "Python venv at $venv_rel is missing or broken — using resolved interpreter"
|
|
257
490
|
append_env "HARNESS_ECOSYSTEM" "python"
|
|
258
|
-
append_env "PYTHON_BIN" "$
|
|
491
|
+
append_env "PYTHON_BIN" "$interpreter"
|
|
259
492
|
return
|
|
260
493
|
fi
|
|
261
494
|
|
|
262
495
|
python_bin="$venv_dir/bin/python"
|
|
496
|
+
if [ -n "$project_min" ]; then
|
|
497
|
+
har_python_warn_if_below_minimum "$python_bin" "$project_min"
|
|
498
|
+
fi
|
|
499
|
+
|
|
263
500
|
# shellcheck disable=SC1091
|
|
264
501
|
source "$venv_dir/bin/activate"
|
|
265
502
|
|
|
266
503
|
if ! run_install_cmd "$dir"; then
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
504
|
+
if ! har_python_install_deps "$dir" "$venv_dir"; then
|
|
505
|
+
pt_log "Installing Python dependencies..."
|
|
506
|
+
if [ -f "$dir/pyproject.toml" ]; then
|
|
507
|
+
(cd "$dir" && pip install -q -e ".[dev]" 2>/dev/null) || (cd "$dir" && pip install -q -e .)
|
|
508
|
+
elif [ -f "$dir/requirements.txt" ]; then
|
|
509
|
+
(cd "$dir" && pip install -q -r requirements.txt)
|
|
510
|
+
elif [ -f "$dir/setup.py" ] || [ -f "$dir/setup.cfg" ]; then
|
|
511
|
+
(cd "$dir" && pip install -q -e .)
|
|
512
|
+
elif [ -f "$dir/Pipfile" ] && command -v pipenv >/dev/null 2>&1; then
|
|
513
|
+
(cd "$dir" && pipenv install --dev)
|
|
514
|
+
python_bin="$(cd "$dir" && pipenv --py)"
|
|
515
|
+
fi
|
|
277
516
|
fi
|
|
278
517
|
fi
|
|
279
518
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# Verification pipeline for CLI/library repos.
|
|
3
|
-
# Outputs JSON to stdout, human-readable progress to stderr.
|
|
3
|
+
# Outputs JSON to stdout (machine contract), human-readable progress to stderr.
|
|
4
|
+
# Passing steps omit `output`. `har env verify` streams progress only.
|
|
4
5
|
#
|
|
5
6
|
# Usage: ./.har/verify.sh <agent-id> [--full]
|
|
6
7
|
#
|
|
@@ -70,7 +71,7 @@ run_step() {
|
|
|
70
71
|
end=$(now_ms)
|
|
71
72
|
elapsed=$(( end - start ))
|
|
72
73
|
|
|
73
|
-
local pass_bool
|
|
74
|
+
local pass_bool
|
|
74
75
|
if [ "$exit_code" = "0" ]; then
|
|
75
76
|
echo "✓ (${elapsed}ms)" >&2
|
|
76
77
|
pass_bool="true"
|
|
@@ -81,14 +82,7 @@ run_step() {
|
|
|
81
82
|
OVERALL_PASS=false
|
|
82
83
|
fi
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
RESULTS_JSON=$(echo "$RESULTS_JSON" | node -e "
|
|
87
|
-
const fs = require('fs');
|
|
88
|
-
let arr = JSON.parse(fs.readFileSync('/dev/stdin','utf8'));
|
|
89
|
-
arr.push({name:'$name',pass:$pass_bool,ms:$elapsed,output:$step_output_escaped});
|
|
90
|
-
process.stdout.write(JSON.stringify(arr));
|
|
91
|
-
" 2>/dev/null || echo "$RESULTS_JSON")
|
|
85
|
+
record_step_result "$name" "$pass_bool" "$elapsed" "$output"
|
|
92
86
|
|
|
93
87
|
if [ "$pass_bool" = "false" ] && [ -z "$FULL" ]; then
|
|
94
88
|
return 1
|
|
@@ -405,6 +405,29 @@ escape_step_output() {
|
|
|
405
405
|
printf '%s' "$1" | node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const s=d.trim().split('\n').slice(0,50).join('\n');process.stdout.write(JSON.stringify(s))})" 2>/dev/null || echo '""'
|
|
406
406
|
}
|
|
407
407
|
|
|
408
|
+
# Append one verify.sh step to RESULTS_JSON (caller global).
|
|
409
|
+
# Passing steps omit output — it already appeared as ✓ on stderr.
|
|
410
|
+
record_step_result() {
|
|
411
|
+
local name="$1"
|
|
412
|
+
local pass_bool="$2"
|
|
413
|
+
local elapsed="$3"
|
|
414
|
+
local output="${4:-}"
|
|
415
|
+
local step_json
|
|
416
|
+
if [ "$pass_bool" = "true" ]; then
|
|
417
|
+
step_json=$(NAME="$name" MS="$elapsed" node -e 'process.stdout.write(JSON.stringify({name:process.env.NAME,pass:true,ms:Number(process.env.MS)}))' 2>/dev/null) || return 0
|
|
418
|
+
else
|
|
419
|
+
local escaped
|
|
420
|
+
escaped=$(escape_step_output "$output")
|
|
421
|
+
step_json=$(NAME="$name" MS="$elapsed" node -e "process.stdout.write(JSON.stringify({name:process.env.NAME,pass:false,ms:Number(process.env.MS),output:$escaped}))" 2>/dev/null) || return 0
|
|
422
|
+
fi
|
|
423
|
+
RESULTS_JSON=$(echo "$RESULTS_JSON" | node -e "
|
|
424
|
+
const fs = require('fs');
|
|
425
|
+
const arr = JSON.parse(fs.readFileSync('/dev/stdin','utf8'));
|
|
426
|
+
arr.push($step_json);
|
|
427
|
+
process.stdout.write(JSON.stringify(arr));
|
|
428
|
+
" 2>/dev/null || echo "$RESULTS_JSON")
|
|
429
|
+
}
|
|
430
|
+
|
|
408
431
|
# Emit "<id>\t<command>" for each registered stage listed in stages.json
|
|
409
432
|
# verificationStages (used by verify --full). Ids without a matching registered
|
|
410
433
|
# stage are inline verify.sh steps and skipped here; lifecycle stages
|