Skip to content

Commit 6560247

Browse files
authored
chore: speed up mobile e2e workflow (#962)
* chore: speed up mobile e2e workflow * chore: disable android e2e job * chore: speed up ios build * fix: bundle js for ios debug build
1 parent 9687830 commit 6560247

File tree

1 file changed

+28
-82
lines changed

1 file changed

+28
-82
lines changed

.github/workflows/mobile-e2e.yml

Lines changed: 28 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ env:
1010
GH_CACHE_VERSION: v1 # Global cache version
1111
GH_GEMS_CACHE_VERSION: v1 # Ruby gems cache version
1212
# Performance optimizations
13-
GRADLE_OPTS: -Dorg.gradle.daemon=false -Dorg.gradle.workers.max=4 -Dorg.gradle.parallel=true -Dorg.gradle.configureondemand=true -Dorg.gradle.caching=true
13+
GRADLE_OPTS: -Dorg.gradle.workers.max=4 -Dorg.gradle.parallel=true -Dorg.gradle.caching=true
1414
CI: true
1515
# Disable Maestro analytics in CI
1616
MAESTRO_CLI_NO_ANALYTICS: true
@@ -29,12 +29,7 @@ on:
2929

3030
jobs:
3131
e2e-android:
32-
# TODO: The Android E2E test job is temporarily disabled due to a recurring
33-
# Maestro driver timeout issue in the CI environment. The emulator becomes
34-
# unresponsive, preventing Maestro from connecting. This needs further
35-
# investigation, but has been disabled to unblock the pipeline.
36-
# To test locally, run `./scripts/test-e2e-local.sh android --workflow-match`
37-
if: false
32+
if: false # Temporarily disable Android E2E until emulator disk issue resolved
3833
concurrency:
3934
group: ${{ github.workflow }}-android-${{ github.ref }}
4035
cancel-in-progress: true
@@ -61,13 +56,13 @@ jobs:
6156
- run: corepack enable
6257
- run: corepack prepare [email protected] --activate
6358
- name: Cache Yarn dependencies
64-
uses: actions/cache@v4
59+
uses: ./.github/actions/cache-yarn
6560
with:
66-
path: .yarn/cache
67-
key: ${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn-${{ hashFiles('**/yarn.lock') }}
68-
restore-keys: |
69-
${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn-
61+
cache-version: ${{ env.GH_CACHE_VERSION }}-node-${{ env.NODE_VERSION_SANITIZED }}
7062
- run: yarn install --immutable --silent
63+
- name: Validate Maestro test file
64+
run: |
65+
[ -f app/tests/e2e/launch.android.flow.yaml ] || { echo "❌ Android E2E test file missing"; exit 1; }
7166
- name: Cache Maestro
7267
id: cache-maestro
7368
uses: actions/cache@v4
@@ -90,42 +85,19 @@ jobs:
9085
uses: android-actions/setup-android@v3
9186
with:
9287
accept-android-sdk-licenses: true
93-
94-
- name: Cache NDK
95-
uses: actions/cache@v4
96-
with:
97-
path: ${{ env.ANDROID_HOME }}/ndk/${{ env.ANDROID_NDK_VERSION }}
98-
key: ${{ runner.os }}-ndk-${{ env.ANDROID_NDK_VERSION }}
9988
- name: Install NDK
10089
run: sdkmanager "ndk;${{ env.ANDROID_NDK_VERSION }}"
10190
- name: Build dependencies (outside emulator)
10291
run: |
10392
echo "Building dependencies..."
10493
yarn workspace @selfxyz/mobile-app run build:deps --silent || { echo "❌ Dependency build failed"; exit 1; }
10594
echo "✅ Dependencies built successfully"
106-
- name: Cache Android build
107-
uses: actions/cache@v4
108-
with:
109-
path: |
110-
app/android/app/build
111-
app/android/.gradle
112-
key: ${{ runner.os }}-android-build-${{ hashFiles('app/android/**/*.gradle*', 'app/android/gradle-wrapper.properties') }}
113-
restore-keys: |
114-
${{ runner.os }}-android-build-
11595
- name: Build Android APK
116-
uses: reactivecircus/android-emulator-runner@v2
117-
with:
118-
api-level: ${{ env.ANDROID_API_LEVEL }}
119-
arch: x86_64
120-
target: google_apis
121-
force-avd-creation: false
122-
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
123-
disable-animations: true
124-
script: |
125-
echo "Building Android APK..."
126-
chmod +x app/android/gradlew
127-
(cd app/android && ./gradlew assembleRelease --quiet --parallel --build-cache --no-configuration-cache) || { echo "❌ Android build failed"; exit 1; }
128-
echo "✅ Android build succeeded"
96+
run: |
97+
echo "Building Android APK..."
98+
chmod +x app/android/gradlew
99+
(cd app/android && ./gradlew assembleDebug --quiet --parallel --build-cache --no-configuration-cache) || { echo "❌ Android build failed"; exit 1; }
100+
echo "✅ Android build succeeded"
129101
- name: Install and Test on Android
130102
uses: reactivecircus/android-emulator-runner@v2
131103
with:
@@ -137,7 +109,7 @@ jobs:
137109
disable-animations: true
138110
script: |
139111
echo "Installing app on emulator..."
140-
APK_PATH="app/android/app/build/outputs/apk/release/app-release.apk"
112+
APK_PATH="app/android/app/build/outputs/apk/debug/app-debug.apk"
141113
[ -f "$APK_PATH" ] || { echo "❌ APK not found at $APK_PATH"; exit 1; }
142114
adb install -r "$APK_PATH" || { echo "❌ App installation failed"; exit 1; }
143115
echo "✅ App installed successfully"
@@ -147,9 +119,7 @@ jobs:
147119
148120
echo "🎭 Running Maestro tests..."
149121
export MAESTRO_DRIVER_STARTUP_TIMEOUT=180000
150-
maestro test tests/e2e/launch.android.flow.yaml --format junit --output app/maestro-results.xml
151-
env:
152-
E2E_BUILD: "true"
122+
maestro test app/tests/e2e/launch.android.flow.yaml --format junit --output app/maestro-results.xml
153123
- name: Upload test results
154124
if: always()
155125
uses: actions/upload-artifact@v4
@@ -191,13 +161,13 @@ jobs:
191161
- run: corepack enable
192162
- run: corepack prepare [email protected] --activate
193163
- name: Cache Yarn dependencies
194-
uses: actions/cache@v4
164+
uses: ./.github/actions/cache-yarn
195165
with:
196-
path: .yarn/cache
197-
key: ${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn-${{ hashFiles('**/yarn.lock') }}
198-
restore-keys: |
199-
${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn-
166+
cache-version: ${{ env.GH_CACHE_VERSION }}-node-${{ env.NODE_VERSION_SANITIZED }}
200167
- run: yarn install --immutable --silent
168+
- name: Validate Maestro test file
169+
run: |
170+
[ -f app/tests/e2e/launch.ios.flow.yaml ] || { echo "❌ iOS E2E test file missing"; exit 1; }
201171
- name: Cache Maestro
202172
id: cache-maestro
203173
uses: actions/cache@v4
@@ -226,13 +196,6 @@ jobs:
226196
xcodebuild -version
227197
echo "Xcode path:"
228198
xcode-select -p
229-
- name: Cache Node modules
230-
uses: actions/cache@v4
231-
with:
232-
path: app/node_modules
233-
key: ${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-${{ hashFiles('app/yarn.lock') }}
234-
restore-keys: |
235-
${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-
236199
- name: Set up Ruby
237200
uses: ruby/setup-ruby@v1
238201
with:
@@ -246,33 +209,14 @@ jobs:
246209
app/ios/Pods
247210
~/Library/Caches/CocoaPods
248211
lock-file: app/ios/Podfile.lock
249-
- name: Cache Xcode build
212+
- name: Cache DerivedData
250213
uses: actions/cache@v4
251214
with:
252-
path: |
253-
app/ios/build
254-
~/Library/Developer/Xcode/DerivedData
255-
~/Library/Caches/com.apple.dt.Xcode
256-
key: ${{ runner.os }}-xcode-${{ env.XCODE_VERSION }}-${{ hashFiles('app/ios/Podfile.lock', 'app/ios/OpenPassport.xcworkspace/contents.xcworkspacedata', 'app/ios/Self.xcworkspace/contents.xcworkspacedata') }}
257-
restore-keys: |
258-
${{ runner.os }}-xcode-${{ env.XCODE_VERSION }}-${{ hashFiles('app/ios/Podfile.lock') }}-
259-
${{ runner.os }}-xcode-${{ env.XCODE_VERSION }}-
260-
- name: Cache Xcode Index
261-
uses: actions/cache@v4
262-
with:
263-
path: app/ios/build/Index.noindex
264-
key: ${{ runner.os }}-xcode-index-${{ env.XCODE_VERSION }}-${{ hashFiles('app/ios/Podfile.lock') }}
265-
restore-keys: |
266-
${{ runner.os }}-xcode-index-${{ env.XCODE_VERSION }}-
267-
- name: Cache iOS Simulator
268-
uses: actions/cache@v4
269-
with:
270-
path: |
271-
~/Library/Developer/CoreSimulator/Devices
272-
~/Library/Developer/Xcode/iOS DeviceSupport
273-
key: ${{ runner.os }}-simulator-${{ env.XCODE_VERSION }}-v1
215+
path: ~/Library/Developer/Xcode/DerivedData
216+
key: ${{ runner.os }}-derived-data-${{ env.XCODE_VERSION }}-${{ hashFiles('app/ios/Podfile.lock', 'app/ios/OpenPassport.xcworkspace/contents.xcworkspacedata', 'app/ios/Self.xcworkspace/contents.xcworkspacedata') }}
274217
restore-keys: |
275-
${{ runner.os }}-simulator-${{ env.XCODE_VERSION }}-
218+
${{ runner.os }}-derived-data-${{ env.XCODE_VERSION }}-${{ hashFiles('app/ios/Podfile.lock') }}-
219+
${{ runner.os }}-derived-data-${{ env.XCODE_VERSION }}-
276220
- name: Verify iOS Runtime
277221
run: |
278222
echo "📱 Verifying iOS Runtime availability..."
@@ -405,13 +349,15 @@ jobs:
405349
echo "✅ Using scheme: ${{ env.IOS_PROJECT_SCHEME }}"
406350
407351
# Use cached derived data and enable parallel builds for faster compilation
352+
# Additional flags disable indexing, restrict architecture, and use whole-module Swift compilation
408353
# Use the simulator that was set up earlier in the workflow
409-
xcodebuild -workspace "$WORKSPACE_PATH" -scheme ${{ env.IOS_PROJECT_SCHEME }} -configuration Release -destination "id=${{ env.IOS_SIMULATOR_ID }}" -derivedDataPath app/ios/build -jobs "$(sysctl -n hw.ncpu)" -parallelizeTargets -quiet || { echo "❌ iOS build failed"; exit 1; }
354+
FORCE_BUNDLING=1 RCT_NO_LAUNCH_PACKAGER=1 \
355+
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; }
410356
echo "✅ iOS build succeeded"
411357
- name: Install and Test on iOS
412358
run: |
413359
echo "Installing app on simulator..."
414-
APP_PATH=$(find app/ios/build/Build/Products/Release-iphonesimulator -name "*.app" | head -1)
360+
APP_PATH=$(find app/ios/build/Build/Products/Debug-iphonesimulator -name "*.app" | head -1)
415361
[ -z "$APP_PATH" ] && { echo "❌ Could not find built iOS app"; exit 1; }
416362
echo "Found app at: $APP_PATH"
417363

0 commit comments

Comments
 (0)