Skip to content

Add linux-arm64 npm packaging - #310

Merged
simongdavies merged 4 commits into
mainfrom
simongdavies-npm-linux-arm64-packaging
Sep 30, 2026
Merged

simongdavies merged 4 commits into
mainfrom
simongdavies-npm-linux-arm64-packaging

Conversation

@simongdavies

@simongdavies simongdavies commented Sep 16, 2026 •

Copy link
Copy Markdown
Member

Layer 2 of a stacked PR — based on #308, not main.

Adds npm packaging for linux-arm64, completing the npm side of the aarch64 support started in #308. Layer 1 added the aarch64-apple-darwin package and the Linux aarch64 CI matrix but deliberately stopped short of Linux arm64 npm packaging; this is that piece.

Review note: the diff shown against main will include #308's commits until that merges. The only commit belonging to this PR is 252ab33.

What this adds

A new @hyperlight-dev/js-host-api-linux-arm64-gnu platform package, mirroring the existing linux-x64-gnu conventions exactly:

Field Value
os ["linux"]
cpu ["arm64"]
libc ["glibc"]
target aarch64-unknown-linux-gnu
runner [self-hosted, Linux, arm64, kvm]

There is no musl aarch64 variant — glibc only, matching the scope of the existing Linux packages.

Wired through: npm/linux-arm64-gnu/package.json (new), the main package.json (napi.targets + optionalDependencies), package-lock.json, npm-publish.yml (matrix, artifact download, staging, versioning, publish, verification, dry-run), the set-version recipe in Justfile, docs/release.md and src/js-host-api/DEVELOPMENT.md.

Notes

FIRST_TIME_PACKAGES. The new package is added to this list because npm cannot configure a trusted publisher for a package that does not exist yet, so its first release must use NPM_TOKEN. It should be removed in a follow-up PR after the first publish, per the procedure already documented in docs/release.md.

Lockfile. As with darwin-arm64 in #308, the root lock edge has no resolved URL and no integrity hash — unavoidable until the package is first published. npm ci silently skips unresolvable optional deps. The lockfile was hand-edited rather than regenerated, so the diff is exactly one line and no libc fields were stripped (npm 10.9.3 does that on regeneration).

Doc fix. docs/release.md said "the npm main package and the three platform packages" when there were already four; corrected straight to five here rather than in #308 to avoid a guaranteed same-line conflict between the two layers.

Co-authored-by: Copilot App [email protected]

@simongdavies
simongdavies added this pull request to stack #311 September 16, 2026 20:37
@simongdavies simongdavies added the kind/enhancement New feature or improvement label Sep 16, 2026
@simongdavies simongdavies added the ready-for-review PR is ready for (re-)review label Sep 16, 2026
Comment thread .github/workflows/ValidatePullRequests.yml Outdated
Comment thread .github/workflows/npm-publish.yml Outdated
Comment thread .github/workflows/npm-publish.yml
@simongdavies
simongdavies force-pushed the simongdavies-npm-linux-arm64-packaging branch 2 times, most recently from 8aeae58 to 5404b0b Compare September 29, 2026 07:50
Base automatically changed from simongdavies-macos-support to main September 29, 2026 09:07
simongdavies and others added 3 commits September 29, 2026 10:07
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 <[email protected]>
Signed-off-by: Simon Davies <[email protected]>
`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/<n>/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 <[email protected]>
Signed-off-by: Simon Davies <[email protected]>
@simongdavies
simongdavies force-pushed the simongdavies-npm-linux-arm64-packaging branch from 5404b0b to c428674 Compare September 29, 2026 09:07
Add native ARM64 tarball validation before publishing and use provenance consistently for the ARM64 package.

Co-authored-by: Copilot App <[email protected]>
Signed-off-by: Simon Davies <[email protected]>
@simongdavies
simongdavies merged commit ed37cdb into main Sep 30, 2026
24 checks passed
@github-actions github-actions Bot removed the ready-for-review PR is ready for (re-)review label Sep 30, 2026
simongdavies added a commit that referenced this pull request Oct 2, 2026
Moves the `lint` step in `.github/workflows/dep_build.yml` so it runs
before the two build steps.

Step order in the `build` job goes from:

```
install nodejs -> Sign node for Hypervisor.framework (macOS) -> fmt -> Build -> Build js-host-api -> lint -> test -> examples...
```

to:

```
install nodejs -> Sign node for Hypervisor.framework (macOS) -> fmt -> lint -> Build -> Build js-host-api -> test -> examples...
```

## Why

- `just lint` runs `cargo hyperlight clippy -p hyperlight-js-runtime`,
`cargo clippy --all-targets`, and `lint-js` (eslint, which does its own
npm install). None of those need build artifacts from the preceding
steps, so nothing was gained by running lint later.
- clippy executes `build.rs`, which builds **and links** the guest, so
lint-first also catches guest toolchain and link failures. This is not
theoretical: during #308 a macOS `llvm-ar` failure surfaced only in the
Build step, many minutes in, when lint-first would have caught it.
- clippy and `cargo build` have separate fingerprints, so reordering
them does not duplicate compilation work.
- Net effect: cheap, fast-failing checks run before expensive ones — the
conventional ordering — shortening the feedback loop on a matrix of 10+
jobs, several on scarce self-hosted runners.

## Scope

Ordering only. The diff is 3 insertions / 3 deletions; parsing the
workflow before and after yields an identical set of steps in a
different order. `fail-fast` and the macOS-only steps from #308 (`Set up
LLVM guest toolchain`, `Sign node for Hypervisor.framework`) are
untouched.

Part of stack #311. Base is `simongdavies-npm-linux-arm64-packaging`
(#310).

Signed-off-by: Simon Davies <[email protected]>
Co-authored-by: Copilot App <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/enhancement New feature or improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants