Skip to content

Commit c38ea9e

Browse files
committed
ci: adds CI for deno and bun
Signed-off-by: Dennis Zhuang <killme2008@gmail.com>
1 parent 3ddce33 commit c38ea9e

4 files changed

Lines changed: 186 additions & 1 deletion

File tree

.github/workflows/ci.yml

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,99 @@ jobs:
8181
- name: Stop GreptimeDB
8282
if: always()
8383
run: docker rm -f greptimedb || true
84+
85+
bun-smoke:
86+
runs-on: ubuntu-latest
87+
steps:
88+
- uses: actions/checkout@v4
89+
- uses: pnpm/action-setup@v4
90+
with:
91+
version: 9.15.9
92+
- uses: actions/setup-node@v4
93+
with:
94+
node-version: 22
95+
cache: pnpm
96+
- uses: oven-sh/setup-bun@v2
97+
with:
98+
bun-version: latest
99+
- run: pnpm install --frozen-lockfile
100+
- name: Start GreptimeDB
101+
env:
102+
GREPTIMEDB_VERSION: v1.0.0
103+
run: |
104+
docker run -d --name greptimedb-bun \
105+
-p 4000:4000 -p 4001:4001 -p 4002:4002 \
106+
"greptime/greptimedb:${GREPTIMEDB_VERSION}" standalone start \
107+
--http-addr 0.0.0.0:4000 \
108+
--rpc-bind-addr 0.0.0.0:4001 \
109+
--mysql-addr 0.0.0.0:4002
110+
- name: Wait for GreptimeDB readiness
111+
run: |
112+
for i in $(seq 1 60); do
113+
if curl -fsS http://127.0.0.1:4000/health >/dev/null 2>&1; then
114+
echo "GreptimeDB is ready"
115+
exit 0
116+
fi
117+
sleep 1
118+
done
119+
echo "GreptimeDB failed to become ready"
120+
docker logs greptimedb-bun
121+
exit 1
122+
- run: bun run scripts/smoke.ts
123+
env:
124+
GREPTIMEDB_ENDPOINT: localhost:4001
125+
GREPTIMEDB_HTTP: http://127.0.0.1:4000
126+
- name: Dump GreptimeDB logs on failure
127+
if: failure()
128+
run: docker logs greptimedb-bun
129+
- name: Stop GreptimeDB
130+
if: always()
131+
run: docker rm -f greptimedb-bun || true
132+
133+
deno-smoke:
134+
runs-on: ubuntu-latest
135+
steps:
136+
- uses: actions/checkout@v4
137+
- uses: pnpm/action-setup@v4
138+
with:
139+
version: 9.15.9
140+
- uses: actions/setup-node@v4
141+
with:
142+
node-version: 22
143+
cache: pnpm
144+
- uses: denoland/setup-deno@v2
145+
with:
146+
deno-version: v2.x
147+
- run: pnpm install --frozen-lockfile
148+
- name: Start GreptimeDB
149+
env:
150+
GREPTIMEDB_VERSION: v1.0.0
151+
run: |
152+
docker run -d --name greptimedb-deno \
153+
-p 4000:4000 -p 4001:4001 -p 4002:4002 \
154+
"greptime/greptimedb:${GREPTIMEDB_VERSION}" standalone start \
155+
--http-addr 0.0.0.0:4000 \
156+
--rpc-bind-addr 0.0.0.0:4001 \
157+
--mysql-addr 0.0.0.0:4002
158+
- name: Wait for GreptimeDB readiness
159+
run: |
160+
for i in $(seq 1 60); do
161+
if curl -fsS http://127.0.0.1:4000/health >/dev/null 2>&1; then
162+
echo "GreptimeDB is ready"
163+
exit 0
164+
fi
165+
sleep 1
166+
done
167+
echo "GreptimeDB failed to become ready"
168+
docker logs greptimedb-deno
169+
exit 1
170+
- run: deno run -A scripts/smoke.ts
171+
env:
172+
GREPTIMEDB_ENDPOINT: localhost:4001
173+
GREPTIMEDB_HTTP: http://127.0.0.1:4000
174+
- name: Dump GreptimeDB logs on failure
175+
if: failure()
176+
run: docker logs greptimedb-deno
177+
- name: Stop GreptimeDB
178+
if: always()
179+
run: docker rm -f greptimedb-deno || true

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ On the 22-column log schema the bulk path reaches **~137k rows/s** (2M rows, bat
148148

149149
- Tested: Node.js 22.x + GreptimeDB 1.0.0 / latest.
150150
- Node.js 20.x: supported (minimum).
151-
- Bun / Deno (node-compat): best-effort, not CI-gated.
151+
- Bun (latest) and Deno (2.x): CI-gated via a smoke-level integration test against a live GreptimeDB. Full unit suite runs on Node only.
152152

153153
See [docs/divergences.md](./docs/divergences.md) for where the TS SDK intentionally differs from the Rust / Go SDKs.
154154

deno.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"nodeModulesDir": "manual",
3+
"unstable": ["sloppy-imports"]
4+
}

