-
Notifications
You must be signed in to change notification settings - Fork 6.1k
137 lines (125 loc) · 6.11 KB
/
Copy pathios-ci.yml
File metadata and controls
137 lines (125 loc) · 6.11 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
name: iOS CI (Kotlin/Native)
# The only place the Apple side can actually be checked.
#
# Klibs for iosArm64 / iosSimulatorArm64 cross compile on any host, so a developer on Windows or
# Linux already knows the shared code COMPILES for iOS. What no other machine can do is RUN it:
# `iosSimulatorArm64Test` is disabled off macOS with "simulator tests require macOS", and it reports
# SKIPPED rather than failing, so a green build elsewhere says nothing about iOS behaviour.
#
# That gap matters most for the four platform actuals under the shared data spine. `utcOffset` is
# written to every record, takes part in contentEqualsTo and is validated by Nightscout, and it comes
# from NSTimeZone on Apple and TimeZone.getOffset on the JVM. NumberFormatParityTest and
# SystemTimeZoneTest in commonTest exist to compare them; this job is where they finally execute.
#
# No secrets: nothing is signed, published or uploaded.
on:
workflow_dispatch:
push:
paths:
- 'core/data/**'
- 'core/nssdk/**'
- 'core/keys/**'
- 'gradle/libs.versions.toml'
- 'buildSrc/**'
- '.github/workflows/ios-ci.yml'
pull_request:
paths:
- 'core/data/**'
- 'core/nssdk/**'
- 'core/keys/**'
- 'gradle/libs.versions.toml'
- 'buildSrc/**'
jobs:
ios:
runs-on: macos-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 1
- name: Load jdk version
run: |
JAVA_VERSION=$(jq -r '.default' .github/jdk-map.json)
echo "JAVA_VERSION=$JAVA_VERSION" >> $GITHUB_ENV
- name: Set up JDK
uses: actions/setup-java@v5
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: 'temurin'
cache: gradle
# Kotlin/Native downloads its own toolchain on first use; without this every run pays for it.
- name: Cache Kotlin/Native
uses: actions/cache@v4
with:
path: ~/.konan
key: konan-${{ runner.os }}-${{ hashFiles('gradle/libs.versions.toml') }}
restore-keys: konan-${{ runner.os }}-
- name: Compile the Apple targets
run: |
# Actions runs `bash -e` but NOT pipefail, so without this the exit code of the pipeline
# would be tee's and a failed Gradle build would report success.
set -o pipefail
./gradlew --console=plain --no-daemon \
:core:data:compileKotlinIosArm64 :core:data:compileKotlinIosSimulatorArm64 \
:core:nssdk:compileKotlinIosArm64 :core:nssdk:compileKotlinIosSimulatorArm64 \
:core:keys:compileKotlinIosArm64 :core:keys:compileKotlinIosSimulatorArm64 \
| tee compile.log
# A disabled Kotlin/Native task reports SKIPPED and still exits 0, so "BUILD SUCCESSFUL" alone
# would stay green even if the whole Apple side silently stopped building. Cross-compilability
# is also transitive: a single cinterop anywhere in the project dependency graph turns these
# into no-ops. Assert the work happened rather than that nothing complained.
- name: Assert the Apple compiles really ran
run: |
if grep -E "Task :core:(data|nssdk|keys):compileKotlinIos(Arm64|SimulatorArm64) (SKIPPED|NO-SOURCE)" compile.log; then
echo "::error::An iOS compile task was skipped instead of executed."
exit 1
fi
for m in data nssdk keys; do
for t in iosArm64 iosSimulatorArm64; do
MANIFEST=$(find core/$m/build/classes/kotlin/$t/main/klib -name manifest 2>/dev/null | head -1)
if [ -z "$MANIFEST" ]; then
echo "::error::core/$m produced no $t klib"
exit 1
fi
echo "core/$m $t -> $(grep native_targets "$MANIFEST")"
done
done
# The part that only exists here. commonTest runs through Kotlin/Native against the real
# NSNumberFormatter and NSTimeZone, which is what no other host can do.
#
# Only :core:data has commonTest today, so it is the one module asserted below. The other two
# are still run: if either grows shared tests later they start executing here with no change to
# this file, and until then they are simply NO-SOURCE.
- name: Run the shared tests on the iOS simulator
# GitHub's macOS runners are UTC, and at UTC every assertion in SystemTimeZoneTest passes
# trivially - the offset is zero whatever unit it is in, so a seconds-instead-of-milliseconds
# bug in the NSTimeZone actual would sail straight through. Pin a zone that has both a
# non-zero offset and daylight saving, so the whole-minutes, range and whole-hour-DST
# assertions actually mean something. Foundation honours TZ on macOS, as does the JVM.
env:
TZ: Europe/Prague
run: |
set -o pipefail
echo "Running with TZ=$TZ"
./gradlew --console=plain --no-daemon \
:core:data:iosSimulatorArm64Test :core:nssdk:iosSimulatorArm64Test :core:keys:iosSimulatorArm64Test \
| tee test.log
- name: Assert the iOS tests really ran
run: |
if grep -E "Task :core:data:iosSimulatorArm64Test (SKIPPED|NO-SOURCE)" test.log; then
echo "::error::Module core:data had its iOS tests skipped instead of executed. On macOS they must run."
exit 1
fi
FOUND=$(find core/data/build/test-results/iosSimulatorArm64Test -name "TEST-*.xml" 2>/dev/null | wc -l)
echo "iOS test result files for :core:data: $FOUND"
[ "$FOUND" -gt 0 ] || { echo "::error::No iOS test results were produced."; exit 1; }
# Surface the counts, so a run that executed zero assertions is visible in the log.
grep -ho 'tests="[0-9]*" skipped="[0-9]*" failures="[0-9]*" errors="[0-9]*"' \
core/data/build/test-results/iosSimulatorArm64Test/TEST-*.xml || true
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: ios-test-results
path: core/*/build/test-results/iosSimulatorArm64Test/**
if-no-files-found: warn