@deeeed/metamask-harness 0.51.0 → 0.51.2
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/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.51.2 - 2026-09-14
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Mobile native builds no longer pass `--no-bundler` to Expo: a Debug configuration starts the bundler regardless, so 0.51.1 left Expo attached to a stray Metro on 8081 and the launch never returned. Instead the build env answers Expo's one `lsof` lookup for the Metro listener from the harness's `metro.pid`; Expo's 350 ms lsof budget is what a busy Mac missed. A reused Metro listener now records its pid too.
|
|
10
|
+
|
|
11
|
+
## 0.51.1 - 2026-09-13
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Mobile native builds run `expo run:ios` / `run:android` with `--no-bundler` (and without `--port`, which Expo refuses next to it): the harness owns Metro on the watcher port, and Expo's post-build port re-check (lsof under a 350 ms budget) aborted a successful 45-minute build on a loaded machine with "Port became busy running another process while the app was compiling".
|
|
16
|
+
- Mobile `verify` waits for the React Native bridge to settle (bounded, best effort) before its live smoke, so a checkout is no longer reported not ready when the app is still hydrating right after a launch or a fixture unlock. `mm-harness prepare` on a fresh full slot build had failed at the final `verify` step this way while a retry a minute later passed.
|
|
5
17
|
## 0.51.0 - 2026-09-13
|
|
6
18
|
|
|
7
19
|
### Added
|
|
@@ -81,6 +81,46 @@ for _rb in "$SCRIPT_DIR/../shared/activate-repo-ruby.sh" "$SCRIPT_DIR/lib/activa
|
|
|
81
81
|
[ -f "$_rb" ] && { . "$_rb"; break; }
|
|
82
82
|
done
|
|
83
83
|
unset _rb
|
|
84
|
+
# shellcheck disable=SC1091
|
|
85
|
+
for _hp in "$SCRIPT_DIR/../shared/harness-path.sh" "$SCRIPT_DIR/lib/harness-path.sh"; do
|
|
86
|
+
[ -f "$_hp" ] && { . "$_hp"; break; }
|
|
87
|
+
done
|
|
88
|
+
unset _hp
|
|
89
|
+
|
|
90
|
+
# Expo's run:ios / run:android bookkeeping asks lsof which process listens on
|
|
91
|
+
# the Metro port, before and after the native build, under a 350 ms budget.
|
|
92
|
+
# lsof scans every process on the machine, so a busy Mac misses that budget
|
|
93
|
+
# and Expo aborts a finished build with "Port became busy running another
|
|
94
|
+
# process while the app was compiling". The harness started that listener and
|
|
95
|
+
# recorded it in metro.pid: answer that one query from the record and hand
|
|
96
|
+
# every other lsof call to the real binary.
|
|
97
|
+
write_lsof_shim() {
|
|
98
|
+
local dir="$1" real_lsof
|
|
99
|
+
real_lsof="$(command -v lsof 2>/dev/null || true)"
|
|
100
|
+
[ -n "$real_lsof" ] || return 0
|
|
101
|
+
{
|
|
102
|
+
printf '#!/usr/bin/env bash\n'
|
|
103
|
+
printf 'REAL_LSOF=%q\n' "$real_lsof"
|
|
104
|
+
cat <<'SHIM'
|
|
105
|
+
# Exactly Expo's listener query and nothing else. A recycled pid after a Metro
|
|
106
|
+
# death is the only way this can lie, and a dead Metro fails the build anyway.
|
|
107
|
+
if [ $# -eq 4 ] && [ "$1" = "-i:${MM_HARNESS_BUILD_WATCHER_PORT:-}" ] && [ "$2" = "-P" ] && [ "$3" = "-t" ] && [ "$4" = "-sTCP:LISTEN" ] \
|
|
108
|
+
&& [ -f "${MM_HARNESS_METRO_PID_FILE:-/nonexistent}" ]; then
|
|
109
|
+
pid="$(cat "$MM_HARNESS_METRO_PID_FILE" 2>/dev/null)"
|
|
110
|
+
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then printf '%s\n' "$pid"; exit 0; fi
|
|
111
|
+
fi
|
|
112
|
+
exec "$REAL_LSOF" "$@"
|
|
113
|
+
SHIM
|
|
114
|
+
} > "$dir/lsof"
|
|
115
|
+
chmod +x "$dir/lsof"
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
metro_pid_file() {
|
|
119
|
+
command -v recipe_runtime_dir >/dev/null 2>&1 || return 1
|
|
120
|
+
local runtime
|
|
121
|
+
runtime="$(recipe_runtime_dir)" || return 1
|
|
122
|
+
printf '%s/%s/metro.pid' "$TARGET" "$runtime"
|
|
123
|
+
}
|
|
84
124
|
|
|
85
125
|
# --- iOS helpers --------------------------------------------------------------
|
|
86
126
|
|
|
@@ -90,7 +130,7 @@ ios_app_installed() {
|
|
|
90
130
|
}
|
|
91
131
|
|
|
92
132
|
run_ios_native_build() (
|
|
93
|
-
local sim_target="$1" bundle_id="$2" reason="$3" build_env="" build_script="" build_type=""
|
|
133
|
+
local sim_target="$1" bundle_id="$2" reason="$3" build_env="" build_script="" build_type="" shim_dir=""
|
|
94
134
|
case "$bundle_id" in
|
|
95
135
|
io.metamask.MetaMask|io.metamask) build_script="start:ios"; build_type="main" ;;
|
|
96
136
|
io.metamask.MetaMask-Flask) build_script="start:ios:flask"; build_type="flask" ;;
|
|
@@ -102,11 +142,15 @@ run_ios_native_build() (
|
|
|
102
142
|
printf '%s; installing with yarn %s (WATCHER_PORT=%s)\n' "$reason" "$build_script" "$PORT" >&2
|
|
103
143
|
build_env="$(mktemp "${TMPDIR:-/tmp}/mm-harness-ios-build-env.XXXXXX")" || return 1
|
|
104
144
|
chmod 600 "$build_env" || { rm -f "$build_env"; return 1; }
|
|
105
|
-
|
|
145
|
+
shim_dir="$(mktemp -d "${TMPDIR:-/tmp}/mm-harness-build-shim.XXXXXX")" || { rm -f "$build_env"; return 1; }
|
|
146
|
+
trap 'rm -rf "$build_env" "$shim_dir"' EXIT HUP INT TERM
|
|
147
|
+
write_lsof_shim "$shim_dir"
|
|
106
148
|
{
|
|
107
149
|
printf 'export MM_HARNESS_BUILD_WATCHER_PORT=%q\n' "$PORT"
|
|
108
150
|
printf 'export MM_HARNESS_BUILD_IOS_SIMULATOR=%q\n' "$sim_target"
|
|
109
151
|
printf 'export MM_HARNESS_BUILD_TYPE=%q\n' "$build_type"
|
|
152
|
+
printf 'export MM_HARNESS_METRO_PID_FILE=%q\n' "$(metro_pid_file || true)"
|
|
153
|
+
printf 'export PATH=%q:"$PATH"\n' "$shim_dir"
|
|
110
154
|
cat <<'BUILD_ENV'
|
|
111
155
|
mm_harness_restore_build_target() {
|
|
112
156
|
export WATCHER_PORT="$MM_HARNESS_BUILD_WATCHER_PORT"
|
|
@@ -281,7 +325,7 @@ android_app_installed() {
|
|
|
281
325
|
}
|
|
282
326
|
|
|
283
327
|
run_android_native_build() (
|
|
284
|
-
local serial="$1" expo_device="$2" pkg="$3" reason="$4" build_env="" build_script=""
|
|
328
|
+
local serial="$1" expo_device="$2" pkg="$3" reason="$4" build_env="" build_script="" shim_dir=""
|
|
285
329
|
case "$pkg" in
|
|
286
330
|
io.metamask) build_script="start:android" ;;
|
|
287
331
|
io.metamask.flask) build_script="start:android:flask" ;;
|
|
@@ -293,11 +337,15 @@ run_android_native_build() (
|
|
|
293
337
|
printf '%s; installing with yarn %s (WATCHER_PORT=%s)\n' "$reason" "$build_script" "$PORT" >&2
|
|
294
338
|
build_env="$(mktemp "${TMPDIR:-/tmp}/mm-harness-android-build-env.XXXXXX")" || return 1
|
|
295
339
|
chmod 600 "$build_env" || { rm -f "$build_env"; return 1; }
|
|
296
|
-
|
|
340
|
+
shim_dir="$(mktemp -d "${TMPDIR:-/tmp}/mm-harness-build-shim.XXXXXX")" || { rm -f "$build_env"; return 1; }
|
|
341
|
+
trap 'rm -rf "$build_env" "$shim_dir"' EXIT HUP INT TERM
|
|
342
|
+
write_lsof_shim "$shim_dir"
|
|
297
343
|
{
|
|
298
344
|
printf 'export MM_HARNESS_BUILD_ANDROID_SERIAL=%q\n' "$serial"
|
|
299
345
|
printf 'export MM_HARNESS_BUILD_ANDROID_EXPO_DEVICE=%q\n' "$expo_device"
|
|
300
346
|
printf 'export MM_HARNESS_BUILD_WATCHER_PORT=%q\n' "$PORT"
|
|
347
|
+
printf 'export MM_HARNESS_METRO_PID_FILE=%q\n' "$(metro_pid_file || true)"
|
|
348
|
+
printf 'export PATH=%q:"$PATH"\n' "$shim_dir"
|
|
301
349
|
cat <<'BUILD_ENV'
|
|
302
350
|
mm_harness_restore_android_build_target() {
|
|
303
351
|
export WATCHER_PORT="$MM_HARNESS_BUILD_WATCHER_PORT"
|
|
@@ -218,6 +218,12 @@ if metro_ready; then
|
|
|
218
218
|
rm -f "$PID_FILE"
|
|
219
219
|
elif metro_listener_valid; then
|
|
220
220
|
printf 'Metro already running and valid on port %s\n' "$PORT" >&2
|
|
221
|
+
# A reused listener still needs its record: the native build answers
|
|
222
|
+
# Expo's port lookup from metro.pid.
|
|
223
|
+
if [ ! -f "$PID_FILE" ]; then
|
|
224
|
+
lsof -nP -iTCP:"$PORT" -sTCP:LISTEN -t 2>/dev/null | head -1 > "$PID_FILE" || true
|
|
225
|
+
[ -s "$PID_FILE" ] || rm -f "$PID_FILE"
|
|
226
|
+
fi
|
|
221
227
|
exit 0
|
|
222
228
|
else
|
|
223
229
|
stop_metro_listener || exit 1
|
|
@@ -414,6 +414,30 @@ if [ "$STATIC_ONLY" = false ]; then
|
|
|
414
414
|
|
|
415
415
|
port_holder_json "$port" > "$ARTIFACTS/logs/port-holder.json"
|
|
416
416
|
|
|
417
|
+
# Right after a launch or a fixture unlock the app's JS thread can stay busy
|
|
418
|
+
# for a while (account hydration); a single CDP probe then times out although
|
|
419
|
+
# the runtime is healthy. When Metro holds the port, let wait-for-bridge
|
|
420
|
+
# absorb that settle before the smoke. Best effort and bounded: the smoke
|
|
421
|
+
# below is the check that counts. The installed overlay carries only this
|
|
422
|
+
# script, so the waiter is resolved from the runner source it was installed
|
|
423
|
+
# from.
|
|
424
|
+
if [ "$status" != "fail" ] && node -e 'process.exit(JSON.parse(require("fs").readFileSync(process.argv[1], "utf8")).listening ? 0 : 1)' "$ARTIFACTS/logs/port-holder.json" 2>/dev/null; then
|
|
425
|
+
wait_sh=""
|
|
426
|
+
for candidate in "$SCRIPT_DIR/wait-for-bridge.sh" "$(cat "$HARNESS_DIR/runner/.runner-source" 2>/dev/null || true)/adapters/mobile/wait-for-bridge.sh"; do
|
|
427
|
+
[ -f "$candidate" ] && { wait_sh="$candidate"; break; }
|
|
428
|
+
done
|
|
429
|
+
if [ -z "$wait_sh" ]; then
|
|
430
|
+
add_note "Mobile bridge settle skipped: wait-for-bridge.sh not found beside verify.sh or under runner/.runner-source; reinstall the runner."
|
|
431
|
+
elif MOBILE_BRIDGE_READY_TIMEOUT_MS="${MOBILE_BRIDGE_READY_TIMEOUT_MS:-90000}" \
|
|
432
|
+
MOBILE_BRIDGE_UNRESPONSIVE_GRACE_MS="${MOBILE_BRIDGE_UNRESPONSIVE_GRACE_MS:-90000}" \
|
|
433
|
+
bash "$wait_sh" --target "$TARGET" --port "$port" --platform "$PLATFORM" \
|
|
434
|
+
> "$ARTIFACTS/logs/wait-for-bridge.log" 2>&1; then
|
|
435
|
+
add_note "Mobile bridge settled before the live smoke (logs/wait-for-bridge.log)."
|
|
436
|
+
else
|
|
437
|
+
add_note "Mobile bridge settle did not complete (waiter exit $?); running the live smoke anyway (logs/wait-for-bridge.log)."
|
|
438
|
+
fi
|
|
439
|
+
fi
|
|
440
|
+
|
|
417
441
|
cat > "$ARTIFACTS/mobile-v1-live-smoke.recipe.json" <<'JSON'
|
|
418
442
|
{
|
|
419
443
|
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|