@@ -30,12 +30,11 @@ jobs:
3030 - name : Discover apps
3131 id : set-apps
3232 run : |
33- # TODO: Implement app discovery logic
34- # For now, we'll use a static list based on current structure
3533 if [ -n "${{ github.event.inputs.app }}" ]; then
3634 apps='["${{ github.event.inputs.app }}"]'
3735 else
38- apps='["playground"]'
36+ # Dynamically discover apps in the /apps directory
37+ apps=$(find apps -maxdepth 1 -mindepth 1 -type d -exec basename {} \; | jq -R . | jq -sc .)
3938 fi
4039 echo "apps=$apps" >> $GITHUB_OUTPUT
4140 echo "Discovered apps: $apps"
@@ -51,42 +50,81 @@ jobs:
5150 app : ${{ fromJson(needs.discover-apps.outputs.apps) }}
5251
5352 steps :
53+ - name : Delete unnecessary tools
54+ uses : jlumbroso/free-disk-space@v1.3.1
55+ with :
56+ android : false # Don't remove Android tools
57+ tool-cache : true # Remove image tool cache - rm -rf "$AGENT_TOOLSDIRECTORY"
58+ docker-images : false # Takes 16s, enable if needed in the future
59+ large-packages : false # includes google-cloud-sdk and it's slow
60+
5461 - name : Checkout code
5562 uses : actions/checkout@v4
5663
64+ - name : Install pnpm
65+ uses : pnpm/action-setup@v2
66+ with :
67+ version : latest
68+
5769 - name : Setup Node.js
5870 uses : actions/setup-node@v4
5971 with :
6072 node-version : ' 18'
6173 cache : ' pnpm'
6274
63- - name : Install pnpm
64- uses : pnpm/action-setup@v2
65- with :
66- version : latest
67-
6875 - name : Install dependencies
6976 run : |
70- # TODO: Install project dependencies
71- echo "Installing dependencies for ${{ matrix.app }}"
77+ pnpm install
78+
79+ - name : Set up JDK 17
80+ uses : actions/setup-java@v3
81+ with :
82+ java-version : ' 17'
83+ distribution : ' temurin'
7284
73- - name : Setup Android environment
85+ - name : Restore APK from cache
86+ id : cache-apk-restore
87+ uses : actions/cache/restore@v4
88+ with :
89+ path : apps/${{ matrix.app }}/android/app/build/outputs/apk/debug/app-debug.apk
90+ key : apk-${{ matrix.app }}
91+
92+ - name : Build Android app
93+ if : steps.cache-apk-restore.outputs.cache-hit != 'true'
94+ working-directory : apps/${{ matrix.app }}
7495 run : |
75- # TODO: Setup Android SDK, emulator, etc.
76- echo "Setting up Android environment for ${{ matrix.app }}"
96+ pnpm nx run @react-native-harness/${{ matrix.app }}:build-android --tasks=assembleDebug
7797
78- - name : Run E2E tests
98+ - name : Save APK to cache
99+ if : steps.cache-apk-restore.outputs.cache-hit != 'true' && success()
100+ uses : actions/cache/save@v4
101+ with :
102+ path : apps/${{ matrix.app }}/android/app/build/outputs/apk/debug/app-debug.apk
103+ key : apk-${{ matrix.app }}
104+
105+ - name : Enable KVM group perms
79106 run : |
80- # TODO: Run E2E tests on Android
81- echo "Running E2E tests for ${{ matrix.app }} on Android"
107+ echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
108+ sudo udevadm control --reload-rules
109+ sudo udevadm trigger --name-match=kvm
110+ ls /dev/kvm
82111
83- - name : Upload test results
84- if : always()
85- uses : actions/upload-artifact@v4
112+ - name : Run E2E tests
113+ uses : reactivecircus/android-emulator-runner@v2
86114 with :
87- name : e2e-results-android-${{ matrix.app }}
88- path : test-results/
89- retention-days : 7
115+ working-directory : apps/${{ matrix.app }}/android
116+ api-level : 35
117+ arch : x86_64
118+ profile : pixel_7
119+ disk-size : 1G
120+ heap-size : 1G
121+ force-avd-creation : false
122+ avd-name : Pixel_8_API_35
123+ disable-animations : true
124+ emulator-options : -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
125+ script : |
126+ adb install -r "./app/build/outputs/apk/debug/app-debug.apk"
127+ pnpm nx run @react-native-harness/${{ matrix.app }}:start --args="test android-native"
90128
91129 e2e-ios :
92130 name : E2E iOS - ${{ matrix.app }}
@@ -102,52 +140,79 @@ jobs:
102140 - name : Checkout code
103141 uses : actions/checkout@v4
104142
143+ - name : Install pnpm
144+ uses : pnpm/action-setup@v2
145+ with :
146+ version : latest
147+
105148 - name : Setup Node.js
106149 uses : actions/setup-node@v4
107150 with :
108151 node-version : ' 18'
109152 cache : ' pnpm'
110153
111- - name : Install pnpm
112- uses : pnpm/action-setup@v2
154+ - name : Install dependencies
155+ run : |
156+ pnpm install
157+
158+ - name : Get build products directory
159+ id : get-build-dir
160+ working-directory : apps/${{ matrix.app }}/ios
161+ run : |
162+ BUILD_DIR=$(xcodebuild -showBuildSettings -workspace Playground.xcworkspace -scheme Playground -configuration Debug -sdk iphonesimulator -destination "platform=iOS Simulator,name=iPhone 16 Pro" 2>/dev/null | grep -w BUILT_PRODUCTS_DIR | awk '{print $3}')
163+ echo "build_dir=$BUILD_DIR" >> $GITHUB_OUTPUT
164+ echo "Build products directory: $BUILD_DIR"
165+
166+ - name : Restore app from cache
167+ id : cache-app-restore
168+ uses : actions/cache/restore@v4
113169 with :
114- version : latest
170+ path : ${{ steps.get-build-dir.outputs.build_dir }}/Playground.app
171+ key : ios-app-${{ matrix.app }}
115172
116- - name : Install dependencies
173+ - name : CocoaPods cache
174+ if : steps.cache-app-restore.outputs.cache-hit != 'true'
175+ uses : actions/cache@v4
176+ with :
177+ path : |
178+ ./apps/${{ matrix.app }}/ios/Pods
179+ ~/Library/Caches/CocoaPods
180+ ~/.cocoapods
181+ key : ${{ matrix.app }}-${{ runner.os }}-pods-${{ hashFiles('./apps/${{ matrix.app }}/ios/Podfile.lock') }}
182+ restore-keys : |
183+ ${{ matrix.app }}-${{ runner.os }}-pods-
184+
185+ - name : Install CocoaPods
186+ if : steps.cache-app-restore.outputs.cache-hit != 'true'
187+ working-directory : apps/${{ matrix.app }}/ios
117188 run : |
118- # TODO: Install project dependencies
119- echo "Installing dependencies for ${{ matrix.app }}"
189+ pod install
120190
121- - name : Run E2E tests
191+ - name : Build iOS app
192+ if : steps.cache-app-restore.outputs.cache-hit != 'true'
193+ working-directory : apps/${{ matrix.app }}
122194 run : |
123- # TODO: Run E2E tests on iOS
124- echo "Running E2E tests for ${{ matrix.app }} on iOS"
195+ pnpm react-native build-ios
196+
197+ - name : Save app to cache
198+ if : steps.cache-app-restore.outputs.cache-hit != 'true' && success()
199+ uses : actions/cache/save@v4
200+ with :
201+ path : ${{ steps.get-build-dir.outputs.build_dir }}/Playground.app
202+ key : ios-app-${{ matrix.app }}
125203
126- - name : Upload test results
127- if : always()
128- uses : actions/upload-artifact@v4
204+ - uses : futureware-tech/simulator-action@v4
129205 with :
130- name : e2e-results-ios-${{ matrix.app }}
131- path : test-results/
132- retention-days : 7
206+ model : ' iPhone 16 Pro'
207+ os : iOS
208+ os_version : 18.2
209+ wait_for_boot : true
210+ erase_before_boot : false
133211
134- e2e-summary :
135- name : E2E Test Summary
136- runs-on : ubuntu-latest
137- needs : [e2e-android, e2e-ios]
138- if : always()
139-
140- steps :
141- - name : Check test results
212+ - name : Install app
142213 run : |
143- # TODO: Aggregate and report test results
144- echo "E2E test summary:"
145- echo "Android tests: ${{ needs.e2e-android.result }}"
146- echo "iOS tests: ${{ needs.e2e-ios.result }}"
147-
148- if [[ "${{ needs.e2e-android.result }}" == "failure" || "${{ needs.e2e-ios.result }}" == "failure" ]]; then
149- echo "Some E2E tests failed"
150- exit 1
151- else
152- echo "All E2E tests passed"
153- fi
214+ xcrun simctl install booted ${{ steps.get-build-dir.outputs.build_dir }}/Playground.app
215+
216+ - name : Run E2E tests
217+ run : |
218+ pnpm nx run @react-native-harness/${{ matrix.app }}:start --args="test ios-native"
0 commit comments