From ad448502e3952de3883b9e7401bf970a8442a89a Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 22 Jan 2026 04:24:42 +0200 Subject: [PATCH 1/5] Update iOS CI to Xcode 26 SDK --- .github/workflows/scripts-ios.yml | 3 +-- scripts/build-ios-app.sh | 4 ++-- scripts/run-ios-ui-tests.sh | 3 +-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/scripts-ios.yml b/.github/workflows/scripts-ios.yml index 5209a9702b..e1abdc45c9 100644 --- a/.github/workflows/scripts-ios.yml +++ b/.github/workflows/scripts-ios.yml @@ -130,7 +130,7 @@ jobs: - name: Run iOS UI screenshot tests env: ARTIFACTS_DIR: ${{ github.workspace }}/artifacts - IOS_SIM_DESTINATION: platform=iOS Simulator,name=iPhone 16 Pro,OS=18.5 + IOS_SIM_DESTINATION: platform=iOS Simulator,name=iPhone 16 Pro,OS=26.0 run: | set -euo pipefail mkdir -p "${ARTIFACTS_DIR}" @@ -152,4 +152,3 @@ jobs: path: artifacts if-no-files-found: warn retention-days: 14 - diff --git a/scripts/build-ios-app.sh b/scripts/build-ios-app.sh index 4990495e80..15eff2516e 100755 --- a/scripts/build-ios-app.sh +++ b/scripts/build-ios-app.sh @@ -5,7 +5,7 @@ set -euo pipefail bia_log() { echo "[build-ios-app] $1"; } # Pin Xcode so CN1’s Java subprocess sees xcodebuild -export DEVELOPER_DIR="/Applications/Xcode_16.4.app/Contents/Developer" +export DEVELOPER_DIR="/Applications/Xcode_26.app/Contents/Developer" export PATH="$DEVELOPER_DIR/usr/bin:$PATH" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" @@ -161,4 +161,4 @@ ARTIFACTS_DIR="${ARTIFACTS_DIR:-$REPO_ROOT/artifacts}" mkdir -p "$ARTIFACTS_DIR" xcodebuild -workspace "$WORKSPACE" -list > "$ARTIFACTS_DIR/xcodebuild-list.txt" 2>&1 || true -exit 0 \ No newline at end of file +exit 0 diff --git a/scripts/run-ios-ui-tests.sh b/scripts/run-ios-ui-tests.sh index 20d2490376..9ac8d27760 100755 --- a/scripts/run-ios-ui-tests.sh +++ b/scripts/run-ios-ui-tests.sh @@ -54,7 +54,7 @@ ri_log "Loading workspace environment from $ENV_FILE" source "$ENV_FILE" # Use the same Xcode as the build step -export DEVELOPER_DIR="/Applications/Xcode_16.4.app/Contents/Developer" +export DEVELOPER_DIR="/Applications/Xcode_26.app/Contents/Developer" export PATH="$DEVELOPER_DIR/usr/bin:$PATH" if [ -z "${JAVA17_HOME:-}" ] || [ ! -x "$JAVA17_HOME/bin/java" ]; then @@ -659,4 +659,3 @@ cp -f "$BUILD_LOG" "$ARTIFACTS_DIR/xcodebuild-build.log" 2>/dev/null || true cp -f "$TEST_LOG" "$ARTIFACTS_DIR/device-runner.log" 2>/dev/null || true exit $comment_rc - From 1f3020d96e602a515ad8dfcc4b73243eb4091e31 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 22 Jan 2026 04:41:07 +0200 Subject: [PATCH 2/5] Make Xcode 26 selection resilient --- scripts/build-ios-app.sh | 9 ++++++++- scripts/run-ios-ui-tests.sh | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/scripts/build-ios-app.sh b/scripts/build-ios-app.sh index 15eff2516e..7e82dd3975 100755 --- a/scripts/build-ios-app.sh +++ b/scripts/build-ios-app.sh @@ -5,7 +5,14 @@ set -euo pipefail bia_log() { echo "[build-ios-app] $1"; } # Pin Xcode so CN1’s Java subprocess sees xcodebuild -export DEVELOPER_DIR="/Applications/Xcode_26.app/Contents/Developer" +XCODE_APP="${XCODE_APP:-/Applications/Xcode_26.app}" +if [ -d "$XCODE_APP" ]; then + export DEVELOPER_DIR="$XCODE_APP/Contents/Developer" +else + DEVELOPER_DIR="$(xcode-select -p)" + bia_log "Xcode 26 not found at $XCODE_APP; using $DEVELOPER_DIR" + export DEVELOPER_DIR +fi export PATH="$DEVELOPER_DIR/usr/bin:$PATH" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" diff --git a/scripts/run-ios-ui-tests.sh b/scripts/run-ios-ui-tests.sh index 9ac8d27760..a091ffd04a 100755 --- a/scripts/run-ios-ui-tests.sh +++ b/scripts/run-ios-ui-tests.sh @@ -54,7 +54,14 @@ ri_log "Loading workspace environment from $ENV_FILE" source "$ENV_FILE" # Use the same Xcode as the build step -export DEVELOPER_DIR="/Applications/Xcode_26.app/Contents/Developer" +XCODE_APP="${XCODE_APP:-/Applications/Xcode_26.app}" +if [ -d "$XCODE_APP" ]; then + export DEVELOPER_DIR="$XCODE_APP/Contents/Developer" +else + DEVELOPER_DIR="$(xcode-select -p)" + ri_log "Xcode 26 not found at $XCODE_APP; using $DEVELOPER_DIR" + export DEVELOPER_DIR +fi export PATH="$DEVELOPER_DIR/usr/bin:$PATH" if [ -z "${JAVA17_HOME:-}" ] || [ ! -x "$JAVA17_HOME/bin/java" ]; then From aac9414699caefe7bb3af5ae2d495da454af0ffc Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 22 Jan 2026 06:03:19 +0200 Subject: [PATCH 3/5] Require Xcode 26 and align iOS 26 simulator --- .github/workflows/scripts-ios.yml | 2 +- scripts/build-ios-app.sh | 12 +++++------- scripts/run-ios-ui-tests.sh | 12 +++++------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/.github/workflows/scripts-ios.yml b/.github/workflows/scripts-ios.yml index e1abdc45c9..37b1f81b0b 100644 --- a/.github/workflows/scripts-ios.yml +++ b/.github/workflows/scripts-ios.yml @@ -130,7 +130,7 @@ jobs: - name: Run iOS UI screenshot tests env: ARTIFACTS_DIR: ${{ github.workspace }}/artifacts - IOS_SIM_DESTINATION: platform=iOS Simulator,name=iPhone 16 Pro,OS=26.0 + IOS_SIM_DESTINATION: platform=iOS Simulator,name=iPhone 16 Pro Max,OS=26.0.1 run: | set -euo pipefail mkdir -p "${ARTIFACTS_DIR}" diff --git a/scripts/build-ios-app.sh b/scripts/build-ios-app.sh index 7e82dd3975..b18451d73a 100755 --- a/scripts/build-ios-app.sh +++ b/scripts/build-ios-app.sh @@ -5,14 +5,12 @@ set -euo pipefail bia_log() { echo "[build-ios-app] $1"; } # Pin Xcode so CN1’s Java subprocess sees xcodebuild -XCODE_APP="${XCODE_APP:-/Applications/Xcode_26.app}" -if [ -d "$XCODE_APP" ]; then - export DEVELOPER_DIR="$XCODE_APP/Contents/Developer" -else - DEVELOPER_DIR="$(xcode-select -p)" - bia_log "Xcode 26 not found at $XCODE_APP; using $DEVELOPER_DIR" - export DEVELOPER_DIR +XCODE_APP="${XCODE_APP:-/Applications/Xcode_26.0.1.app}" +if [ ! -d "$XCODE_APP" ]; then + bia_log "Xcode 26 not found at $XCODE_APP. Set XCODE_APP to the Xcode 26 app bundle path." >&2 + exit 1 fi +export DEVELOPER_DIR="$XCODE_APP/Contents/Developer" export PATH="$DEVELOPER_DIR/usr/bin:$PATH" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" diff --git a/scripts/run-ios-ui-tests.sh b/scripts/run-ios-ui-tests.sh index a091ffd04a..e703bc4594 100755 --- a/scripts/run-ios-ui-tests.sh +++ b/scripts/run-ios-ui-tests.sh @@ -54,14 +54,12 @@ ri_log "Loading workspace environment from $ENV_FILE" source "$ENV_FILE" # Use the same Xcode as the build step -XCODE_APP="${XCODE_APP:-/Applications/Xcode_26.app}" -if [ -d "$XCODE_APP" ]; then - export DEVELOPER_DIR="$XCODE_APP/Contents/Developer" -else - DEVELOPER_DIR="$(xcode-select -p)" - ri_log "Xcode 26 not found at $XCODE_APP; using $DEVELOPER_DIR" - export DEVELOPER_DIR +XCODE_APP="${XCODE_APP:-/Applications/Xcode_26.0.1.app}" +if [ ! -d "$XCODE_APP" ]; then + ri_log "Xcode 26 not found at $XCODE_APP. Set XCODE_APP to the Xcode 26 app bundle path." >&2 + exit 3 fi +export DEVELOPER_DIR="$XCODE_APP/Contents/Developer" export PATH="$DEVELOPER_DIR/usr/bin:$PATH" if [ -z "${JAVA17_HOME:-}" ] || [ ! -x "$JAVA17_HOME/bin/java" ]; then From 0276b5453b607326036d85c6ee9f2d885654e2cf Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 22 Jan 2026 07:48:28 +0200 Subject: [PATCH 4/5] Let iOS CI auto-select simulator destination --- .github/workflows/scripts-ios.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/scripts-ios.yml b/.github/workflows/scripts-ios.yml index 37b1f81b0b..28ca4fa0d6 100644 --- a/.github/workflows/scripts-ios.yml +++ b/.github/workflows/scripts-ios.yml @@ -130,7 +130,6 @@ jobs: - name: Run iOS UI screenshot tests env: ARTIFACTS_DIR: ${{ github.workspace }}/artifacts - IOS_SIM_DESTINATION: platform=iOS Simulator,name=iPhone 16 Pro Max,OS=26.0.1 run: | set -euo pipefail mkdir -p "${ARTIFACTS_DIR}" From 878870cf8a489ded2d393b04476442e11c203b47 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 22 Jan 2026 18:58:04 +0200 Subject: [PATCH 5/5] Log and retry simctl launch --- scripts/run-ios-ui-tests.sh | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/scripts/run-ios-ui-tests.sh b/scripts/run-ios-ui-tests.sh index e703bc4594..4b826b4a88 100755 --- a/scripts/run-ios-ui-tests.sh +++ b/scripts/run-ios-ui-tests.sh @@ -480,6 +480,28 @@ APP_PROCESS_NAME="${WRAPPER_NAME%.app}" LOG_STREAM_PID=$! sleep 2 + LAUNCH_LOG="$ARTIFACTS_DIR/simctl-launch.log" + + launch_simulator_app() { + local target="$1" + local attempt=1 + while true; do + local output + if output="$(xcrun simctl launch "$target" "$BUNDLE_IDENTIFIER" 2>&1)"; then + printf '%s\n' "$output" >> "$LAUNCH_LOG" + return 0 + fi + printf '%s\n' "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] simctl launch failed (attempt $attempt): $output" >> "$LAUNCH_LOG" + if [ "$attempt" -ge 2 ]; then + return 1 + fi + ri_log "simctl launch failed (attempt $attempt), retrying" + xcrun simctl bootstatus "$target" -b >/dev/null 2>&1 || true + sleep 5 + attempt=$((attempt + 1)) + done + } + ri_log "Installing simulator app bundle" INSTALL_START=$(date +%s) if [ -n "$SIM_DEVICE_ID" ]; then @@ -490,8 +512,8 @@ APP_PROCESS_NAME="${WRAPPER_NAME%.app}" INSTALL_END=$(date +%s) LAUNCH_START=$(date +%s) - if ! xcrun simctl launch "$SIM_DEVICE_ID" "$BUNDLE_IDENTIFIER" >/dev/null 2>&1; then - ri_log "FATAL: simctl launch failed" + if ! launch_simulator_app "$SIM_DEVICE_ID"; then + ri_log "FATAL: simctl launch failed (see $LAUNCH_LOG)" exit 11 fi LAUNCH_END=$(date +%s) @@ -503,8 +525,8 @@ APP_PROCESS_NAME="${WRAPPER_NAME%.app}" INSTALL_END=$(date +%s) LAUNCH_START=$(date +%s) - if ! xcrun simctl launch booted "$BUNDLE_IDENTIFIER" >/dev/null 2>&1; then - ri_log "FATAL: simctl launch failed" + if ! launch_simulator_app booted; then + ri_log "FATAL: simctl launch failed (see $LAUNCH_LOG)" exit 11 fi LAUNCH_END=$(date +%s)