diff --git a/.github/workflows/scripts-ios.yml b/.github/workflows/scripts-ios.yml index 3c8b0b6315..37d21d3026 100644 --- a/.github/workflows/scripts-ios.yml +++ b/.github/workflows/scripts-ios.yml @@ -420,6 +420,16 @@ jobs: CN1SS_REPORT_TITLE: 'iOS Metal screenshot updates' CN1SS_SUCCESS_MESSAGE: '✅ Native iOS Metal screenshot tests passed.' CN1SS_COMMENT_LOG_PREFIX: '[run-ios-device-tests-metal]' + # Enable Apple's Metal API Validation in the simulator. Catches + # render-pass / pipeline-state mismatches at the moment they + # happen (issue #5103: stencil pixel-format mismatch shipped in + # four consecutive 7.0.x releases because no test exercised the + # validation layer). assert mode crashes the app on the first + # validation error -- the missed CN1SS:SUITE:FINISHED marker + # then fails this step. run-ios-ui-tests.sh forwards both vars + # to the launched app via simctl --setenv. + MTL_DEBUG_LAYER: '1' + MTL_DEBUG_LAYER_ERROR_MODE: 'assert' run: | set -euo pipefail mkdir -p "${ARTIFACTS_DIR}" diff --git a/scripts/run-ios-ui-tests.sh b/scripts/run-ios-ui-tests.sh index 6d1400154b..2f0a8f180a 100755 --- a/scripts/run-ios-ui-tests.sh +++ b/scripts/run-ios-ui-tests.sh @@ -625,6 +625,24 @@ APP_PROCESS_NAME="${WRAPPER_NAME%.app}" LAUNCH_LOG="$ARTIFACTS_DIR/simctl-launch.log" + # Thread Metal validation env vars (if set in the caller's environment) + # through to the launched app. simctl on Xcode 26 does NOT take a + # --setenv flag (`xcrun simctl help launch` confirms); the documented + # mechanism is exporting SIMCTL_CHILD_= in the shell that + # invokes simctl, which the launch helper unwraps into = + # for the child. CI's Metal job sets MTL_DEBUG_LAYER / + # MTL_DEBUG_LAYER_ERROR_MODE at the step level so iOS render-pass / + # pipeline-state mismatches (issue #5103) abort the app immediately + # instead of producing undefined behaviour off-CI. + if [ -n "${MTL_DEBUG_LAYER:-}" ]; then + export SIMCTL_CHILD_MTL_DEBUG_LAYER="${MTL_DEBUG_LAYER}" + ri_log "Forwarding MTL_DEBUG_LAYER=${MTL_DEBUG_LAYER} to simulator app (via SIMCTL_CHILD_)" + fi + if [ -n "${MTL_DEBUG_LAYER_ERROR_MODE:-}" ]; then + export SIMCTL_CHILD_MTL_DEBUG_LAYER_ERROR_MODE="${MTL_DEBUG_LAYER_ERROR_MODE}" + ri_log "Forwarding MTL_DEBUG_LAYER_ERROR_MODE=${MTL_DEBUG_LAYER_ERROR_MODE} to simulator app (via SIMCTL_CHILD_)" + fi + launch_simulator_app() { local target="$1" local attempt=1