-
Notifications
You must be signed in to change notification settings - Fork 0
187 lines (176 loc) · 8.38 KB
/
Copy pathci.yml
File metadata and controls
187 lines (176 loc) · 8.38 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
# Runs automatically on pull requests and on pushes to main/develop, with a
# manual `workflow_dispatch` fallback. Mirrors the local `just verify` gate,
# which stays the fast pre-commit check (ADR-0015).
name: ci
on:
pull_request:
push:
branches: [main, develop]
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
check:
name: fmt · clippy · test · doc
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- uses: Swatinem/rust-cache@v2
- name: Format
run: cargo fmt --all --check
- name: Clippy (warnings denied)
run: cargo clippy --workspace --all-targets -- -D warnings
- name: Clippy (optional otlp feature — keeps the gated exporter from rotting)
run: cargo clippy -p quiverdb-server --features otlp --all-targets -- -D warnings
- name: Clippy (optional raft feature — keeps the gated consensus adapter from rotting)
run: cargo clippy -p quiverdb-server --features raft --all-targets -- -D warnings
- name: Clippy (optional cuda feature — keeps the gated GPU kernel from rotting)
# cudarc dynamically loads the CUDA driver at runtime, so the feature
# *compiles* without a CUDA toolchain.
run: cargo clippy -p quiverdb-index --features cuda --all-targets -- -D warnings
- name: Test (optional cuda feature — the CPU fallback on a GPU-less machine)
# This runner has no CUDA driver, which is exactly the case worth gating: a
# `cuda` build must degrade to the CPU kernel there, not fail. Only clippy ran
# here before, which is why a panicking driver load shipped unnoticed — the
# GPU-side assertions self-skip without a device, so this is safe everywhere.
run: cargo test -p quiverdb-index --features cuda gpu
- name: Format + clippy (cockpit-shots — its own workspace, not in --workspace above)
run: |
cargo fmt --manifest-path tools/cockpit-shots/Cargo.toml --check
cargo clippy --manifest-path tools/cockpit-shots/Cargo.toml --all-targets -- -D warnings
- name: Test (workspace, excluding the crash-recovery stress test)
run: cargo test --workspace -- --skip kill_mid_write_preserves_acknowledged_writes
- name: Test (optional raft feature — consensus adapter + server wiring)
# The `raft` filter (substring) runs the in-process/gRPC adapter unit
# tests (`raft::…`) and the `raft_cluster` server-wiring failover test.
run: "cargo test -p quiverdb-server --features raft raft"
- name: Crash-recovery stress test (retried — kill -9 timing is runner-sensitive)
# The kill-mid-write gate SIGKILLs a writer at randomized points and asserts
# recovery. A genuine recovery regression is deterministic and fails every
# attempt (so the job still fails and you are notified); a rare transient
# reopen error under the runner's virtualized I/O timing passes on a retry,
# so it no longer fails the job on a false positive. The test surfaces the
# underlying error + on-disk state when it does fail (see the test source).
run: |
for attempt in 1 2 3; do
echo "::group::crash_recovery attempt ${attempt}"
if cargo test -p quiverdb-core --test crash_recovery; then
echo "::endgroup::"
echo "crash_recovery passed on attempt ${attempt}"
exit 0
fi
echo "::endgroup::"
echo "crash_recovery attempt ${attempt} failed"
done
echo "crash_recovery failed all attempts — a real recovery regression" >&2
exit 1
- name: Docs
run: cargo doc --workspace --no-deps
env:
RUSTDOCFLAGS: -D warnings
coverage:
name: coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview
- uses: Swatinem/rust-cache@v2
- uses: taiki-e/install-action@cargo-llvm-cov
# The roadmap has asserted a >=80% coverage gate since Phase 3, but nothing
# enforced it — `just coverage` was a local HTML report run by hand, so the
# number in the docs was an unverified claim. The measured workspace figure is
# ~90.6% line, so the gate is set at 85%: comfortably above what the roadmap
# promises, with enough headroom that ordinary churn does not trip it. Skips the
# same crash-recovery stress test the `check` job runs separately, whose kill -9
# timing is runner-sensitive.
- name: Coverage (workspace, gate at 85% lines)
run: >-
cargo llvm-cov --workspace --summary-only --fail-under-lines 85
-- --skip kill_mid_write_preserves_acknowledged_writes
package:
name: package (publishability)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
# `--no-verify` skips the registry verification build (a dependent crate's
# deps are not on crates.io yet — the chicken-and-egg the first publish
# resolves), so this checks the crate metadata and that every crate packages
# cleanly. It fails the moment a crate loses `description`/`license`/… (ADR-0056).
- name: cargo package (metadata + tarball)
run: cargo package --workspace --no-verify
- uses: astral-sh/setup-uv@v7
- name: Build + test the Python SDK
working-directory: sdks/python
run: |
uv build
uvx twine check dist/*
# Run the SDK test suite — includes the cross-language cipher KAT (F-13),
# so drift from the shared kat/client-ciphers.json fails the build.
uv run pytest -q
- uses: pnpm/action-setup@v6
with:
version: "11.6.0" # matches packageManager; pnpm 11 needs Node >= 22.13
- uses: actions/setup-node@v7
with:
node-version: "22"
- name: Build + test + dry-run pack the TypeScript SDK
working-directory: sdks/typescript
run: |
pnpm install --frozen-lockfile
pnpm build
# Run the SDK test suite — includes the cross-language cipher KAT (F-13).
pnpm test
npm pack --dry-run
# Boots a real encrypted server and drives every external surface the way an
# operator does — REST, both SDKs, the CLI importer, and the MCP server over
# stdio. This existed as `just acceptance` but ran only by hand, which left the
# SDKs effectively untested against a live server: their own suites mock the
# transport entirely, so a wire-format change on the server ships green. It takes
# well under a minute, which is cheap for the surface it covers.
acceptance:
name: acceptance (live server, every surface)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: astral-sh/setup-uv@v7
- uses: pnpm/action-setup@v6
with:
version: "11.6.0" # matches packageManager; pnpm 11 needs Node >= 22.13
- uses: actions/setup-node@v7
with:
node-version: "22"
- name: Acceptance run
run: bash scripts/acceptance.sh
helm:
name: helm lint + template
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: azure/setup-helm@v5
- name: Helm lint
run: helm lint infra/helm/quiver --set encryption.masterKey="$(openssl rand -hex 32)"
- name: Helm template (with key)
run: helm template q infra/helm/quiver --set encryption.masterKey="$(openssl rand -hex 32)" > /dev/null
- name: Helm template (insecure)
run: helm template q infra/helm/quiver --set encryption.insecure=true > /dev/null
# Dynamic OWASP ZAP scan of a live server (ADR-0069). Skipped on pull requests
# (it builds and boots the server + pulls the ZAP image — too heavy for every
# push); it runs on main/develop pushes and manual dispatch so a DAST regression
# is caught on the mainline before a release tag hits the blocking gate in
# release.yml.
dast:
name: DAST (OWASP ZAP)
if: ${{ github.event_name != 'pull_request' }}
uses: ./.github/workflows/dast.yml