Skip to content

Commit 1863153

Browse files
committed
Review Feedabck
Signed-off-by: Simon Davies <simongdavies@users.noreply.github.com>
1 parent 8797ef1 commit 1863153

File tree

7 files changed

+114
-17
lines changed

7 files changed

+114
-17
lines changed

.github/workflows/npm-publish.yml

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ permissions:
3333
contents: read
3434
id-token: write
3535

36+
concurrency:
37+
group: npm-publish-${{ inputs.version }}
38+
cancel-in-progress: false
39+
3640
env:
3741
WORKING_DIR: src/js-host-api
3842

@@ -45,6 +49,9 @@ jobs:
4549
- target: x86_64-unknown-linux-gnu
4650
os: [self-hosted, Linux, X64, "1ES.Pool=hld-kvm-amd"]
4751
build_name: linux-x64-gnu
52+
- target: x86_64-unknown-linux-musl
53+
os: [self-hosted, Linux, X64, "1ES.Pool=hld-kvm-amd"]
54+
build_name: linux-x64-musl
4855
- target: x86_64-pc-windows-msvc
4956
os: [self-hosted, Windows, X64, "1ES.Pool=hld-win2022-amd"]
5057
build_name: win32-x64-msvc
@@ -54,6 +61,11 @@ jobs:
5461
with:
5562
fetch-depth: 0
5663

64+
- name: Validate version format
65+
run: node -e "if (!/^\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?$/.test(process.env.VERSION)) { console.error('Invalid version:', process.env.VERSION); process.exit(1); }"
66+
env:
67+
VERSION: ${{ inputs.version }}
68+
5769
- name: Hyperlight setup
5870
uses: hyperlight-dev/ci-setup-workflow@v1.8.0
5971
with:
@@ -72,13 +84,19 @@ jobs:
7284

7385
- name: Set package version
7486
working-directory: ${{ env.WORKING_DIR }}
75-
shell: bash
76-
run: |
77-
npm version ${{ inputs.version }} --no-git-tag-version --allow-same-version
87+
run: npm version ${{ inputs.version }} --no-git-tag-version --allow-same-version
88+
89+
- name: Install musl tools
90+
if: contains(matrix.target, 'musl')
91+
run: sudo apt-get update && sudo apt-get install -y musl-tools
92+
93+
- name: Add musl Rust target
94+
if: contains(matrix.target, 'musl')
95+
run: rustup target add x86_64-unknown-linux-musl
7896

7997
- name: Build native module
8098
working-directory: ${{ env.WORKING_DIR }}
81-
run: npm run build
99+
run: npm run build -- --target ${{ matrix.target }}
82100

83101
- name: Upload artifact
84102
uses: actions/upload-artifact@v8
@@ -93,6 +111,11 @@ jobs:
93111
steps:
94112
- uses: actions/checkout@v6
95113

114+
- name: Validate version format
115+
run: node -e "if (!/^\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?$/.test(process.env.VERSION)) { console.error('Invalid version:', process.env.VERSION); process.exit(1); }"
116+
env:
117+
VERSION: ${{ inputs.version }}
118+
96119
- name: Setup Node.js
97120
uses: actions/setup-node@v6
98121
with:
@@ -105,12 +128,18 @@ jobs:
105128
working-directory: ${{ env.WORKING_DIR }}
106129
run: npm ci --ignore-scripts --omit=optional
107130

108-
- name: Download Linux artifact
131+
- name: Download Linux GNU artifact
109132
uses: actions/download-artifact@v8
110133
with:
111134
name: bindings-linux-x64-gnu
112135
path: ${{ env.WORKING_DIR }}/artifacts/linux-x64-gnu
113136

