Skip to content

fix(ci): fail releases that bundle native code for the wrong CPU - #54982

Merged
Hona merged 1 commit into
anomalyco:devfrom
Hona:release-arch-guard
Oct 13, 2026
Merged

Hona merged 1 commit into
anomalyco:devfrom
Hona:release-arch-guard

Conversation

@Hona

@Hona Hona commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

2.0.27 shipped two Windows ARM64 regressions that every check passed. Each one shows up only on ARM64 hardware, which CI never runs:

  • CLI: the ARM64 binary embedded an x64 rust_pty.dll (bun-pty 0.4.9), so no terminal could open.
  • Desktop: the ARM64 package bundled @lydell/node-pty-win32-x64, so WSL commands failed.

Both are fixed on dev (#54689). This PR fails the build if either class of bug comes back.

flowchart LR
  A["bun build --compile<br/>build-node SEA"] --> B["NativeArch.verify(exe, target.arch)"]
  C["electron-builder afterPack"] --> D["Electron arch == CLI target?"]
  D --> E["NativeArch.verify(opencode-cli, arch)"]
  E --> F["NativeArch.verify(each node-pty .node/.dll/.exe)"]
Loading

script/native-arch.ts finds every PE, ELF and Mach-O image in a file, including the libraries Bun and Node SEA embed in a compiled executable, and reads each image's CPU. A universal Mach-O counts as all of its slices.

$ NativeArch.verify("opencode.exe", "arm64")   # 2.0.27 cli-windows-arm64
Error: opencode.exe must contain only arm64 code, but has PE x64 at byte 199953284

Against shipped binaries

Binary Images found Result
2.0.27 Bun CLI ×10 (darwin, linux glibc/musl, windows x64/baseline) 6–7 per binary, all target arch pass
2.0.27 cli-windows-arm64 PE arm64 ×6, PE x64 ×1 (rust_pty.dll) fail
beta Node SEA ×4 (darwin-arm64, linux-arm64, windows arm64/x64) 7–9 per binary, all target arch pass
Windows ARM64 compile with dev's bun-pty 0.4.11 + OpenTUI + fff PE arm64 ×6 pass
Same compile with bun-pty 0.4.9 PE x64 at rust_pty.dll fail

Each scan of a ~200 MB executable takes about 300 ms.

afterPack, driven with real binaries and node-pty prebuilds

Packaging Result
arm64 Electron, arm64 CLI, arm64 node-pty pass
x64 Electron, x64 CLI, x64 node-pty pass
arm64 Electron, OPENCODE_CLI_TARGET left on the x64 host Packaging arm64 Electron with the x86_64-pc-windows-msvc CLI
arm64 Electron, 2.0.27's ARM64 CLI opencode-cli.exe must contain only arm64 code, but has PE x64 at byte 199953284
arm64 Electron, x64 node-pty files in the arm64 package conpty_console_list.node must contain only arm64 code

Added by the opencode bot (AI-generated).

Related: #54689

2.0.27's ARM64 Windows CLI embedded an x64 rust_pty.dll and its ARM64 desktop bundled x64 node-pty. Both only fail on ARM64 hardware, which CI never runs, so the build now checks every native image against the target.
@Hona
Hona requested a review from Brendonovich as a code owner October 13, 2026 00:19
Copilot AI balanced review requested due to automatic review settings October 13, 2026 00:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check works as described, and I found nothing that should block a merge.

How I checked it: I cross-compiled small Bun executables that embed bun-pty's arm64 or x64 rust_pty library. Windows ARM64 and Darwin ARM64 builds pass with the matching library and fail with the wrong one (has PE x64 at byte …, Mach-O x64). A Linux x64 build that embeds an arm64 DLL also fails. I also ran script/build.ts with the check for opencode-windows-arm64 and opencode-darwin-x64. Both builds finished cleanly; the Windows ARM64 binary has 7 arm64 images and nothing else. Typecheck passes in packages/cli and packages/desktop, and the desktop config tests pass.

I didn't run the desktop afterPack checks because they need real electron-builder packaging. From reading the code, the arch comparison matches the publish.yml desktop matrix.

Public API: unchanged (build and packaging scripts only).

Related: #54689

@Hona
Hona merged commit 3731aac into anomalyco:dev Oct 13, 2026
13 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.

2 participants