scripts/smoke.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Cross-runtime smoke test — runs on Node, Bun, and Deno.
3+
*
4+
* Exercises the critical path that defines "can you even use this SDK on this
5+
* runtime": construct a Client, do one unary write, query the row count back
6+
* via the GreptimeDB HTTP SQL API, close the client. Any runtime-level
7+
* incompatibility in @grpc/grpc-js shows up here as a connection/stream
8+
* failure before the write resolves.
9+
*
10+
* Intentionally uses no `node:*` imports — only the SDK plus the global
11+
* `fetch` (available on all three runtimes).
12+
*
13+
* Env:
14+
* GREPTIMEDB_ENDPOINT (default: localhost:4001) gRPC target
15+
* GREPTIMEDB_HTTP (default: http://127.0.0.1:4000) HTTP base URL
16+
*
17+
* Run:
18+
* bun run scripts/smoke.ts
19+
* deno run -A scripts/smoke.ts
20+
* pnpm tsx scripts/smoke.ts # Node path (via tsx)
21+
*/
22+
23+
import { Client, DataType, Precision, Table } from '../src/index.js';
24+
25+
const ROW_COUNT = 5;
26+
27+
async function main(): Promise<void> {
28+
const endpoint = process.env.GREPTIMEDB_ENDPOINT ?? 'localhost:4001';
29+
const httpBase = process.env.GREPTIMEDB_HTTP ?? 'http://127.0.0.1:4000';
30+
const tableName = `smoke_test_${Date.now()}`;
31+
32+
const client = new Client(Client.create(endpoint).withDatabase('public').build());
33+
34+
try {
35+
const now = Date.now();
36+
const table = Table.new(tableName)
37+
.addTagColumn('host', DataType.String)
38+
.addFieldColumn('usage', DataType.Float64)
39+
.addTimestampColumn('ts', Precision.Millisecond);
40+
41+
for (let i = 0; i < ROW_COUNT; i++) {
42+
table.addRow([`server-${i}`, 10 + i, now + i]);
43+
}
44+
45+
const result = await client.write(table);
46+
if (result.value !== ROW_COUNT) {
47+
throw new Error(`write returned ${result.value} rows, expected ${ROW_COUNT}`);
48+
}
49+
50+
const observed = await queryCount(httpBase, tableName);
51+
if (observed !== ROW_COUNT) {
52+
throw new Error(`SELECT COUNT(*) returned ${observed}, expected ${ROW_COUNT}`);
53+
}
54+
55+
console.log(`smoke ok: wrote ${ROW_COUNT} rows to ${tableName}, verified via HTTP SQL`);
56+
} finally {
57+
await client.close();
58+
}
59+
}
60+
61+
// GreptimeDB HTTP SQL API: POST /v1/sql?db=<db> with form-encoded `sql=...`.
62+
async function queryCount(httpBase: string, table: string): Promise<number> {
63+
const url = `${httpBase.replace(/\/$/, '')}/v1/sql?db=public`;
64+
const res = await fetch(url, {
65+
method: 'POST',
66+
headers: { 'content-type': 'application/x-www-form-urlencoded' },
67+
body: new URLSearchParams({ sql: `SELECT COUNT(*) FROM ${table}` }),
68+
});
69+
if (!res.ok) {
70+
throw new Error(`HTTP SQL ${res.status}: ${await res.text()}`);
71+
}
72+
const body = (await res.json()) as {
73+
output?: { records?: { rows?: unknown[][] } }[];
74+
};
75+
const cell = body.output?.[0]?.records?.rows?.[0]?.[0];
76+
if (typeof cell !== 'number' && typeof cell !== 'bigint') {
77+
throw new Error(`unexpected SQL response shape: ${JSON.stringify(body)}`);
78+
}
79+
return Number(cell);
80+
}
81+
82+
main().catch((err: unknown) => {
83+
console.error('smoke failed:', err);
84+
process.exit(1);
85+
});

0 commit comments

Comments
 (0)