From 547eb7676df427de6b5195005e2a3b0322a72f1c Mon Sep 17 00:00:00 2001 From: Luke Parker <10430890+Hona@users.noreply.github.com> Date: Thu, 12 Mar 2026 10:25:09 +1000 Subject: [PATCH] feat(windows): add arm64 release targets for cli and desktop (#16696) --- .github/workflows/publish.yml | 7 +++++++ .../scripts/finalize-latest-yml.ts | 14 +++++++++++--- packages/desktop-electron/scripts/utils.ts | 7 ++++++- packages/desktop/scripts/finalize-latest-json.ts | 2 ++ packages/desktop/scripts/utils.ts | 5 +++++ packages/opencode/package.json | 1 + packages/opencode/script/build.ts | 4 ++++ packages/opencode/src/file/ripgrep.ts | 1 + 8 files changed, 37 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 079e6d6f0..b425b32a5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -115,6 +115,9 @@ jobs: target: x86_64-apple-darwin - host: macos-latest target: aarch64-apple-darwin + # github-hosted: blacksmith lacks ARM64 MSVC cross-compilation toolchain + - host: windows-2025 + target: aarch64-pc-windows-msvc - host: blacksmith-4vcpu-windows-2025 target: x86_64-pc-windows-msvc - host: blacksmith-4vcpu-ubuntu-2404 @@ -258,6 +261,10 @@ jobs: - host: macos-latest target: aarch64-apple-darwin platform_flag: --mac --arm64 + # github-hosted: blacksmith lacks ARM64 MSVC cross-compilation toolchain + - host: "windows-2025" + target: aarch64-pc-windows-msvc + platform_flag: --win --arm64 - host: "blacksmith-4vcpu-windows-2025" target: x86_64-pc-windows-msvc platform_flag: --win diff --git a/packages/desktop-electron/scripts/finalize-latest-yml.ts b/packages/desktop-electron/scripts/finalize-latest-yml.ts index 42ec23b64..aa2ae5c96 100644 --- a/packages/desktop-electron/scripts/finalize-latest-yml.ts +++ b/packages/desktop-electron/scripts/finalize-latest-yml.ts @@ -78,9 +78,17 @@ async function read(subdir: string, filename: string): Promise = {} -// Windows: single arch, pass through -const win = await read("latest-yml-x86_64-pc-windows-msvc", "latest.yml") -if (win) output["latest.yml"] = serialize(win) +// Windows: merge arm64 + x64 into single file +const winX64 = await read("latest-yml-x86_64-pc-windows-msvc", "latest.yml") +const winArm64 = await read("latest-yml-aarch64-pc-windows-msvc", "latest.yml") +if (winX64 || winArm64) { + const base = winArm64 ?? winX64! + output["latest.yml"] = serialize({ + version: base.version, + files: [...(winArm64?.files ?? []), ...(winX64?.files ?? [])], + releaseDate: base.releaseDate, + }) +} // Linux x64: pass through const linuxX64 = await read("latest-yml-x86_64-unknown-linux-gnu", "latest-linux.yml") diff --git a/packages/desktop-electron/scripts/utils.ts b/packages/desktop-electron/scripts/utils.ts index 4c9af1fc7..1c0add87d 100644 --- a/packages/desktop-electron/scripts/utils.ts +++ b/packages/desktop-electron/scripts/utils.ts @@ -19,6 +19,11 @@ export const SIDECAR_BINARIES: Array<{ rustTarget: string; ocBinary: string; ass ocBinary: "opencode-darwin-x64-baseline", assetExt: "zip", }, + { + rustTarget: "aarch64-pc-windows-msvc", + ocBinary: "opencode-windows-arm64", + assetExt: "zip", + }, { rustTarget: "x86_64-pc-windows-msvc", ocBinary: "opencode-windows-x64-baseline", @@ -41,7 +46,7 @@ export const RUST_TARGET = Bun.env.RUST_TARGET function nativeTarget() { const { platform, arch } = process if (platform === "darwin") return arch === "arm64" ? "aarch64-apple-darwin" : "x86_64-apple-darwin" - if (platform === "win32") return "x86_64-pc-windows-msvc" + if (platform === "win32") return arch === "arm64" ? "aarch64-pc-windows-msvc" : "x86_64-pc-windows-msvc" if (platform === "linux") return arch === "arm64" ? "aarch64-unknown-linux-gnu" : "x86_64-unknown-linux-gnu" throw new Error(`Unsupported platform: ${platform}/${arch}`) } diff --git a/packages/desktop/scripts/finalize-latest-json.ts b/packages/desktop/scripts/finalize-latest-json.ts index 5445e0640..a2b95d2c4 100644 --- a/packages/desktop/scripts/finalize-latest-json.ts +++ b/packages/desktop/scripts/finalize-latest-json.ts @@ -101,6 +101,7 @@ const targets = [ { key: "linux-x86_64-rpm", asset: "opencode-desktop-linux-x86_64.rpm" }, { key: "linux-aarch64-deb", asset: "opencode-desktop-linux-arm64.deb" }, { key: "linux-aarch64-rpm", asset: "opencode-desktop-linux-aarch64.rpm" }, + { key: "windows-aarch64-nsis", asset: "opencode-desktop-windows-arm64.exe" }, { key: "windows-x86_64-nsis", asset: "opencode-desktop-windows-x64.exe" }, { key: "darwin-x86_64-app", asset: "opencode-desktop-darwin-x64.app.tar.gz" }, { @@ -129,6 +130,7 @@ const alias = (key: string, source: string) => { alias("linux-x86_64", "linux-x86_64-deb") alias("linux-aarch64", "linux-aarch64-deb") +alias("windows-aarch64", "windows-aarch64-nsis") alias("windows-x86_64", "windows-x86_64-nsis") alias("darwin-x86_64", "darwin-x86_64-app") alias("darwin-aarch64", "darwin-aarch64-app") diff --git a/packages/desktop/scripts/utils.ts b/packages/desktop/scripts/utils.ts index 2629eb466..06ff25946 100644 --- a/packages/desktop/scripts/utils.ts +++ b/packages/desktop/scripts/utils.ts @@ -11,6 +11,11 @@ export const SIDECAR_BINARIES: Array<{ rustTarget: string; ocBinary: string; ass ocBinary: "opencode-darwin-x64-baseline", assetExt: "zip", }, + { + rustTarget: "aarch64-pc-windows-msvc", + ocBinary: "opencode-windows-arm64", + assetExt: "zip", + }, { rustTarget: "x86_64-pc-windows-msvc", ocBinary: "opencode-windows-x64-baseline", diff --git a/packages/opencode/package.json b/packages/opencode/package.json index fe991ad8a..e277977f7 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -36,6 +36,7 @@ "@parcel/watcher-linux-arm64-musl": "2.5.1", "@parcel/watcher-linux-x64-glibc": "2.5.1", "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", "@parcel/watcher-win32-x64": "2.5.1", "@standard-schema/spec": "1.0.0", "@tsconfig/bun": "catalog:", diff --git a/packages/opencode/script/build.ts b/packages/opencode/script/build.ts index 4ff610862..81694aeac 100755 --- a/packages/opencode/script/build.ts +++ b/packages/opencode/script/build.ts @@ -108,6 +108,10 @@ const allTargets: { arch: "x64", avx2: false, }, + { + os: "win32", + arch: "arm64", + }, { os: "win32", arch: "x64", diff --git a/packages/opencode/src/file/ripgrep.ts b/packages/opencode/src/file/ripgrep.ts index b1068f5d8..601c82e94 100644 --- a/packages/opencode/src/file/ripgrep.ts +++ b/packages/opencode/src/file/ripgrep.ts @@ -100,6 +100,7 @@ export namespace Ripgrep { }, "x64-darwin": { platform: "x86_64-apple-darwin", extension: "tar.gz" }, "x64-linux": { platform: "x86_64-unknown-linux-musl", extension: "tar.gz" }, + "arm64-win32": { platform: "aarch64-pc-windows-msvc", extension: "zip" }, "x64-win32": { platform: "x86_64-pc-windows-msvc", extension: "zip" }, } as const