Repository navigation
216 lines (189 loc) · 7.95 KB
/
Copy pathtests.yml
File metadata and controls
216 lines (189 loc) · 7.95 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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# SPDX-License-Identifier: Apache-2.0
#
# Unit-test gate for pushes and PRs to main.
#
# Package.swift declares binary targets under build_products/XCFrameworks
# and compiles against the idb PrivateHeaders modules staged next to them,
# so both must exist before any swift build / swift test. Building them
# (scripts/build.sh dev: idb clone + XcodeGen project generation + four
# xcodebuild passes) measures ~2 min on hosted runners; caching the output
# still halves warm-run wall time and avoids the network clone. Keyed on
# everything that shapes it: the build script (pins IDB_GIT_REF) and the
# selected Xcode version. The frameworks are static archives built without
# library evolution, so their Swift modules are toolchain-locked — the
# Xcode version in the key is what keeps a cached build consumable.
name: Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
# Kotlin bridge and Swift client must agree on the wire
# protocol_version; scripts/check-protocol-parity.sh was written to
# run in CI and needs nothing beyond a POSIX shell.
protocol-parity:
name: Bridge protocol parity
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Check Kotlin/Swift protocol version parity
run: ./scripts/check-protocol-parity.sh
# JVM unit tests for the Kotlin bridge (bridge/app/src/test). No
# emulator involved; ubuntu keeps this off the macOS critical path.
bridge-unit-tests:
name: Bridge unit tests
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v7
# Gradle 8.7 rejects JDK 22+; pin 17 (project floor).
- name: Set up JDK 17
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: '17'
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v6
- name: Run bridge JVM unit tests
working-directory: bridge
run: ./gradlew --no-daemon testDebugUnitTest
# The Android-only Linux build (the `#if os(Linux)` graph in
# Package.swift): SimUseCore, AndroidBackend and the SimUseLinux
# executable, plus the two test targets that build there. Nothing
# Apple-shaped is involved, so it needs no XCFrameworks and stays off
# the macOS critical path. `make` is macOS-only; call swift directly.
linux:
name: Build and unit tests (Linux, Android only)
runs-on: ubuntu-latest
container: swift:6.3
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@v7
# The workspace belongs to the runner user, not the container's
# root, so git refuses it and VersionPlugin's `git describe`
# would fall back to no version.
- name: Trust the checkout
run: git config --global --add safe.directory "${GITHUB_WORKSPACE}"
- name: Build
run: swift build
- name: Run unit tests
timeout-minutes: 10
run: swift test
- name: Smoke-check built binary
run: .build/debug/sim-use --help
unit-tests:
name: Unit tests (macOS)
runs-on: macos-26
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v7
# The FB* frameworks build against SimulatorKit, which Xcode 27
# removed. Pin the newest Xcode 26.x on the image rather than the
# image default, which will eventually move past 26.
- name: Select latest Xcode 26
id: xcode
run: |
XCODE_APP="$(ls -d /Applications/Xcode_26*.app | sort -V | tail -n 1)"
if [[ -z "${XCODE_APP}" ]]; then
echo "::error::No Xcode 26.x found on this runner image" >&2
exit 1
fi
sudo xcode-select -s "${XCODE_APP}/Contents/Developer"
xcodebuild -version
swift --version
# Include the Xcode build id, not just the marketing version:
# two betas of the same version ship incompatible Swift
# compilers, and the FB* swiftmodules are toolchain-locked.
echo "version=$(xcodebuild -version | awk 'NR==1 {v=$2} /^Build version/ {b=$3} END {print v "-" b}')" >> "${GITHUB_OUTPUT}"
# Separate restore/save so a red test run still persists the
# expensive framework build for the next attempt.
- name: Restore FB XCFrameworks cache
id: xcframeworks-cache
uses: actions/cache/restore@v6
with:
path: |
build_products/XCFrameworks
build_products/PrivateHeaders
key: fb-xcframeworks-${{ runner.arch }}-xcode-${{ steps.xcode.outputs.version }}-${{ hashFiles('scripts/build.sh') }}
# The idb checkout generates its Xcode project with XcodeGen.
- name: Install XcodeGen
if: steps.xcframeworks-cache.outputs.cache-hit != 'true'
run: command -v xcodegen >/dev/null 2>&1 || brew install xcodegen
- name: Build FB XCFrameworks
if: steps.xcframeworks-cache.outputs.cache-hit != 'true'
run: ./scripts/build.sh dev
- name: Save FB XCFrameworks cache
if: steps.xcframeworks-cache.outputs.cache-hit != 'true'
uses: actions/cache/save@v6
with:
path: |
build_products/XCFrameworks
build_products/PrivateHeaders
key: ${{ steps.xcframeworks-cache.outputs.cache-primary-key }}
- name: Cache SwiftPM build
uses: actions/cache@v6
with:
path: .build
key: spm-${{ runner.arch }}-xcode-${{ steps.xcode.outputs.version }}-${{ hashFiles('Package.resolved', 'Package.swift') }}
restore-keys: |
spm-${{ runner.arch }}-xcode-${{ steps.xcode.outputs.version }}-
- name: Install xcsift
run: brew install xcsift
# make test is self-sufficient: it syncs the bundled skill
# resources and swift test builds every target the test bundle
# depends on, including the sim-use executable the smoke step
# runs. make picks xcsift up from PATH and condenses the output
# to a TOON summary itself; SIM_USE_RAW_LOG additionally saves
# the raw swift output, kept as an artifact on failure or
# cancellation for forensics the condensed view can't serve
# (e.g. grepping daemon log lines, or finding the last test that
# started before a hang). The step timeout bounds a wedged test
# run well below the job timeout so the artifact still uploads.
- name: Run unit tests
timeout-minutes: 20
run: make test
env:
SIM_USE_RAW_LOG: ${{ runner.temp }}/test.log
# Mirror the condensed result into the job summary panel
# (gradle/actions does the same for the bridge job), regenerated
# from the raw log. always() so a red test run still gets its
# summary; the file guard covers failures before the test step
# ever ran.
- name: Publish test summary
if: always()
shell: bash
run: |
if [[ -s "${RUNNER_TEMP}/test.log" ]]; then
{
echo "## Unit tests (macOS)"
echo '```yaml'
xcsift --coverage -w -f toon < "${RUNNER_TEMP}/test.log"
echo '```'
} >> "${GITHUB_STEP_SUMMARY}"
fi
# failure() is false when a step or job times out (that's a
# cancellation), and a hang is exactly when the partial raw log
# matters most — cover both.
- name: Upload raw logs on failure
if: failure() || cancelled()
uses: actions/upload-artifact@v7
with:
name: raw-swift-logs
path: ${{ runner.temp }}/*.log
if-no-files-found: ignore
retention-days: 7
# Loads the FB* frameworks through dyld, catching link/rpath
# regressions that compilation alone would miss.
- name: Smoke-check built binary
run: .build/debug/sim-use --help