Skip to content

Commit 59a3f75

Browse files
authored
Add GitHub Actions iOS CI workflow (#6)
1 parent 710a69d commit 59a3f75

1 file changed

Lines changed: 132 additions & 0 deletions

File tree

.github/workflows/ios-ci.yml

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
name: iOS CI
2+
3+
on:
4+
push:
5+
branches:
6+
- '**'
7+
pull_request:
8+
workflow_dispatch:
9+
10+
concurrency:
11+
group: ios-ci-${{ github.workflow }}-${{ github.ref }}
12+
cancel-in-progress: true
13+
14+
jobs:
15+
build-and-test:
16+
name: Build and Test (SOPA)
17+
runs-on: macos-15
18+
timeout-minutes: 30
19+
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v4
23+
24+
- name: Select Xcode
25+
uses: maxim-lobanov/setup-xcode@v1
26+
with:
27+
xcode-version: latest-stable
28+
29+
- name: Show Xcode version
30+
run: |
31+
xcodebuild -version
32+
swift --version
33+
34+
- name: Resolve Swift packages
35+
run: |
36+
xcodebuild \
37+
-project SOPA.xcodeproj \
38+
-scheme SOPA \
39+
-resolvePackageDependencies
40+
41+
- name: Find iOS simulator destination
42+
id: sim
43+
shell: bash
44+
run: |
45+
set -euo pipefail
46+
DEST_LINE=$(
47+
xcodebuild \
48+
-project SOPA.xcodeproj \
49+
-scheme SOPA \
50+
-showdestinations \
51+
| grep -m1 "platform:iOS Simulator" || true
52+
)
53+
54+
DEVICE_UDID=$(echo "${DEST_LINE}" | sed -n 's/.*id:\([0-9A-F-]\{36\}\).*/\1/p')
55+
56+
if [[ -z "${DEVICE_UDID:-}" ]]; then
57+
echo "No concrete simulator destination found, creating one via simctl."
58+
59+
RUNTIME_ID=$(
60+
xcrun simctl list runtimes available \
61+
| sed -nE 's/.*- (com\.apple\.CoreSimulator\.SimRuntime\.iOS-[[:alnum:]-]+).*/\1/p' \
62+
| tail -n 1
63+
)
64+
65+
if [[ -z "${RUNTIME_ID:-}" ]]; then
66+
# Fallback for alternate simctl output formats.
67+
RUNTIME_ID=$(
68+
xcrun simctl list runtimes available \
69+
| sed -nE 's/.*\((com\.apple\.CoreSimulator\.SimRuntime\.iOS-[^)]*)\).*/\1/p' \
70+
| tail -n 1
71+
)
72+
fi
73+
74+
DEVICE_TYPE_ID=$(
75+
xcrun simctl list devicetypes \
76+
| sed -nE 's/.*iPhone 16.*\((com\.apple\.CoreSimulator\.SimDeviceType\.[^)]*)\).*/\1/p' \
77+
| tail -n 1
78+
)
79+
80+
if [[ -z "${DEVICE_TYPE_ID:-}" ]]; then
81+
DEVICE_TYPE_ID=$(
82+
xcrun simctl list devicetypes \
83+
| sed -nE 's/.*iPhone.*\((com\.apple\.CoreSimulator\.SimDeviceType\.[^)]*)\).*/\1/p' \
84+
| head -n 1
85+
)
86+
fi
87+
88+
if [[ -z "${RUNTIME_ID:-}" || -z "${DEVICE_TYPE_ID:-}" ]]; then
89+
echo "Unable to resolve runtime/device type for simulator creation."
90+
xcrun simctl list runtimes available
91+
xcrun simctl list devicetypes
92+
exit 1
93+
fi
94+
95+
DEVICE_UDID=$(xcrun simctl create "SOPA-CI-iPhone" "${DEVICE_TYPE_ID}" "${RUNTIME_ID}")
96+
97+
if [[ -z "${DEVICE_UDID:-}" ]]; then
98+
echo "Failed to create simulator device."
99+
exit 1
100+
fi
101+
fi
102+
103+
xcrun simctl boot "${DEVICE_UDID}" || true
104+
xcrun simctl bootstatus "${DEVICE_UDID}" -b || true
105+
106+
echo "destination=id=${DEVICE_UDID}" >> "$GITHUB_OUTPUT"
107+
echo "Using destination id=${DEVICE_UDID}"
108+
109+
- name: Build
110+
run: |
111+
xcodebuild \
112+
-project SOPA.xcodeproj \
113+
-scheme SOPA \
114+
-destination '${{ steps.sim.outputs.destination }}' \
115+
build
116+
117+
- name: Test
118+
run: |
119+
xcodebuild \
120+
-project SOPA.xcodeproj \
121+
-scheme SOPA \
122+
-destination '${{ steps.sim.outputs.destination }}' \
123+
-resultBundlePath TestResults.xcresult \
124+
test
125+
126+
- name: Upload test results
127+
if: always()
128+
uses: actions/upload-artifact@v4
129+
with:
130+
name: xcresult
131+
path: TestResults.xcresult
132+
if-no-files-found: ignore

0 commit comments

Comments
 (0)