From 35b85b522b149be8edbb3b5f854c602b7722574f Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Wed, 16 Sep 2026 21:35:20 +0100 Subject: [PATCH 1/4] Add linux-arm64 npm packaging Adds the `@hyperlight-dev/js-host-api-linux-arm64-gnu` platform package so Linux aarch64 consumers get a prebuilt native binary, completing the npm side of aarch64 support. Mirrors the existing `linux-x64-gnu` package conventions: `os: [linux]`, `cpu: [arm64]`, `libc: [glibc]`. There is no musl aarch64 variant. The publish matrix builds `aarch64-unknown-linux-gnu` on `[self-hosted, Linux, arm64, kvm]`, matching the Linux aarch64 runner labels already used by dep_build.yml. That target is native on those runners, so unlike the musl entry it needs no extra `rustup target add`. The new package is added to FIRST_TIME_PACKAGES because it has no npm trusted publisher until it is published once. As with darwin-arm64, its root lockfile edge has no `resolved` URL or `integrity` hash until the first release; `npm ci` skips unresolvable optional deps, and this was verified to exit 0 plainly, with --omit=optional, and with --os=linux --cpu=arm64. docs/release.md said `three platform packages` while there were already four; corrected to five along with the package count updates. Note: this has never run on real Linux aarch64 hardware. CI is the first execution. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: Simon Davies --- .github/workflows/npm-publish.yml | 27 +++++++++++++++-- Justfile | 3 +- docs/release.md | 10 ++++--- src/js-host-api/DEVELOPMENT.md | 1 + .../npm/linux-arm64-gnu/package.json | 30 +++++++++++++++++++ src/js-host-api/package-lock.json | 1 + src/js-host-api/package.json | 4 ++- 7 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 src/js-host-api/npm/linux-arm64-gnu/package.json diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 51b1a99..0721746 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -47,7 +47,7 @@ env: # Comma-delimited npm package names that have not yet been published and # therefore cannot have a trusted publisher configured. Remove each package # in a follow-up PR after its first release and trusted-publisher setup. - FIRST_TIME_PACKAGES: ",@hyperlight-dev/js-host-api-darwin-arm64," + FIRST_TIME_PACKAGES: ",@hyperlight-dev/js-host-api-darwin-arm64,@hyperlight-dev/js-host-api-linux-arm64-gnu," jobs: build: @@ -67,6 +67,9 @@ jobs: - target: aarch64-apple-darwin os: macos-15 build_name: darwin-arm64 + - target: aarch64-unknown-linux-gnu + os: [self-hosted, Linux, arm64, kvm] + build_name: linux-arm64-gnu runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v7 @@ -223,6 +226,12 @@ jobs: name: bindings-darwin-arm64 path: ${{ env.WORKING_DIR }}/artifacts/darwin-arm64 + - name: Download Linux arm64 GNU artifact + uses: actions/download-artifact@v8 + with: + name: bindings-linux-arm64-gnu + path: ${{ env.WORKING_DIR }}/artifacts/linux-arm64-gnu + - name: Download JS bindings uses: actions/download-artifact@v8 with: @@ -240,10 +249,12 @@ jobs: mv artifacts/linux-x64-musl/*.node npm/linux-x64-musl/js-host-api.linux-x64-musl.node mv artifacts/win32-x64-msvc/*.node npm/win32-x64-msvc/js-host-api.win32-x64-msvc.node mv artifacts/darwin-arm64/*.node npm/darwin-arm64/js-host-api.darwin-arm64.node + mv artifacts/linux-arm64-gnu/*.node npm/linux-arm64-gnu/js-host-api.linux-arm64-gnu.node ls -la npm/linux-x64-gnu/ ls -la npm/linux-x64-musl/ ls -la npm/win32-x64-msvc/ ls -la npm/darwin-arm64/ + ls -la npm/linux-arm64-gnu/ - name: Set package versions working-directory: ${{ env.WORKING_DIR }} @@ -256,6 +267,7 @@ jobs: cd ../linux-x64-musl && npm version "$VERSION" --no-git-tag-version --allow-same-version cd ../win32-x64-msvc && npm version "$VERSION" --no-git-tag-version --allow-same-version cd ../darwin-arm64 && npm version "$VERSION" --no-git-tag-version --allow-same-version + cd ../linux-arm64-gnu && npm version "$VERSION" --no-git-tag-version --allow-same-version env: VERSION: ${{ inputs.version }} @@ -336,6 +348,13 @@ jobs: env: NODE_AUTH_TOKEN: ${{ (github.event_name == 'workflow_dispatch' || contains(env.FIRST_TIME_PACKAGES, ',@hyperlight-dev/js-host-api-darwin-arm64,')) && secrets.NPM_TOKEN || '' }} + - name: Publish Linux arm64 GNU package + if: ${{ !inputs.dry_run }} + working-directory: ${{ env.WORKING_DIR }}/npm/linux-arm64-gnu + run: npm publish --access public --ignore-scripts ${{ (github.event_name == 'workflow_dispatch' || contains(env.FIRST_TIME_PACKAGES, ',@hyperlight-dev/js-host-api-linux-arm64-gnu,')) && '' || '--provenance' }} + env: + NODE_AUTH_TOKEN: ${{ (github.event_name == 'workflow_dispatch' || contains(env.FIRST_TIME_PACKAGES, ',@hyperlight-dev/js-host-api-linux-arm64-gnu,')) && secrets.NPM_TOKEN || '' }} + - name: Publish main package if: ${{ !inputs.dry_run }} working-directory: ${{ env.WORKING_DIR }} @@ -353,7 +372,8 @@ jobs: "@hyperlight-dev/js-host-api-linux-x64-gnu" \ "@hyperlight-dev/js-host-api-linux-x64-musl" \ "@hyperlight-dev/js-host-api-win32-x64-msvc" \ - "@hyperlight-dev/js-host-api-darwin-arm64"; do + "@hyperlight-dev/js-host-api-darwin-arm64" \ + "@hyperlight-dev/js-host-api-linux-arm64-gnu"; do if npm view "$pkg@$VERSION" version > /dev/null 2>&1; then echo "✅ $pkg@$VERSION published" else @@ -386,5 +406,8 @@ jobs: echo "--- @hyperlight-dev/js-host-api-darwin-arm64 ---" npm pack ./npm/darwin-arm64 --dry-run echo "" + echo "--- @hyperlight-dev/js-host-api-linux-arm64-gnu ---" + npm pack ./npm/linux-arm64-gnu --dry-run + echo "" echo "--- @hyperlight-dev/js-host-api ---" npm pack --dry-run \ No newline at end of file diff --git a/Justfile b/Justfile index 29a3672..f24f275 100644 --- a/Justfile +++ b/Justfile @@ -226,12 +226,13 @@ set-version version: cargo update \ --manifest-path src/hyperlight-js-runtime/tests/fixtures/extended_runtime/Cargo.toml \ -p hyperlight-js-runtime -p hyperlight-js-common - # npm: main + the 4 platform package.json versions (--ignore-scripts avoids needing node_modules) + # npm: main + the 5 platform package.json versions (--ignore-scripts avoids needing node_modules) cd src/js-host-api && npm version {{ version }} --no-git-tag-version --allow-same-version --ignore-scripts cd src/js-host-api/npm/linux-x64-gnu && npm version {{ version }} --no-git-tag-version --allow-same-version --ignore-scripts cd src/js-host-api/npm/linux-x64-musl && npm version {{ version }} --no-git-tag-version --allow-same-version --ignore-scripts cd src/js-host-api/npm/win32-x64-msvc && npm version {{ version }} --no-git-tag-version --allow-same-version --ignore-scripts cd src/js-host-api/npm/darwin-arm64 && npm version {{ version }} --no-git-tag-version --allow-same-version --ignore-scripts + cd src/js-host-api/npm/linux-arm64-gnu && npm version {{ version }} --no-git-tag-version --allow-same-version --ignore-scripts # Verify the npm lockfile cd src/js-host-api && npm ci --dry-run --omit=optional --ignore-scripts diff --git a/docs/release.md b/docs/release.md index e09d3fa..8285f81 100644 --- a/docs/release.md +++ b/docs/release.md @@ -10,7 +10,7 @@ Do this with the `just set-version` recipe. **Always use this instead of bumping - every workspace crate's `version` and the root `Cargo.lock`, - the excluded `extended_runtime` fixture's own `Cargo.lock` (a bare `cargo set-version` can't reach it, and a stale one fails the `native_modules --locked` build), -- the npm main package and the three platform packages, +- the npm main package and the five platform packages, - the root package version in `src/js-host-api/package-lock.json`. Keep `optionalDependencies` on the latest published version so `npm ci` can use @@ -68,12 +68,13 @@ Trusted publishing is configured on [npmjs.com](https://www.npmjs.com/) for each 3. Set **Organization**: `hyperlight-dev`, **Repository**: `hyperlight-js`, **Workflow**: `CreateRelease.yml` 4. Save -This must be done for all 5 packages: +This must be done for all 6 packages: - `@hyperlight-dev/js-host-api` - `@hyperlight-dev/js-host-api-linux-x64-gnu` - `@hyperlight-dev/js-host-api-linux-x64-musl` - `@hyperlight-dev/js-host-api-win32-x64-msvc` - `@hyperlight-dev/js-host-api-darwin-arm64` +- `@hyperlight-dev/js-host-api-linux-arm64-gnu` > **Note:** Trusted publishers are configured per package, and npm cannot configure one for a > package that does not exist yet. The publish workflow therefore has a temporary @@ -114,12 +115,13 @@ If you need to publish npm packages manually via `workflow_dispatch`, you'll nee 1. **Temporarily allow token-based publishing on npmjs.com** - Go to each package on [npmjs.com](https://www.npmjs.com/) → Settings → Publishing access - Change from "Require two-factor authentication and disallow tokens" to "Require two-factor authentication or automation tokens" - - Do this for all 5 packages: + - Do this for all 6 packages: - `@hyperlight-dev/js-host-api` - `@hyperlight-dev/js-host-api-linux-x64-gnu` - `@hyperlight-dev/js-host-api-linux-x64-musl` - `@hyperlight-dev/js-host-api-win32-x64-msvc` - `@hyperlight-dev/js-host-api-darwin-arm64` + - `@hyperlight-dev/js-host-api-linux-arm64-gnu` 2. **Create an npm automation token** - Go to [npmjs.com](https://www.npmjs.com/) → Access Tokens → Generate New Token → Granular Access Token @@ -141,5 +143,5 @@ If you need to publish npm packages manually via `workflow_dispatch`, you'll nee 5. **Clean up immediately after publishing** - Delete the `NPM_TOKEN` repo secret on GitHub → Settings → Secrets and variables → Actions - Revoke the npm token on npmjs.com → Access Tokens - - Re-enable "Require two-factor authentication and disallow tokens" on all 5 packages + - Re-enable "Require two-factor authentication and disallow tokens" on all 6 packages - Verify the packages published correctly: `npm view @hyperlight-dev/js-host-api versions` diff --git a/src/js-host-api/DEVELOPMENT.md b/src/js-host-api/DEVELOPMENT.md index 8ad5b9a..c7277cf 100644 --- a/src/js-host-api/DEVELOPMENT.md +++ b/src/js-host-api/DEVELOPMENT.md @@ -67,6 +67,7 @@ The npm release consists of the following packages: | `@hyperlight-dev/js-host-api-linux-x64-musl` | Linux x86_64 (musl/Alpine) native binary | | `@hyperlight-dev/js-host-api-win32-x64-msvc` | Windows x86_64 native binary | | `@hyperlight-dev/js-host-api-darwin-arm64` | macOS aarch64 (Apple Silicon) native binary | +| `@hyperlight-dev/js-host-api-linux-arm64-gnu` | Linux aarch64 (glibc) native binary | ### How Platform Selection Works diff --git a/src/js-host-api/npm/linux-arm64-gnu/package.json b/src/js-host-api/npm/linux-arm64-gnu/package.json new file mode 100644 index 0000000..bd01526 --- /dev/null +++ b/src/js-host-api/npm/linux-arm64-gnu/package.json @@ -0,0 +1,30 @@ +{ + "name": "@hyperlight-dev/js-host-api-linux-arm64-gnu", + "version": "0.4.0", + "os": [ + "linux" + ], + "cpu": [ + "arm64" + ], + "main": "js-host-api.linux-arm64-gnu.node", + "files": [ + "js-host-api.linux-arm64-gnu.node" + ], + "description": "Node.js API bindings for Hyperlight JS - Linux arm64 gnu", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "git+https://github.com/hyperlight-dev/hyperlight-js.git" + }, + "homepage": "https://github.com/hyperlight-dev/hyperlight-js#readme", + "bugs": { + "url": "https://github.com/hyperlight-dev/hyperlight-js/issues" + }, + "engines": { + "node": ">= 18" + }, + "libc": [ + "glibc" + ] +} diff --git a/src/js-host-api/package-lock.json b/src/js-host-api/package-lock.json index 2b60cb2..656d62a 100644 --- a/src/js-host-api/package-lock.json +++ b/src/js-host-api/package-lock.json @@ -20,6 +20,7 @@ }, "optionalDependencies": { "@hyperlight-dev/js-host-api-darwin-arm64": "0.4.0", + "@hyperlight-dev/js-host-api-linux-arm64-gnu": "0.4.0", "@hyperlight-dev/js-host-api-linux-x64-gnu": "0.4.0", "@hyperlight-dev/js-host-api-linux-x64-musl": "0.4.0", "@hyperlight-dev/js-host-api-win32-x64-msvc": "0.4.0" diff --git a/src/js-host-api/package.json b/src/js-host-api/package.json index c24ae37..cf6134c 100644 --- a/src/js-host-api/package.json +++ b/src/js-host-api/package.json @@ -31,12 +31,14 @@ "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl", "x86_64-pc-windows-msvc", - "aarch64-apple-darwin" + "aarch64-apple-darwin", + "aarch64-unknown-linux-gnu" ] }, "license": "Apache-2.0", "optionalDependencies": { "@hyperlight-dev/js-host-api-darwin-arm64": "0.4.0", + "@hyperlight-dev/js-host-api-linux-arm64-gnu": "0.4.0", "@hyperlight-dev/js-host-api-linux-x64-gnu": "0.4.0", "@hyperlight-dev/js-host-api-linux-x64-musl": "0.4.0", "@hyperlight-dev/js-host-api-win32-x64-msvc": "0.4.0" From 46800e67c7dd059b3614bb91e8299f78e882ff75 Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Wed, 16 Sep 2026 21:50:19 +0100 Subject: [PATCH 2/4] Run PR validation on stacked pull requests `ValidatePullRequests.yml` and `PRLabelChecker.yml` both filtered on `branches`, and that filter is evaluated against the pull request's own base ref. Stacked pull requests target the layer below them rather than `main`, so neither workflow fired for them: a stacked layer got only CodeQL and DCO, with no build, benchmarks, license-header, spelling or label check. That is worse than it sounds, because it defers all breakage to merge time. A layer is only built once the layer below merges and GitHub retargets it to `main`, so a stack is validated one layer at a time, in sequence, after each merge, instead of in parallel while it is being reviewed. Drop the `branches` filter from both rather than adding a pattern for stack branch names, which would only encode one contributor's naming convention. No long-lived non-`main` branches are used as pull request bases: every branch is either `release/**`, which the filter already matched, or an ordinary feature or dependabot branch, which are pull request heads rather than bases. `PRLabelChecker.yml` is widened as well because `check-labels` is a required status check on `main`. Base retargeting raises an `edited` event, which is not in that workflow's `types`, so a layer labelled while it still targeted the layer below would never run the check, and nothing would re-fire it afterwards, leaving a required check pending and blocking the merge. Check runs attach to the head SHA, so running once while the layer is stacked keeps the result valid through retargeting. Concurrency is unaffected: the group is keyed on `github.ref`, which is `refs/pull//merge` for pull request events and therefore already unique per pull request. This does mean more concurrent matrix builds when several layers are open at once, which is the intended trade for not serialising failures to merge time. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: Simon Davies --- .github/workflows/PRLabelChecker.yml | 7 ++++++- .github/workflows/ValidatePullRequests.yml | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/PRLabelChecker.yml b/.github/workflows/PRLabelChecker.yml index bc84ed2..2e72497 100644 --- a/.github/workflows/PRLabelChecker.yml +++ b/.github/workflows/PRLabelChecker.yml @@ -1,7 +1,12 @@ name: Label Checker +# No `branches:` filter, for the same reason as ValidatePullRequests.yml. +# `check-labels` is a required check on `main`, and base retargeting raises an +# `edited` event, which is absent from the types below. A layer labelled while +# it still targets the layer below would therefore never run this check, and +# after retargeting nothing re-fires it, leaving a required check permanently +# pending. Running on every base keeps the result attached to the head SHA. on: pull_request: - branches: main types: [opened, labeled, unlabeled, synchronize, reopened] permissions: pull-requests: read diff --git a/.github/workflows/ValidatePullRequests.yml b/.github/workflows/ValidatePullRequests.yml index b2aeedf..5238470 100644 --- a/.github/workflows/ValidatePullRequests.yml +++ b/.github/workflows/ValidatePullRequests.yml @@ -2,9 +2,15 @@ name: Validate Pull Request +# No `branches:` filter: PRs in a stack target the layer below them rather than +# `main`, and the filter is evaluated against the PR's own base ref, so a +# filtered trigger leaves every stacked layer without build or test coverage +# until the layer below merges and GitHub retargets it. That serialises all +# breakage to merge time. `report-ci-status` is a required check on `main`, and +# check runs attach to the head SHA, so running here means the result is already +# present when a layer is retargeted. on: pull_request: - branches: [ main, 'release/**' ] # Cancels old running job if a new one is triggered (e.g. by a push onto the same branch). # This will cancel dependent jobs as well, such as dep_build and dep_benchmarks From c4286745b9b0a63e42866e80330dd06489121f8e Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Mon, 21 Sep 2026 12:30:15 +0100 Subject: [PATCH 3/4] Revert unnecessary branch filter changes Signed-off-by: Simon Davies --- .github/workflows/PRLabelChecker.yml | 7 +------ .github/workflows/ValidatePullRequests.yml | 8 +------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/.github/workflows/PRLabelChecker.yml b/.github/workflows/PRLabelChecker.yml index 2e72497..bc84ed2 100644 --- a/.github/workflows/PRLabelChecker.yml +++ b/.github/workflows/PRLabelChecker.yml @@ -1,12 +1,7 @@ name: Label Checker -# No `branches:` filter, for the same reason as ValidatePullRequests.yml. -# `check-labels` is a required check on `main`, and base retargeting raises an -# `edited` event, which is absent from the types below. A layer labelled while -# it still targets the layer below would therefore never run this check, and -# after retargeting nothing re-fires it, leaving a required check permanently -# pending. Running on every base keeps the result attached to the head SHA. on: pull_request: + branches: main types: [opened, labeled, unlabeled, synchronize, reopened] permissions: pull-requests: read diff --git a/.github/workflows/ValidatePullRequests.yml b/.github/workflows/ValidatePullRequests.yml index 5238470..b2aeedf 100644 --- a/.github/workflows/ValidatePullRequests.yml +++ b/.github/workflows/ValidatePullRequests.yml @@ -2,15 +2,9 @@ name: Validate Pull Request -# No `branches:` filter: PRs in a stack target the layer below them rather than -# `main`, and the filter is evaluated against the PR's own base ref, so a -# filtered trigger leaves every stacked layer without build or test coverage -# until the layer below merges and GitHub retargets it. That serialises all -# breakage to merge time. `report-ci-status` is a required check on `main`, and -# check runs attach to the head SHA, so running here means the result is already -# present when a layer is retargeted. on: pull_request: + branches: [ main, 'release/**' ] # Cancels old running job if a new one is triggered (e.g. by a push onto the same branch). # This will cancel dependent jobs as well, such as dep_build and dep_benchmarks From 741f6652a716d352d9dc9b7972bd07db31338d37 Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Tue, 29 Sep 2026 16:45:50 +0100 Subject: [PATCH 4/4] Validate Linux ARM64 npm package Add native ARM64 tarball validation before publishing and use provenance consistently for the ARM64 package. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: Simon Davies --- .github/workflows/npm-publish.yml | 68 ++++++++++++++++++++++++++++++- src/js-host-api/test-pack.sh | 22 +++++----- 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 0721746..05129fc 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -162,8 +162,72 @@ jobs: ${{ env.WORKING_DIR }}/index.d.ts if-no-files-found: error - publish: + validate-linux-arm64: needs: build + runs-on: [self-hosted, Linux, arm64, kvm] + steps: + - uses: actions/checkout@v7 + + - name: Setup Node.js + uses: actions/setup-node@v7 + with: + node-version: '22.22.3' + cache: 'npm' + cache-dependency-path: 'src/js-host-api/package-lock.json' + + - name: Verify Linux arm64 runner + run: | + test "$(uname -m)" = "aarch64" + test "$(node -p process.arch)" = "arm64" + + - name: Download Linux arm64 GNU artifact + uses: actions/download-artifact@v8 + with: + name: bindings-linux-arm64-gnu + path: ${{ env.WORKING_DIR }}/artifacts/linux-arm64-gnu + + - name: Download JS bindings + uses: actions/download-artifact@v8 + with: + name: js-bindings + path: ${{ env.WORKING_DIR }}/js-bindings + + - name: Prepare Linux arm64 package + working-directory: ${{ env.WORKING_DIR }} + run: | + mv artifacts/linux-arm64-gnu/*.node npm/linux-arm64-gnu/js-host-api.linux-arm64-gnu.node + mv js-bindings/index.js index.js + mv js-bindings/index.d.ts index.d.ts + + - name: Set package versions + working-directory: ${{ env.WORKING_DIR }} + run: | + npm version "$VERSION" --no-git-tag-version --allow-same-version --ignore-scripts + cd npm/linux-arm64-gnu + npm version "$VERSION" --no-git-tag-version --allow-same-version --ignore-scripts + env: + VERSION: ${{ inputs.version }} + + - name: Update Linux arm64 optional dependency version + working-directory: ${{ env.WORKING_DIR }} + run: | + node -e " + const fs = require('fs'); + const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); + pkg.optionalDependencies['@hyperlight-dev/js-host-api-linux-arm64-gnu'] = process.env.VERSION; + fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n'); + " + env: + VERSION: ${{ inputs.version }} + + - name: Validate Linux arm64 release tarballs + working-directory: ${{ env.WORKING_DIR }} + run: ./test-pack.sh + env: + PLATFORM_PACKAGE: linux-arm64-gnu + + publish: + needs: [build, validate-linux-arm64] # Trusted publishing (OIDC) requires GitHub-hosted runners. # The publish job only downloads pre-built artifacts and runs npm publish, # so it does not need self-hosted runners with KVM/Hyperlight. @@ -351,7 +415,7 @@ jobs: - name: Publish Linux arm64 GNU package if: ${{ !inputs.dry_run }} working-directory: ${{ env.WORKING_DIR }}/npm/linux-arm64-gnu - run: npm publish --access public --ignore-scripts ${{ (github.event_name == 'workflow_dispatch' || contains(env.FIRST_TIME_PACKAGES, ',@hyperlight-dev/js-host-api-linux-arm64-gnu,')) && '' || '--provenance' }} + run: npm publish --access public --ignore-scripts --provenance env: NODE_AUTH_TOKEN: ${{ (github.event_name == 'workflow_dispatch' || contains(env.FIRST_TIME_PACKAGES, ',@hyperlight-dev/js-host-api-linux-arm64-gnu,')) && secrets.NPM_TOKEN || '' }} diff --git a/src/js-host-api/test-pack.sh b/src/js-host-api/test-pack.sh index 6e1a77c..e76b079 100755 --- a/src/js-host-api/test-pack.sh +++ b/src/js-host-api/test-pack.sh @@ -13,6 +13,8 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PACK_DIR="/tmp/hyperlight-npm-test-pack" INSTALL_DIR="/tmp/hyperlight-npm-test-install" MACOS_INSTALL_DIR="/tmp/hyperlight-npm-test-install-macos" +PLATFORM_PACKAGE="${PLATFORM_PACKAGE:-linux-x64-gnu}" +PLATFORM_BINARY="js-host-api.${PLATFORM_PACKAGE}.node" REQUIRE_MACOS_PACKAGE="${REQUIRE_MACOS_PACKAGE:-0}" # ── Cleanup ────────────────────────────────────────────────────────── @@ -27,16 +29,16 @@ if [ ! -f "package.json" ]; then exit 1 fi -# In CI the .node binary is already in npm/linux-x64-gnu/; locally it's in the project root. -if ls npm/linux-x64-gnu/*.node 1>/dev/null 2>&1; then - echo "📦 Platform binary already present in npm/linux-x64-gnu/" +# In CI the .node binary is already in its platform package; locally it's in the project root. +if ls "npm/${PLATFORM_PACKAGE}"/*.node 1>/dev/null 2>&1; then + echo "📦 Platform binary already present in npm/${PLATFORM_PACKAGE}/" elif ls ./*.node 1>/dev/null 2>&1; then NATIVE_BINARY=$(ls ./*.node | head -1) BINARY_NAME=$(basename "${NATIVE_BINARY}") echo "📦 Copying ${BINARY_NAME} into platform package..." - cp "${NATIVE_BINARY}" npm/linux-x64-gnu/"${BINARY_NAME}" + cp "${NATIVE_BINARY}" "npm/${PLATFORM_PACKAGE}/${PLATFORM_BINARY}" else - echo "❌ Error: No .node binary found. Run 'npm run build' first, or ensure CI artifacts are staged." >&2 + echo "❌ Error: No .node binary found for ${PLATFORM_PACKAGE}. Run 'npm run build' first, or ensure CI artifacts are staged." >&2 exit 1 fi @@ -50,8 +52,8 @@ else fi # ── Step 1: Pack platform package ─────────────────────────────────── -echo "📦 Packing platform package (linux-x64-gnu)..." -PLATFORM_TGZ=$(npm pack ./npm/linux-x64-gnu --pack-destination "${PACK_DIR}" 2>/dev/null) +echo "📦 Packing platform package (${PLATFORM_PACKAGE})..." +PLATFORM_TGZ=$(npm pack "./npm/${PLATFORM_PACKAGE}" --pack-destination "${PACK_DIR}" 2>/dev/null) PLATFORM_TGZ_PATH="${PACK_DIR}/${PLATFORM_TGZ}" echo " → ${PLATFORM_TGZ_PATH}" @@ -114,10 +116,10 @@ echo "" echo "✅ Validating platform package contents..." PLATFORM_FILES=$(tar tzf "${PLATFORM_TGZ_PATH}") -if echo "${PLATFORM_FILES}" | grep -q '\.node$'; then - echo " ✅ .node binary present" +if echo "${PLATFORM_FILES}" | grep -q "^package/${PLATFORM_BINARY}$"; then + echo " ✅ ${PLATFORM_BINARY} present" else - echo " ❌ MISSING: .node binary" >&2 + echo " ❌ MISSING: ${PLATFORM_BINARY}" >&2 exit 1 fi