@@ -24,6 +24,7 @@ concurrency:
2424 cancel-in-progress : true
2525
2626jobs :
27+ # Android example E2E tests (min/max devices)
2728 android-e2e :
2829 name : Android E2E - ${{ matrix.device }}
2930 if : ${{ github.event_name == 'schedule' || inputs.run_android }}
@@ -36,11 +37,21 @@ jobs:
3637 steps :
3738 - uses : actions/checkout@v4
3839
39- - name : Setup Android CI
40- uses : ./.github/actions/setup-android-ci
40+ - name : Enable KVM
41+ run : |
42+ echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
43+ sudo udevadm control --reload-rules
44+ sudo udevadm trigger --name-match=kvm
45+
46+ - name : Setup Gradle cache
47+ uses : actions/cache@v4
4148 with :
42- device : ${{ matrix.device }}
43- working-directory : examples/android
49+ path : |
50+ ~/.gradle/caches
51+ ~/.gradle/wrapper
52+ key : ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
53+ restore-keys : |
54+ ${{ runner.os }}-gradle-
4455
4556 - name : Install Devbox
4657 uses : jetify-com/devbox-install-action@v0.14.0
@@ -57,17 +68,17 @@ jobs:
5768 TEST_TUI : false
5869 run : devbox run --pure test:e2e
5970
60- - name : Upload logs
61- if : failure ()
71+ - name : Upload reports and logs
72+ if : always ()
6273 uses : actions/upload-artifact@v4
6374 with :
64- name : android-${{ matrix.device }}-logs
75+ name : android-${{ matrix.device }}-reports
6576 path : |
66- examples/android/reports/android-e2e-logs/
77+ examples/android/reports/
6778 examples/android/app/build/outputs/
68- examples/android/build/
6979 retention-days : 7
7080
81+ # iOS example E2E tests (min/max devices)
7182 ios-e2e :
7283 name : iOS E2E - ${{ matrix.device }}
7384 if : ${{ github.event_name == 'schedule' || inputs.run_ios }}
8495 steps :
8596 - uses : actions/checkout@v4
8697
87- - name : Setup iOS CI
88- uses : ./.github/actions/setup-ios-ci
98+ - name : Setup CocoaPods cache
99+ uses : actions/cache@v4
100+ with :
101+ path : |
102+ ~/.cocoapods/repos
103+ ~/Library/Caches/CocoaPods
104+ key : ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
105+ restore-keys : |
106+ ${{ runner.os }}-pods-
107+
108+ - name : Setup Xcode build cache
109+ uses : actions/cache@v4
110+ with :
111+ path : |
112+ ~/Library/Developer/Xcode/DerivedData
113+ key : ${{ runner.os }}-xcode-${{ hashFiles('**/*.xcodeproj/**', '**/*.xcworkspace/**') }}
114+ restore-keys : |
115+ ${{ runner.os }}-xcode-
89116
90117 - name : Install Devbox
91118 uses : jetify-com/devbox-install-action@v0.14.0
@@ -102,16 +129,17 @@ jobs:
102129 TEST_TUI : false
103130 run : devbox run --pure test:e2e
104131
105- - name : Upload logs
106- if : failure ()
132+ - name : Upload reports and logs
133+ if : always ()
107134 uses : actions/upload-artifact@v4
108135 with :
109- name : ios-${{ matrix.device }}-logs
136+ name : ios-${{ matrix.device }}-reports
110137 path : |
111- /tmp/ ios-e2e-logs /
138+ examples/ ios/reports /
112139 ~/Library/Logs/CoreSimulator/
113140 retention-days : 7
114141
142+ # React Native E2E tests (Android min/max, iOS min/max, Web)
115143 react-native-e2e :
116144 name : React Native E2E - ${{ matrix.platform }}-${{ matrix.device }}
117145 if : ${{ github.event_name == 'schedule' || inputs.run_react_native }}
@@ -135,6 +163,10 @@ jobs:
135163 - platform : ios
136164 device : max
137165 os : macos-15
166+ # Web test (fast, no device needed)
167+ - platform : web
168+ device : none
169+ os : ubuntu-24.04
138170 steps :
139171 - uses : actions/checkout@v4
140172
@@ -145,16 +177,44 @@ jobs:
145177 cache : ' npm'
146178 cache-dependency-path : examples/react-native/package-lock.json
147179
148- - name : Setup Android CI
180+ - name : Enable KVM (Android only)
181+ if : matrix.platform == 'android'
182+ run : |
183+ echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
184+ sudo udevadm control --reload-rules
185+ sudo udevadm trigger --name-match=kvm
186+
187+ - name : Setup Gradle cache (Android only)
149188 if : matrix.platform == 'android'
150- uses : ./.github/ actions/setup-android-ci
189+ uses : actions/cache@v4
151190 with :
152- device : ${{ matrix.device }}
153- working-directory : examples/react-native
191+ path : |
192+ ~/.gradle/caches
193+ ~/.gradle/wrapper
194+ key : ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
195+ restore-keys : |
196+ ${{ runner.os }}-gradle-
154197
155- - name : Setup iOS CI
198+ - name : Setup CocoaPods cache ( iOS only)
156199 if : matrix.platform == 'ios'
157- uses : ./.github/actions/setup-ios-ci
200+ uses : actions/cache@v4
201+ with :
202+ path : |
203+ ~/.cocoapods/repos
204+ ~/Library/Caches/CocoaPods
205+ key : ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
206+ restore-keys : |
207+ ${{ runner.os }}-pods-
208+
209+ - name : Setup Xcode build cache (iOS only)
210+ if : matrix.platform == 'ios'
211+ uses : actions/cache@v4
212+ with :
213+ path : |
214+ ~/Library/Developer/Xcode/DerivedData
215+ key : ${{ runner.os }}-xcode-${{ hashFiles('**/*.xcodeproj/**', '**/*.xcworkspace/**') }}
216+ restore-keys : |
217+ ${{ runner.os }}-xcode-
158218
159219 - name : Install Devbox
160220 uses : jetify-com/devbox-install-action@v0.14.0
@@ -166,25 +226,35 @@ jobs:
166226 env :
167227 EMU_HEADLESS : ${{ matrix.platform == 'android' && '1' || '0' }}
168228 SIM_HEADLESS : ${{ matrix.platform == 'ios' && '1' || '0' }}
169- BOOT_TIMEOUT : 240
229+ BOOT_TIMEOUT : 300
170230 TEST_TIMEOUT : 900
171231 ANDROID_DEFAULT_DEVICE : ${{ matrix.device }}
172232 IOS_DEFAULT_DEVICE : ${{ matrix.device }}
173233 TEST_TUI : false
174- run : devbox run --pure test:e2e:${{ matrix.platform }}
234+ run : |
235+ if [ "${{ matrix.platform }}" = "android" ]; then
236+ # Use wrapper script for platform-specific optimization
237+ bash tests/run-android-tests.sh
238+ elif [ "${{ matrix.platform }}" = "ios" ]; then
239+ # Use wrapper script for platform-specific optimization
240+ bash tests/run-ios-tests.sh
241+ elif [ "${{ matrix.platform }}" = "web" ]; then
242+ devbox run test:e2e:web
243+ fi
175244
176- - name : Upload logs
177- if : failure ()
245+ - name : Upload reports and logs
246+ if : always ()
178247 uses : actions/upload-artifact@v4
179248 with :
180- name : react-native-${{ matrix.platform }}-${{ matrix.device }}-logs
249+ name : react-native-${{ matrix.platform }}-${{ matrix.device }}-reports
181250 path : |
182251 examples/react-native/reports/
183252 examples/react-native/android/app/build/outputs/
184253 examples/react-native/ios/build/
185254 ~/Library/Logs/CoreSimulator/
186255 retention-days : 7
187256
257+ # Summary status check
188258 e2e-summary :
189259 name : E2E Test Summary
190260 runs-on : ubuntu-latest
@@ -199,9 +269,9 @@ jobs:
199269 echo " React Native E2E: ${{ needs.react-native-e2e.result }}"
200270 echo ""
201271
202- if [[ "${{ needs.android-e2e.result }}" != "success" ]] || \
203- [[ "${{ needs.ios-e2e.result }}" != "success" ]] || \
204- [[ "${{ needs.react-native-e2e.result }}" != "success" ]]; then
272+ if [[ "${{ needs.android-e2e.result }}" != "success" && "${{ needs.android-e2e.result }}" != "skipped" ]] || \
273+ [[ "${{ needs.ios-e2e.result }}" != "success" && "${{ needs.ios-e2e.result }}" != "skipped" ]] || \
274+ [[ "${{ needs.react-native-e2e.result }}" != "success" && "${{ needs.react-native-e2e.result }}" != "skipped" ]]; then
205275 echo "::error::One or more E2E test suites failed"
206276 echo "::error::Check the individual job logs for details"
207277 echo "::error::Logs available in artifacts"
0 commit comments