fix(ci): trust @balena/compose-parser so balena deploy can parse compose#2922
Merged
Conversation
balena-cli 25.x parses docker-compose.yml via @balena/compose-parser, a Node wrapper around a Go binary (compose-go) that's downloaded by a postinstall script. `bun install -g` blocks lifecycle scripts by default, so the Go binary never lands in node_modules/@balena/compose-parser/bin/. At deploy time the spawn returns empty stdout, the parser JSON.parses an empty string, and balena-cli reports `Error parsing composition file …: Unexpected end of JSON input` against a perfectly valid compose file — the failure mode of run 26115123191 against v2026.05.0. `bun pm trust @balena/compose-parser` retroactively runs only the compose-parser postinstall (plus its actual transitive deps). Using the broader `--trust` also runs @ronomon/direct-io's native build, which fails on the runner and isn't needed for `balena deploy`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
This was referenced May 19, 2026
vpetersson
added a commit
that referenced
this pull request
May 19, 2026
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Issues Fixed
Re-dispatching `build-balena-disk-image.yaml` against v2026.05.0 after merging #2921 now fails all matrix legs at the `Deploy to balena fleet` step:
```
Error parsing composition file "/home/runner/work/Anthias/Anthias/balena-deploy/docker-compose.yml":
Unexpected end of JSON input
```
Failed run: https://github.com/Screenly/Anthias/actions/runs/26115123191/job/76802347247
Description
The compose file is well-formed (~2 KB of valid YAML, parses cleanly with `@balena/compose-parser` locally). The error is misleading — it actually comes from `JSON.parse("")` deep in the parser, which happens when its underlying Go binary is missing.
Root cause. balena-cli 25.x parses compose files via `@balena/compose-parser`, a Node wrapper around a Go binary (compose-go) downloaded into `node_modules/@balena/compose-parser/bin/balena-compose-parser` by a postinstall script. `bun install -g` blocks lifecycle scripts by default ("Blocked 9 postinstalls" in the install log), so the Go binary never lands. At deploy time the spawn returns empty stdout, the parser JSON.parses an empty string, and balena-cli rewraps it as "Error parsing composition file".
Reproduced locally:
```
bun install -g balena-cli@25.1.3
find ~/.bun -name balena-compose-parser → empty
cd ~/.bun/install/global && bun pm trust @balena/compose-parser
node -e "require('@balena/compose-parser').parse('balena-deploy/docker-compose.yml')"
→ SUCCESS: anthias-celery, anthias-server, anthias-viewer, redis
```
Why now? balena-cli 22.x (pre-#2854) used a pure-JS YAML parser. #2854 bumped balena-cli to 25.1.3 (which switched to the Go-binary path) AND moved the install from `npm install -g` to `bun install -g`. Either change alone would have been fine; the combination breaks deploy.
Fix. Targeted `bun pm trust @balena/compose-parser` after the install. Trusts only the package we actually need a postinstall for; avoids `--trust` (all) which also triggers `@ronomon/direct-io`'s native build, which fails on the runner and isn't needed for `balena deploy`.
Checklist