Skip to content

Commit 4811951

Browse files
committed
Replace deprectated prebuld
1 parent 2ca26e8 commit 4811951

File tree

9 files changed

+239
-1713
lines changed

9 files changed

+239
-1713
lines changed

.github/workflows/ci.yml

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,17 @@ jobs:
143143
echo "CXXFLAGS=${CXXFLAGS:-} -include ../src/gcc-preinclude.h" >> $GITHUB_ENV
144144
145145
- name: Build binaries
146-
run: yarn prebuild -a ${{ env.TARGET }}
146+
run: yarn prebuild
147147

148148
- name: Print binary info
149149
if: contains(matrix.os, 'ubuntu')
150150
run: |
151-
ldd build/**/node_sqlite3.node
151+
BIN=$(find prebuilds -name "*.node" | head -1)
152+
ldd "$BIN"
152153
echo "---"
153-
nm build/**/node_sqlite3.node | grep "GLIBC_" | c++filt || true
154+
nm "$BIN" | grep "GLIBC_" | c++filt || true
154155
echo "---"
155-
file build/**/node_sqlite3.node
156+
file "$BIN"
156157
157158
- name: Run tests
158159
run: yarn test
@@ -166,8 +167,10 @@ jobs:
166167
retention-days: 7
167168

168169
- name: Upload binaries to GitHub Release
169-
run: yarn upload --upload-all ${{ github.token }}
170+
run: gh release upload ${GITHUB_REF#refs/tags/} prebuilds/* --clobber
170171
if: matrix.node == 24 && startsWith(github.ref, 'refs/tags/')
172+
env:
173+
GH_TOKEN: ${{ github.token }}
171174

172175
build-musl:
173176
permissions:
@@ -209,8 +212,54 @@ jobs:
209212
retention-days: 7
210213

211214
- name: Upload binaries to GitHub Release
212-
run: yarn install --frozen-lockfile --ignore-scripts && yarn upload --upload-all ${{ github.token }}
215+
run: |
216+
gh release upload ${GITHUB_REF#refs/tags/} prebuilds/* --clobber
213217
if: startsWith(github.ref, 'refs/tags/')
218+
env:
219+
GH_TOKEN: ${{ github.token }}
220+
221+
package:
222+
needs: [build, build-musl]
223+
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request') || (github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/'))
224+
runs-on: ubuntu-latest
225+
steps:
226+
- uses: actions/checkout@v6
227+
- uses: actions/setup-node@v6
228+
with:
229+
node-version: 24
230+
231+
- name: Install dependencies
232+
run: yarn install --frozen-lockfile --ignore-scripts
233+
234+
- name: Download all prebuilt binary artifacts
235+
uses: actions/download-artifact@v5
236+
with:
237+
path: prebuilds-artifacts
238+
merge-multiple: true
239+
240+
- name: Merge prebuilds into package
241+
run: |
242+
mkdir -p prebuilds
243+
# Each artifact may contain platform-specific subdirs
244+
# Copy all prebuilds from artifacts into prebuilds/
245+
cp -r prebuilds-artifacts/*/ prebuilds/ 2>/dev/null || true
246+
# Also handle flat structure (files directly in artifact root)
247+
cp -r prebuilds-artifacts/ prebuilds/ 2>/dev/null || true
248+
# Verify the prebuilds are present
249+
find prebuilds -name '*.node' -type f
250+
251+
- name: Create npm tarball
252+
run: |
253+
npm pack
254+
echo "npm tarball created:"
255+
ls -la *.tgz
256+
257+
- name: Upload npm tarball as commit artifact
258+
uses: actions/upload-artifact@v7
259+
with:
260+
name: npm-package-tarball
261+
path: '*.tgz'
262+
retention-days: 7
214263

215264
publish-npm:
216265
needs: [build, build-musl]
@@ -229,5 +278,18 @@ jobs:
229278
- name: Install dependencies
230279
run: yarn install --frozen-lockfile --ignore-scripts
231280

281+
- name: Download all prebuilt binary artifacts
282+
uses: actions/download-artifact@v5
283+
with:
284+
path: prebuilds-artifacts
285+
merge-multiple: true
286+
287+
- name: Merge prebuilds into package
288+
run: |
289+
mkdir -p prebuilds
290+
cp -r prebuilds-artifacts/*/ prebuilds/ 2>/dev/null || true
291+
cp -r prebuilds-artifacts/ prebuilds/ 2>/dev/null || true
292+
find prebuilds -name '*.node' -type f
293+
232294
- name: Publish to npm
233295
run: npm publish