137+
- name: Download Linux musl artifact
138+
uses: actions/download-artifact@v8
139+
with:
140+
name: bindings-linux-x64-musl
141+
path: ${{ env.WORKING_DIR }}/artifacts/linux-x64-musl
142+
114143
- name: Download Windows artifact
115144
uses: actions/download-artifact@v8
116145
with:
@@ -125,19 +154,24 @@ jobs:
125154
run: |
126155
# Rename artifacts to match napi-rs naming convention
127156
mv artifacts/linux-x64-gnu/*.node npm/linux-x64-gnu/js-host-api.linux-x64-gnu.node
157+
mv artifacts/linux-x64-musl/*.node npm/linux-x64-musl/js-host-api.linux-x64-musl.node
128158
mv artifacts/win32-x64-msvc/*.node npm/win32-x64-msvc/js-host-api.win32-x64-msvc.node
129159
ls -la npm/linux-x64-gnu/
160+
ls -la npm/linux-x64-musl/
130161
ls -la npm/win32-x64-msvc/
131162
132163
- name: Set package versions
133164
working-directory: ${{ env.WORKING_DIR }}
134165
run: |
135166
# Update main package version
136-
npm version ${{ inputs.version }} --no-git-tag-version --allow-same-version
167+
npm version "$VERSION" --no-git-tag-version --allow-same-version
137168
138169
# Update platform package versions
139-
cd npm/linux-x64-gnu && npm version ${{ inputs.version }} --no-git-tag-version --allow-same-version
140-
cd ../win32-x64-msvc && npm version ${{ inputs.version }} --no-git-tag-version --allow-same-version
170+
cd npm/linux-x64-gnu && npm version "$VERSION" --no-git-tag-version --allow-same-version
171+
cd ../linux-x64-musl && npm version "$VERSION" --no-git-tag-version --allow-same-version
172+
cd ../win32-x64-msvc && npm version "$VERSION" --no-git-tag-version --allow-same-version
173+
env:
174+
VERSION: ${{ inputs.version }}
141175

142176
- name: Update optionalDependencies versions
143177
working-directory: ${{ env.WORKING_DIR }}
@@ -148,12 +182,14 @@ jobs:
148182
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
149183
for (const dep of Object.keys(pkg.optionalDependencies || {})) {
150184
if (dep.startsWith('@hyperlight/js-host-api-')) {
151-
pkg.optionalDependencies[dep] = '${{ inputs.version }}';
185+
pkg.optionalDependencies[dep] = process.env.VERSION;
152186
}
153187
}
154188
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
155189
"
156190
cat package.json
191+
env:
192+
VERSION: ${{ inputs.version }}
157193

158194
- name: Generate JS bindings (index.js and index.d.ts)
159195
working-directory: ${{ env.WORKING_DIR }}
@@ -162,36 +198,46 @@ jobs:
162198
npx napi prepublish -t npm --skip-gh-release
163199
ls -la index.js index.d.ts
164200
165-
- name: Publish Linux package
166-
if: ${{ !inputs.dry-run }}
201+
- name: Publish Linux GNU package
202+
if: ${{ !inputs['dry-run'] }}
167203
working-directory: ${{ env.WORKING_DIR }}/npm/linux-x64-gnu
168204
run: npm publish --access public
169205
env:
170206
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
171207

208+
- name: Publish Linux musl package
209+
if: ${{ !inputs['dry-run'] }}
210+
working-directory: ${{ env.WORKING_DIR }}/npm/linux-x64-musl
211+
run: npm publish --access public
212+
env:
213+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
214+
172215
- name: Publish Windows package
173-
if: ${{ !inputs.dry-run }}
216+
if: ${{ !inputs['dry-run'] }}
174217
working-directory: ${{ env.WORKING_DIR }}/npm/win32-x64-msvc
175218
run: npm publish --access public
176219
env:
177220
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
178221

179222
- name: Publish main package
180-
if: ${{ !inputs.dry-run }}
223+
if: ${{ !inputs['dry-run'] }}
181224
working-directory: ${{ env.WORKING_DIR }}
182225
run: npm publish --access public
183226
env:
184227
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
185228

186229
- name: Dry run - show what would be published
187-
if: ${{ inputs.dry-run }}
230+
if: ${{ inputs['dry-run'] }}
188231
working-directory: ${{ env.WORKING_DIR }}
189232
run: |
190233
echo "=== DRY RUN - Would publish the following packages ==="
191234
echo ""
192235
echo "--- @hyperlight/js-host-api-linux-x64-gnu ---"
193236
npm pack ./npm/linux-x64-gnu --dry-run
194237
echo ""
238+
echo "--- @hyperlight/js-host-api-linux-x64-musl ---"
239+
npm pack ./npm/linux-x64-musl --dry-run
240+
echo ""
195241
echo "--- @hyperlight/js-host-api-win32-x64-msvc ---"
196242
npm pack ./npm/win32-x64-msvc --dry-run
197243
echo ""

src/js-host-api/.npmignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,6 @@ test-examples.sh
3030

3131
# Exclude artifacts directory (only used during CI)
3232
artifacts/
33+
34+
# Exclude platform sub-packages (published separately as optionalDependencies)
35+
npm/

src/js-host-api/README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -634,10 +634,19 @@ To create an npm token:
634634

635635
### Package Structure
636636

637-
The npm release consists of three packages:
637+
The npm release consists of the following packages:
638638

639639
| Package | Description |
640640
|---------|-------------|
641641
| `@hyperlight/js-host-api` | Main package (installs correct binary automatically) |
642-
| `@hyperlight/js-host-api-linux-x64-gnu` | Linux x86_64 native binary |
642+
| `@hyperlight/js-host-api-linux-x64-gnu` | Linux x86_64 (glibc) native binary |
643+
| `@hyperlight/js-host-api-linux-x64-musl` | Linux x86_64 (musl/Alpine) native binary |
643644
| `@hyperlight/js-host-api-win32-x64-msvc` | Windows x86_64 native binary |
645+
646+
### How Platform Selection Works
647+
648+
This project uses the [napi-rs](https://napi.rs/docs/deep-dive/release#3-the-native-addon-for-different-platforms-is-distributed-through-different-npm-packages) approach for distributing native addons across platforms. Each platform-specific binary is published as a separate npm package and listed as an `optionalDependency` of the main package.
649+
650+
**At install time:** npm uses the `os`, `cpu`, and `libc` fields in each platform sub-package's `package.json` to determine which optional dependency to install. Packages that don't match the user's platform are silently skipped. The main package itself does **not** have `os`/`cpu` fields because it contains only JavaScript — restricting it would prevent installation on unsupported platforms even for type-checking or development purposes.
651+
652+
**At runtime:** The napi-rs generated `index.js` detects the platform (including glibc vs musl on Linux) and loads the correct `.node` binary.

src/js-host-api/npm/linux-x64-gnu/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,8 @@
2323
},
2424
"engines": {
2525
"node": ">= 18"
26-
}
26+
},
27+
"libc": [
28+
"glibc"
29+
]
2730
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "@hyperlight/js-host-api-linux-x64-musl",
3+
"version": "0.17.0",
4+
"os": [
5+
"linux"
6+
],
7+
"cpu": [
8+
"x64"
9+
],
10+
"main": "js-host-api.linux-x64-musl.node",
11+
"files": [
12+
"js-host-api.linux-x64-musl.node"
13+
],
14+
"description": "Node.js API bindings for Hyperlight JS - Linux x64 musl",
15+
"license": "Apache-2.0",
16+
"repository": {
17+
"type": "git",
18+
"url": "git+https://github.com/hyperlight-dev/hyperlight-js.git"
19+
},
20+
"homepage": "https://github.com/hyperlight-dev/hyperlight-js#readme",
21+
"bugs": {
22+
"url": "https://github.com/hyperlight-dev/hyperlight-js/issues"
23+
},
24+
"engines": {
25+
"node": ">= 18"
26+
},
27+
"libc": [
28+
"musl"
29+
]
30+
}

src/js-host-api/package-lock.json

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/js-host-api/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@
1616
"binaryName": "js-host-api",
1717
"targets": [
1818
"x86_64-unknown-linux-gnu",
19+
"x86_64-unknown-linux-musl",
1920
"x86_64-pc-windows-msvc"
2021
]
2122
},
2223
"license": "Apache-2.0",
2324
"optionalDependencies": {
2425
"@hyperlight/js-host-api-linux-x64-gnu": "0.17.0",
26+
"@hyperlight/js-host-api-linux-x64-musl": "0.17.0",
2527
"@hyperlight/js-host-api-win32-x64-msvc": "0.17.0"
2628
},
2729
"devDependencies": {

0 commit comments

Comments
 (0)