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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
# Continuous integration — runs on every pull request + every push to
# main. Blocks PR merge when anything fails (once branch protection is
# configured on the GitHub side — see docs/release-plan.md Phase 6c).
#
# Jobs:
# - rust-build-and-test {ubuntu, macos, windows} cargo build + test
# - rust-lint ubuntu fmt + clippy + doc
# - python-sdk {ubuntu, macos, windows} maturin develop + pytest
# - nodejs-sdk {ubuntu, macos, windows} napi build + node --test
# - go-sdk {ubuntu, macos} cgo against libsqlrite_c + go test
# - wasm-build ubuntu wasm-pack build + size report
# - desktop-build ubuntu npm ci + cargo build -p sqlrite-desktop
#
# All jobs use caching so a warm PR run takes 2–3 minutes on ubuntu.
# Go CI skips Windows for Phase 6b — Go's cgo on Windows needs a mingw
# setup that we haven't wired into the Go sidecar; deferred follow-up.
name: CI
on:
pull_request:
push:
branches:
# Cancel previous CI runs on the same branch when a new push arrives.
# Saves compute + shortens PR feedback loops.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
env:
# Suppress the "incremental compilation is not recommended for CI"
# advice line-noise across every Rust job. We don't want incremental
# on CI anyway (every run is from scratch).
CARGO_INCREMENTAL: '0'
# Colored cargo output survives into the GitHub Actions log view.
CARGO_TERM_COLOR: always
# Note: we intentionally do NOT set `RUSTFLAGS: '-D warnings'` at
# the workflow level. The codebase has ~24 pre-existing clippy
# warnings (mostly cosmetic — overindented docstrings, `Vec::new()
# + push` patterns, etc.) that will get cleaned up incrementally.
# Once the count is zero, we'll tighten by adding `-D warnings`
# here. Hard clippy errors (deny-by-default lints like
# `approx_constant`) still fail CI without this flag — that's the
# backstop for real correctness issues.
jobs:
# ---------------------------------------------------------------------------
# Rust: build + test the whole workspace (minus the desktop crate —
# it needs a frontend build, handled in its own job).
rust-build-and-test:
name: rust (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
defaults:
run:
# Bash on every OS — Windows uses Git Bash (preinstalled on
# `windows-latest`). Without this, Windows defaults to pwsh,
# which doesn't understand bash's backslash line-continuation
# in multi-line `run:` blocks.
shell: bash
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo
uses: Swatinem/rust-cache@v2
with:
# Bucket by OS + job — separate caches so a Linux miss
# doesn't steal macOS's target dir and vice versa.
shared-key: rust-build-and-test
# Exclusions explained:
#
# - `sqlrite-desktop` needs the Svelte frontend built first
# (handled in the `desktop-build` job).
#
# - `sqlrite-python` + `sqlrite-nodejs` are PyO3/napi-rs
# extension-module cdylibs. Their `extension-module` feature
# tells the Rust toolchain not to link libpython / libnode at
# compile time, so `--all-targets` fails on macOS when it
# tries to build the auto-generated test binary for their
# rlib targets (unresolved Python/Node symbols). The per-SDK
# `python-sdk` + `nodejs-sdk` jobs below exercise these
# crates through their native tooling (maturin / napi-rs).
- name: cargo build
run: |
cargo build --workspace \
--exclude sqlrite-desktop \
--exclude sqlrite-python \
--exclude sqlrite-nodejs \
--all-targets
- name: cargo test
run: |
cargo test --workspace \
--exclude sqlrite-desktop \
--exclude sqlrite-python \
--exclude sqlrite-nodejs
# ---------------------------------------------------------------------------
# Rust: lint — fmt + clippy + doc. One cell (ubuntu) because these
# are platform-independent checks. Runs in parallel with the matrix
# build/test job above.
rust-lint:
name: rust lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust + components
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
with:
shared-key: rust-lint
- name: cargo fmt
run: cargo fmt --all -- --check
- name: cargo clippy
# No `-D warnings` for now — see the top-level env comment.
# Deny-by-default lints (the ones that surface real bugs,
# e.g. `approx_constant`) still fail without the flag.
# Exclude the extension-module SDK cdylibs for the same
# reason as `rust-build-and-test` — their test binaries
# can't link standalone.
run: |
cargo clippy --workspace \
--exclude sqlrite-desktop \
--exclude sqlrite-python \
--exclude sqlrite-nodejs \
--all-targets
- name: cargo doc
# `--no-deps` skips deps docs (they build on docs.rs, not here).
# Not warnings-as-errors yet — same rationale as clippy above.
run: |
cargo doc --workspace \
--exclude sqlrite-desktop \
--exclude sqlrite-python \
--exclude sqlrite-nodejs \
--no-deps
# ---------------------------------------------------------------------------
# Python SDK: build the PyO3 extension, install into a venv, run pytest.
python-sdk:
name: python-sdk (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
defaults:
run:
# Bash on every runner (Windows' git bash is available via
# `shell: bash`) so the same commands work everywhere — no
# PowerShell / cmd fork.
shell: bash
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: pip
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
shared-key: python-sdk-${{ matrix.os }}
# maturin develop needs a virtualenv or conda env to install
# into. We create one per job + export VIRTUAL_ENV so every
# subsequent step sees it. Cross-platform: Windows venvs have
# `Scripts/` instead of `bin/`, so we pick the right path.
- name: Create venv
run: |
python -m venv .venv
if [ -d .venv/bin ]; then
echo "VIRTUAL_ENV=$PWD/.venv" >> "$GITHUB_ENV"
echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
else
echo "VIRTUAL_ENV=$PWD/.venv" >> "$GITHUB_ENV"
echo "$PWD/.venv/Scripts" >> "$GITHUB_PATH"
fi
- name: Install maturin + pytest
run: pip install maturin pytest
- name: maturin develop
working-directory: sdk/python
run: maturin develop
- name: pytest
working-directory: sdk/python
run: python -m pytest tests/
# ---------------------------------------------------------------------------
# Node.js SDK: napi-rs build produces a .node binary. `npm test`
# exercises the node:test suite against it.
nodejs-sdk:
name: nodejs-sdk (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: sdk/nodejs/package-lock.json
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
shared-key: nodejs-sdk-${{ matrix.os }}
- name: npm ci
working-directory: sdk/nodejs
run: npm ci
- name: npm run build
working-directory: sdk/nodejs
run: npm run build
- name: npm test
working-directory: sdk/nodejs
run: npm test
# ---------------------------------------------------------------------------
# Go SDK: cgo-linked against libsqlrite_c. We build the FFI crate in
# release mode first so the .so / .dylib is available for go test.
#
# Skips Windows for Phase 6b — Go's cgo on Windows needs a mingw
# toolchain that isn't preinstalled on `windows-latest` runners; a
# follow-up task in the roadmap adds it.
go-sdk:
name: go-sdk (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.21'
cache-dependency-path: sdk/go/go.mod
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
shared-key: go-sdk-${{ matrix.os }}
- name: Build libsqlrite_c
# The Go driver's `#cgo LDFLAGS` references target/release.
run: cargo build --release -p sqlrite-ffi
- name: go test ./...
working-directory: sdk/go
run: go test -v ./...
# ---------------------------------------------------------------------------
# WASM: only the build + size check (no tests — the WASM module's
# behavior is covered by the other SDKs' test suites; WASM just
# re-targets the same engine). One cell because WASM is a
# cross-compilation target, not a host OS.
wasm-build:
name: wasm-build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@v2
with:
# sdk/wasm is its own workspace (see Cargo.toml comment);
# key it separately so it doesn't blow the main cache.
workspaces: sdk/wasm
shared-key: wasm-build
- name: Install wasm-pack
uses: jetli/wasm-pack-action@v0.4.0
- name: wasm-pack build --target web --release
working-directory: sdk/wasm
run: wasm-pack build --target web --release
- name: Report .wasm size
# Surfaces size regressions in PR logs. Not a hard limit yet;
# if/when we set a budget, convert to a failing check.
working-directory: sdk/wasm
run: |
size=$(stat -c '%s' pkg/sqlrite_wasm_bg.wasm 2>/dev/null || stat -f '%z' pkg/sqlrite_wasm_bg.wasm)
echo "::notice title=WASM bundle size::sqlrite_wasm_bg.wasm = $size bytes ($(( size / 1024 )) KiB)"
# ---------------------------------------------------------------------------
# Desktop: Tauri's Rust side + the Svelte frontend. Needs Node to
# build the frontend first because Tauri's build.rs looks for the
# compiled assets in `desktop/dist/`.
#
# One cell (ubuntu) for CI speed — release builds are tested in the
# Phase 6e desktop-release workflow's build matrix on all three OSes.
# Here we just need to prove the Rust side compiles.
desktop-build:
name: desktop-build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: desktop/package-lock.json
- uses: dtolnay/rust-toolchain@stable
# Tauri needs Linux webkit + friends before cargo build runs.
- name: Install Tauri Linux deps
run: |
sudo apt-get update
sudo apt-get install -y \
libwebkit2gtk-4.1-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
patchelf
- uses: Swatinem/rust-cache@v2
with:
shared-key: desktop-build
- name: npm ci
working-directory: desktop
run: npm ci
- name: Build frontend
working-directory: desktop
run: npm run build
- name: Build Rust side
run: cargo build -p sqlrite-desktop