@@ -3,26 +3,39 @@ name: iOS Build & Test (macOS)
33permissions :
44 contents : read
55
6- # DISABLED for testing
7- # on:
8- # push:
9- # branches: [ master, submission-v* ]
10- # pull_request:
11- # types: [ opened, synchronize, reopened ]
12- # merge_group:
13- # types: [ checks_requested ]
14- #
6+ on :
7+ workflow_dispatch :
8+ push :
9+ branches : [ master, submission-v* ]
10+ pull_request :
11+ types : [ opened, synchronize, reopened ]
12+ merge_group :
13+ types : [ checks_requested ]
1514
16- on : [workflow_dispatch]
15+ env :
16+ BROWSERSTACK_CREDENTIALS : ${{ secrets.BROWSERSTACK_CREDENTIALS }}
1717
1818jobs :
19- build :
19+ computed :
20+ runs-on : ubuntu-22.04
21+ steps :
22+ - name : Compute build number
23+ id : set
24+ env :
25+ OFFSET : ${{ vars.FLUTTER_BUILD_NUMBER_OFFSET }}
26+ run : echo "build_number=$((GITHUB_RUN_NUMBER + ${OFFSET:-0}))" >> "$GITHUB_OUTPUT"
27+ outputs :
28+ build_number : ${{ steps.set.outputs.build_number }}
29+
30+ build-and-test :
2031 name : Build and test iOS app
32+ needs : computed
2133 # https://github.com/actions/runner-images/blob/main/images/macos/macos-15-arm64-Readme.md
2234 runs-on : macos-15
2335 timeout-minutes : 180
2436 env :
2537 PERF_TEST : true
38+ FLUTTER_BUILD_NUMBER : ${{ needs.computed.outputs.build_number }}
2639 # Because iPhone simulator on GitHub Actions is not reliable, and caused a lot of test failures,
2740 # we run only 1 benchmark to validate the build.
2841 BENCHMARK_IDS : " image_classification_v2"
5972 path : /tmp/bazel_cache
6073 key : ${{ runner.os }}-bazel_cache-${{ hashFiles('**/BUILD', '**/WORKSPACE') }}
6174 restore-keys : ${{ runner.os }}-bazel_cache-
75+ - name : Install the Apple certificate and provisioning profile
76+ env :
77+ IOS_BUILD_CERTIFICATE_BASE64 : ${{ secrets.IOS_BUILD_CERTIFICATE_BASE64 }}
78+ IOS_BUILD_CERTIFICATE_PASSWORD : ${{ secrets.IOS_BUILD_CERTIFICATE_PASSWORD }}
79+ IOS_BUILD_PROVISION_PROFILE_BASE64 : ${{ secrets.IOS_BUILD_PROVISION_PROFILE_BASE64 }}
80+ IOS_KEYCHAIN_PASSWORD : ${{ secrets.IOS_KEYCHAIN_PASSWORD }}
81+ run : |
82+ CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
83+ PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
84+ KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
85+
86+ echo -n "$IOS_BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
87+ echo -n "$IOS_BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
88+
89+ security create-keychain -p "$IOS_KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
90+ security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
91+ security unlock-keychain -p "$IOS_KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
92+
93+ security import $CERTIFICATE_PATH -P "$IOS_BUILD_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
94+ security set-key-partition-list -S apple-tool:,apple: -k "$IOS_KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
95+ security list-keychain -d user -s $KEYCHAIN_PATH
96+
97+ mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
98+ cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
6299 - name : Build iOS app
63100 env :
64101 BAZEL_OUTPUT_ROOT_ARG : " --output_user_root=/tmp/bazel_output"
@@ -85,3 +122,79 @@ jobs:
85122 max_attempts : 2
86123 command : |
87124 make flutter/test/integration
125+ - name : Build iOS test package
126+ env :
127+ DEVELOPMENT_TEAM : ${{ secrets.APPLE_DEVELOPMENT_TEAM }}
128+ run : |
129+ make flutter/ios/test-package
130+ - name : Upload test package artifact
131+ uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
132+ with :
133+ name : ios-test-package-${{ needs.computed.outputs.build_number }}
134+ path : output/ios-test-package/*.zip
135+ retention-days : 28
136+ if-no-files-found : error
137+ - name : Clean up keychain and provisioning profile
138+ if : ${{ always() }}
139+ run : |
140+ security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
141+ rm ~/Library/MobileDevice/Provisioning\ Profiles/build_pp.mobileprovision
142+
143+ test-ios-browserstack :
144+ name : ${{ matrix.backend }}-${{ matrix.device }}
145+ needs :
146+ - computed
147+ - build-and-test
148+ runs-on : ubuntu-22.04
149+ timeout-minutes : 60
150+ strategy :
151+ fail-fast : false
152+ max-parallel : 2
153+ matrix :
154+ include :
155+ - backend : " tflite"
156+ device : " iPhone 16 Pro-18"
157+ - backend : " apple"
158+ device : " iPhone 16 Pro-18"
159+ env :
160+ TEST_PACKAGE_NAME : ios_tests-${{ needs.computed.outputs.build_number }}.zip
161+ BROWSERSTACK_LOGS_DIR : /tmp/browserstack-device-logs
162+ steps :
163+ - uses : actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
164+ - name : Download test package
165+ uses : actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
166+ with :
167+ name : ios-test-package-${{ needs.computed.outputs.build_number }}
168+ path : /tmp
169+ - name : Upload test package to BrowserStack
170+ run : |
171+ curl -u "$BROWSERSTACK_CREDENTIALS" \
172+ -X POST "https://api-cloud.browserstack.com/app-automate/flutter-integration-tests/v2/ios/test-package" \
173+ -F "file=@/tmp/$TEST_PACKAGE_NAME" \
174+ -F "custom_id=$TEST_PACKAGE_NAME"
175+ - uses : nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
176+ name : Trigger App Automate
177+ env :
178+ BROWSERSTACK_PLATFORM : ios
179+ BROWSERSTACK_CREDENTIALS : ${{ secrets.BROWSERSTACK_CREDENTIALS }}
180+ BROWSERSTACK_PROJECT : ${{ github.event.repository.name }}
181+ BROWSERSTACK_TEST_PACKAGE : ${{ env.TEST_PACKAGE_NAME }}
182+ BROWSERSTACK_BUILD_TAG : ${{ matrix.device }}
183+ BROWSERSTACK_LOGS_DIR : ${{ env.BROWSERSTACK_LOGS_DIR }}
184+ BROWSERSTACK_DEVICES : >-
185+ ["${{ matrix.device }}"]
186+ with :
187+ timeout_minutes : 60
188+ max_attempts : 2
189+ retry_wait_seconds : 300
190+ retry_on_exit_code : 9
191+ command : |
192+ bash .github/workflows/scripts/browserstack-app-automate.sh
193+ - name : Upload BrowserStack logs
194+ uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
195+ if : always()
196+ with :
197+ name : logs-${{ matrix.backend }}-${{ matrix.device }}-${{ needs.computed.outputs.build_number }}
198+ path : ${{ env.BROWSERSTACK_LOGS_DIR }}
199+ retention-days : 28
200+ if-no-files-found : error
0 commit comments