Skip to content

chore(toolchain): pin bun 1.4.0, and the coverage hole a pin bump alone would have opened - #534

Merged
cevheri merged 2 commits into
mainfrom
chore/bun-1.4.0
Aug 31, 2026
Merged

chore(toolchain): pin bun 1.4.0, and the coverage hole a pin bump alone would have opened#534
cevheri merged 2 commits into
mainfrom
chore/bun-1.4.0

Conversation

@cevheri

@cevheri cevheri commented Aug 31, 2026

Copy link
Copy Markdown
Member

Moves the pinned toolchain from Bun 1.3.14 to 1.4.0 — package.json's packageManager, the
Dockerfile's build base and the twenty bun-version lines across the workflows.

It is not only a pin. Two things travel with it, and one of them changes what a user sees.

The Storage tab starts reporting SQLite table sizes

Bun 1.4.0 bundles SQLite 3.53.2 with SQLITE_ENABLE_DBSTAT_VTAB compiled in — on the Linux and
Windows builds; macOS is excluded below. On 1.3.14 it was
not, so bun:sqlite answered no such table: dbstat and the provider omitted tableSize /
tableSizeBytes — the Storage tab drew "N/A" for the Tables and Indexes cards and "-" for each
table's share. From this pin it reads real page bytes.

Re-measured on 2026-08-31 on Linux x86_64, seeding 200 rows of a 4096-character payload into big with an index
on payload and 200 short rows into small. Under the same Bun 1.4.0 the two drivers returned
byte-identical getTableStats() output:

# LIBREDB_SQLITE_DRIVER unset (bun:sqlite) and LIBREDB_SQLITE_DRIVER=node
{"tableName":"big","rowCount":200,"tableSize":"904 KB","tableSizeBytes":925696,
 "indexSize":"908 KB","indexSizeBytes":929792,"totalSize":"1.77 MB","totalSizeBytes":1855488}
{"tableName":"small","rowCount":200,"tableSize":"4 KB","tableSizeBytes":4096,
 "indexSize":"0 B","indexSizeBytes":0,"totalSize":"4 KB","totalSizeBytes":4096}

So the driver divergence docs/providers/sqlite.md §7.2 documents closes on this pin. The 1.3.14
row stays in that table rather than being rewritten: an install pinned to an older image still
behaves that way, and the absent-field arm it justifies is still live for any build without
dbstat. The comment on TableStats.tableSize is corrected the same way — the omission is a
property of the SQLite build behind the driver, never of the driver's name.

macOS does not get this, and the docs now say so. There bun:sqlite dlopens Apple's
/usr/lib/libsqlite3.dylib rather than Bun's amalgamation — oven-sh/bun#16717,
open since 2025-01, reproduced by Bun's own triage bot, which is why sqlite_version() reads
3.43.2 there on 1.4.0. So the absent-dbstat arm stays live for reasons beyond an old pin, and
every claim in this change is scoped to the build rather than to the driver's name. The same
correction was applied to three comment sites outside the original diff that still asserted
"present on node:sqlite, absent on bun:sqlite" as a property of the driver.

A test that passed while covering nothing

tests/unit/db/sqlite-driver.test.ts asserted the driver-load failure path by relying on the
runtime not implementing node:sqlite, and skipped itself when the import resolved:

if (firstError === undefined) return;

Bun 1.4.0 implements node:sqlite. So on the new pin that test passes while the whole catch in
loadSQLiteDriver goes unexercised — a green suite and eight uncovered lines
(sqlite-driver.ts 169, 176-185) against a 100% gate. A pin bump alone would have turned the
required coverage check red for a reason nothing in the diff named.

loadSQLiteDriver now takes an injectable loader, the way loadNodeSQLiteDriver already takes an
injectable importer and for the same stated reason. The failure arm is a property of the test
rather than of whichever Bun is installed.

The upgrade also makes something newly testable: with node:sqlite present, the adapter can be
driven against the real DatabaseSync for the first time instead of a stand-in, so the three
bridges it promises are now asserted against the real module — get() mapping a miss to null,
run() narrowing bigint changes to number, and all() returning plain rows.

What was checked and found not to apply

Measured rather than assumed, against the 1.4.0 release notes:

