Skip to content

Commit 573315b

Browse files
committed
Merge iOS BrowserStack workflow into iOS Build & Test (macOS)
Consolidate two separate iOS CI workflows into one to reduce duplication. The build-and-test job now includes certificate install, test package build, and artifact upload. BrowserStack testing runs as a single downstream job.
1 parent 14e3cc0 commit 573315b

2 files changed

Lines changed: 124 additions & 246 deletions

File tree

.github/workflows/ios-browserstack-test.yml

Lines changed: 0 additions & 235 deletions
This file was deleted.

.github/workflows/ios-build-test-macos.yml

Lines changed: 124 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,39 @@ name: iOS Build & Test (macOS)
33
permissions:
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

1818
jobs:
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"
@@ -59,6 +72,30 @@ jobs:
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

Comments
 (0)