Skip to content

Commit 1059365

Browse files
[CI] Update iOS runtimes' download (#530)
1 parent 82bd989 commit 1059365

File tree

8 files changed

+139
-36
lines changed

8 files changed

+139
-36
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: 'Setup iOS Runtime'
2+
description: 'Download and Install requested iOS Runtime'
3+
runs:
4+
using: "composite"
5+
steps:
6+
- name: Cache iOS Simulator Runtime
7+
uses: actions/cache@v4
8+
id: runtime-cache
9+
with:
10+
path: ./*.dmg
11+
key: ipsw-runtime-ios-${{ inputs.version }}
12+
restore-keys: ipsw-runtime-ios-${{ inputs.version }}
13+
- name: Setup iOS Simulator Runtime
14+
shell: bash
15+
run: |
16+
brew install blacktop/tap/ipsw
17+
bundle exec fastlane install_runtime ios:${{ inputs.version }}
18+
xcrun simctl list runtimes
19+
- name: Create Custom iOS Simulator
20+
shell: bash
21+
run: |
22+
ios_version_dash=$(echo "${{ inputs.version }}" | tr '.' '-') # ex: 16.4 -> 16-4
23+
xcrun simctl create custom-test-device "${{ inputs.device }}" "com.apple.CoreSimulator.SimRuntime.iOS-$ios_version_dash"
24+
xcrun simctl list devices ${{ inputs.version }}
25+
26+
inputs:
27+
version:
28+
description: "iOS Runtime Version"
29+
required: true
30+
device:
31+
description: "iOS Simulator Model"
32+
required: true

.github/workflows/cron-checks.yml

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,14 @@ env:
1717
jobs:
1818
build-test-app-and-frameworks:
1919
name: Build Test App and Frameworks
20-
runs-on: macos-13
20+
runs-on: macos-14
2121
steps:
2222
- uses: actions/[email protected]
2323
- uses: ./.github/actions/ruby-cache
2424
- uses: ./.github/actions/xcode-cache
2525
- name: Build
2626
run: bundle exec fastlane build_test_app_and_frameworks
2727
timeout-minutes: 60
28-
env:
29-
XCODE_VERSION: "15.2" # Should match the minimum version in dependent jobs
3028
- uses: actions/upload-artifact@v4
3129
if: success()
3230
with:
@@ -42,16 +40,16 @@ jobs:
4240
strategy:
4341
matrix:
4442
include:
45-
- ios: 17.2
46-
xcode: 15.2
43+
- ios: 17.4
44+
xcode: 15.4
4745
os: macos-14
48-
device: "iPhone 15 Pro"
46+
device: "iPhone 14 Pro"
4947
setup_runtime: false
5048
- ios: 16.4
51-
xcode: 15.2
49+
xcode: 15.3
5250
os: macos-14
53-
device: "iPhone 14 Pro Max"
54-
setup_runtime: false
51+
device: "iPhone 14 Pro"
52+
setup_runtime: true
5553
fail-fast: false
5654
runs-on: ${{ matrix.os }}
5755
env:
@@ -70,16 +68,13 @@ jobs:
7068
INSTALL_ALLURE: true
7169
INSTALL_YEETD: true
7270
SKIP_MINT_BOOTSTRAP: true
73-
- name: Cache iOS Simulator Runtime
74-
uses: actions/cache@v4
75-
id: runtime-cache
76-
with:
77-
path: ~/Library/Caches/XcodeInstall/
78-
key: runtime-ios-${{ matrix.ios }}
79-
restore-keys: runtime-ios-${{ matrix.ios }}
80-
- name: Setup iOS ${{ matrix.ios }} Runtime
71+
SKIP_BREW_BOOTSTRAP: true
72+
- uses: ./.github/actions/setup-ios-runtime
8173
if: ${{ matrix.setup_runtime }}
82-
run: bundle exec fastlane install_sim ios:"${{ matrix.ios }}"
74+
timeout-minutes: 60
75+
with:
76+
version: ${{ matrix.ios }}
77+
device: ${{ matrix.device }}
8378
- name: Launch Allure TestOps
8479
run: bundle exec fastlane allure_launch cron:true
8580
- name: Run UI Tests (Debug)
@@ -156,7 +151,7 @@ jobs:
156151
steps:
157152
- uses: actions/[email protected]
158153
- uses: ./.github/actions/ruby-cache
159-
- name: List Xcode versions xcversion sees
154+
- name: List Xcode versions
160155
run: mdfind "kMDItemCFBundleIdentifier = 'com.apple.dt.Xcode'"
161156
timeout-minutes: 25
162157
- name: Build SwiftUI

.github/workflows/smoke-checks.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ jobs:
127127
INSTALL_ALLURE: true
128128
INSTALL_YEETD: true
129129
SKIP_MINT_BOOTSTRAP: true
130+
SKIP_BREW_BOOTSTRAP: true
130131
- name: Run UI Tests (Debug)
131132
run: bundle exec fastlane test_e2e_mock device:"${{ env.IOS_SIMULATOR_DEVICE }}" batch:'${{ matrix.batch }}' test_without_building:true
132133
timeout-minutes: 100
@@ -207,7 +208,7 @@ jobs:
207208
steps:
208209
- uses: actions/[email protected]
209210
- uses: ./.github/actions/ruby-cache
210-
- name: List Xcode versions xcversion sees
211+
- name: List Xcode versions
211212
run: mdfind "kMDItemCFBundleIdentifier = 'com.apple.dt.Xcode'"
212213
timeout-minutes: 25
213214
- name: Build SwiftUI

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# OS X
22
.DS_Store
33

4+
# Environment Variables
5+
.env
6+
47
# Xcode
58
#
69
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
@@ -67,6 +70,7 @@ Products/
6770
# For more information about the recommended setup visit:
6871
# https://docs.fastlane.tools/best-practices/source-control/#source-control
6972

73+
!fastlane/.env
7074
fastlane/report.xml
7175
fastlane/Preview.html
7276
fastlane/screenshots
@@ -91,3 +95,4 @@ derived_data/
9195
spm_cache/
9296
.buildcache
9397
buildcache
98+
*.dmg

Scripts/bootstrap.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@ ln -sf ../../hooks/pre-commit.sh .git/hooks/pre-commit
3737
chmod +x .git/hooks/pre-commit
3838
chmod +x ./hooks/git-format-staged
3939

40-
puts "Install brew dependencies"
41-
brew bundle -d
40+
if [ "${SKIP_BREW_BOOTSTRAP:-}" != true ]; then
41+
puts "Install brew dependencies"
42+
brew bundle -d
43+
fi
4244

4345
if [ "${SKIP_MINT_BOOTSTRAP:-}" != true ]; then
4446
puts "Bootstrap Mint dependencies"

Scripts/install_ios_runtime.sh

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/bin/bash -e
2+
# Copyright 2024 Namespace Labs Inc. Licensed under the MIT License.
3+
4+
log() { echo "👉 ${1}" >&2; }
5+
die() { log "${1}"; exit 1; }
6+
[ $# -eq 1 ] || die "usage: $0 path/to/runtime.dmg"
7+
8+
dmg=$1
9+
mountpoint=$(mktemp -d)
10+
staging=$(mktemp -d)
11+
12+
cleanup() {
13+
if [ -d "$staging" ]; then
14+
set +e
15+
log "Removing $staging..."
16+
rm -r "$staging"
17+
log "Unmounting $mountpoint..."
18+
hdiutil detach "$mountpoint" >&2
19+
fi
20+
21+
if [ -d "$mountpoint" ]; then
22+
log "Removing $mountpoint..."
23+
rmdir "$mountpoint"
24+
fi
25+
}
26+
trap cleanup EXIT
27+
28+
log "Mounting $dmg on $mountpoint..."
29+
hdiutil attach "$dmg" -mountpoint "$mountpoint" >&2
30+
31+
if ! ls "$mountpoint"/*.pkg >/dev/null 2>&1; then
32+
log "Detected a modern volume runtime; installing with simctl..."
33+
xcrun simctl runtime add "$1"
34+
exit 0
35+
fi
36+
37+
log "Detected packaged runtime."
38+
39+
bundle=$(echo "$mountpoint"/*.pkg)
40+
basename=$(basename "$bundle")
41+
sdkname=${basename%.*}
42+
log "Found package $bundle (sdk $sdkname)."
43+
44+
log "Expanding package $bundle to $staging/expanded..."
45+
pkgutil --expand "$bundle" "$staging/expanded"
46+
47+
dest=/Library/Developer/CoreSimulator/Profiles/Runtimes/$sdkname.simruntime
48+
# The package would try to install itself into volume root; this is wrong.
49+
log "Rewriting package install location to $dest..."
50+
sed -I '' "s|<pkg-info|<pkg-info install-location=\"$dest\"|" "$staging/expanded/PackageInfo"
51+
52+
log "Re-assembling the package $staging/$basename..."
53+
pkgutil --flatten "$staging/expanded" "$staging/$basename"
54+
55+
log "Installing $staging/$basename..."
56+
sudo installer -pkg "$staging/$basename" -target /
57+
58+
version=$(plutil -extract CFBundleName raw "$dest/Contents/Info.plist")
59+
log "Installed $version."

fastlane/.env

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT=180
3+
FASTLANE_XCODEBUILD_SETTINGS_RETRIES=10
4+
FASTLANE_SKIP_ACTION_SUMMARY=true
5+
FASTLANE_HIDE_PLUGINS_TABLE=true
6+
FASTLANE_SKIP_UPDATE_CHECK=true
7+
FASTLANE_HIDE_CHANGELOG=true

fastlane/Fastfile

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ is_localhost = !is_ci
2020
before_all do |lane|
2121
if is_ci
2222
setup_ci
23-
ENV['FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT'] = '180'
24-
ENV['FASTLANE_XCODEBUILD_SETTINGS_RETRIES'] = '10'
2523
xcversion(version: xcode_version) unless [:publish_release, :allure_launch, :allure_upload, :copyright, :pod_lint].include?(lane)
2624
end
2725
end
@@ -247,13 +245,13 @@ private_lane :parallelize_tests_on_ci do |options|
247245
UI.success("Tests in total: #{only_testing.flatten.size}. Running #{only_testing_batch.size} of them ⌛️")
248246
scan(options[:scan].merge(only_testing: only_testing_batch))
249247
rescue StandardError
250-
failed_tests = retreive_failed_e2e_tests
248+
failed_tests = retreive_failed_tests
251249
UI.important("Re-running #{failed_tests.size} failed tests ⌛️")
252250
scan(options[:scan].merge(only_testing: failed_tests))
253251
end
254252
end
255253

256-
private_lane :retreive_failed_e2e_tests do
254+
private_lane :retreive_failed_tests do
257255
report_path = 'test_output/report.junit'
258256
raise UI.user_error!('There is no junit report to parse') unless File.file?(report_path)
259257

@@ -388,17 +386,21 @@ lane :rubocop do
388386
sh('bundle exec rubocop')
389387
end
390388

391-
lane :install_sim do |options|
392-
xcode_install_cache_dir = File.expand_path('~/Library/Caches/XcodeInstall')
393-
sim_dmg_path = Dir["#{xcode_install_cache_dir}/*.dmg"].first
394-
sim_pkg_path = Dir["#{xcode_install_cache_dir}/*.pkg"].first
395-
if is_localhost || sim_dmg_path.nil? || sim_pkg_path.nil?
396-
sh("bundle exec xcversion simulators --install='iOS #{options[:ios]}'")
389+
lane :install_runtime do |options|
390+
runtimes = `xcrun simctl runtime list -j`
391+
UI.message("👉 Runtime list:\n#{runtimes}")
392+
simulators = JSON.parse(runtimes).select do |_, sim|
393+
sim['platformIdentifier'].end_with?('iphonesimulator') && sim['version'] == options[:ios] && sim['state'] == 'Ready'
394+
end
395+
396+
if simulators.empty?
397+
Dir.chdir('..') do
398+
sh("echo 'iOS #{options[:ios]} Simulator' | ipsw download xcode --sim") if Dir['*.dmg'].first.nil?
399+
sh("./Scripts/install_ios_runtime.sh #{Dir['*.dmg'].first}")
400+
UI.success("iOS #{options[:ios]} Runtime successfuly installed")
401+
end
397402
else
398-
sh("hdiutil attach '#{sim_dmg_path}'")
399-
sh("sudo installer -pkg '#{sim_pkg_path}' -target /")
400-
mount_point = sh("hdiutil attach '#{sim_dmg_path}' | grep Volumes | cut -f 3").strip
401-
sh("hdiutil detach '#{mount_point}'")
403+
UI.important("iOS #{options[:ios]} Runtime already exists")
402404
end
403405
end
404406

0 commit comments

Comments
 (0)