-
-
Notifications
You must be signed in to change notification settings - Fork 51
340 lines (306 loc) · 14.2 KB
/
integration_tests_app_ci.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
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
# Copyright (c) 2022 Sharezone UG (haftungsbeschränkt)
# Licensed under the EUPL-1.2-or-later.
#
# You may obtain a copy of the Licence at:
# https://joinup.ec.europa.eu/software/page/eupl
#
# SPDX-License-Identifier: EUPL-1.2
# This workflow is used to run integration tests on the app.
#
# We only run the integration tests in our merge group to save macOS machines.
name: integration-tests-app-ci
on:
pull_request:
paths:
# We trigger also this workflow, if this workflow is changed, so that new
# changes can be tested.
- ".github/workflows/integration_tests_app_ci.yml"
merge_group:
types:
- checks_requested
# Set permissions to none.
#
# Using the broad default permissions is considered a bad security practice
# and would cause alerts from our scanning tools.
permissions: {}
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# We can't use the official "paths" filter because it has no support for merge
# groups and we would need some kind of fallback CI when a check is required
# but ignored because of the path filter.
#
# See:
# * https://github.com/community/community/discussions/45899 (merge groups)
# * https://github.com/github/docs/commit/4364076e0fb56c2579ae90cd048939eaa2c18954
# (workaround for required checks with path filters)
changes:
runs-on: ubuntu-22.04
outputs:
changesFound: ${{ steps.filter.outputs.changesFound }}
steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
- uses: AurorNZ/paths-filter@7c547bdd24124b0d69e07c96b62fd7fec5ced19a
id: filter
with:
filters: |
changesFound:
# When we change the Flutter version, we need to trigger this workflow.
- ".fvm/fvm_config.json"
# We only build and deploy a new version, when user relevant files
# or integration test files changed.
- "app/**"
- "lib/**"
- "app/integration_test/**"
# We trigger also this workflow, if this workflow is changed, so that new
# changes will be applied.
- ".github/workflows/integration_tests_app_ci.yml"
# The following paths are excluded from the above paths. It's important to
# list the paths at the end of the file, so that the exclude paths are
# applied.
#
# See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#example-including-and-excluding-paths.
- "!**/*.md"
- "!**/*.mdx"
- "!**/*.gitignore"
- "!**/firebase.json"
- "!**/.firebaserc"
- "!app/android/fastlane/**"
android-integration-test:
needs: changes
runs-on: ubuntu-22.04
if: ${{ needs.changes.outputs.changesFound == 'true' }}
# Don't use less than 90 minutes. Often 40 minutes are enough but sometimes
# (~5% of the time) build takes longer and then is a long timeout needed.
defaults:
run:
working-directory: app/android
timeout-minutes: 90
steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
# Java is needed for building the APK, see
# https://github.com/marketplace/actions/flutter-action.
- uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0
with:
distribution: "temurin"
java-version: "11"
- name: Set Flutter version from FVM config file to environment variables
uses: kuhnroyal/flutter-fvm-config-action@6ffa30473b346f7d7c63cf9e03e6a886f940a72b
- uses: subosito/flutter-action@main
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
channel: ${{ env.FLUTTER_CHANNEL }}
- name: Build Instrumentation Test
env:
# In gradlew, we can't just pass --dart-define as we do with "flutter
# test". We need to convert the key and the value into base64, like
# "[email protected]" becomes to
# "VVNFUl8xX0VNQUlMPXVzZXJAZXhhbXBsZS5jb20=".
#
# The secrets already contain the base64 encoded values. We don't
# encode them in the workflow file, because we could easily leak the
# base64 encoded version in logs.
USER_1_EMAIL_BASE64: ${{ secrets.INTEGRATION_TEST_USER_1_EMAIL_DART_DEFINE_BASE64 }}
USER_1_PASSWORD_BASE64: ${{ secrets.INTEGRATION_TEST_USER_1_PASSWORD_DART_DEFINE_BASE64 }}
run: |
# Flutter build is required to generate files in android/ to build the
# gradle project.
#
# We are using the prod flavor because we were not able to set up
# Firebase Test Lab with the dev flavor. We always got "No tests
# found.".
flutter build apk \
--target=lib/main_prod.dart \
--flavor prod \
--config-only
./gradlew app:assembleProdDebugAndroidTest
./gradlew app:assembleProdDebug \
-Ptarget=integration_test/app_test.dart \
-Pdart-defines="$USER_1_EMAIL_BASE64,$USER_1_PASSWORD_BASE64"
- name: Setup credentials
env:
TEST_LAB_CREDENTIALS: ${{ secrets.FIREBASE_TEST_LAB_DEV_KEY }}
run: |
echo $TEST_LAB_CREDENTIALS > firebase-test-lab.json
gcloud auth activate-service-account --key-file=firebase-test-lab.json
gcloud --quiet config set project sharezone-debug
# Runs our integration tests with Firebase Test Lab.
#
# Advantages of Firebase Test Lab:
# * We can use a Linux runner instead of a macOS runner in
# Github Actions (macOS runner is required for using an Android emulator).
# * We can run the tests on a real device instead of an emulator.
# * We get a screen recording of the test run which we can use to
# investigate test failures.
# * Increases the speed of the CI by 10 minutes (compared to running the
# tests on a macOS runner).
#
# Helpful documentation:
# * https://firebase.google.com/docs/test-lab/android/command-line
- name: Run Integration tests
run: |
gcloud firebase test android run \
--type instrumentation \
--app ../build/app/outputs/apk/prod/debug/app-prod-debug.apk \
--test ../build/app/outputs/apk/androidTest/prod/debug/app-prod-debug-androidTest.apk \
--device model=Pixel2,version=30,locale=en,orientation=portrait \
--timeout 3m
# It can easily happen that a dependency changed but the .lock file is not
# updated. Or other cases where files are changed during a build.
# Therefore, fails this check if there are Git changes.
- name: Fail if there are Git diffs
run: |
# Fail if there are Git diffs and print the diff.
git diff --exit-code
# Print the Git diff with the file names and their status as a
# summary.
git diff --name-status
ios-integration-test:
needs: changes
# We are using macos-12 instead macos-13 because with macos-13 we have job
# times of 40 - 120 minutes.
#
# Before switching back to macos-13, we should check if the job times are
# still that long by running the job with a matrix (3 runs).
runs-on: macos-12
if: ${{ needs.changes.outputs.changesFound == 'true' }}
timeout-minutes: 60
steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
- name: Set Flutter version from FVM config file to environment variables
uses: kuhnroyal/flutter-fvm-config-action@6ffa30473b346f7d7c63cf9e03e6a886f940a72b
- uses: subosito/flutter-action@48cafc24713cca54bbe03cdc3a423187d413aafa
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
channel: ${{ env.FLUTTER_CHANNEL }}
# Use format expected by FVM.
# Else this won't be recognized as an installed version when setting
# '.../flutter' as the FVM Flutter version cache folder.
cache-path: "${{ runner.tool_cache }}/flutter/:version:"
- name: Install FVM
run: |
flutter pub global activate fvm 2.4.1
fvm config --cache-path '${{ runner.tool_cache }}/flutter'
# Because macos-12 doesn't have Metal support, we need to disable Impeller
# https://github.com/flutter/flutter/issues/126768
- name: Disable Impeller
working-directory: app/ios/Runner
run: /usr/libexec/PlistBuddy -c "Add :FLTEnableImpeller bool false" Info.plist
- uses: futureware-tech/simulator-action@736249ceb5ed7916224ed6b6d3c3582fd8049deb
id: simulator
with:
model: "iPhone 13"
- name: Run integration tests
working-directory: app
env:
USER_1_EMAIL: ${{ secrets.INTEGRATION_TEST_USER_1_EMAIL }}
USER_1_PASSWORD: ${{ secrets.INTEGRATION_TEST_USER_1_PASSWORD }}
SIMULATOR_UDID: ${{ steps.simulator.outputs.udid }}
# We use the `flutter drive` instead of the `flutter test` command
# because the test command times out after 12 minutes. But building the
# app takes more than 12 minutes... It seems so that there is no way to
# set the timeout (the --timeout argument has not effect). Tracking
# issue: https://github.com/flutter/flutter/issues/105913
run: |
# We need to run the integration tests with the prod flavor because
# using not the default flavor will cause an exception when
# uninstalling the app, see:
# https://github.com/flutter/flutter/issues/88690
fvm flutter drive \
--driver=test_driver/integration_test.dart \
--target=integration_test/app_test.dart \
--flavor prod \
--dart-define=USER_1_EMAIL=$USER_1_EMAIL \
--dart-define=USER_1_PASSWORD=$USER_1_PASSWORD \
-d $SIMULATOR_UDID
web-integration-test:
needs: changes
runs-on: ubuntu-22.04
if: ${{ needs.changes.outputs.changesFound == 'true' }}
timeout-minutes: 30
steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
- name: Set Flutter version from FVM config file to environment variables
uses: kuhnroyal/flutter-fvm-config-action@6ffa30473b346f7d7c63cf9e03e6a886f940a72b
- uses: subosito/flutter-action@48cafc24713cca54bbe03cdc3a423187d413aafa
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
channel: ${{ env.FLUTTER_CHANNEL }}
# Use format expected by FVM.
# Else this won't be recognized as an installed version when setting
# '.../flutter' as the FVM Flutter version cache folder.
cache-path: "${{ runner.tool_cache }}/flutter/:version:"
- name: Install FVM
run: |
flutter pub global activate fvm 2.4.1
fvm config --cache-path '${{ runner.tool_cache }}/flutter'
- name: Install chromedriver
uses: nanasess/setup-chromedriver@2c49495f83dd47aa7cee6b3d20cd5a5a3e1e016d
- name: Run integration tests
working-directory: app
env:
USER_1_EMAIL: ${{ secrets.INTEGRATION_TEST_USER_1_EMAIL }}
USER_1_PASSWORD: ${{ secrets.INTEGRATION_TEST_USER_1_PASSWORD }}
# We use the `flutter drive` command because `flutter test` is not
# available for the web yet.
run: |
chromedriver --port=4444 &
fvm flutter drive \
--driver=test_driver/integration_test.dart \
--target=integration_test/app_test.dart \
--flavor dev \
--dart-define=USER_1_EMAIL=$USER_1_EMAIL \
--dart-define=USER_1_PASSWORD=$USER_1_PASSWORD \
-d web-server
# At the moment, Flutter Integration Tests are not working with GitHub Actions
# and Flutter +3.7 (see https://github.com/flutter/flutter/issues/118469).
#
# To still have a verification that the app can be built, we just build the
# macOS app.
macos-build-test:
needs: changes
runs-on: macos-13
if: ${{ needs.changes.outputs.changesFound == 'true' }}
timeout-minutes: 60
defaults:
run:
working-directory: app
steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
- name: Install Codemagic CLI Tools
run: pip3 install codemagic-cli-tools==0.46.2
- name: Setup signing
env:
# The following secrets are used by the Codemagic CLI tool. It's important
# to use the same names as the CLI tool expects.
CERTIFICATE_PRIVATE_KEY: ${{ secrets.SHAREZONE_CERTIFICATE_PRIVATE_KEY }}
APP_STORE_CONNECT_KEY_IDENTIFIER: ${{ secrets.SHAREZONE_APP_STORE_CONNECT_KEY_IDENTIFIER }}
APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.SHAREZONE_APP_STORE_CONNECT_ISSUER_ID }}
APP_STORE_CONNECT_PRIVATE_KEY: ${{ secrets.SHAREZONE_APP_STORE_CONNECT_PRIVATE_KEY }}
BUNDLE_ID: de.codingbrain.sharezone.app
run: |
# Even when are trying to build app, we need to use "--platform IOS".
# The reason for this that our production bundle ID was created for
# IOS only. However, it's still possible to sign a macOS app with an
# iOS bundle ID (requires "--strict-match-identifier", otherwise the
# tool would try to use our de.codingbrain.sharezone.app.dev bundle ID
# which is a universal bundle ID and has no specific platform).
#
# See https://github.com/codemagic-ci-cd/cli-tools/issues/314
app-store-connect fetch-signing-files $BUNDLE_ID \
--platform IOS \
--type MAC_APP_STORE \
--strict-match-identifier \
--create
keychain initialize
keychain add-certificates
xcode-project use-profiles
- name: Set Flutter version from FVM config file to environment variables
uses: kuhnroyal/flutter-fvm-config-action@6ffa30473b346f7d7c63cf9e03e6a886f940a72b
- uses: subosito/flutter-action@48cafc24713cca54bbe03cdc3a423187d413aafa
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
channel: ${{ env.FLUTTER_CHANNEL }}
- name: Build macOS app
run: |
flutter build macos \
-t lib/main_prod.dart