Skip to content

fix(ci): install balena-cli via npm so native postinstalls run#2925

Merged
vpetersson merged 1 commit into
masterfrom
fix/ci-balena-cli-via-npm
May 19, 2026
Merged

fix(ci): install balena-cli via npm so native postinstalls run#2925
vpetersson merged 1 commit into
masterfrom
fix/ci-balena-cli-via-npm

Conversation

@vpetersson
Copy link
Copy Markdown
Contributor

Issues Fixed

Run 26116718700 failed every `balena-build-images` matrix leg during `Install balena CLI`:

```
error: install script from "drivelist" exited with 1
##[error]Process completed with exit code 1.
```

Root cause: drivelist's `install` lifecycle script runs node-gyp to build a native addon used by `balena preload`. bun fetched node-gyp via bunx into a broken cache state (the bundled `undici` was missing `./pool`), so the rebuild crashed at module-resolve time.

This is the second class of "bun blocks/breaks native postinstalls" failure in the same workflow — #2922 already worked around it for `@balena/compose-parser` via `bun pm trust`. Chasing per-package escape hatches isn't sustainable.

Description

Install balena-cli via `npm install -g` instead of `bun install -g` in both balena-cli-using jobs. Verified locally on Node 22.22.1:

```
$ npm install -g balena-cli@25.1.3
added 1102 packages in 21s
$ find ~/.npm-prefix -name "drivelist.node" -o -name "balena-compose-parser"
…/drivelist/build/Release/drivelist.node ← native build ✓
…/@balena/compose-parser/bin/balena-compose-parser ← Go binary ✓
```

Removes from `build-balena-disk-image.yaml`:

`install-bun.sh` stays — `deploy-website.yaml`, `javascript-lint.yaml`, and `test-runner.yml` still use bun for local `package.json` installs, where bun's `trustedDependencies` field works.

Checklist

  • I have performed a self-review of my own code.
  • New and existing unit tests pass locally and on CI with my changes.
  • I have done an end-to-end test for Raspberry Pi devices.
  • I have tested my changes for x86 devices.
  • I added a documentation for the changes I have made (when necessary).

balena-cli's transitive deps include native modules whose `install`
or `postinstall` lifecycle scripts ship binaries critical to the
commands we use:

  - @balena/compose-parser ships a Go binary (compose-go wrapper) used
    by `balena deploy`. Missing → "Unexpected end of JSON input".
  - drivelist builds a native `.node` addon used by `balena preload`
    via node-gyp. Missing → preload errors.

`bun install -g` blocks lifecycle scripts by default. The
compose-parser case had a targeted workaround (#2922,
`bun pm trust @balena/compose-parser`), but `balena-build-images`
also needs drivelist, and bun's bunx-managed node-gyp tripped over
a broken undici dependency when rebuilding it (run 26116718700,
pi5 leg). Rather than chase per-package trust + native-build
escape hatches, install balena-cli via npm, which runs all
lifecycle scripts inline and uses the runner's pre-resolved
node-gyp toolchain.

This drops the `Install bun` and `bun pm trust @balena/compose-parser`
steps from both balena-cloud-deploy and balena-build-images, and the
now-unreferenced BUN_VERSION env var. install-bun.sh stays — other
workflows (deploy-website, javascript-lint, test-runner) still use
bun for local package.json installs, where the trustedDependencies
field works.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vpetersson vpetersson requested a review from a team as a code owner May 19, 2026 18:30
@vpetersson vpetersson self-assigned this May 19, 2026
@sonarqubecloud
Copy link
Copy Markdown

@vpetersson vpetersson merged commit f4e31b7 into master May 19, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant