-
-
Notifications
You must be signed in to change notification settings - Fork 76
289 lines (252 loc) · 11.1 KB
/
test-native.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
name: Native Integration Tests
env:
# Relative path from the monorepo root to the app
test_app_path: tests/test
# Package name in the monorepo
test_app_package_name: test-test
# Used for cache keys, must be unique among all workflows
app_identifier: ios-test-app
on:
push:
pull_request:
jobs:
build-ios-test-dev-container:
name: Build iOS Test Development Container App
uses: ./.github/workflows/build-ios-test-app.yml
secrets: inherit
permissions:
contents: read
pull-requests: read
with:
configuration: Debug
build-ios-test-app:
name: Build iOS Release App
uses: ./.github/workflows/build-ios-test-app.yml
secrets: inherit
permissions:
contents: read
pull-requests: read
with:
configuration: Release
# test-ios-native:
# name: iOS Development Integration Test
# needs:
# - build-ios-test-dev-container
# runs-on: macos-14
# defaults:
# run:
# working-directory: ${{ env.test_app_path }}
# steps:
# - name: Checkout
# uses: actions/checkout@v4
# - name: Install
# uses: ./.github/actions/install
# with:
# workspace-focus: ${{ env.test_app_package_name }}
# - name: Start Dev Server
# run: node scripts/start-dev-server.mjs --no-wait
# - name: Download Dev Container App
# uses: actions/cache/restore@v4
# with:
# fail-on-cache-miss: true
# key: ${{ needs.build-ios-test-dev-container.outputs.built-app-cache-key }}
# path: ${{ needs.build-ios-test-dev-container.outputs.built-app-path }}
# - name: Get Simulator UDID
# id: get-simulator-udid
# run: |
# AVAILABLE_SIMULATORS=$(xcrun simctl list devices available --json)
# echo "Available simulators: $AVAILABLE_SIMULATORS"
# RUNTIME=$(echo $AVAILABLE_SIMULATORS | jq -r '.devices | keys | map(select(test("iOS"))) | last')
# echo "Runtime: $RUNTIME"
# SIMULATOR_INFO=$(echo $AVAILABLE_SIMULATORS | jq ".devices.\"$RUNTIME\" | map(select(.name | test(\"iPhone\"))) | last")
# SIMULATOR_UDID=$(echo $SIMULATOR_INFO | jq -r .udid)
# echo "Simulator info: $SIMULATOR_INFO"
# echo "Simulator UDID: $SIMULATOR_UDID"
# echo "simulator_udid=$SIMULATOR_UDID" >> $GITHUB_OUTPUT
# - name: Boot Simulator
# env:
# SIMULATOR_UDID: ${{ steps.get-simulator-udid.outputs.simulator_udid }}
# run: xcrun simctl boot $SIMULATOR_UDID
# - name: Install Maestro
# uses: ./.github/actions/install-maestro
# id: install-maestro
# - name: Wait for Dev Server to Be Ready
# run: node scripts/start-dev-server.mjs --check-only
# - name: Get a Copy of the Bundle
# run: |
# echo 'Fetching the React Native bundle in the background, since the first request can take a while pre-bundling dependencies and producing the first bundle without a cache. The bundle we got can also serve as troubleshooting material in case of a failure, and will be uploaded as an artifact.'
# wget -O bundle.ios.js 'http://localhost:8081/index.bundle?platform=ios' &
# - name: Install Dev Container App in Simulator
# env:
# SIMULATOR_UDID: ${{ steps.get-simulator-udid.outputs.simulator_udid }}
# APP_PATH: ${{ needs.build-ios-test-dev-container.outputs.built-app-path }}
# working-directory: .
# run: xcrun simctl install $SIMULATOR_UDID $APP_PATH
# - name: Test
# run: |
# export PATH="$PATH":"$HOME/.maestro/bin"
# export MAESTRO_DRIVER_STARTUP_TIMEOUT=180000 # 3 minutes
# maestro test maestro-flows/basic.yaml
# - name: Upload Dev Container App
# uses: actions/[email protected]
# # Only upload if the test failed to save space
# if: ${{ failure() }}
# continue-on-error: true
# with:
# name: dev-container-app
# path: |
# path: ${{ needs.build-ios-test-dev-container.outputs.built-app-path }}
# - name: Upload Server Log
# uses: actions/[email protected]
# if: ${{ always() }}
# continue-on-error: true
# with:
# name: dev-server.log
# path: |
# ${{ env.test_app_path }}/dev-server.log
# - name: Prepare Maestro Logs
# id: prepare-maestro-logs
# if: ${{ always() && steps.install-maestro.outcome == 'success' }}
# continue-on-error: true
# run: cp -r "$HOME/.maestro/tests" maestro-logs
# - name: Upload Maestro Logs
# uses: actions/[email protected]
# if: ${{ always() && steps.prepare-maestro-logs.outcome == 'success' }}
# continue-on-error: true
# with:
# name: release-maestro-logs
# path: |
# ${{ env.test_app_path }}/maestro-logs
# - name: Upload Maestro Screenshots
# uses: actions/[email protected]
# if: ${{ always() && steps.install-maestro.outcome == 'success' }}
# continue-on-error: true
# with:
# name: release-maestro-screenshots
# path: |
# ${{ env.test_app_path }}/maestro-screenshots
# - name: Upload Reference React Native Bundle
# uses: actions/[email protected]
# if: ${{ always() }}
# continue-on-error: true
# with:
# name: dev-sample-bundle.ios.js
# path: |
# ${{ env.test_app_path }}/bundle.ios.js
test-ios-native-release:
name: iOS Release Integration Test
# Note: Some parts of the native build process are not covered by this test:
# * We do not test the generated Xcode project has the Build Phase "Bundle React Native code and images" setup correctly using the standard `react-native bundle` command. This is done by the "vxrn/expo-plugin" Expo plugin which users should include in their `app.json` configuration. If that didn't work properally, Expo prebuild may setup the Xcode project to use Expo's custom bundle command that uses Metro.
# * We do not test `react-native/scripts/react-native-xcode.sh`, instead we copy parts of it into our test scripts, simulating parts of the build process without running the whole native build.
needs:
- build-ios-test-app
runs-on: macos-14
defaults:
run:
working-directory: ${{ env.test_app_path }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install
uses: ./.github/actions/install
with:
workspace-focus: ${{ env.test_app_package_name }}
- name: Download Built Native App
uses: actions/cache/restore@v4
with:
fail-on-cache-miss: true
key: ${{ needs.build-ios-test-app.outputs.built-app-cache-key }}
path: ${{ needs.build-ios-test-app.outputs.built-app-path }}
- name: Get Simulator UDID
id: get-simulator-udid
run: |
AVAILABLE_SIMULATORS=$(xcrun simctl list devices available --json)
echo "Available simulators: $AVAILABLE_SIMULATORS"
RUNTIME=$(echo $AVAILABLE_SIMULATORS | jq -r '.devices | keys | map(select(test("iOS"))) | last')
echo "Runtime: $RUNTIME"
SIMULATOR_INFO=$(echo $AVAILABLE_SIMULATORS | jq ".devices.\"$RUNTIME\" | map(select(.name | test(\"iPhone\"))) | last")
SIMULATOR_UDID=$(echo $SIMULATOR_INFO | jq -r .udid)
echo "Simulator info: $SIMULATOR_INFO"
echo "Simulator UDID: $SIMULATOR_UDID"
echo "simulator_udid=$SIMULATOR_UDID" >> $GITHUB_OUTPUT
- name: Boot Simulator
env:
SIMULATOR_UDID: ${{ steps.get-simulator-udid.outputs.simulator_udid }}
run: xcrun simctl boot $SIMULATOR_UDID
- name: Install Maestro
id: install-maestro
uses: ./.github/actions/install-maestro
- name: Patch Packages
run: |
node_modules/.bin/one patch
# Prebuild and pod install because we need hermesc which is installed by pod install
- name: Prebuild
run: |
node_modules/.bin/expo prebuild --platform ios --no-install # --no-install is used to skip installing dependencies, specifically `pod install` as we want to do it after the Cache Pods step
- name: Cache Pods
uses: actions/cache@v4
env:
cache-name: ${{ env.app_identifier }}-pods
with:
path: ${{ env.test_app_path }}/ios/Pods
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles(format('{0}/ios/Podfile.lock', env.test_app_path)) }}
restore-keys: |
${{ runner.os }}-${{ env.cache-name }}-
- name: Pod Install
run: |
cd ios && pod install
- name: Bundle React Native code and images
run: |
mkdir test-bundle-output
node_modules/.bin/react-native bundle --platform ios --dev false --bundle-output test-bundle-output/main.tmp.jsbundle --assets-dest test-bundle-output
ios/Pods/hermes-engine/destroot/bin/hermesc -emit-binary -max-diagnostic-width=80 -O -output-source-map -out test-bundle-output/main.jsbundle test-bundle-output/main.tmp.jsbundle
- name: Replace JS Bundle and Assets in App
run: |
cp -r test-bundle-output/. ${{ github.workspace }}/${{ needs.build-ios-test-app.outputs.built-app-path }}/
- name: Check .app
id: check-app
run: |
if [ ! -e ${{ github.workspace }}/${{ needs.build-ios-test-app.outputs.built-app-path }} ]; then
echo "Error: .app not found"
exit 1
fi
- name: Install App in Simulator
env:
SIMULATOR_UDID: ${{ steps.get-simulator-udid.outputs.simulator_udid }}
APP_PATH: ${{ needs.build-ios-test-app.outputs.built-app-path }}
working-directory: .
run: xcrun simctl install $SIMULATOR_UDID $APP_PATH
- name: Test
run: |
export PATH="$PATH":"$HOME/.maestro/bin"
export MAESTRO_DRIVER_STARTUP_TIMEOUT=180000 # 3 minutes
maestro test maestro-flows/basic.yaml
- name: Upload App
uses: actions/[email protected]
if: ${{ always() && steps.check-app.outcome == 'success' }}
continue-on-error: true
with:
name: release-app
path: |
${{ needs.build-ios-test-app.outputs.built-app-path }}
- name: Prepare Maestro Logs
id: prepare-maestro-logs
if: ${{ always() && steps.install-maestro.outcome == 'success' }}
continue-on-error: true
run: cp -r "$HOME/.maestro/tests" maestro-logs
- name: Upload Maestro Logs
uses: actions/[email protected]
if: ${{ always() && steps.prepare-maestro-logs.outcome == 'success' }}
continue-on-error: true
with:
name: release-maestro-logs
path: |
${{ env.test_app_path }}/maestro-logs
- name: Upload Maestro Screenshots
uses: actions/[email protected]
if: ${{ always() && steps.install-maestro.outcome == 'success' }}
continue-on-error: true
with:
name: release-maestro-screenshots
path: |
${{ env.test_app_path }}/maestro-screenshots