Deprecated: Function get_magic_quotes_gpc() is deprecated in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 99

Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 619

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1169

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176
8000 fix jest tests Β· selfxyz/self@cd1ef4c Β· GitHub
Nothing Special   »   [go: up one dir, main page]

Skip to content

Confirm Identification Screen + animation json dist setup #1275

Confirm Identification Screen + animation json dist setup

Confirm Identification Screen + animation json dist setup #1275

Workflow file for this run

name: Mobile E2E
env:
# Build environment versions
JAVA_VERSION: 17
ANDROID_API_LEVEL: 33
ANDROID_NDK_VERSION: 27.0.12077973
XCODE_VERSION: 16.4
# Cache versions
GH_CACHE_VERSION: v1 # Global cache version
GH_GEMS_CACHE_VERSION: v1 # Ruby gems cache version
# Performance optimizations
GRADLE_OPTS: -Dorg.gradle.workers.max=4 -Dorg.gradle.parallel=true -Dorg.gradle.caching=true
CI: true
# Disable Maestro analytics in CI
MAESTRO_CLI_NO_ANALYTICS: true
MAESTRO_VERSION: 1.41.0
on:
pull_request:
branches:
- dev
- staging
- main
paths:
- "app/**"
- "packages/mobile-sdk-alpha/**"
- ".github/workflows/mobile-e2e.yml"
jobs:
android-build-test:
# Currently build-only for Android with private repos. E2E steps are preserved but skipped (if: false).
# To re-enable full E2E: change `if: false` to `if: true` on Maestro and emulator steps.
concurrency:
group: ${{ github.workflow }}-android-${{ github.ref }}
cancel-in-progress: true
timeout-minutes: 120
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Read and sanitize Node.js version
shell: bash
run: |
if [ ! -f .nvmrc ] || [ -z "$(cat .nvmrc)" ]; then
echo "❌ .nvmrc is missing or empty"; exit 1;
fi
VERSION="$(tr -d '\r\n' < .nvmrc)&qu 8000 ot;
VERSION="${VERSION#v}"
if ! [[ "$VERSION" =~ ^[0-9]+(\.[0-9]+){0,2}$ ]]; then
echo "Invalid .nvmrc content: '$VERSION'"; exit 1;
fi
echo "NODE_VERSION=$VERSION" >> "$GITHUB_ENV"
echo "NODE_VERSION_SANITIZED=${VERSION//\//-}" >> "$GITHUB_ENV"
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- run: corepack enable
- run: corepack prepare yarn@4.6.0 --activate
- name: Cache Yarn dependencies
uses: ./.github/actions/cache-yarn
with:
path: |
.yarn/cache
.yarn/install-state.gz
.yarn/unplugged
cache-version: ${{ env.GH_CACHE_VERSION }}-node-${{ env.NODE_VERSION_SANITIZED }}-${{ hashFiles('.yarnrc.yml') }}
- name: Toggle Yarn hardened mode for trusted PRs
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false }}
run: echo "YARN_ENABLE_HARDENED_MODE=0" >> $GITHUB_ENV
- name: Install deps (internal PRs and protected branches)
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false }}
run: yarn install --immutable --silent
env:
SELFXYZ_INTERNAL_REPO_PAT: ${{ secrets.SELFXYZ_INTERNAL_REPO_PAT }}
- name: Install deps (forked PRs - no secrets)
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true }}
run: yarn install --immutable --silent
- name: Validate Maestro test file
if: false # Skip for build-only test - keep logic for future E2E
run: |
[ -f app/tests/e2e/launch.android.flow.yaml ] || { echo "❌ Android E2E test file missing"; exit 1; }
- name: Cache Maestro
if: false # Skip for build-only test - keep logic for future E2E
id: cache-maestro
uses: actions/cache@v4
with:
path: ~/.maestro
key: ${{ runner.os }}-maestro-${{ env.MAESTRO_VERSION }}
- name: Install Maestro
if: false # Skip for build-only test - keep logic for future E2E
run: curl -Ls "https://get.maestro.mobile.dev" | bash
- name: Add Maestro to path
if: false # Skip for build-only test - keep logic for future E2E
run: echo "$HOME/.maestro/bin" >> "$GITHUB_PATH"
- name: Free up disk space
uses: ./.github/actions/free-disk-space
- name: Setup Java environment
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: ${{ env.JAVA_VERSION }}
- name: Cache Gradle packages
uses: ./.github/actions/cache-gradle
- name: Setup Android SDK
uses: android-actions/setup-android@v3
with:
accept-android-sdk-licenses: true
- name: Install NDK
run: sdkmanager "ndk;${{ env.ANDROID_NDK_VERSION }}"
- name: Build dependencies (outside emulator)
run: |
echo "Building dependencies..."
# Ensure Yarn 4.6.0 is active
corepack enable
corepack prepare yarn@4.6.0 --activate
yarn workspace @selfxyz/mobile-app run build:deps || { echo "❌ Dependency build failed"; exit 1; }
echo "βœ… Dependencies built successfully"
- name: Clone android-passport-nfc-reader
uses: ./.github/actions/clone-android-passport-nfc-reader
with:
working_directory: app
selfxyz_internal_pat: ${{ secrets.SELFXYZ_INTERNAL_REPO_PAT }}
- name: Build Android APK
run: |
echo "Building Android APK..."
chmod +x app/android/gradlew
(cd app/android && ./gradlew assembleDebug --quiet --parallel --build-cache --no-configuration-cache) || { echo "❌ Android build failed"; exit 1; }
echo "βœ… Android build succeeded"
- name: Clean up Gradle build artifacts
uses: ./.github/actions/cleanup-gradle-artifacts
- name: Verify APK and android-passport-nfc-reader integration
run: |
echo "πŸ” Verifying build artifacts..."
APK_PATH="app/android/app/build/outputs/apk/debug/app-debug.apk"
[ -f "$APK_PATH" ] || { echo "❌ APK not found at $APK_PATH"; exit 1; }
echo "βœ… APK found at $APK_PATH"
# Check APK size
APK_SIZE=$(stat -f%z "$APK_PATH" 2>/dev/null || stat -c%s "$APK_PATH" 2>/dev/null || echo "unknown")
echo "πŸ“± APK size: $APK_SIZE bytes"
# Verify android-passport-nfc-reader was properly integrated (skip for forks)
if [ -z "${SELFXYZ_INTERNAL_REPO_PAT:-}" ]; then
echo "πŸ”• No PAT available β€” skipping private module verification"
elif [ -d "app/android/android-passport-nfc-reader" ]; then
echo "βœ… android-passport-nfc-reader directory exists"
echo "πŸ“ android-passport-nfc-reader contents:"
ls -la app/android/android-passport-nfc-reader/ | head -10
else
echo "❌ android-passport-nfc-reader directory not found"
exit 1
fi
echo "πŸŽ‰ Build verification completed successfully!"
echo "ℹ️ Emulator testing is temporarily disabled - build testing only"
- name: Install and Test on Android
if: false # Skip emulator/E2E for build-only test - keep logic for future E2E
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ env.ANDROID_API_LEVEL }}
arch: x86_64
target: google_apis
force-avd-creation: false
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -camera-front none -memory 8192 -cores 4 -accel on
disable-animations: true
script: |
echo "Installing app on emulator..."
APK_PATH="app/android/app/build/outputs/apk/debug/app-debug.apk"
[ -f "$APK_PATH" ] || { echo "❌ APK not found at $APK_PATH"; exit 1; }
adb install -r "$APK_PATH" || { echo "❌ App installation failed"; exit 1; }
echo "βœ… App installed successfully"
echo "⏰ Giving the emulator a moment to settle..."
sleep 5
echo "🎭 Running Maestro tests..."
export MAESTRO_DRIVER_STARTUP_TIMEOUT=180000
maestro test app/tests/e2e/launch.android.flow.yaml --format junit --output app/maestro-results.xml
- name: Upload test results
if: false # Skip for build-only test - keep logic for future E2E
uses: actions/upload-artifact@v4
with:
name: maestro-results-android
path: app/maestro-results.xml
if-no-files-found: warn
e2e-ios:
timeout-minutes: 120
runs-on: macos-latest-large
concurrency:
group: ${{ github.workflow }}-ios-${{ github.ref }}
cancel-in-progress: true
env:
# iOS project configuration - hardcoded for E2E testing stability
# Note: During migration, project name is "Self" but scheme is still "OpenPassport"
# mobile-deploy.yml uses secrets for production deployment
IOS_PROJECT_NAME: "Self"
IOS_PROJECT_SCHEME: "OpenPassport"
steps:
- uses: actions/checkout@v4
- name: Read and sanitize Node.js version
shell: bash
run: |
if [ ! -f .nvmrc ] || [ -z "$(cat .nvmrc)" ]; then
echo "❌ .nvmrc is missing or empty"; exit 1;
fi
VERSION="$(tr -d '\r\n' < .nvmrc)"
VERSION="${VERSION#v}"
if ! [[ "$VERSION" =~ ^[0-9]+(\.[0-9]+){0,2}$ ]]; then
echo "Invalid .nvmrc content: '$VERSION'"; exit 1;
fi
echo "NODE_VERSION=$VERSION" >> "$GITHUB_ENV"
echo "NODE_VERSION_SANITIZED=${VERSION//\//-}" >> "$GITHUB_ENV"
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- run: corepack enable
- run: corepack prepare yarn@4.6.0 --activate
- name: Cache Yarn dependencies
uses: ./.github/actions/cache-yarn
with:
path: |
.yarn/cache
.yarn/install-state.gz
.yarn/unplugged
cache-version: ${{ env.GH_CACHE_VERSION }}-node-${{ env.NODE_VERSION_SANITIZED }}-${{ hashFiles('.yarnrc.yml') }}
- name: Toggle Yarn hardened mode for trusted PRs
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false }}
run: echo "YARN_ENABLE_HARDENED_MODE=0" >> $GITHUB_ENV
- name: Install deps (internal PRs and protected branches)
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false }}
run: yarn install --immutable --silent
env:
SELFXYZ_INTERNAL_REPO_PAT: ${{ secrets.SELFXYZ_INTERNAL_REPO_PAT }}
- name: Install deps (forked PRs - no secrets)
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true }}
run: yarn install --immutable --silent
- name: Validate Maestro test file
run: |
[ -f app/tests/e2e/launch.ios.flow.yaml ] || { echo "❌ iOS E2E test file missing"; exit 1; }
- name: Cache Maestro
id: cache-maestro
uses: actions/cache@v4
with:
path: ~/.maestro
key: ${{ runner.os }}-maestro-${{ env.MAESTRO_VERSION }}
- name: Install Maestro
if: steps.cache-maestro.outputs.cache-hit != 'true'
run: curl -Ls "https://get.maestro.mobile.dev" | bash
- name: Add Maestro to path
run: echo "$HOME/.maestro/bin" >> "$GITHUB_PATH"
- name: Set up Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ${{ env.XCODE_VERSION }}
- name: Configure Xcode path
run: |
echo "πŸ”§ Configuring Xcode path to fix iOS SDK issues..."
# Fix for macOS 15 runner iOS SDK issues
# See: https://github.com/actions/runner-images/issues/12758
sudo xcode-select --switch /Applications/Xcode_${{ env.XCODE_VERSION }}.app
echo "βœ… Xcode path configured"
# Verify Xcode setup
echo "Xcode version:"
xcodebuild -version
echo "Xcode path:"
xcode-select -p
- name: Setup ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ github.job }}-${{ runner.os }}
- name: Add ccache to PATH
run: echo "/usr/local/opt/ccache/libexec" >> $GITHUB_PATH
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.3"
bundler-cache: true
working-directory: app
- name: Cache Pods
uses: ./.github/actions/cache-pods
with:
path: |
app/ios/Pods
~/Library/Caches/CocoaPods
lock-file: app/ios/Podfile.lock
- name: Cache DerivedData
uses: actions/cache@v4
with:
path: app/ios/build
key: ${{ runner.os }}-derived-data-${{ env.GH_CACHE_VERSION }}-${{ env.XCODE_VERSION }}-${{ hashFiles('app/ios/Podfile.lock', 'yarn.lock') }}
restore-keys: |
${{ runner.os }}-derived-data-${{ env.GH_CACHE_VERSION }}-${{ env.XCODE_VERSION }}-
${{ runner.os }}-derived-data-${{ env.GH_CACHE_VERSION }}-
- name: Verify iOS Runtime
run: |
echo "πŸ“± Verifying iOS Runtime availability..."
echo "Available iOS runtimes:"
DD26 xcrun simctl list runtimes | grep iOS
- name: Build dependencies (outside main flow)
run: |
echo "Building dependencies..."
yarn workspace @selfxyz/mobile-app run build:deps || { echo "❌ Dependency build failed"; exit 1; }
echo "βœ… Dependencies built successfully"
- name: Install iOS dependencies
run: |
echo "Installing iOS dependencies..."
cd app/ios
echo "πŸ“¦ Installing pods via centralized script…"
BUNDLE_GEMFILE=../Gemfile bundle exec bash scripts/pod-install-with-cache-fix.sh || { echo "❌ Pod install failed"; exit 1; }
env:
SELFXYZ_INTERNAL_REPO_PAT: ${{ secrets.SELFXYZ_INTERNAL_REPO_PAT }}
- name: Setup iOS Simulator
run: |
echo "Setting up iOS Simulator..."
# First, check what simulators are actually available
echo "Available simulators:"
xcrun simctl list devices available || {
echo "❌ Failed to list available devices"
echo "Trying to list all devices:"
xcrun simctl list devices || {
echo "❌ Failed to list any devices"
exit 1
}
}
# Find iPhone SE (3rd generation) simulator
echo "Finding iPhone SE (3rd generation) simulator..."
AVAILABLE_SIMULATOR=$(xcrun simctl list devices available | grep "iPhone SE (3rd generation)" | head -1 | sed -E 's/.*\(([A-F0-9-]+)\).*/\1/')
if [ -z "$AVAILABLE_SIMULATOR" ]; then
echo "iPhone SE (3rd generation) not found, trying any iPhone SE..."
AVAILABLE_SIMULATOR=$(xcrun simctl list devices available | grep "iPhone SE" | head -1 | sed -E 's/.*\(([A-F0-9-]+)\).*/\1/')
fi
if [ -z "$AVAILABLE_SIMULATOR" ]; then
echo "No iPhone SE found, trying any iPhone..."
AVAILABLE_SIMULATOR=$(xcrun simctl list devices available | grep "iPhone" | head -1 | sed -E 's/.*\(([A-F0-9-]+)\).*/\1/')
fi
if [ -z "$AVAILABLE_SIMULATOR" ]; then
echo "❌ No available iPhone simulator found"
echo "Creating a new iPhone SE (3rd generation) simulator..."
# Create a new iPhone SE (3rd generation) simulator
xcrun simctl create "iPhone SE (3rd generation)" "iPhone SE (3rd generation)" || {
echo "❌ Failed to create iPhone SE (3rd generation) simulator"
echo "Trying to create any iPhone SE simulator..."
xcrun simctl create "iPhone SE" "iPhone SE" || {
echo "❌ Failed to create simulator"
exit 1
}
}
AVAILABLE_SIMULATOR=$(xcrun simctl list devices | grep "iPhone SE" | sed -E 's/.*\(([A-F0-9-]+)\).*/\1/')
fi
echo "Using simulator: $AVAILABLE_SIMULATOR"
# Get simulator name for display
SIMULATOR_NAME=$(xcrun simctl list devices | grep "$AVAILABLE_SIMULATOR" | sed -E 's/^[[:space:]]*([^(]+).*/\1/' | xargs)
echo "Simulator name: $SIMULATOR_NAME"
# Boot simulator and wait for it to be ready
echo "Booting simulator..."
xcrun simctl boot "$AVAILABLE_SIMULATOR" || {
echo "❌ Failed to boot simulator"
exit 1
}
echo "Waiting for simulator to be ready..."
xcrun simctl bootstatus "$AVAILABLE_SIMULATOR" -b
# Wait for simulator to be fully ready
echo "Waiting for simulator to be fully ready..."
sleep 15
echo "Simulator status:"
xcrun simctl list devices | grep "$AVAILABLE_SIMULATOR"
# Store simulator ID for later use
echo "IOS_SIMULATOR_ID=$AVAILABLE_SIMULATOR" >> $GITHUB_ENV
echo "IOS_SIMULATOR_NAME=$SIMULATOR_NAME" >> $GITHUB_ENV
- name: Resolve iOS workspace
run: |
WORKSPACE_OPEN="app/ios/OpenPassport.xcworkspace"
WORKSPACE_SELF="app/ios/Self.xcworkspace"
if xcodebuild -list -workspace "$WORKSPACE_OPEN" 2>/dev/null | grep -q "OpenPassport"; then
WORKSPACE_PATH="$WORKSPACE_OPEN"
else
WORKSPACE_PATH="$WORKSPACE_SELF"
fi
echo "WORKSPACE_PATH=$WORKSPACE_PATH" >> "$GITHUB_ENV"
echo "Resolved workspace: $WORKSPACE_PATH"
- name: Build iOS App
run: |
echo "Building iOS app..."
echo "Project: ${{ env.IOS_PROJECT_NAME }}, Scheme: ${{ env.IOS_PROJECT_SCHEME }}"
# Verify workspace exists before building
if [ -z "$WORKSPACE_PATH" ]; then
echo "❌ WORKSPACE_PATH is not set"
exit 1
fi
if [ ! -d "$WORKSPACE_PATH" ]; then
echo "❌ Workspace not found at: $WORKSPACE_PATH"
echo "Available workspaces:"
find app/ios -name "*.xcworkspace" -type d
exit 1
fi
# Verify scheme exists by listing available schemes
echo "Verifying scheme availability..."
AVAILABLE_SCHEMES=$(xcodebuild -list -workspace "$WORKSPACE_PATH" 2>/dev/null | grep -A 200 "Schemes:" | grep -v "Schemes:" | xargs)
echo "Available schemes (first 20): $(echo $AVAILABLE_SCHEMES | cut -d' ' -f1-20)..."
if [[ ! "$AVAILABLE_SCHEMES" =~ ${{ env.IOS_PROJECT_SCHEME }} ]]; then
echo "❌ Scheme '${{ env.IOS_PROJECT_SCHEME }}' not found"
echo "Full scheme list:"
xcodebuild -list -workspace "$WORKSPACE_PATH" 2>/dev/null | grep -A 200 "Schemes:" | grep -v "Schemes:" | head -50
exit 1
fi
echo "βœ… Using workspace: $WORKSPACE_PATH"
echo "βœ… Using scheme: ${{ env.IOS_PROJECT_SCHEME }}"
# Use cached derived data and enable parallel builds for faster compilation
# Additional flags disable indexing, restrict architecture, and use whole-module Swift compilation
# Use the simulator that was set up earlier in the workflow
FORCE_BUNDLING=1 RCT_NO_LAUNCH_PACKAGER=1 \
xcodebuild -workspace "$WORKSPACE_PATH" -scheme ${{ env.IOS_PROJECT_SCHEME }} -configuration Debug -destination "id=${{ env.IOS_SIMULATOR_ID }}" -derivedDataPath app/ios/build -jobs "$(sysctl -n hw.ncpu)" -parallelizeTargets -quiet COMPILER_INDEX_STORE_ENABLE=NO ONLY_ACTIVE_ARCH=YES SWIFT_COMPILATION_MODE=wholemodule || { echo "❌ iOS build failed"; exit 1; }
echo "βœ… iOS build succeeded"
- name: Install and Test on iOS
run: |
echo "Installing app on simulator..."
APP_PATH=$(find app/ios/build/Build/Products/Debug-iphonesimulator -name "*.app" | head -1)
[ -z "$APP_PATH" ] && { echo "❌ Could not find built iOS app"; exit 1; }
echo "Found app at: $APP_PATH"
echo "πŸ” Determining app bundle ID from built app..."
IOS_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print CFBundleIdentifier" "$APP_PATH/Info.plist")
[ -z "$IOS_BUNDLE_ID" ] && { echo "❌ Could not determine bundle ID from $APP_PATH/Info.plist"; exit 1; }
echo "βœ… App Bundle ID: $IOS_BUNDLE_ID"
# Use the dynamic simulator ID
SIMULATOR_ID="${IOS_SIMULATOR_ID:-iPhone SE (3rd generation)}"
echo "Installing on simulator: $SIMULATOR_ID"
echo "Removing any existing app installation..."
xcrun simctl uninstall "$SIMULATOR_ID" "$IOS_BUNDLE_ID" 2>/dev/null || true
echo "Installing app..."
xcrun simctl install "$SIMULATOR_ID" "$APP_PATH"
if [ $? -ne 0 ]; then
echo "❌ iOS app installation failed"
exit 1
fi
echo "Verifying app installation..."
if xcrun simctl get_app_container "$SIMULATOR_ID" "$IOS_BUNDLE_ID" app >/dev/null 2>&1; then
echo "βœ… App successfully installed"
else
echo "❌ App installation verification failed"
exit 1
fi
echo "πŸš€ Testing app launch capability..."
xcrun simctl launch "$SIMULATOR_ID" "$IOS_BUNDLE_ID" || {
echo "⚠️ Direct app launch test failed - this might be expected."
}
echo "⏰ Checking simulator readiness..."
sleep 10
# Probe container as readiness check instead of listapps
xcrun simctl get_app_container "$SIMULATOR_ID" "$IOS_BUNDLE_ID" app >/dev/null 2>&1 || sleep 5
echo "Running Maestro tests..."
echo "Starting test execution..."
maestro test app/tests/e2e/launch.ios.flow.yaml --format junit --output app/maestro-results.xml || {
echo "Maestro test failed, but continuing to upload results..."
exit 1
}
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: maestro-results-ios
path: app/maestro-results.xml
if-no-files-found: warn
0