Skip to content

Conversation

@wojtekn
Copy link
Contributor

@wojtekn wojtekn commented Oct 22, 2025

Related issues

Proposed Changes

Adds support for building Windows ARM64 binaries alongside x64, following the same architecture matrix pattern used for macOS builds.

Changes

Build Scripts:

  • Added make:windows-x64 and make:windows-arm64 npm scripts
  • Updated .buildkite/commands/build-for-windows.ps1 to accept architecture parameter
  • Made scripts/package-appx.mjs architecture-aware

CI Pipeline:

  • Converted Windows Dev/Release builds to use matrix builds for both x64 and arm64
  • Both architectures now build in parallel

Distribution:

  • Updated Fastlane to handle both Windows architectures separately
  • Modified scripts/generate-releases-manifest.mjs to generate architecture-specific manifest entries
  • Updated CDN filenames to include architecture: studio-win32-{arch}-v{version}.exe

Cleanup:

  • Removed deprecated make:windows-dev and make:windows-release scripts

Breaking Change ⚠️

The releases.json manifest structure for Windows has changed from:

"win32": { "sha": "...", "url": "..." }

To:

"win32": {
  "x64": { "sha": "...", "url": "..." },
  "arm64": { "sha": "...", "url": "..." }
}

The backend update API (wpcom/v2/studio-app/updates) will need to be updated to look up releases[version][platform][arch] instead of releases[version][platform] for Windows. The app already sends process.arch in the update request.

Testing Instructions

I tested:

  • arch-specific builds locally on a real Windows machine with both npm run make:windows-x64 and npm run make:windows-arm64
  • the arm64 build on Windows running on Parallels, and it worked fine (first site creation 24 seconds, next one 13 seconds)

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

@wojtekn wojtekn self-assigned this Oct 22, 2025
@github-actions
Copy link

github-actions bot commented Oct 22, 2025

📊 Performance Test Results

Comparing a74b5f8 vs trunk

site-editor

Metric trunk a74b5f8 Diff Change
load 10197.00 ms 9492.00 ms -705.00 ms 🟢 -6.9%

site-startup

Metric trunk a74b5f8 Diff Change
siteCreation 23139.00 ms 17161.00 ms -5978.00 ms 🟢 -25.8%
siteStartup 5980.00 ms 6002.00 ms +22.00 ms 🔴 0.4%

Results are median values from multiple test runs.

Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change

sha: windowsReleaseInfo.sha1,
url: `${ cdnURL }/${ baseName }-win32-v${ version }-full.nupkg`,
size: windowsReleaseInfo.size,
releasesData[ 'dev' ][ 'win32' ] = releasesData[ 'dev' ][ 'win32' ] ?? {};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We will need to update the API endpoint that handles app updates to account for this change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added 194541-ghe-Automattic/wpcom

@wojtekn wojtekn force-pushed the add/windows-arm-build branch from 64146fc to 5c47b7f Compare October 23, 2025 09:41
@wojtekn wojtekn requested review from a team and mokagio October 23, 2025 09:44
@wojtekn wojtekn marked this pull request as ready for review October 23, 2025 09:44
Copy link
Contributor

@bcotrim bcotrim left a comment

Choose a reason for hiding this comment

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

LGTM 👍

In my physical Windows machine the x64 worked as usual, the arm64 failed to run (also as expected I believe)

Image

In my Windows VM running on macOS, both versions work, with arm64 having a noticeable better performance running Studio and creating/starting sites.

Copy link
Contributor

@mokagio mokagio left a comment

Choose a reason for hiding this comment

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

Looking good 👍

If ($LastExitCode -ne 0) { Exit $LastExitCode }

Write-Host "--- :node: Building App for Windows ($BuildType)"
Write-Host "--- :node: Building App for Windows ($BuildType) - $Architecture"
Copy link
Contributor

Choose a reason for hiding this comment

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

Formatting nitpick:

Suggested change
Write-Host "--- :node: Building App for Windows ($BuildType) - $Architecture"
Write-Host "--- :node: Building App for Windows ($BuildType - $Architecture)"

Comment on lines -22 to +23
"make:windows-release": "powershell -File .buildkite/commands/build-for-windows.ps1 -BuildType release",
"make:windows-dev": "powershell -File .buildkite/commands/build-for-windows.ps1 -BuildType dev",
"make:windows-x64": "electron-vite build --outDir=dist && electron-forge make --arch=x64 --platform=win32",
"make:windows-arm64": "electron-vite build --outDir=dist && electron-forge make --arch=arm64 --platform=win32",
Copy link
Contributor

Choose a reason for hiding this comment

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

With this change, we look the npm run make:windows... command for dev vs release builds, exchanging it for x64 vs arm64.

Given the following check in the PS1 to build the app

# Run appropriate script based on build type
if ($BuildType -eq $BUILD_TYPE_DEV) {
Write-Host "Preparing dev build..."
node ./scripts/prepare-dev-build-version.mjs
If ($LastExitCode -ne 0) { Exit $LastExitCode }
$env:IS_DEV_BUILD="true"
} else {
Write-Host "Preparing release build..."
node ./scripts/confirm-tag-matches-version.mjs
If ($LastExitCode -ne 0) { Exit $LastExitCode }
}

I think this will result in calls to these commands building for release by default. This seems consistent with the other make:... and I think it's okay, but thought I'd to call it out just in case.

@wojtekn wojtekn force-pushed the add/windows-arm-build branch from b2980c1 to 6883410 Compare October 24, 2025 10:07
@AliSoftware
Copy link
Contributor

Note that currently our prepare_windows_host_for_app_distribution.ps1 helper, which is responsible—amongst other things—for installing tools like the Windows SDK and MSVC compiler, currently only installs the x86 compiler and not the ARM64 one.

So if you have any npm native dependencies that require native compilation (typically via node-gyb), it'll likely fail for arm64 due to not finding the compiler for that architecture.

@mokagio is currently working on pre-provisioning our Windows CI machines (custom AMI) so that the Windows SDK and MSVC tools would soon be pre-installed in those windows CI instances, not only to avoid having to install them from scratch on every job but also so that we pre-install the ARM64 compiler component too in addition to the x86 one.
But until then it's likely your ARM64 build will fail (unless you install the ARM64 compiler manually as part of your step command for that platform, but I'm not sure it's worth it going that route vs waiting for the new pre-provisioned AMI to be available?)

@wojtekn
Copy link
Contributor Author

wojtekn commented Oct 24, 2025

@AliSoftware, thanks for sharing those details.

As far as I understand, fs-ext is the only affected package, and node-gyp can cross-compile for arm64 when running on x64.

The build completes, and the resulting binary runs on ARM. Do you see anything that can still break?

@AliSoftware
Copy link
Contributor

node-gyp can cross-compile for arm64 when running on x64

even if the MSVC ARM64 compiler is not installed on the x64 machine doing the compilation?! Color me surprised 🤔

I wonder if the compilation passed for ARM64 this time just because of something like that dependency being available as a pre-compiled binary and not needing node-gyb to compile it locally (which would explain why it didn't need to have the ARM64 compiler installed)? 🤔

@wojtekn
Copy link
Contributor Author

wojtekn commented Oct 24, 2025

even if the MSVC ARM64 compiler is not installed on the x64 machine doing the compilation?! Color me surprised 🤔

I wonder if the compilation passed for ARM64 this time just because of something like that dependency being available as a pre-compiled binary and not needing node-gyb to compile it locally (which would explain why it didn't need to have the ARM64 compiler installed)? 🤔

I checked it more - downloaded the arm64 build from this branch, installed the app on ARM (Parallels on Mac), located fs_ext.node in app.asar.unpack, and it looks like it's x64:

% file ~/Downloads/fs_ext.node                    
fs_ext.node: PE32+ executable (DLL) (GUI) x86-64, for MS Windows

It would mean that build and compilation works just fine without further changes, but the arm64 build compiles native dependencies for x64, and it works well on Windows on arm64, thanks to x64 emulation? (It works already for the Intel binary, which works on arm64).

@wojtekn wojtekn merged commit 374b512 into trunk Oct 24, 2025
12 checks passed
@wojtekn wojtekn deleted the add/windows-arm-build branch October 24, 2025 14:17
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.

4 participants