1 name: CI
2
3 on:
4 push:
5 pull_request:
6 workflow_dispatch:
7
8 concurrency:
9 group: ci-${{ github.ref }}
10 cancel-in-progress: true
11
12 permissions:
13 contents: read
14
15 jobs:
16 # ── Dart / Flutter SDK validation ────────────────────────────────────────
17 dart-sdk:
18 name: Dart SDK (Flutter)
19 runs-on: ubuntu-latest
20 steps:
21 - uses: actions/checkout@v6
22 - uses: subosito/flutter-action@v2
23 with:
24 flutter-version-file: sdk/dart/.flutter-version
25 channel: stable
26 cache: true
27 - name: Install Dart dependencies
28 working-directory: sdk/dart
29 run: flutter pub get
30 - name: Analyze Dart package
31 working-directory: sdk/dart
32 run: flutter analyze --no-fatal-infos
33 - name: Analyze score-sensitive generated Dart files
34 working-directory: sdk/dart
35 run: |
36 flutter analyze lib/src/frb_generated.dart/api.dart
37 flutter analyze lib/src/frb_generated.dart/frb_generated.dart
38 flutter analyze lib/src/frb_generated.dart/frb_generated.io.dart
39 - name: Verify Apple SwiftPM manifests exist
40 working-directory: sdk/dart
41 run: |
42 test -f ios/onde_inference/Package.swift
43 test -f ios/onde_inference/Sources/onde_inference/OndeInferencePlugin.swift
44 test -f macos/onde_inference/Package.swift
45 test -f macos/onde_inference/Sources/onde_inference/OndeInferencePlugin.swift
46 - name: Run Dart package tests
47 working-directory: sdk/dart
48 run: flutter test
49 - name: Restore generated files modified by flutter pub get
50 working-directory: sdk/dart
51 run: git checkout -- . 2>/dev/null || true
52 - name: Dry-run Dart publish
53 working-directory: sdk/dart
54 run: flutter pub publish --dry-run
55
56 # ── Formatting ────────────────────────────────────────────────────────────
57 fmt:
58 name: Format
59 runs-on: macos-26
60 steps:
61 - uses: actions/checkout@v6
62 - uses: dtolnay/rust-toolchain@stable
63 with:
64 components: rustfmt
65 - run: cargo fmt --all -- --check
66
67 # ── Lint ──────────────────────────────────────────────────────────────────
68 clippy:
69 name: Clippy (macOS)
70 runs-on: macos-26
71 env:
72 GRESIQ_API_KEY_DEV: ${{ secrets.GRESIQ_API_KEY_DEV }}
73 GRESIQ_API_SECRET_DEV: ${{ secrets.GRESIQ_API_SECRET_DEV }}
74 GRESIQ_API_KEY_PRODUCTION: ${{ secrets.GRESIQ_API_KEY_PRODUCTION }}
75 GRESIQ_API_SECRET_PRODUCTION: ${{ secrets.GRESIQ_API_SECRET_PRODUCTION }}
76 HF_TOKEN: ${{ secrets.HF_TOKEN }}
77 steps:
78 - uses: actions/checkout@v6
79 - uses: dtolnay/rust-toolchain@stable
80 with:
81 components: clippy
82 - uses: Swatinem/rust-cache@v2
83 with:
84 cache-bin: false
85 - run: cargo clippy --all-targets -- -D warnings
86
87 # ── Tests (macOS — the only platform where tests run natively) ────────────
88 test:
89 name: Test (macOS)
90 runs-on: macos-26
91 env:
92 GRESIQ_API_KEY_DEV: ${{ secrets.GRESIQ_API_KEY_DEV }}
93 GRESIQ_API_SECRET_DEV: ${{ secrets.GRESIQ_API_SECRET_DEV }}
94 GRESIQ_API_KEY_PRODUCTION: ${{ secrets.GRESIQ_API_KEY_PRODUCTION }}
95 GRESIQ_API_SECRET_PRODUCTION: ${{ secrets.GRESIQ_API_SECRET_PRODUCTION }}
96 HF_TOKEN: ${{ secrets.HF_TOKEN }}
97 steps:
98 - uses: actions/checkout@v6
99 - uses: dtolnay/rust-toolchain@stable
100 - uses: Swatinem/rust-cache@v2
101 with:
102 cache-bin: false
103 - run: cargo test --lib
104
105 # ── Cross-compile checks for Darwin platforms (highest priority) ─────────
106 check-macos-arm64:
107 name: Check (macOS arm64)
108 runs-on: macos-26
109 env:
110 GRESIQ_API_KEY_DEV: ${{ secrets.GRESIQ_API_KEY_DEV }}
111 GRESIQ_API_SECRET_DEV: ${{ secrets.GRESIQ_API_SECRET_DEV }}
112 GRESIQ_API_KEY_PRODUCTION: ${{ secrets.GRESIQ_API_KEY_PRODUCTION }}
113 GRESIQ_API_SECRET_PRODUCTION: ${{ secrets.GRESIQ_API_SECRET_PRODUCTION }}
114 HF_TOKEN: ${{ secrets.HF_TOKEN }}
115 steps:
116 - uses: actions/checkout@v6
117 - uses: dtolnay/rust-toolchain@stable
118 with:
119 targets: aarch64-apple-darwin
120 - uses: Swatinem/rust-cache@v2
121 with:
122 cache-bin: false
123 key: macos-arm64
124 - run: cargo check --target aarch64-apple-darwin
125
126 check-macos-intel:
127 name: Check (macOS x86_64)
128 runs-on: macos-26
129 env:
130 GRESIQ_API_KEY_DEV: ${{ secrets.GRESIQ_API_KEY_DEV }}
131 GRESIQ_API_SECRET_DEV: ${{ secrets.GRESIQ_API_SECRET_DEV }}
132 GRESIQ_API_KEY_PRODUCTION: ${{ secrets.GRESIQ_API_KEY_PRODUCTION }}
133 GRESIQ_API_SECRET_PRODUCTION: ${{ secrets.GRESIQ_API_SECRET_PRODUCTION }}
134 HF_TOKEN: ${{ secrets.HF_TOKEN }}
135 steps:
136 - uses: actions/checkout@v6
137 - uses: dtolnay/rust-toolchain@stable
138 with:
139 targets: x86_64-apple-darwin
140 - uses: Swatinem/rust-cache@v2
141 with:
142 cache-bin: false
143 key: macos-intel
144 - run: cargo check --target x86_64-apple-darwin
145
146 check-ios:
147 name: Check (iOS device)
148 runs-on: macos-26
149 env:
150 GRESIQ_API_KEY_DEV: ${{ secrets.GRESIQ_API_KEY_DEV }}
151 GRESIQ_API_SECRET_DEV: ${{ secrets.GRESIQ_API_SECRET_DEV }}
152 GRESIQ_API_KEY_PRODUCTION: ${{ secrets.GRESIQ_API_KEY_PRODUCTION }}
153 GRESIQ_API_SECRET_PRODUCTION: ${{ secrets.GRESIQ_API_SECRET_PRODUCTION }}
154 HF_TOKEN: ${{ secrets.HF_TOKEN }}
155 steps:
156 - uses: actions/checkout@v6
157 - uses: dtolnay/rust-toolchain@stable
158 with:
159 targets: aarch64-apple-ios
160 - uses: Swatinem/rust-cache@v2
161 with:
162 cache-bin: false
163 key: ios
164 - run: cargo check --target aarch64-apple-ios
165
166 check-ios-sim:
167 name: Check (iOS simulator)
168 runs-on: macos-26
169 env:
170 GRESIQ_API_KEY_DEV: ${{ secrets.GRESIQ_API_KEY_DEV }}
171 GRESIQ_API_SECRET_DEV: ${{ secrets.GRESIQ_API_SECRET_DEV }}
172 GRESIQ_API_KEY_PRODUCTION: ${{ secrets.GRESIQ_API_KEY_PRODUCTION }}
173 GRESIQ_API_SECRET_PRODUCTION: ${{ secrets.GRESIQ_API_SECRET_PRODUCTION }}
174 HF_TOKEN: ${{ secrets.HF_TOKEN }}
175 steps:
176 - uses: actions/checkout@v6
177 - uses: dtolnay/rust-toolchain@stable
178 with:
179 targets: aarch64-apple-ios-sim
180 - uses: Swatinem/rust-cache@v2
181 with:
182 cache-bin: false
183 key: ios-sim
184 - run: cargo check --target aarch64-apple-ios-sim
185
186 check-tvos:
187 name: Check (tvOS device)
188 runs-on: macos-26
189 env:
190 GRESIQ_API_KEY_DEV: ${{ secrets.GRESIQ_API_KEY_DEV }}
191 GRESIQ_API_SECRET_DEV: ${{ secrets.GRESIQ_API_SECRET_DEV }}
192 GRESIQ_API_KEY_PRODUCTION: ${{ secrets.GRESIQ_API_KEY_PRODUCTION }}
193 GRESIQ_API_SECRET_PRODUCTION: ${{ secrets.GRESIQ_API_SECRET_PRODUCTION }}
194 HF_TOKEN: ${{ secrets.HF_TOKEN }}
195 steps:
196 - uses: actions/checkout@v6
197 - uses: dtolnay/rust-toolchain@nightly
198 with:
199 components: rust-src
200 - uses: Swatinem/rust-cache@v2
201 with:
202 cache-bin: false
203 key: tvos
204 - run: cargo +nightly check -Z build-std --target aarch64-apple-tvos
205
206 check-tvos-sim:
207 name: Check (tvOS simulator)
208 runs-on: macos-26
209 env:
210 GRESIQ_API_KEY_DEV: ${{ secrets.GRESIQ_API_KEY_DEV }}
211 GRESIQ_API_SECRET_DEV: ${{ secrets.GRESIQ_API_SECRET_DEV }}
212 GRESIQ_API_KEY_PRODUCTION: ${{ secrets.GRESIQ_API_KEY_PRODUCTION }}
213 GRESIQ_API_SECRET_PRODUCTION: ${{ secrets.GRESIQ_API_SECRET_PRODUCTION }}
214 HF_TOKEN: ${{ secrets.HF_TOKEN }}
215 steps:
216 - uses: actions/checkout@v6
217 - uses: dtolnay/rust-toolchain@nightly
218 with:
219 components: rust-src
220 - uses: Swatinem/rust-cache@v2
221 with:
222 cache-bin: false
223 key: tvos-sim
224 - run: cargo +nightly check -Z build-std --target aarch64-apple-tvos-sim
225
226 check-visionos:
227 name: Check (visionOS device)
228 runs-on: macos-26
229 env:
230 GRESIQ_API_KEY_DEV: ${{ secrets.GRESIQ_API_KEY_DEV }}
231 GRESIQ_API_SECRET_DEV: ${{ secrets.GRESIQ_API_SECRET_DEV }}
232 GRESIQ_API_KEY_PRODUCTION: ${{ secrets.GRESIQ_API_KEY_PRODUCTION }}
233 GRESIQ_API_SECRET_PRODUCTION: ${{ secrets.GRESIQ_API_SECRET_PRODUCTION }}
234 HF_TOKEN: ${{ secrets.HF_TOKEN }}
235 steps:
236 - uses: actions/checkout@v6
237 - uses: dtolnay/rust-toolchain@nightly
238 with:
239 components: rust-src
240 - uses: Swatinem/rust-cache@v2
241 with:
242 cache-bin: false
243 key: visionos
244 - run: cargo +nightly check -Z build-std --target aarch64-apple-visionos
245
246 check-visionos-sim:
247 name: Check (visionOS simulator)
248 runs-on: macos-26
249 env:
250 GRESIQ_API_KEY_DEV: ${{ secrets.GRESIQ_API_KEY_DEV }}
251 GRESIQ_API_SECRET_DEV: ${{ secrets.GRESIQ_API_SECRET_DEV }}
252 GRESIQ_API_KEY_PRODUCTION: ${{ secrets.GRESIQ_API_KEY_PRODUCTION }}
253 GRESIQ_API_SECRET_PRODUCTION: ${{ secrets.GRESIQ_API_SECRET_PRODUCTION }}
254 HF_TOKEN: ${{ secrets.HF_TOKEN }}
255 steps:
256 - uses: actions/checkout@v6
257 - uses: dtolnay/rust-toolchain@nightly
258 with:
259 components: rust-src
260 - uses: Swatinem/rust-cache@v2
261 with:
262 cache-bin: false
263 key: visionos-sim
264 - run: cargo +nightly check -Z build-std --target aarch64-apple-visionos-sim
265
266 check-watchos:
267 name: Check (watchOS device)
268 runs-on: macos-26
269 env:
270 GRESIQ_API_KEY_DEV: ${{ secrets.GRESIQ_API_KEY_DEV }}
271 GRESIQ_API_SECRET_DEV: ${{ secrets.GRESIQ_API_SECRET_DEV }}
272 GRESIQ_API_KEY_PRODUCTION: ${{ secrets.GRESIQ_API_KEY_PRODUCTION }}
273 GRESIQ_API_SECRET_PRODUCTION: ${{ secrets.GRESIQ_API_SECRET_PRODUCTION }}
274 HF_TOKEN: ${{ secrets.HF_TOKEN }}
275 steps:
276 - uses: actions/checkout@v6
277 - uses: dtolnay/rust-toolchain@nightly
278 with:
279 components: rust-src
280 - uses: Swatinem/rust-cache@v2
281 with:
282 cache-bin: false
283 key: watchos
284 - run: cargo +nightly check -Z build-std --target aarch64-apple-watchos
285
286 check-watchos-sim:
287 name: Check (watchOS simulator)
288 runs-on: macos-26
289 env:
290 GRESIQ_API_KEY_DEV: ${{ secrets.GRESIQ_API_KEY_DEV }}
291 GRESIQ_API_SECRET_DEV: ${{ secrets.GRESIQ_API_SECRET_DEV }}
292 GRESIQ_API_KEY_PRODUCTION: ${{ secrets.GRESIQ_API_KEY_PRODUCTION }}
293 GRESIQ_API_SECRET_PRODUCTION: ${{ secrets.GRESIQ_API_SECRET_PRODUCTION }}
294 HF_TOKEN: ${{ secrets.HF_TOKEN }}
295 steps:
296 - uses: actions/checkout@v6
297 - uses: dtolnay/rust-toolchain@nightly
298 with:
299 components: rust-src
300 - uses: Swatinem/rust-cache@v2
301 with:
302 cache-bin: false
303 key: watchos-sim
304 - run: cargo +nightly check -Z build-std --target aarch64-apple-watchos-sim
305
306 # ── Cross-compile checks for Unix-family platforms ────────────────────────
307 check-linux:
308 name: Check (Linux x86_64)
309 runs-on: ubuntu-latest
310 env:
311 GRESIQ_API_KEY_DEV: ${{ secrets.GRESIQ_API_KEY_DEV }}
312 GRESIQ_API_SECRET_DEV: ${{ secrets.GRESIQ_API_SECRET_DEV }}
313 GRESIQ_API_KEY_PRODUCTION: ${{ secrets.GRESIQ_API_KEY_PRODUCTION }}
314 GRESIQ_API_SECRET_PRODUCTION: ${{ secrets.GRESIQ_API_SECRET_PRODUCTION }}
315 HF_TOKEN: ${{ secrets.HF_TOKEN }}
316 steps:
317 - uses: actions/checkout@v6
318 - uses: dtolnay/rust-toolchain@stable
319 with:
320 targets: x86_64-unknown-linux-gnu
321 - uses: Swatinem/rust-cache@v2
322 with:
323 cache-bin: false
324 key: linux-x86_64
325 - run: cargo check --target x86_64-unknown-linux-gnu
326
327 check-android:
328 name: Check (Android arm64)
329 runs-on: ubuntu-latest
330 env:
331 GRESIQ_API_KEY_DEV: ${{ secrets.GRESIQ_API_KEY_DEV }}
332 GRESIQ_API_SECRET_DEV: ${{ secrets.GRESIQ_API_SECRET_DEV }}
333 GRESIQ_API_KEY_PRODUCTION: ${{ secrets.GRESIQ_API_KEY_PRODUCTION }}
334 GRESIQ_API_SECRET_PRODUCTION: ${{ secrets.GRESIQ_API_SECRET_PRODUCTION }}
335 HF_TOKEN: ${{ secrets.HF_TOKEN }}
336 CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER: aarch64-linux-android34-clang
337 CC_aarch64_linux_android: aarch64-linux-android34-clang
338 AR_aarch64_linux_android: llvm-ar
339 steps:
340 - uses: actions/checkout@v6
341 - uses: dtolnay/rust-toolchain@stable
342 with:
343 targets: aarch64-linux-android
344 - uses: android-actions/setup-android@v4
345 - name: Configure Android NDK toolchain
346 shell: bash
347 run: |
348 echo "${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin" >> "$GITHUB_PATH"
349 - uses: Swatinem/rust-cache@v2
350 with:
351 cache-bin: false
352 key: android-arm64
353 - run: cargo check --target aarch64-linux-android
354
355 # ── Cross-compile checks for Windows (lowest priority) ────────────────────
356 check-windows:
357 name: Check (Windows x86_64)
358 runs-on: windows-latest
359 env:
360 GRESIQ_API_KEY_DEV: ${{ secrets.GRESIQ_API_KEY_DEV }}
361 GRESIQ_API_SECRET_DEV: ${{ secrets.GRESIQ_API_SECRET_DEV }}
362 GRESIQ_API_KEY_PRODUCTION: ${{ secrets.GRESIQ_API_KEY_PRODUCTION }}
363 GRESIQ_API_SECRET_PRODUCTION: ${{ secrets.GRESIQ_API_SECRET_PRODUCTION }}
364 HF_TOKEN: ${{ secrets.HF_TOKEN }}
365 steps:
366 - uses: actions/checkout@v6
367 - uses: dtolnay/rust-toolchain@stable
368 with:
369 targets: x86_64-pc-windows-msvc
370 - uses: Swatinem/rust-cache@v2
371 with:
372 cache-bin: false
373 key: windows-x86_64
374 - run: cargo check --target x86_64-pc-windows-msvc