@@ -74,10 +74,131 @@ jobs:
7474 restore-keys : |
7575 ${{ runner.os }}-spm-
7676
77+ - name : Select iOS Simulator Runtime (installed)
78+ id : pick_ios
79+ shell : bash
80+ run : |
81+ set -euo pipefail
82+
83+ RESULT=$(python3 - <<'PY'
84+ import re, subprocess, sys
85+
86+ def ver_key(version):
87+ return tuple(int(part) for part in version.split('.'))
88+
89+ text = subprocess.check_output(["xcrun", "simctl", "list", "devices"], text=True)
90+ lines = text.splitlines()
91+ current_ver = None
92+ candidates = []
93+
94+ for line in lines:
95+ header = re.match(r"^-- iOS ([0-9]+(?:\.[0-9]+)*) --$", line.strip())
96+ if header:
97+ current_ver = header.group(1)
98+ continue
99+ if current_ver is None:
100+ continue
101+ if "(unavailable)" in line:
102+ continue
103+ if "iPhone" not in line:
104+ continue
105+
106+ raw = line.strip()
107+ if "platform:" in raw and "name:" in raw and "OS:" in raw:
108+ kv = {}
109+ for part in raw.split(","):
110+ if ":" not in part:
111+ continue
112+ k, v = part.split(":", 1)
113+ kv[k.strip()] = v.strip()
114+ name = kv.get("name", raw)
115+ else:
116+ name = raw
117+ name = re.sub(r"\s+\([0-9A-Fa-f-]{36}\)\s+\(.*\)$", "", name)
118+
119+ candidates.append((current_ver, name))
120+
121+ if len(candidates) <= 0:
122+ print("No available iPhone simulators found", file=sys.stderr)
123+ sys.exit(1)
124+
125+ latest_version = max((candidate[0] for candidate in candidates), key=ver_key)
126+ latest_candidates = [
127+ candidate for candidate in candidates
128+ if candidate[0] == latest_version
129+ ]
130+ chosen_version, chosen_device_name = min(
131+ latest_candidates,
132+ key=lambda candidate: candidate[1]
133+ )
134+
135+ print(f"{chosen_version}|{chosen_device_name}")
136+ sys.exit(0)
137+ PY
138+ )
139+
140+ if [ -z "${RESULT:-}" ]; then
141+ echo "No iPhone simulator devices detected." >&2
142+ exit 1
143+ fi
144+
145+ IFS='|' read -r IOS_VER DEVICE_NAME <<< "$RESULT"
146+
147+ echo "Chosen iOS runtime version (iPhone): $IOS_VER"
148+ echo "Chosen simulator: $DEVICE_NAME"
149+
150+ echo "ios_version=$IOS_VER" >> "$GITHUB_OUTPUT"
151+ echo "device_name=$DEVICE_NAME" >> "$GITHUB_OUTPUT"
152+
77153 - name : Build
78- uses : ./.github/actions/ios-simulator-build
79- with :
80- scheme : ${{ env.SCHEME }}
154+ shell : bash
155+ env :
156+ IOS_VER : ${{ steps.pick_ios.outputs.ios_version }}
157+ DEVICE_NAME : ${{ steps.pick_ios.outputs.device_name }}
158+ run : |
159+ set -euo pipefail
160+ set -x
161+ SPM_DIR="$GITHUB_WORKSPACE/.spm"
162+ mkdir -p "$SPM_DIR"
163+
164+ xcodebuild -version
165+
166+ echo "Using scheme: $SCHEME"
167+ echo "Using simulator: $DEVICE_NAME (iOS ${IOS_VER})"
168+
169+ set -o pipefail
170+ set +e
171+ echo "== Resolving Swift Package dependencies =="
172+ xcodebuild \
173+ -scheme "$SCHEME" \
174+ -configuration Debug \
175+ -clonedSourcePackagesDirPath "$SPM_DIR" \
176+ -resolvePackageDependencies
177+ echo "== Starting xcodebuild build =="
178+ xcodebuild \
179+ -scheme "$SCHEME" \
180+ -configuration Debug \
181+ -destination "platform=iOS Simulator,OS=${IOS_VER},name=${DEVICE_NAME}" \
182+ -clonedSourcePackagesDirPath "$SPM_DIR" \
183+ -skipPackagePluginValidation \
184+ -skipMacroValidation \
185+ -showBuildTimingSummary \
186+ build \
187+ | tee build.log
188+ echo "== xcodebuild finished =="
189+ XC_STATUS=${PIPESTATUS[0]}
190+ set -e
191+
192+ if [ -f build.log ]; then
193+ echo "== error: lines =="
194+ if grep -i "error:" build.log; then
195+ if [ "$XC_STATUS" -eq 0 ]; then
196+ XC_STATUS=1
197+ fi
198+ fi
199+ fi
200+
201+ exit $XC_STATUS
81202
82203 - name : Comment build failure on PR
83204 if : failure() && github.event.pull_request.head.repo.fork == false
0 commit comments