README.md

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,23 +36,25 @@ yarn add @homeofthings/sqlite3
3636

3737
### Prebuilt binaries
3838

39-
`@homeofthings/sqlite3` uses [Node-API](https://nodejs.org/api/n-api.html) so prebuilt binaries do not need to be built for specific Node versions. Prebuilt binaries are available for Node-API v3 and v6. Check the [Node-API version matrix](https://nodejs.org/api/n-api.html#node-api-version-matrix) to ensure your Node version supports one of these. Requires Node.js v20.17.0 or later.
39+
`@homeofthings/sqlite3` uses [Node-API](https://nodejs.org/api/n-api.html) so prebuilt binaries do not need to be built for specific Node versions. Prebuilt binaries are built as NAPI-version-agnostic (`node.napi.*.node`) using the `--napi` flag, and work on any Node.js version that supports the NAPI version used at compile time. Requires Node.js v20.17.0 or later.
4040

41-
The module uses [`prebuild-install`](https://github.com/prebuild/prebuild-install) to download the prebuilt binary for your platform, if it exists. These binaries are hosted on GitHub Releases. The following targets are currently provided:
41+
Prebuilt binaries are bundled inside the npm package using [`prebuildify`](https://github.com/prebuild/prebuildify) and loaded at runtime by [`node-gyp-build`](https://github.com/prebuild/node-gyp-build). No separate download step is needed — `npm install` just works. The following targets are currently provided:
4242

4343
* `darwin-arm64`
4444
* `darwin-x64`
45-
* `linux-arm64`
46-
* `linux-x64`
47-
* `linuxmusl-arm64`
48-
* `linuxmusl-x64`
45+
* `linux-arm64` (glibc)
46+
* `linux-x64` (glibc)
47+
* `linux-arm64` (musl)
48+
* `linux-x64` (musl)
4949
* `win32-x64`
5050

51-
Unfortunately, [prebuild](https://github.com/prebuild/prebuild/issues/174) cannot differentiate between `armv6` and `armv7`, and instead uses `arm` as the `{arch}`. Until that is fixed, you will still need to install `sqlite3` from [source](#source-install).
52-
5351
Support for other platforms and architectures may be added in the future if CI supports building on them.
5452

55-
If your environment isn't supported, it'll use `node-gyp` to build SQLite, but you will need to install a C++ compiler and linker.
53+
If your platform isn't supported, `node-gyp-build` automatically falls back to building from source using `node-gyp`. For custom builds (e.g., SQLCipher, external SQLite), use `--build-from-source`:
54+
55+
```bash
56+
npm install @homeofthings/sqlite3 --build-from-source --sqlite_libname=sqlcipher --sqlite=/usr/
57+
```
5658

5759
### Other ways to install
5860

@@ -135,23 +137,23 @@ db.close();
135137
To skip searching for pre-compiled binaries, and force a build from source, use
136138

137139
```bash
138-
npm install --build-from-source --sqlite=/usr/local
140+
npm install @homeofthings/sqlite3 --build-from-source --sqlite=/usr/local
139141
```
140142

141143
If building against an external sqlite3 make sure to have the development headers available. Mac OS X ships with these by default. If you don't have them installed, install the `-dev` package with your package manager, e.g. `apt-get install libsqlite3-dev` for Debian/Ubuntu. Make sure that you have at least `libsqlite3` >= 3.6.
142144

143145
Note, if building against homebrew-installed sqlite on OS X you can do:
144146

145147
```bash
146-
npm install --build-from-source --sqlite=/usr/local/opt/sqlite/
148+
npm install @homeofthings/sqlite3 --build-from-source --sqlite=/usr/local/opt/sqlite/
147149
```
148150

149151
## Custom file header (magic)
150152

151153
The default sqlite file header is "SQLite format 3". You can specify a different magic, though this will make standard tools and libraries unable to work with your files.
152154

153155
```bash
154-
npm install --build-from-source --sqlite_magic="MyCustomMagic15"
156+
npm install @homeofthings/sqlite3 --build-from-source --sqlite_magic="MyCustomMagic15"
155157
```
156158

157159
Note that the magic *must* be exactly 15 characters long (16 bytes including null terminator).
@@ -174,7 +176,7 @@ npm install @homeofthings/sqlite3 --build-from-source --runtime=node-webkit --ta
174176
You can also run this command from within a `@homeofthings/sqlite3` checkout:
175177

176178
```bash
177-
npm install --build-from-source --runtime=node-webkit --target_arch=ia32 --target=$(NODE_WEBKIT_VERSION)
179+
npm install @homeofthings/sqlite3 --build-from-source --runtime=node-webkit --target_arch=ia32 --target=$(NODE_WEBKIT_VERSION)
178180
```
179181

180182
Remember the following:

docs/DEVELOP.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ This project uses [npm version](https://docs.npmjs.com/cli/v10/commands/npm-vers
2222
```
2323

2424
The CI workflow will automatically:
25-
- Build binaries for all platforms
26-
- Upload them as release assets
27-
- Publish the package to npm
25+
- Build prebuilt binaries for all platforms
26+
- Upload them to GitHub Release
27+
- Publish the package to npm (with bundled prebuilt binaries)
2828

2929
3. ** Edit the generated Pre-release
3030
- select "Generate release notes" and adjust them to your needs
@@ -44,12 +44,15 @@ When you push a tag (e.g., `v6.0.2`), the CI workflow will:
4444

4545
1. Build prebuilt binaries for:
4646
- macOS (x64, arm64)
47-
- Linux (x64, arm64)
48-
- Windows (x64, ia32)
47+
- Linux glibc (x64, arm64)
48+
- Linux musl (x64, arm64)
49+
- Windows (x64)
4950

5051
2. Upload binaries to GitHub Release
5152

52-
3. Publish to npm using trusted publishing (no NPM_TOKEN required)
53+
3. Merge all prebuilt binaries into the npm package and publish to npm
54+
55+
On PRs and pushes to main (non-tag), the CI also creates an npm tarball artifact (via `npm pack`) so the package contents can be inspected before publishing.
5356

5457
## Checking the release
5558

@@ -75,4 +78,4 @@ This ensures:
7578
Before committing changes:
7679
1. Run `yarn lint --fix` to fix code style issues
7780
2. Run `yarn test` to ensure all tests pass
78-
3. Review changes before pushing
81+
3. Review changes before pushing

lib/sqlite3-binding.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
module.exports = require('bindings')('node_sqlite3.node');
1+
module.exports = require('node-gyp-build')(require('path').join(__dirname, '..'));

memory-bank/build-system.md

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ SQLite library build configuration:
5757
### Standard Build
5858

5959
```bash
60-
# Install with prebuild or compile
60+
# Install with prebuilt binaries or compile from source
6161
yarn install
6262

6363
# Explicit rebuild
@@ -125,17 +125,11 @@ The `NAPI_VERSION` define is set via `napi_build_version` variable in binding.gy
125125
**How it works**:
126126
- The `napi_build_version` variable is automatically set by node-gyp based on the target Node.js version
127127
- For local builds, it's stored in `build/config.gypi` (e.g., `"napi_build_version": "9"`)
128-
- For prebuilds, the `prebuild` package passes it via `--napi_build_version=<version>` flag
128+
- For prebuilds, `prebuildify` passes it via the `--napi` flag which builds a single NAPI-version-agnostic binary (named `@homeofthings+sqlite3.<libc>.node`). The actual NAPI version used at compile time is determined by the Node.js version running the build (e.g., Node 24 supports NAPI v9). Since NAPI is backward compatible, a binary built with NAPI v9 runs on any Node.js supporting v9 or lower.
129129

130130
### NAPI Versions Configuration
131131

132-
The `package.json` specifies which NAPI versions to build prebuilt binaries for:
133-
134-
```json
135-
"binary": {
136-
"napi_versions": [3, 6]
137-
}
138-
```
132+
With `prebuildify --napi`, the NAPI version is auto-detected from the build Node.js version — it is not explicitly configured. The CI builds prebuilds on Node 24 (which supports NAPI v9), producing a single `@homeofthings+sqlite3.glibc.node` binary per platform. The historical `[3, 6]` configuration from the old `binary.napi_versions` package.json field is no longer used.
139133

140134
**Why multiple versions?**
141135

@@ -183,40 +177,65 @@ The `ASSERT_STATUS` macro in src/macros.h is enabled when `DEBUG` is defined:
183177
The native addon is loaded via lib/sqlite3-binding.js:
184178

185179
```javascript
186-
module.exports = require('bindings')('node_sqlite3.node');
180+
module.exports = require('node-gyp-build')(require('path').join(__dirname, '..'));
187181
```
188182

189-
The `bindings` package searches:
190-
1. `build/Debug/node_sqlite3.node`
191-
2. `build/Release/node_sqlite3.node`
183+
The project root directory (`path.join(__dirname, "..")`) is passed instead of `__dirname` because `node-gyp-build` looks for `prebuilds/` and `build/` directories relative to the path it receives. Since `sqlite3-binding.js` is in `lib/`, passing `__dirname` would cause it to look in `lib/prebuilds/` and `lib/build/` — which do not exist.
192184

193-
**Note**: Debug builds take precedence if both exist.
185+
The `node-gyp-build` package resolves the native binary in this order:
186+
1. `build/Release/node_sqlite3.node` — local release build
187+
2. `build/Debug/node_sqlite3.node` — local debug build
188+
3. `prebuilds/<platform>-<arch>/@homeofthings+sqlite3.<libc>.node` — bundled prebuilt binary
194189

195-
## Prebuilt Binaries
190+
**Note**: Local builds take precedence over prebuilt binaries. To force a source build (which creates `build/Release/` and takes precedence), use `npm install --build-from-source`.
196191

197-
### Downloading Prebuilts
192+
## Prebuilt Binaries
198193

199-
```bash
200-
yarn install # Automatically downloads prebuilt if available
201-
```
194+
Prebuilt binaries are bundled inside the npm package using `prebuildify` and loaded at runtime by `node-gyp-build`. This eliminates the need for a separate download step during `npm install`.
202195

203196
### Building Prebuilts
204197

205198
```bash
206-
yarn prebuild # Build for all NAPI versions
199+
yarn prebuild # Build prebuilt binaries using prebuildify
207200
```
208201

209-
### Uploading Prebuilts
202+
The `prebuild` script runs: `prebuildify --napi --strip --tag-libc`
203+
204+
Flags:
205+
- `--napi`: Build a NAPI-version-agnostic binary (produces `@homeofthings+sqlite3.*.node`)
206+
- `--strip`: Strip debug symbols from binaries
207+
- `--tag-libc`: Tag binaries with libc variant (glibc vs musl)
208+
209+
### Binary Naming Convention
210+
211+
With `--tag-libc`, prebuildify produces binaries tagged with the libc variant:
212+
213+
| Platform | Binary Name |
214+
|---------------|------------------------|
215+
| Linux (glibc) | `@homeofthings+sqlite3.glibc.node` |
216+
| Linux (musl) | `@homeofthings+sqlite3.musl.node` |
217+
| macOS | `@homeofthings+sqlite3.node` |
218+
| Windows | `@homeofthings+sqlite3.node` |
219+
220+
At runtime, `node-gyp-build` determines the libc variant by checking for Alpine Linux (via `/etc/alpine-release`) — if present, it selects the `musl` binary; otherwise, it selects `glibc`. It does not depend on the `detect-libc` package.
221+
222+
### Source Build Fallback
223+
224+
The `install` script runs `node-gyp-build` which tests whether the prebuilt binary works. If it does, no compilation is needed. If it doesn't (unsupported platform), `node-gyp-build` automatically falls back to `node-gyp rebuild`.
225+
226+
For custom builds (e.g., SQLCipher), use `--build-from-source` to skip the prebuilt test and force compilation:
210227

211228
```bash
212-
yarn upload # Upload to GitHub releases
229+
npm install @homeofthings/sqlite3 --build-from-source
213230
```
214231

232+
The `--build-from-source` flag is handled by the `node-gyp-build` CLI (not `prebuild-install`). It checks `npm_config_build_from_source` and skips the prebuilt test, going straight to `node-gyp rebuild`.
233+
215234
## Platform Support
216235

217236
- Node.js >= 20.17.0
218-
- NAPI versions: 3, 6
219-
- Platforms: Linux, macOS, Windows (see prebuild configuration)
237+
- NAPI: version-agnostic (`@homeofthings+sqlite3.*.node`), built with NAPI v9 on Node 24
238+
- Platforms: Linux (glibc + musl), macOS, Windows (see CI configuration)
220239

221240
## Security Hardening
222241

@@ -305,9 +324,10 @@ Applied to all macOS builds (see `binding.gyp`):
305324

306325
### Native Module Not Found
307326

308-
1. Verify build output exists: `ls build/Release/node_sqlite3.node`
309-
2. Check if bindings package is installed: `yarn install`
327+
1. Verify prebuilt binary exists: `ls prebuilds/`
328+
2. Verify build output exists: `ls build/Release/node_sqlite3.node`
310329
3. Try explicit rebuild: `yarn rebuild`
330+
4. Force source build: `npm install @homeofthings/sqlite3 --build-from-source`
311331

312332
### Debug Symbols Missing
313333

0 commit comments

Comments
 (0)