Item Finding
Bun issue #32793 — a leaked setSystemTime() non-deterministically breaks Date.now() in other files The only file installing a fake clock, tests/unit/lib/api/rate-limit.test.ts, restores it in afterEach. Not reachable here
Bun.serve no longer serves sourcemaps for HTML routes in production Used only in scripts/build-azure-package.mjs, which is not a production path
The default trusted-dependencies list now applies only to npm-registry packages Ours is an explicit list — esbuild, oracledb, ssh2 — and all three come from the registry
bun.lock format Unchanged: lockfileVersion: 1 before and after, bun install reports "no changes", and the file's checksum does not move
better-sqlite3 crashes under Bun Pre-existing and architectural, not a regression: oven-sh/bun#4290 has been open since 2023-08-24 because Bun implements N-API but not the V8 C++ API these NAN addons link against. This repo already routes that dependency through Node harnesses (tests/integration/db/sqlite-node-harness.ts, tests/integration/storage/sqlite-credential-encryption-node-harness.ts), so Bun was never its runtime

Verification

  • All six gates green on this branch, plus bun run coverage:check at 100%
  • docker build on the new oven/bun:1.4.0 base succeeds, and the image serves
    GET /api/db/health200 {"status":"healthy"} and GET /login200. Worth noting for
    reviewers: the runtime stage of that image runs Node, not Bun (node --version → v26.7.0
    inside the container, bun absent), so for Docker this pin is a build-time change only
  • The image build performs a fresh bun install under 1.4.0, which a local install against an
    existing node_modules could not have proven

Deliberately not here

Bun 1.4.0's bun test --isolate clears the ESM and CJS module registries per file and cleans up
handles a file leaks — which is what tests/run-core.sh currently buys with one OS process per
test file. --parallel and --shard are adjacent. Adopting them would rework the coverage-merge
machinery behind a required gate, so it belongs in its own change rather than riding on a pin.

@codecov

codecov Bot commented Aug 31, 2026

Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

ℹ️ You can also turn on project coverage checks and project coverage reporting on Pull Request comment

Thanks for integrating Codecov - We've got you covered ☂️

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Pins Bun 1.4.0 consistently while adapting SQLite coverage and documenting its dbstat behavior.

Changes:

  • Updates Bun pins across package, Docker, CI, release, and publishing paths.
  • Adds deterministic SQLite driver failure injection and real node:sqlite testing.
  • Updates SQLite size documentation and runtime notes, though platform-specific claims need correction.

Reviewed changes

Copilot reviewed 16 out of 17 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
package.json Pins Bun 1.4.0.
Dockerfile Updates the dependency-stage Bun image.
bin/studio.js Documents Node shebang requirements.
src/lib/db/providers/sql/sqlite-driver.ts Adds an injectable driver loader.
src/lib/db/types.ts Updates table-size field documentation.
tests/unit/db/sqlite-driver.test.ts Adds real-module and deterministic failure tests.
docs/providers/sqlite.md Records updated dbstat measurements.
.github/ISSUE_TEMPLATE/bug_report.md Updates the example Bun version.
.github/workflows/agent-eval.yml Updates the Bun workflow pin.
.github/workflows/ci.yml Updates all CI Bun installations.
.github/workflows/distribution-check.yml Updates the distribution-check pin.
.github/workflows/docker-build-push.yml Updates Docker workflow pins.
.github/workflows/flatpak-smoke.yml Updates the Flatpak smoke-test pin.
.github/workflows/integration-check.yml Updates the integration-check pin.
.github/workflows/npm-publish.yml Updates npm publishing pins.
.github/workflows/release-artifacts.yml Updates release workflow pins.
.github/workflows/security-scan.yml Updates the security workflow pin.
Suppressed comments (1)

docs/providers/sqlite.md:401

  • This historical framing is followed immediately by text that still presents driver divergence as current: lines 403-420 say changing LIBREDB_SQLITE_DRIVER changes the answer and show bun:sqlite omitting sizes. That contradicts the new Bun 1.4.0 result above. Reframe the old output as the behavior of a build without dbstat, while describing both current measured adapters as populated.
