Skip to content

Commit d420f31

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

File tree

7 files changed

+106
-15
lines changed

7 files changed

+106
-15
lines changed

.github/workflows/npm-publish.yml

Lines changed: 52 additions & 12 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
@@ -74,11 +81,21 @@ jobs:
7481
working-directory: ${{ env.WORKING_DIR }}
7582
shell: bash
7683
run: |
77-
npm version ${{ inputs.version }} --no-git-tag-version --allow-same-version
84+
npm version "$VERSION" --no-git-tag-version --allow-same-version
85+
env:
86+
VERSION: ${{ inputs.version }}
87+
88+
- name: Install musl tools
89+
if: contains(matrix.target, 'musl')
90+
run: sudo apt-get update && sudo apt-get install -y musl-tools
91+
92+
- name: Add musl Rust target
93+
if: contains(matrix.target, 'musl')
94+
run: rustup target add x86_64-unknown-linux-musl
7895

7996
- name: Build native module
8097
working-directory: ${{ env.WORKING_DIR }}
81-
run: npm run build
98+
run: npm run build -- --target ${{ matrix.target }}
8299

83100
- name: Upload artifact
84101
uses: actions/upload-artifact@v8
@@ -105,12 +122,18 @@ jobs:
105122
working-directory: ${{ env.WORKING_DIR }}
106123
run: npm ci --ignore-scripts --omit=optional
107124

108-
- name: Download Linux artifact
125+
- name: Download Linux GNU artifact
109126
uses: actions/download-artifact@v8
110127
with:
111128
name: bindings-linux-x64-gnu
112129
path: ${{ env.WORKING_DIR }}/artifacts/linux-x64-gnu
113130

131+
- name: Download Linux musl artifact
132+
uses: actions/download-artifact@v8
133+
with:
134+
name: bindings-linux-x64-musl
135+
path: ${{ env.WORKING_DIR }}/artifacts/linux-x64-musl
136+
114137
- name: Download Windows artifact
115138
uses: actions/download-artifact@v8
116139
with:
@@ -125,19 +148,24 @@ jobs:
125148
run: |
126149
# Rename artifacts to match napi-rs naming convention
127150
mv artifacts/linux-x64-gnu/*.node npm/linux-x64-gnu/js-host-api.linux-x64-gnu.node
151+
mv artifacts/linux-x64-musl/*.node npm/linux-x64-musl/js-host-api.linux-x64-musl.node
128152
mv artifacts/win32-x64-msvc/*.node npm/win32-x64-msvc/js-host-api.win32-x64-msvc.node
129153
ls -la npm/linux-x64-gnu/
154+
ls -la npm/linux-x64-musl/
130155
ls -la npm/win32-x64-msvc/
131156
132157
- name: Set package versions
133158
working-directory: ${{ env.WORKING_DIR }}
134159
run: |
135160
# Update main package version
136-
npm version ${{ inputs.version }} --no-git-tag-version --allow-same-version
161+
npm version "$VERSION" --no-git-tag-version --allow-same-version
137162
138163
# 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
164+
cd npm/linux-x64-gnu && npm version "$VERSION" --no-git-tag-version --allow-same-version
165+
cd ../linux-x64-musl && npm version "$VERSION" --no-git-tag-version --allow-same-version
166+
cd ../win32-x64-msvc && npm version "$VERSION" --no-git-tag-version --allow-same-version
167+
env:
168+
VERSION: ${{ inputs.version }}
141169

142170
- name: Update optionalDependencies versions
143171
working-directory: ${{ env.WORKING_DIR }}
@@ -148,12 +176,14 @@ jobs:
148176
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
149177
for (const dep of Object.keys(pkg.optionalDependencies || {})) {
150178
if (dep.startsWith('@hyperlight/js-host-api-')) {
151-
pkg.optionalDependencies[dep] = '${{ inputs.version }}';
179+
pkg.optionalDependencies[dep] = process.env.VERSION;
152180
}
153181
}
154182
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
155183
"
156184
cat package.json
185+
env:
186+
VERSION: ${{ inputs.version }}
157187

158188
- name: Generate JS bindings (index.js and index.d.ts)
159189
working-directory: ${{ env.WORKING_DIR }}
@@ -162,36 +192,46 @@ jobs:
162192
npx napi prepublish -t npm --skip-gh-release
163193
ls -la index.js index.d.ts
164194
165-
- name: Publish Linux package
166-
if: ${{ !inputs.dry-run }}
195+
- name: Publish Linux GNU package
196+
if: ${{ !inputs['dry-run'] }}
167197
working-directory: ${{ env.WORKING_DIR }}/npm/linux-x64-gnu
168198
run: npm publish --access public
169199
env:
170200
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
171201

202+
- name: Publish Linux musl package
203+
if: ${{ !inputs['dry-run'] }}
204+
working-directory: ${{ env.WORKING_DIR }}/npm/linux-x64-musl
205+
run: npm publish --access public
206+
env:
207+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
208+
172209
- name: Publish Windows package
173-
if: ${{ !inputs.dry-run }}
210+
if: ${{ !inputs['dry-run'] }}
174211
working-directory: ${{ env.WORKING_DIR }}/npm/win32-x64-msvc
175212
run: npm publish --access public
176213
env:
177214
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
178215

179216
- name: Publish main package
180-
if: ${{ !inputs.dry-run }}
217+
if: ${{ !inputs['dry-run'] }}
181218
working-directory: ${{ env.WORKING_DIR }}
182219
run: npm publish --access public
183220
env:
184221
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
185222

186223
- name: Dry run - show what would be published
187-
if: ${{ inputs.dry-run }}
224+
if: ${{ inputs['dry-run'] }}
188225
working-directory: ${{ env.WORKING_DIR }}
189226
run: |
190227
echo "=== DRY RUN - Would publish the following packages ==="
191228
echo ""
192229
echo "--- @hyperlight/js-host-api-linux-x64-gnu ---"
193230
npm pack ./npm/linux-x64-gnu --dry-run
194231
echo ""
232+
echo "--- @hyperlight/js-host-api-linux-x64-musl ---"
233+
npm pack ./npm/linux-x64-musl --dry-run
234+
echo ""
195235
echo "--- @hyperlight/js-host-api-win32-x64-msvc ---"
196236
npm pack ./npm/win32-x64-msvc --dry-run
197237
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)