Repository navigation
ci: publish the Linux packages like the macOS ones, tested on the GB10 - #81
Conversation
The Linux wheel and npm engine package were built and tested on every run but uploaded only with PUBLISH_LINUX, because the engine licence granted use on Apple Silicon only. With Linux on NVIDIA GPUs licensed too, every release uploads both platforms' packages, and the variable goes. test-linux moves from GitHub's ubuntu-24.04-arm, which has no NVIDIA GPU or CUDA runtime, to the self-hosted GB10, and checks what test-macos checks: the Python and Node bindings load the engine, and a program linked against each install starts. It works under RUNNER_TEMP, since a self-hosted runner keeps its workspace between runs, and forbids a superfluid download on the shared machine.
IsuraManchanayake
left a comment
There was a problem hiding this comment.
Codex Review
Reviewed d9207f75ae75d142584b6a21544519cde570b739 together with basecompute/baseRT-internal#785. One P2 finding is attached inline: the new Linux Node smoke test reports success for library/binding failures.
The two-platform registry probes, package selection and upload lists are otherwise consistent. Local checks passed:
- actionlint, all 18 publish shell blocks, and this tree's 17 packaging tests;
- nine upload/dry-run decision cases and five registry cases, including a macOS-only partial publication correctly requiring both PyPI and npm work;
- a default three-package npm build using matching cached 0.4.1 source/bundles as fixtures, confirming that the main package depends on both platform engines;
- the normal Node probe against the installed macOS engine. Negative cases exposed the inline finding: missing/invalid libraries and an unresolved binding symbol also exited zero.
These local checks do not establish that the new GB10 job runs successfully: the actual 0.4.2 bundles, pinned tools on that runner, and release/publish workflow execution remain untested here. The updated licence must be in the first Linux release's bundles, and the GB10 runner must be enabled for this repository, as the PR already specifies.
| try { new BaseRTModel("/nonexistent.base"); } catch (e) { | ||
| if (/Cannot find libbaseRT/.test(e.message)) throw e; | ||
| console.log("engine loaded:", e.message.split("\n")[0]); |
There was a problem hiding this comment.
Codex Review — [P2] Accept only the expected missing-model failure
This treats every exception except Cannot find libbaseRT as a successful load. Koffi reports failed dynamic loads as Failed to load shared library: ... and missing API symbols as Cannot find function ..., so both are swallowed here. I ran this exact snippet with a missing library, an invalid library, and a binding requesting a missing symbol: every case printed engine loaded: and exited 0. A CUDA kernel-library initialization failure would also be accepted as an ordinary model-loading exception. The Python/C version probes do not cover Node binding setup or kernel initialization, so they do not close this gap. Require the specific expected file-not-found error for /nonexistent.base, rethrow every other error, and fail if construction unexpectedly succeeds; apply the same correction to the matching macOS probe too.
There was a problem hiding this comment.
Fixed in 1d2be94. Both Node probes, on macOS and the GB10, now:
- accept only the engine's own refusal,
Failed to load model: Failed to open model: /nonexistent.base(the backend-neutral loader produces it on Metal and CUDA alike); - rethrow every other error, a missing symbol included;
- fail if construction succeeds.
I checked locally against packages built from the current source with the 0.4.1 engine. The real engine passes. An invalid libbaseRT.dylib now fails with koffi's Failed to load shared library.
The missing-library case showed a second gap. With the package's engine gone, the bindings fall back to an engine installed elsewhere; here that was an older 0.4.0 in ~/.basert, which then loaded.
- npm: the linked-program step already fails in that case, since it links against the engine package's folder.
- pip: that step links against whatever
_find_library()returns, so a fallback engine passed everything. Both pip steps now assert that the path is the wheel's_engine/again. The earlier Linux job had that check and the GB10 rewrite dropped it. On a shared runner, an installed engine would otherwise pass every check.
There was a problem hiding this comment.
Codex Review: Verified fixed in 1d2be94. The exact updated probe passes with the real macOS engine and now rejects all three previously reproduced failures (missing/invalid library and missing symbol). It also rejects simulated kernel-load errors and unexpected construction success. Confirmed the restored Python assertion rejects an actual fallback to an external engine. No further issue with this change.
The Node probe took any error but "Cannot find libbaseRT" as proof the
engine loaded, so koffi failing to load the library or one of its
symbols passed. It now accepts only the engine's own refusal of the
missing model ("Failed to load model: Failed to open model:
/nonexistent.base", the same on Metal and CUDA), rethrows anything
else, and fails if the model loads. Both install jobs run it.
The pip steps assert again that the bindings found the wheel's own
engine. Without it they fall back to an engine installed elsewhere, and
on the shared GB10 that one would pass every later check, the linked
program included.
IsuraManchanayake
left a comment
There was a problem hiding this comment.
Codex Review — follow-up
Reviewed 1d2be944d5712c006f9ce87160ff7495928335d6, including the response to the previous review and the full current diff. The previous P2 is fixed; no additional actionable findings.
Both platform jobs now use identical Node probes that accept the expected missing-model error and reject other failures. The Python probes again reject an engine found outside the wheel.
Validation on the actual snippets extracted from this revision:
- Eight Node cases passed: the real installed macOS engine and a controlled expected-error case succeeded; missing library, invalid library, unresolved binding symbol, simulated CUDA kernel-load failure, wrong missing-model error, and unexpected construction success all failed as intended.
- The Python check accepted the bundled engine and rejected both an explicit external library and an actual fallback to a separate installation after removing the bundled engine from the fixture.
- actionlint, all 18 shell blocks, and the diff whitespace check passed.
The real-engine checks used cached 0.4.1 macOS package fixtures; they do not validate a fresh 0.4.2 CUDA build. The new GB10 publish job, including its pinned tool setup and end-to-end package execution, remains unrun in this review. The registry/publication logic is unchanged from the previous reviewed revision.
Linux is published the same way macOS is: every release uploads the Linux wheel and
@basecompute/basert-linux-arm64-cudaalongside the macOS ones, and the Linux install tests run on the DGX Spark (GB10) that builds the CUDA engine.Changes (
publish.yml)PUBLISH_LINUX. The plan's Linux switch, the registry checks' Linux-only lists, the build's--engines, the PyPI job's step that dropped the Linux wheel, and the npm job's engine list all go. The main npm package now always lists both engine packages as optional dependencies.test-linuxruns on[self-hosted, Linux, ARM64, gb10]instead ofubuntu-24.04-arm. GitHub's arm64 runners have no NVIDIA GPU or CUDA runtime, so that job could only check that the packages install and that the bindings point at the right file. On the GB10 it checks whattest-macoschecks:pip installthe Linux wheel, runbasert --version,chat --helpandserve --help, and load the engine through the Python bindings (baseRT_version_string);npm installthe main package with the Linux engine package, runbasert, and load the engine through the Node bindings;libbaseRT.so.0resolves inside the package, and run it. That load pulls in the CUDA driver and cuBLAS, so a missing CUDA library fails here.RUNNER_TEMP, because a self-hosted runner keeps its workspace between runs. It setsBASERT_SUPERFLUID_AUTO_INSTALL=0, soserve --helpnever installs superfluid on the shared machine.Before merging
LICENSE, and until now it granted use on Apple Silicon only. The release that first publishes Linux must carry the new licence.test-linuxwaits in the queue and every upload waits with it. As for the M4 Pro runner this repository already uses, keep fork pull request workflows requiring approval, since a fork PR could target a self-hosted runner. Checked from job records: the GB10 runners are org runners in the same group that already runs this repository's M4 Pro jobs, and fork PR workflows from all external contributors need approval.Not verified
publish.ymlruns only on a published release or by hand frommain. Its first run is a dry run ifPUBLISH_ENABLEDis unset.setup-pythonandsetup-nodehave to install the pinned 3.14.9 and Node 24.21.0 into the GB10's tool cache. setup-python matches its Linux builds to Ubuntu 24.04, which DGX OS 7 is based on.bash -n-checked everyrunblock locally; no actionlint run.