Pārlūkot izejas kodu

feat(windows): add arm64 release targets for cli and desktop (#16696)

Luke Parker 5 mēneši atpakaļ
vecāks
revīzija
547eb7676d

+ 7 - 0
.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

+ 11 - 3
packages/desktop-electron/scripts/finalize-latest-yml.ts

@@ -78,9 +78,17 @@ async function read(subdir: string, filename: string): Promise<LatestYml | undef
 
 const output: Record<string, string> = {}
 
-// 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")

+ 6 - 1
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}`)
 }

+ 2 - 0
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")

+ 5 - 0
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",

+ 1 - 0
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:",

+ 4 - 0
packages/opencode/script/build.ts

@@ -108,6 +108,10 @@ const allTargets: {
     arch: "x64",
     avx2: false,
   },
+  {
+    os: "win32",
+    arch: "arm64",
+  },
   {
     os: "win32",
     arch: "x64",

+ 1 - 0
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