Files
WerkoutIOS/scripts/hardware/watch_disconnect_hardware_pass.sh

133 lines
4.6 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
cd "$ROOT_DIR"
TS="$(date -u +"%Y%m%dT%H%M%SZ")"
OUT_DIR="${TMPDIR:-/tmp}/werkout_watch_hardware_pass_${TS}"
mkdir -p "$OUT_DIR"
export SWIFTPM_MODULECACHE_OVERRIDE="${TMPDIR:-/tmp}/werkout_swiftpm_module_cache"
export CLANG_MODULE_CACHE_PATH="${TMPDIR:-/tmp}/werkout_clang_module_cache"
export XDG_CACHE_HOME="${TMPDIR:-/tmp}/werkout_xdg_cache"
mkdir -p "$SWIFTPM_MODULECACHE_OVERRIDE" "$CLANG_MODULE_CACHE_PATH" "$XDG_CACHE_HOME"
PKG_CACHE_DIR="$OUT_DIR/package_cache"
PKG_CLONES_DIR="$OUT_DIR/source_packages"
XCODE_TEMP_HOME="$OUT_DIR/home"
mkdir -p "$PKG_CACHE_DIR" "$PKG_CLONES_DIR" "$XCODE_TEMP_HOME"
IOS_DEST_FILE="$OUT_DIR/ios_showdestinations.txt"
WATCH_DEST_FILE="$OUT_DIR/watch_showdestinations.txt"
HOME="$XCODE_TEMP_HOME" xcodebuild -project iphone/Werkout_ios.xcodeproj \
-scheme 'Werkout_ios' \
-disableAutomaticPackageResolution \
-clonedSourcePackagesDirPath "$PKG_CLONES_DIR" \
-packageCachePath "$PKG_CACHE_DIR" \
-showdestinations > "$IOS_DEST_FILE" 2>&1 || {
echo "Failed to query iOS destinations."
echo "Inspect: $IOS_DEST_FILE"
tail -n 80 "$IOS_DEST_FILE" || true
exit 3
}
HOME="$XCODE_TEMP_HOME" xcodebuild -project iphone/Werkout_ios.xcodeproj \
-scheme 'Werkout_watch Watch App' \
-disableAutomaticPackageResolution \
-clonedSourcePackagesDirPath "$PKG_CLONES_DIR" \
-packageCachePath "$PKG_CACHE_DIR" \
-showdestinations > "$WATCH_DEST_FILE" 2>&1 || {
echo "Failed to query watchOS destinations."
echo "Inspect: $WATCH_DEST_FILE"
tail -n 80 "$WATCH_DEST_FILE" || true
exit 3
}
IOS_ELIGIBLE_LINE="$(awk '/Available destinations/{flag=1;next}/Ineligible destinations/{flag=0}flag' "$IOS_DEST_FILE" \
| rg "platform:iOS, arch:arm64, id:" \
| rg -v "placeholder" \
| head -n 1 || true)"
WATCH_ELIGIBLE_LINE="$(awk '/Available destinations/{flag=1;next}/Ineligible destinations/{flag=0}flag' "$WATCH_DEST_FILE" \
| rg "platform:watchOS, arch:" \
| rg -v "undefined_arch|placeholder" \
| head -n 1 || true)"
if [[ -z "$IOS_ELIGIBLE_LINE" ]]; then
echo "No eligible physical iOS destination found."
echo "Inspect: $IOS_DEST_FILE"
exit 2
fi
if [[ -z "$WATCH_ELIGIBLE_LINE" ]]; then
echo "No eligible physical watchOS destination found."
echo "Inspect: $WATCH_DEST_FILE"
exit 2
fi
IOS_ID="$(echo "$IOS_ELIGIBLE_LINE" | sed -E 's/.*id:([^,]+),.*/\1/')"
WATCH_ID="$(echo "$WATCH_ELIGIBLE_LINE" | sed -E 's/.*id:([^,]+),.*/\1/')"
echo "Using iOS destination: $IOS_ELIGIBLE_LINE"
echo "Using watchOS destination: $WATCH_ELIGIBLE_LINE"
echo
echo "Preflight compile for selected hardware destinations..."
set -o pipefail
HOME="$XCODE_TEMP_HOME" xcodebuild -project iphone/Werkout_ios.xcodeproj \
-scheme 'Werkout_ios' \
-configuration Debug \
-destination "id=$IOS_ID" \
-disableAutomaticPackageResolution \
-clonedSourcePackagesDirPath "$PKG_CLONES_DIR" \
-packageCachePath "$PKG_CACHE_DIR" \
CODE_SIGNING_ALLOWED=NO \
build > "$OUT_DIR/ios_hardware_build.log" 2>&1
HOME="$XCODE_TEMP_HOME" xcodebuild -project iphone/Werkout_ios.xcodeproj \
-scheme 'Werkout_watch Watch App' \
-configuration Debug \
-destination "id=$WATCH_ID" \
-disableAutomaticPackageResolution \
-clonedSourcePackagesDirPath "$PKG_CLONES_DIR" \
-packageCachePath "$PKG_CACHE_DIR" \
CODE_SIGNING_ALLOWED=NO \
build > "$OUT_DIR/watch_hardware_build.log" 2>&1
cat > "$OUT_DIR/manual_disconnect_reconnect_checklist.md" <<'EOF'
# Manual Hardware Disconnect/Reconnect Pass
1. Launch iOS app on the selected physical iPhone/iPad.
2. Launch watch app on the paired physical Apple Watch.
3. Start a workout from iOS and confirm watch receives first exercise.
4. Disconnect watch from phone transport:
- Disable Bluetooth on iPhone for 30 seconds, or
- Enable Airplane Mode on watch for 30 seconds.
5. While disconnected, trigger 5+ state changes on phone:
- Next/previous exercise
- Pause/resume
- Complete workout
6. Reconnect transport.
7. Verify on watch:
- Latest state is applied.
- No crash.
- No infinite stale replay loop.
8. Repeat with two cycles of disconnect/reconnect in same workout.
Pass criteria:
- Watch converges to current exercise/time state after each reconnect.
- Queue replay does not exceed recent max-capped payload behavior.
- Completion payload arrives exactly once.
Log capture suggestion:
log stream --style compact --predicate '(subsystem == "com.werkout.ios" || subsystem == "com.werkout.watch")'
EOF
echo
echo "Hardware preflight complete."
echo "Artifacts: $OUT_DIR"
echo "Runbook: $OUT_DIR/manual_disconnect_reconnect_checklist.md"