Skip to content

Commit 8cf9eb3

Browse files
authored
Merge pull request #879 from VastBlast/js-bindings-rewrite
Rewrite JS Bindings
2 parents acb266f + b5ecedf commit 8cf9eb3

35 files changed

Lines changed: 3462 additions & 1581 deletions

.github/workflows/nodejs.yml

Lines changed: 241 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,257 @@
11
name: NodeJS
2+
23
on:
3-
push:
4-
tags:
5-
- 'v*'
64
pull_request:
75
branches:
8-
- master
6+
- master
7+
push:
8+
tags:
9+
- 'v*'
10+
permissions:
11+
contents: read
12+
id-token: write
13+
14+
env:
15+
CI: true
16+
17+
defaults:
18+
run:
19+
shell: bash
20+
working-directory: bindings/js
21+
922
jobs:
1023
test:
24+
name: Test (${{ matrix.os }} / Node ${{ matrix.node }})
25+
runs-on: ${{ matrix.os }}
1126
strategy:
1227
fail-fast: false
1328
matrix:
14-
#os: [ubuntu-latest, macos-latest, windows-latest]
15-
os: [ubuntu-latest, macos-latest]
16-
node: [16, 18, 20]
17-
runs-on: ${{ matrix.os }}
29+
os: [ubuntu-latest, macos-latest, windows-latest]
30+
node: [20.x, 22.x, 24.x]
1831
steps:
19-
- uses: actions/checkout@v6
20-
- uses: actions/setup-go@v6
21-
with:
22-
go-version: '>=1.17'
23-
- uses: actions/setup-node@v6
24-
with:
25-
node-version: ${{ matrix.node }}
26-
- name: Install node-gyp
27-
run: npm install -g node-gyp
28-
- name: Build from source
29-
run: |
30-
cd bindings/js
31-
npm --version
32-
node --version
33-
npm ci --build-from-source
34-
npm test
35-
36-
build:
32+
- uses: actions/checkout@v6
33+
34+
- uses: actions/setup-go@v6
35+
with:
36+
go-version-file: go.mod
37+
cache: true
38+
cache-dependency-path: |
39+
go.sum
40+
bindings/js/go/go.sum
41+
42+
- uses: actions/setup-node@v6
43+
with:
44+
node-version: ${{ matrix.node }}
45+
cache: npm
46+
cache-dependency-path: bindings/js/package-lock.json
47+
48+
- name: Install MinGW (Windows)
49+
if: runner.os == 'Windows'
50+
shell: pwsh
51+
run: choco install mingw --no-progress -y
52+
53+
- name: Set package version
54+
run: &set_version_script |
55+
node - <<'NODE'
56+
const fs = require('fs');
57+
const path = require('path');
58+
const version = (process.env.PKG_VERSION || '0.0.0-ci').replace(/^v/, '');
59+
for (const file of ['package.json', 'package-lock.json']) {
60+
const full = path.join(process.cwd(), file);
61+
const json = JSON.parse(fs.readFileSync(full, 'utf8'));
62+
json.version = version;
63+
if (json.packages && json.packages['']) {
64+
json.packages[''].version = version;
65+
}
66+
fs.writeFileSync(full, JSON.stringify(json, null, 2) + '\n');
67+
}
68+
NODE
69+
env:
70+
PKG_VERSION: 0.0.0-${{ matrix.os }}-${{ matrix.node }}
71+
72+
- name: Install dependencies
73+
env:
74+
NODE_MINIFY_FORCE_BUILD: '1'
75+
CGO_ENABLED: 1
76+
run: npm ci
77+
78+
- name: Run tests
79+
run: npm test
80+
81+
prebuilds:
82+
name: Prebuild (${{ matrix.goos }}/${{ matrix.goarch }})
83+
needs: test
84+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
85+
runs-on: ${{ matrix.os }}
3786
strategy:
3887
fail-fast: false
3988
matrix:
40-
os: [ubuntu-latest, macos-latest]
41-
#os: [ubuntu-latest, macos-latest, windows-latest]
42-
runs-on: ${{ matrix.os }}
89+
include:
90+
- os: ubuntu-latest
91+
goos: linux
92+
goarch: amd64
93+
- os: ubuntu-latest
94+
goos: linux
95+
goarch: arm64
96+
cc: aarch64-linux-gnu-gcc
97+
- os: macos-latest
98+
goos: darwin
99+
goarch: arm64
100+
- os: windows-latest
101+
goos: windows
102+
goarch: amd64
43103
steps:
44-
- uses: actions/checkout@v6
45-
- uses: actions/setup-go@v6
46-
with:
47-
go-version: '>=1.17'
48-
- uses: actions/setup-node@v6
49-
- name: Install node-gyp and prebuildify
50-
run: npm install --location=global node-gyp node-gyp-build node-api-headers prebuildify
51-
- name: Install dependencies
52-
run: |
53-
cd bindings/js
54-
npm install node-gyp-build node-api-headers
55-
- name: Build
56-
run: make -C bindings/js
57-
- name: Test
58-
run: |
59-
cd bindings/js
60-
npm test
61-
- uses: actions/upload-artifact@v5
62-
with:
63-
name: ${{ matrix.os }}.node
64-
path: bindings/js/prebuilds/*/*.node
65-
66-
deploy:
67-
if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')
68-
needs: [build]
104+
- uses: actions/checkout@v6
105+
106+
- uses: actions/setup-go@v6
107+
with:
108+
go-version-file: go.mod
109+
cache: true
110+
cache-dependency-path: |
111+
go.sum
112+
bindings/js/go/go.sum
113+
114+
- uses: actions/setup-node@v6
115+
with:
116+
node-version: '24'
117+
cache: npm
118+
cache-dependency-path: bindings/js/package-lock.json
119+
120+
- name: Install cross compiler (linux/arm64)
121+
if: matrix.cc == 'aarch64-linux-gnu-gcc'
122+
run: |
123+
sudo apt-get update
124+
sudo apt-get install -y gcc-aarch64-linux-gnu
125+
126+
- name: Install MinGW (Windows)
127+
if: runner.os == 'Windows'
128+
shell: pwsh
129+
run: choco install mingw --no-progress -y
130+
131+
- name: Set package version
132+
run: *set_version_script
133+
env:
134+
PKG_VERSION: ${{ github.ref_name || '0.0.0-prebuild' }}
135+
136+
- name: Install dependencies (JS only)
137+
run: npm ci --ignore-scripts
138+
139+
- name: Build Go library
140+
env:
141+
GOOS: ${{ matrix.goos }}
142+
GOARCH: ${{ matrix.goarch }}
143+
CGO_ENABLED: 1
144+
CC: ${{ matrix.cc || (runner.os == 'Windows' && 'gcc') || '' }}
145+
NODE_MINIFY_FORCE_BUILD: 1
146+
run: npm run build:go
147+
148+
- name: Upload artifact
149+
uses: actions/upload-artifact@v5
150+
with:
151+
name: prebuild-${{ matrix.goos }}-${{ matrix.goarch }}
152+
path: bindings/js/build/${{ matrix.goos }}-${{ matrix.goarch }}
153+
if-no-files-found: error
154+
155+
package:
156+
name: Package and publish
157+
needs: prebuilds
158+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
69159
runs-on: ubuntu-latest
160+
permissions:
161+
contents: read
162+
id-token: write
70163
steps:
71-
- uses: actions/checkout@v6
72-
- uses: actions/setup-node@v6
73-
with:
74-
registry-url: 'https://registry.npmjs.org'
75-
- name: Install node-gyp and prebuildify
76-
run: npm install --location=global node-gyp node-gyp-build node-api-headers prebuildify
77-
- uses: actions/download-artifact@v6
78-
with:
79-
path: bindings/js/prebuilds
80-
- name: Move artifacts
81-
run: cd bindings/js/prebuilds && mv */* .
82-
- name: Publish
83-
env:
84-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
85-
run: make -C bindings/js publish
164+
- uses: actions/checkout@v6
165+
166+
- uses: actions/setup-node@v6
167+
with:
168+
node-version: '24'
169+
cache: npm
170+
cache-dependency-path: bindings/js/package-lock.json
171+
registry-url: 'https://registry.npmjs.org'
172+
173+
- name: Set package version
174+
run: *set_version_script
175+
env:
176+
PKG_VERSION: ${{ github.ref_name || '0.0.0-dev' }}
177+
178+
- name: Download prebuilts
179+
uses: actions/download-artifact@v6
180+
with:
181+
pattern: prebuild-*
182+
path: bindings/js/build/_artifacts
183+
184+
- name: Organize prebuilts into platform folders
185+
run: |
186+
set -euo pipefail
187+
shopt -s globstar nullglob
188+
189+
artifact_root="build/_artifacts"
190+
found_any=0
191+
192+
for artifact in "$artifact_root"/prebuild-*; do
193+
[ -d "$artifact" ] || continue
194+
found_any=1
195+
196+
platform="${artifact##*/}"
197+
platform="${platform#prebuild-}"
198+
dest="build/${platform}"
199+
mkdir -p "$dest"
200+
201+
moved=0
202+
203+
for candidate in \
204+
"$artifact/bindings/js/build/${platform}" \
205+
"$artifact/build/${platform}" \
206+
"$artifact/${platform}"
207+
do
208+
if [ -d "$candidate" ]; then
209+
mv "$candidate"/* "$dest"/
210+
moved=1
211+
break
212+
fi
213+
done
214+
215+
if [ "$moved" -eq 0 ]; then
216+
for f in "$artifact"/**/minify.*; do
217+
mv "$f" "$dest"/
218+
moved=1
219+
done
220+
fi
221+
222+
if [ "$moved" -eq 0 ]; then
223+
echo "No prebuilts found for $platform" >&2
224+
exit 1
225+
fi
226+
done
227+
228+
if [ "$found_any" -eq 0 ]; then
229+
echo "No prebuild artifacts were downloaded" >&2
230+
exit 1
231+
fi
232+
233+
rm -rf "$artifact_root"
234+
235+
- name: Install dependencies (JS only)
236+
env:
237+
NODE_MINIFY_SKIP_BUILD: 1
238+
run: npm ci --ignore-scripts
239+
240+
- name: Build TypeScript artifacts
241+
run: npm run build:ts
242+
243+
- name: Verify prebuilts
244+
run: |
245+
ls -R build
246+
find build -maxdepth 2 -type f -name "minify.*"
247+
if find build -maxdepth 1 -type f -name "minify.*" | grep -q .; then
248+
echo "Prebuilts must live under platform-specific folders" >&2
249+
exit 1
250+
fi
251+
252+
- name: Publish to npm
253+
if: github.event_name == 'push'
254+
env:
255+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
256+
NPM_CONFIG_PROVENANCE: 'true'
257+
run: npm publish --access public --provenance

.gitignore

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ parse/tests/*/suppressions
1414
parse/tests/*/corpus/*
1515
!parse/tests/*/corpus/*.*
1616
bindings/js/build
17-
bindings/js/prebuilds
18-
bindings/js/minify.h
19-
bindings/js/minify.a
17+
bindings/js/.cache
2018
bindings/js/node_modules
2119
bindings/js/example/package-lock.json
2220
bindings/js/example/node_modules

bindings/js/.npmignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules/
2+
test/
3+
example/
4+
.cache/

bindings/js/Makefile

Lines changed: 0 additions & 44 deletions
This file was deleted.

0 commit comments

Comments
 (0)