-
-
Notifications
You must be signed in to change notification settings - Fork 368
183 lines (161 loc) · 6.58 KB
/
Copy pathios-tests.yml
File metadata and controls
183 lines (161 loc) · 6.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
name: iOS Tests
on:
# No paths filter here on purpose. See the note in macos-tests.yml: a workflow skipped by a
# paths filter never reports, so a required check would hang on every unrelated pull request.
pull_request:
push:
branches: [main]
paths:
- "TableProMobile/**"
- "Configs/**"
- "Packages/TableProCore/**"
- "Libs/**"
- ".github/workflows/ios-tests.yml"
workflow_dispatch:
# Only one run per PR/branch at a time; new pushes cancel pending older ones.
concurrency:
group: ios-tests-${{ github.ref }}
cancel-in-progress: true
# A downgrade or an exact match is always allowed for a called workflow; only asking for more than
# the caller holds fails at run creation. Declaring read cannot break a caller, and it stops every
# job here from inheriting a write token if the repository default is ever flipped.
permissions:
contents: read
env:
XCODE_PROJECT: TableProMobile/TableProMobile.xcodeproj
XCODE_SCHEME: TableProMobile
TEST_DESTINATION: "platform=iOS Simulator,name=iPhone 17 Pro,OS=latest"
jobs:
changes:
name: Detect relevant changes
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
run: ${{ steps.decide.outputs.run }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- name: Decide whether the iOS suite needs to run
id: decide
env:
EVENT_NAME: ${{ github.event_name }}
BASE_SHA: ${{ github.event.pull_request.base.sha }}
# Shared with macos-tests.yml; see scripts/ci/detect-changed-paths.sh.
run: |
set -euo pipefail
RUN=$(scripts/ci/detect-changed-paths.sh \
--event "$EVENT_NAME" \
--base "$BASE_SHA" \
'TableProMobile/' 'Configs/' 'Packages/TableProCore/' 'Libs/' 'scripts/' \
'\.github/actions/' '\.github/workflows/ios-tests\.yml$')
echo "run=$RUN" >> "$GITHUB_OUTPUT"
test:
name: Run iOS Tests
needs: changes
if: needs.changes.outputs.run == 'true'
runs-on: macos-26
timeout-minutes: 25
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Select Xcode
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0
with:
xcode-version: '26.4.1'
- name: Install xcbeautify
run: brew list xcbeautify &>/dev/null || brew install xcbeautify
# macos-26 lazy-loads simulator runtimes; -downloadPlatform pulls the runtime
# matching Xcode's SDK and is a no-op when it is already present. The download
# endpoint flakes on hosted runners, so a failure falls back to checking whether
# the test device already exists before failing the job.
- name: Install iOS simulator runtime
run: |
if sudo xcodebuild -downloadPlatform iOS; then
exit 0
fi
echo "::warning::xcodebuild -downloadPlatform iOS failed; checking for an existing simulator"
device_name="$(echo "$TEST_DESTINATION" | sed -n 's/.*name=\([^,]*\).*/\1/p')"
if xcrun simctl list devices available | grep -qF "$device_name ("; then
echo "$device_name simulator is already available; continuing."
exit 0
fi
echo "::error::$device_name simulator is not available and the runtime download failed."
exit 1
- name: Setup XcodeGen
uses: ./.github/actions/setup-xcodegen
# The iOS project only. The macOS spec names Libs/dylibs/*.dylib by path and XcodeGen
# validates that at generation time, so generating it here failed before the static
# libraries were even downloaded, and nothing in this job builds it.
- name: Generate Xcode project
run: scripts/generate-project.sh ios
- name: Cache static libraries
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: Libs
# Include C bridge stub headers in the cache key so the iOS xcframework set
# refreshes whenever a bridge surface (e.g. a new driver's headers) changes.
key: ${{ runner.os }}-libs-${{ hashFiles('Libs/checksums.sha256', 'Plugins/MSSQLDriverPlugin/CFreeTDS/include/sybdb.h', 'TableProMobile/TableProMobile/CBridges/CDuckDB/CDuckDB.h') }}
- name: Download static libraries
env:
GH_TOKEN: ${{ github.token }}
run: scripts/download-libs.sh
- name: Resolve Swift package dependencies
run: |
xcodebuild -resolvePackageDependencies \
-project "$XCODE_PROJECT" \
-scheme "$XCODE_SCHEME" \
-skipPackagePluginValidation
- name: Run unit tests
run: |
set -o pipefail
xcodebuild test \
-project "$XCODE_PROJECT" \
-scheme "$XCODE_SCHEME" \
-destination "$TEST_DESTINATION" \
-only-testing:TableProMobileTests \
-skipPackagePluginValidation \
-resultBundlePath TestResults.xcresult \
CODE_SIGNING_ALLOWED=NO \
| xcbeautify --renderer github-actions
- name: Upload test results
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ios-test-results
path: TestResults.xcresult
retention-days: 7
# Diagnostics only on failure so happy-path runs stay quiet.
- name: Show simulator state on failure
if: failure()
run: |
echo "=== iOS runtimes ==="
xcrun simctl list runtimes | grep -E "iOS|tvOS" || true
echo "=== Eligible scheme destinations ==="
xcodebuild -showdestinations \
-project "$XCODE_PROJECT" \
-scheme "$XCODE_SCHEME" \
-skipPackagePluginValidation 2>&1 \
| grep -E "iOS Simulator.*iPhone" || true
# The one check to mark required on main. See the note in macos-tests.yml.
gate:
name: iOS Tests Gate
if: always()
needs: [changes, test]
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Require the suite to have passed or been skipped
env:
RESULTS: ${{ join(needs.*.result, ' ') }}
run: |
set -euo pipefail
echo "suite results: $RESULTS"
for result in $RESULTS; do
case "$result" in
success|skipped) ;;
*)
echo "The iOS suite reported '$result'." >&2
exit 1
;;
esac
done