The bytes differ from the 2026-08-24 row above because the seed is not the same file, not
because the drivers disagree — that comparison is a separate measurement, kept as the
record of what Bun 1.3.14 did. The 1.3.14 row is not history: an install pinned to an
older image still behaves that way, which is why the absent-field arm below stays.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/providers/sqlite.md Outdated
Comment on lines +383 to +385
**The divergence closed on Bun 1.4.0.** That Bun bundles SQLite 3.53.2 with
`SQLITE_ENABLE_DBSTAT_VTAB` compiled in, so `bun:sqlite` answers where 1.3.14 raised
`no such table: dbstat`, and the pinned runtime moved to it on 2026-08-31. Re-measured
Comment thread src/lib/db/types.ts Outdated
Comment on lines +851 to +855
* `dbstat` virtual table, which is a compile-time option the build behind the driver
* decides - present on node:sqlite, absent on bun:sqlite through Bun 1.3.14 ("no such
* table: dbstat", measured 2026-08-24 on SQLite 3.53.0) and present again from Bun
* 1.4.0 / SQLite 3.53.2 (re-measured 2026-08-31, where both drivers return identical
* bytes). So the omission is a property of the build, not of the driver's name, and
Comment on lines +165 to +168
* The loader is injectable for the same reason `loadNodeSQLiteDriver`'s importer is:
* the failure arm is otherwise reachable only on a runtime that lacks the module, so a
* test asserting it is really asserting a property of the installed Bun. It was written
* that way once and went quietly unexercised the day Bun 1.4.0 shipped `node:sqlite`.
Bun 1.4.0 bundles SQLite 3.53.2 with SQLITE_ENABLE_DBSTAT_VTAB only on its Linux and
Windows builds. On macOS bun:sqlite dlopens Apple's /usr/lib/libsqlite3.dylib instead
(oven-sh/bun#16717, open, reproduced by upstream triage), so sqlite_version() still
reads 3.43.2 there and what dbstat does is Apple's build's answer, unmeasured here.
The measurement now records its OS and architecture, and the section that presented
driver divergence in the present tense is reframed around the build.

Also drops the stale claim, in three comment sites, that Bun cannot import node:sqlite -
1.4.0 can, and the injectable seams exist for deterministic test isolation instead.
@cevheri

cevheri commented Aug 31, 2026

Copy link
Copy Markdown
Member Author

All four Copilot points verified against upstream rather than adopted on their face, and all four held — fixed in 43b7b15.

The macOS claim (two comments, plus the platform framing). Confirmed, and the citation understates it: oven-sh/bun#16717 is open, and on the duplicate #31247 Bun's own triage bot reproduced it — macOS bun:sqlite dlopens /usr/lib/libsqlite3.dylib, Apple ships 3.43.2 on macOS 15, and the bundled amalgamation is linked only on Linux and Windows. (#31249, the static-link fix, was closed as AI slop rather than on the merits, so nothing about the mechanism is settled by its closure.) My own measurement was Linux x86_64, Bun 1.4.0, sqlite_version() = 3.53.2, dbstat present. That OS and architecture are now recorded, the version claim is scoped to the builds that carry Bun's SQLite, and macOS is stated as unmeasured rather than assumed either way.

The stale node:sqlite comments. Correct — the module documented both claims at once. createNodeSQLiteDriver said node:sqlite "cannot be imported" under Bun and loadNodeSQLiteDriver said Bun "lacks node:sqlite", while the new test imports it. Both now describe the seams as deterministic test isolation.

The suppressed comment about lines 403-420. Also correct, and the sharpest of the four: the block below the new paragraph presented driver divergence in the present tense and printed bun:sqlite omitting sizes, directly contradicting the byte-identical result above it. Reframed around the build, with the sample labelled as captured on 1.3.14.

Two sites the review could not see carried the same defect outside the diff — sqlite.ts:123 ("node:sqlite carries it, bun:sqlite does not") and sqlite.ts:969 ("absent on bun:sqlite") — plus the doc's §7.2 heading, which asserted the refuted framing in its own title. All three are corrected, and the three in-document anchors were updated with the heading.

Comments and prose only; no executable line moves.

@sonarqubecloud

Copy link
Copy Markdown

@cevheri
cevheri merged commit 6d41cfc into main Aug 31, 2026
27 checks passed
@cevheri
cevheri deleted the chore/bun-1.4.0 branch August 31, 2026 21:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants