Add FuelBoard device and IPA helpers
This commit is contained in:
@@ -6,12 +6,14 @@ cd "$(dirname "$0")/.."
|
|||||||
PROJECT="$PWD/FuelBoard.xcodeproj"
|
PROJECT="$PWD/FuelBoard.xcodeproj"
|
||||||
SCHEME="FuelBoard"
|
SCHEME="FuelBoard"
|
||||||
DERIVED_DATA="/tmp/fuelboard-build-ipas"
|
DERIVED_DATA="/tmp/fuelboard-build-ipas"
|
||||||
SERVE_DIR="/tmp/ipa-serve"
|
SERVE_DIR="$PWD/Builds"
|
||||||
FULL_IPA="$SERVE_DIR/FuelBoard-watch.ipa"
|
FULL_IPA="$SERVE_DIR/FuelBoard-watch.ipa"
|
||||||
SIDELOAD_IPA="$SERVE_DIR/FuelBoard-sideload.ipa"
|
SIDELOAD_IPA="$SERVE_DIR/FuelBoard-sideload.ipa"
|
||||||
HOST="192.168.1.131"
|
HOST="192.168.1.131"
|
||||||
PORT="8765"
|
PORT="8765"
|
||||||
|
|
||||||
|
export SERVE_DIR
|
||||||
|
|
||||||
APP_PATH="$DERIVED_DATA/Build/Products/Release-iphoneos/FuelBoard.app"
|
APP_PATH="$DERIVED_DATA/Build/Products/Release-iphoneos/FuelBoard.app"
|
||||||
STAGE_FULL="/tmp/fuelboard-ipa-stage-full"
|
STAGE_FULL="/tmp/fuelboard-ipa-stage-full"
|
||||||
STAGE_SIDELOAD="/tmp/fuelboard-ipa-stage-sideload"
|
STAGE_SIDELOAD="/tmp/fuelboard-ipa-stage-sideload"
|
||||||
@@ -46,7 +48,9 @@ import os, shutil, zipfile
|
|||||||
app = '/tmp/fuelboard-build-ipas/Build/Products/Release-iphoneos/FuelBoard.app'
|
app = '/tmp/fuelboard-build-ipas/Build/Products/Release-iphoneos/FuelBoard.app'
|
||||||
stage = '/tmp/fuelboard-ipa-stage-full'
|
stage = '/tmp/fuelboard-ipa-stage-full'
|
||||||
payload = os.path.join(stage, 'Payload')
|
payload = os.path.join(stage, 'Payload')
|
||||||
out = '/tmp/ipa-serve/FuelBoard-watch.ipa'
|
serve = os.environ['SERVE_DIR']
|
||||||
|
out = os.path.join(serve, 'FuelBoard-watch.ipa')
|
||||||
|
os.makedirs(serve, exist_ok=True)
|
||||||
if os.path.exists(stage):
|
if os.path.exists(stage):
|
||||||
shutil.rmtree(stage)
|
shutil.rmtree(stage)
|
||||||
os.makedirs(payload, exist_ok=True)
|
os.makedirs(payload, exist_ok=True)
|
||||||
@@ -73,7 +77,8 @@ import os, shutil, zipfile
|
|||||||
app = '/tmp/fuelboard-build-ipas/Build/Products/Release-iphoneos/FuelBoard.app'
|
app = '/tmp/fuelboard-build-ipas/Build/Products/Release-iphoneos/FuelBoard.app'
|
||||||
stage = '/tmp/fuelboard-ipa-stage-sideload'
|
stage = '/tmp/fuelboard-ipa-stage-sideload'
|
||||||
payload = os.path.join(stage, 'Payload')
|
payload = os.path.join(stage, 'Payload')
|
||||||
out = '/tmp/ipa-serve/FuelBoard-sideload.ipa'
|
serve = os.environ['SERVE_DIR']
|
||||||
|
out = os.path.join(serve, 'FuelBoard-sideload.ipa')
|
||||||
if os.path.exists(stage):
|
if os.path.exists(stage):
|
||||||
shutil.rmtree(stage)
|
shutil.rmtree(stage)
|
||||||
os.makedirs(payload, exist_ok=True)
|
os.makedirs(payload, exist_ok=True)
|
||||||
@@ -117,6 +122,7 @@ for name, path in paths.items():
|
|||||||
PY
|
PY
|
||||||
|
|
||||||
echo "==> URLs"
|
echo "==> URLs"
|
||||||
|
echo "Serving: ipa-serve # in $(basename "$PWD"), or: ipa-serve fuelboard"
|
||||||
echo "Watch-capable IPA: http://$HOST:$PORT/FuelBoard-watch.ipa"
|
echo "Watch-capable IPA: http://$HOST:$PORT/FuelBoard-watch.ipa"
|
||||||
echo "Sideload-safe IPA: http://$HOST:$PORT/FuelBoard-sideload.ipa"
|
echo "Sideload-safe IPA: http://$HOST:$PORT/FuelBoard-sideload.ipa"
|
||||||
echo "Xcode log: /tmp/fuelboard-build-ipas-xcodebuild.log"
|
echo "Xcode log: /tmp/fuelboard-build-ipas-xcodebuild.log"
|
||||||
|
|||||||
Executable
+73
@@ -0,0 +1,73 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# install.sh — build FuelBoard dev-signed and install straight to a paired iPhone.
|
||||||
|
#
|
||||||
|
# Streamlined flow (single command):
|
||||||
|
# ./scripts/install.sh # build + install + launch on the first paired iPhone
|
||||||
|
# ./scripts/install.sh --device UDID # target a specific device (xcrun devicectl list devices)
|
||||||
|
# ./scripts/install.sh --no-launch # install but don't auto-launch
|
||||||
|
#
|
||||||
|
# Why this exists: sideloading (SideStore/AltStore) got replaced on 2026-09-25 by a
|
||||||
|
# proper dev-signed install via devicectl — the phone is paired, so no LAN server,
|
||||||
|
# no delete/reinstall dance, and the installed app is a real signed build. The
|
||||||
|
# Release config targets the device (not the simulator) and reuses Xcode automatic
|
||||||
|
# signing with the project's DEVELOPMENT_TEAM.
|
||||||
|
#
|
||||||
|
# Requires: a paired + unlocked iPhone (xcrun devicectl list devices), and the
|
||||||
|
# Apple Development identity in the keychain.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
|
PROJECT="$PWD/FuelBoard.xcodeproj"
|
||||||
|
SCHEME="FuelBoard"
|
||||||
|
DERIVED_DATA="/tmp/fuelboard-devinstall"
|
||||||
|
APP="$DERIVED_DATA/Build/Products/Release-iphoneos/FuelBoard.app"
|
||||||
|
DEVICE=""
|
||||||
|
DEVICE_NAME="(first paired iPhone)"
|
||||||
|
LAUNCH=1
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--device) DEVICE="$2"; shift 2 ;;
|
||||||
|
--no-launch) LAUNCH=0; shift ;;
|
||||||
|
*) echo "unknown arg: $1" >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Resolve the device if not given: the first connected physical iPhone.
|
||||||
|
# devicectl --device wants the CoreDevice Identifier (field 3 of `list devices`,
|
||||||
|
# e.g. C519BE18-...). NOTE: xcodebuild -destination wants the hardware UDID
|
||||||
|
# (00008130-...), so we build with the generic platform destination and only use
|
||||||
|
# the CoreDevice Identifier for devicectl install/launch.
|
||||||
|
if [[ -z "$DEVICE" ]]; then
|
||||||
|
DEVICE="$(xcrun devicectl list devices 2>/dev/null | awk '/(available \(paired\))/ && /iPhone/ {print $3; exit}')"
|
||||||
|
if [[ -z "$DEVICE" ]]; then
|
||||||
|
echo "install.sh: no paired iPhone found. Check: xcrun devicectl list devices" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Build (Release, dev-signed, generic iOS destination)"
|
||||||
|
rm -rf "$DERIVED_DATA"
|
||||||
|
xcodebuild -project "$PROJECT" -scheme "$SCHEME" -configuration Release \
|
||||||
|
-destination 'generic/platform=iOS' \
|
||||||
|
-derivedDataPath "$DERIVED_DATA" \
|
||||||
|
CODE_SIGN_STYLE=Automatic \
|
||||||
|
build 2>&1 | grep -E "error:|BUILD (SUCCEEDED|FAILED)|Signing Identity" | tail -8
|
||||||
|
|
||||||
|
echo "==> Verify bundle"
|
||||||
|
test -d "$APP" || { echo "build failed: no app at $APP" >&2; exit 1; }
|
||||||
|
echo " bundle: $(plutil -extract CFBundleIdentifier raw "$APP/Info.plist")" \
|
||||||
|
" $(plutil -extract CFBundleShortVersionString raw "$APP/Info.plist")" \
|
||||||
|
"($(plutil -extract CFBundleVersion raw "$APP/Info.plist"))"
|
||||||
|
|
||||||
|
echo "==> Install via devicectl"
|
||||||
|
xcrun devicectl device install app --device "$DEVICE" "$APP" 2>&1 | tail -6
|
||||||
|
|
||||||
|
if [[ "$LAUNCH" -eq 1 ]]; then
|
||||||
|
BID="$(plutil -extract CFBundleIdentifier raw "$APP/Info.plist")"
|
||||||
|
echo "==> Launch"
|
||||||
|
xcrun devicectl device process launch --device "$DEVICE" "$BID" 2>&1 | tail -4
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Done ✅ (delete the old icon on the phone if you want it refreshed)"
|
||||||
Reference in New Issue
Block a user