@@ -37,12 +37,12 @@ jobs:
3737 runs-on : macos-26
3838 steps :
3939 - name : Git Checkout
40- uses : actions/checkout@v4
40+ uses : actions/checkout@v5
4141 with :
4242 fetch-depth : 0 # required to be able to find Git tags
4343
44- - name : Select Xcode version
45- run : sudo xcodes select 26.2
44+ - name : Select Xcode
45+ run : sudo xcodes select 26.3
4646
4747 - name : Install Runtimes
4848 uses : nick-fields/retry@v3
@@ -55,174 +55,124 @@ jobs:
5555 run : |
5656 set -eo pipefail
5757 export LIB_VERSION=$(git describe --tags `git rev-list --tags --max-count=1`)
58- pod lib lint SwiftUIIntrospect.podspec --allow-warnings
58+ pod lib lint SwiftUIIntrospect.podspec --allow-warnings --skip-tests
5959
6060 ci :
6161 if : github.event_name != 'pull_request' || !contains(github.event.pull_request.title, '[skip ci]')
62- name : ${{ matrix.runtime[0] }} ${{ matrix.runtime[1] }}
63- runs-on : macos-26
62+ name : ${{ matrix.name }}
63+ runs-on : ${{ matrix.runner || ' macos-26' }}
6464 strategy :
6565 fail-fast : false
6666 matrix :
67- runtime :
68- - [iOS, 15, 5]
69- - [iOS, 16, 4]
70- - [iOS, 17, 5]
71- - [iOS, 18, 6]
72- - [iOS, 26, 0]
73-
74- - [iPadOS, 15, 5]
75- - [iPadOS, 16, 4]
76- - [iPadOS, 17, 5]
77- - [iPadOS, 18, 6]
78- - [iPadOS, 26, 0]
79-
80- - [macCatalyst, 15, 0]
81- - [macOS, 15, 0]
82-
83- - [tvOS, 15, 4]
84- - [tvOS, 16, 4]
85- - [tvOS, 17, 5]
86- - [tvOS, 18, 5]
87- - [tvOS, 26, 0]
88-
89- - [visionOS, 1, 2]
90- - [visionOS, 2, 5]
91- - [visionOS, 26, 0]
92-
93- - [watchOS, 8, 5]
94- - [watchOS, 9, 4]
95- - [watchOS, 10, 5]
96- - [watchOS, 11, 5]
97- - [watchOS, 26, 0]
67+ include :
68+ # iOS (iPhone)
69+ - { name: "iOS 15.5", runtime: "iOS 15.5", device: "iPhone 13 Pro" }
70+ - { name: "iOS 16.4", runtime: "iOS 16.4", device: "iPhone 14 Pro" }
71+ - { name: "iOS 17.5", runtime: "iOS 17.5", device: "iPhone 15 Pro" }
72+ - { name: "iOS 18.5", runtime: "iOS 18.5", device: "iPhone 16 Pro", runner: macos-15 }
73+ - { name: "iOS 26.2", runtime: "iOS 26.2", device: "iPhone 17 Pro" }
74+ # iPadOS
75+ - { name: "iPadOS 15.5", runtime: "iOS 15.5", device: "iPad Pro (11-inch) (3rd generation)" }
76+ - { name: "iPadOS 16.4", runtime: "iOS 16.4", device: "iPad Pro (11-inch) (4th generation)" }
77+ - { name: "iPadOS 17.5", runtime: "iOS 17.5", device: "iPad Pro 11-inch (M4)" }
78+ - { name: "iPadOS 18.5", runtime: "iOS 18.5", device: "iPad Pro 11-inch (M4)", runner: macos-15 }
79+ - { name: "iPadOS 26.0", runtime: "iOS 26.0", device: "iPad Pro 11-inch (M4)" }
80+ # macOS / macCatalyst
81+ - { name: "macCatalyst 15", destination: "platform=macOS,variant=Mac Catalyst", runner: macos-15 }
82+ - { name: "macCatalyst 26", destination: "platform=macOS,variant=Mac Catalyst" }
83+ - { name: "macOS 15", destination: "platform=macOS", runner: macos-15 }
84+ - { name: "macOS 26", destination: "platform=macOS" }
85+ # tvOS
86+ - { name: "tvOS 15.4", runtime: "tvOS 15.4", device: "Apple TV" }
87+ - { name: "tvOS 16.4", runtime: "tvOS 16.4", device: "Apple TV" }
88+ - { name: "tvOS 17.5", runtime: "tvOS 17.5", device: "Apple TV" }
89+ - { name: "tvOS 18.5", runtime: "tvOS 18.5", device: "Apple TV", runner: macos-15 }
90+ - { name: "tvOS 26.2", runtime: "tvOS 26.2", device: "Apple TV" }
91+ # visionOS
92+ - { name: "visionOS 1.2", runtime: "visionOS 1.2", device: "Apple Vision Pro (at 2732x2048)" }
93+ - { name: "visionOS 2.5", runtime: "visionOS 2.5", device: "Apple Vision Pro (at 2732x2048)", runner: macos-15 }
94+ - { name: "visionOS 26.2", runtime: "visionOS 26.2", device: "Apple Vision Pro" }
95+ # watchOS (build-only, no test support)
96+ - { name: "watchOS 8.5", runtime: "watchOS 8.5", device: "Apple Watch Series 7 (45mm)", build_only: true }
97+ - { name: "watchOS 9.4", runtime: "watchOS 9.4", device: "Apple Watch Series 8 (45mm)", build_only: true }
98+ - { name: "watchOS 10.5", runtime: "watchOS 10.5", device: "Apple Watch Series 9 (45mm)", build_only: true }
99+ - { name: "watchOS 11.5", runtime: "watchOS 11.5", device: "Apple Watch Series 10 (42mm)", build_only: true, runner: macos-15 }
100+ - { name: "watchOS 26.2", runtime: "watchOS 26.2", device: "Apple Watch Series 11 (42mm)", build_only: true }
98101 steps :
99102 - name : Git Checkout
100103 uses : actions/checkout@v5
101104
102- - name : Set Environment Variables
103- run : |
104- set -euo pipefail
105-
106- PLATFORM="${{ matrix.runtime[0] }}"
107- MAJOR="${{ matrix.runtime[1] }}"
108- MINOR="${{ matrix.runtime[2] }}"
109-
110- if [ "$PLATFORM" = "iPadOS" ]; then
111- PLATFORM=iOS
112- SCRIPT_PLATFORM=ipados
113- else
114- case "$PLATFORM" in
115- iOS) SCRIPT_PLATFORM=ios ;;
116- macOS) SCRIPT_PLATFORM=macos ;;
117- macCatalyst) SCRIPT_PLATFORM=mac-catalyst ;;
118- tvOS) SCRIPT_PLATFORM=tvos ;;
119- visionOS) SCRIPT_PLATFORM=visionos ;;
120- watchOS) SCRIPT_PLATFORM=watchos ;;
121- esac
122- fi
123-
124- if [ "$PLATFORM" = "macCatalyst" ]; then
125- XCB_PLATFORM="mac-catalyst"
126- else
127- XCB_PLATFORM="$PLATFORM"
128- fi
129-
130- RUNTIME="$PLATFORM $MAJOR.$MINOR"
131-
132- echo "PLATFORM=$PLATFORM" >> $GITHUB_ENV
133- echo "MAJOR=$MAJOR" >> $GITHUB_ENV
134- echo "MINOR=$MINOR" >> $GITHUB_ENV
135- echo "RUNTIME=$RUNTIME" >> $GITHUB_ENV
136- echo "SCRIPT_PLATFORM=$SCRIPT_PLATFORM" >> $GITHUB_ENV
137-
138- - if : ${{ env.PLATFORM != 'macCatalyst' && env.PLATFORM != 'macOS' }}
139- name : Download Default ${{ env.PLATFORM }} Runtime
140- run : xcodebuild -downloadPlatform ${{ env.PLATFORM }}
141- continue-on-error : true
142-
143- - if : ${{ env.PLATFORM != 'macCatalyst' && env.PLATFORM != 'macOS' }}
144- name : Check for ${{ env.RUNTIME }} Runtime
145- run : |
146- if xcrun simctl list runtimes | grep -q "$RUNTIME"; then
147- echo "has_runtime=true" >> "$GITHUB_ENV"
148- else
149- echo "has_runtime=false" >> "$GITHUB_ENV"
150- fi
151-
152- - name : Select Xcode 26.0
153- uses : mxcl/xcodebuild@v3
154- with :
155- xcode : ~26.0
156- action : none
157- verbosity : xcbeautify
105+ - name : Select Xcode
106+ run : sudo xcodes select 26.3
158107
159- - if : env.has_runtime == 'false'
160- name : List Downloadable Runtimes
161- run : xcodes runtimes --include-betas
162-
163- - if : env.has_runtime == 'false'
164- name : Download Required ${{ env.RUNTIME }} Runtime
108+ - name : Install ${{ matrix.runtime }} Runtime
109+ if : matrix.runtime
165110 uses : nick-fields/retry@v3
166111 with :
167- timeout_minutes : 15
112+ timeout_minutes : 10
168113 max_attempts : 3
169- command : sudo xcodes runtimes install "$RUNTIME"
170-
171- - if : ${{ env.PLATFORM != 'macCatalyst' && env.PLATFORM != 'macOS' }}
172- name : Create Required Simulators
114+ command : |
115+ RUNTIME="${{ matrix.runtime }}"
116+ if ! xcodes runtimes 2>/dev/null | grep -qF "$RUNTIME (Installed)"; then
117+ sudo xcodes runtimes install "$RUNTIME" --aria2 $(which aria2c)
118+ fi
119+
120+ - name : Create Simulator
121+ if : matrix.device
173122 run : |
174123 set -eo pipefail
175124 xcrun simctl delete all
176- OUTPUT=$(script/create_simulators --platform ${{ env.SCRIPT_PLATFORM }} --version ${{ env.MAJOR }} | tee /dev/stderr)
177- FIRST_UDID=$(printf "%s\n" "$OUTPUT" | awk '/^(Created:|Already exists:)/{print $NF}' | head -n1)
178- if [ -n "$FIRST_UDID" ]; then
179- echo "SIM_UDID=$FIRST_UDID" >> "$GITHUB_ENV"
180- echo "Captured SIM_UDID=$FIRST_UDID"
181- fi
182125
183- - name : List Available Runtimes, Simulators, and Destinations
184- run : |
185- xcrun simctl list
186- xcodebuild -scheme "SwiftUIIntrospect" -showdestinations
126+ # Look up runtime identifier by display name (handles internal names like xrOS for visionOS)
127+ RUNTIME="${{ matrix.runtime }}"
128+ RUNTIME_ID=$(xcrun simctl list runtimes -j | jq -r --arg name "$RUNTIME" '.runtimes[] | select(.isAvailable) | select(.name == $name) | .identifier')
129+ if [ -z "$RUNTIME_ID" ] || [ "$RUNTIME_ID" = "null" ]; then
130+ echo "::error::Runtime '$RUNTIME' not found. Available:"
131+ xcrun simctl list runtimes
132+ exit 1
133+ fi
134+ echo "Runtime: $RUNTIME_ID"
187135
188- - if : ${{ env.PLATFORM != 'watchOS' }}
189- name : Build Showcase
190- uses : davdroman/xcodebuild@destination
191- with :
192- xcode : ~26.0
193- platform : ${{ env.XCB_PLATFORM }}
194- platform-version : ~${{ env.MAJOR }}.${{ env.MINOR }}
195- destination : ${{ env.SIM_UDID }}
196- action : build
197- scheme : Showcase
198- configuration : Debug
199- verbosity : xcbeautify
136+ # Look up device type by display name, with fallback identifier construction
137+ DEVICE_TYPE=$(xcrun simctl list devicetypes -j | jq -r --arg name "${{ matrix.device }}" '.devicetypes[] | select(.name == $name) | .identifier')
138+ if [ -z "$DEVICE_TYPE" ] || [ "$DEVICE_TYPE" = "null" ]; then
139+ DEVICE_TYPE="com.apple.CoreSimulator.SimDeviceType.$(echo "${{ matrix.device }}" | sed 's/[()]//g; s/ */-/g; s/[^A-Za-z0-9-]//g')"
140+ echo "Device type not found by name, using fallback: $DEVICE_TYPE"
141+ fi
200142
201- - if : ${{ env.PLATFORM == 'watchOS' }}
202- name : Build Library
203- uses : davdroman/xcodebuild@destination
204- with :
205- xcode : ~26.0
206- platform : ${{ env.XCB_PLATFORM }}
207- platform-version : ~${{ env.MAJOR }}.${{ env.MINOR }}
208- destination : ${{ env.SIM_UDID }}
209- action : build
210- scheme : SwiftUIIntrospect
211- configuration : Debug
212- verbosity : xcbeautify
143+ UDID=$(xcrun simctl create "${{ matrix.device }}" "$DEVICE_TYPE" "$RUNTIME_ID")
144+ echo "SIM_UDID=$UDID" >> "$GITHUB_ENV"
145+ echo "Created simulator: ${{ matrix.device }} -> $UDID"
213146
214- - if : ${{ env.PLATFORM != 'watchOS' }}
215- name : Run Tests
216- uses : davdroman/xcodebuild@destination
217- with :
218- xcode : ~26.0
219- platform : ${{ env.XCB_PLATFORM }}
220- platform-version : ~${{ env.MAJOR }}.${{ env.MINOR }}
221- destination : ${{ env.SIM_UDID }}
222- action : test
223- scheme : SwiftUIIntrospectTests
224- configuration : Debug
225- verbosity : xcbeautify
147+ - name : Build Showcase
148+ if : ${{ !matrix.build_only }}
149+ run : |
150+ set -eo pipefail
151+ xcodebuild build \
152+ -scheme Showcase \
153+ -destination "${{ matrix.destination || format('id={0}', env.SIM_UDID) }}" \
154+ -configuration Debug \
155+ | xcbeautify
156+
157+ - name : Build Library
158+ if : ${{ matrix.build_only == true }}
159+ run : |
160+ set -eo pipefail
161+ xcodebuild build \
162+ -scheme SwiftUIIntrospect \
163+ -destination "id=${{ env.SIM_UDID }}" \
164+ -configuration Debug \
165+ | xcbeautify
166+
167+ - name : Run Tests
168+ if : ${{ !matrix.build_only }}
169+ run : |
170+ set -eo pipefail
171+ xcodebuild test \
172+ -scheme SwiftUIIntrospectTests \
173+ -destination "${{ matrix.destination || format('id={0}', env.SIM_UDID) }}" \
174+ -configuration Debug \
175+ | xcbeautify
226176
227177 framework-archiving :
228178 if : github.event_name != 'pull_request' || !contains(github.event.pull_request.title, '[skip ci]')
@@ -231,31 +181,24 @@ jobs:
231181 strategy :
232182 fail-fast : false
233183 matrix :
234- platform : [iOS, macCatalyst, macOS, tvOS, visionOS, watchOS]
235184 include :
236- - platform : iOS
237- destination : " generic/platform=iOS"
238- - platform : macCatalyst
239- destination : " platform=macOS,variant=Mac Catalyst"
240- - platform : macOS
241- destination : " generic/platform=macOS"
242- - platform : tvOS
243- destination : " generic/platform=tvOS"
244- - platform : visionOS
245- destination : " generic/platform=visionOS"
246- - platform : watchOS
247- destination : " generic/platform=watchOS"
185+ - { platform: iOS, destination: "generic/platform=iOS" }
186+ - { platform: macCatalyst, destination: "platform=macOS,variant=Mac Catalyst" }
187+ - { platform: macOS, destination: "generic/platform=macOS" }
188+ - { platform: tvOS, destination: "generic/platform=tvOS" }
189+ - { platform: visionOS, destination: "generic/platform=visionOS" }
190+ - { platform: watchOS, destination: "generic/platform=watchOS" }
248191 steps :
249192 - name : Git Checkout
250193 uses : actions/checkout@v5
251194
252- - name : Select Xcode version
253- run : sudo xcodes select 26.2
195+ - name : Select Xcode
196+ run : sudo xcodes select 26.3
254197
255198 - name : Archive Framework
256199 run : |
257200 xcodebuild archive \
258- -scheme " SwiftUIIntrospectTestFramework" \
201+ -scheme SwiftUIIntrospectTestFramework \
259202 -destination "${{ matrix.destination }}" \
260203 -archivePath .build/archiving/${{ matrix.platform }} \
261204 SKIP_INSTALL=NO \
0 commit comments