Skip to content

chore: cross-compile release artifacts on Linux - #463

Open
Mohamed Mansour (mohamedmansour) wants to merge 6 commits into
microsoft:mainfrom
mohamedmansour:mohamedmansour-linux-cross-compilation-plan
Open

chore: cross-compile release artifacts on Linux#463
Mohamed Mansour (mohamedmansour) wants to merge 6 commits into
microsoft:mainfrom
mohamedmansour:mohamedmansour-linux-cross-compilation-plan

Conversation

@mohamedmansour

@mohamedmansour Mohamed Mansour (mohamedmansour) commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Why

Release builds currently depend on separate Linux, macOS, and Windows runners. Consolidating release artifact production onto Linux reduces runner complexity and makes the release toolchain reproducible while preserving the supported native distributions.

What changed

  • Adds host-aware publish-build backends: Cargo for Linux, cargo-xwin for Windows MSVC, and cargo-zigbuild for macOS ARM64.
  • Collapses Azure release production into one five-target Linux matrix and moves Windows PR builds onto Linux cross-compilation.
  • Secures macOS release cross-builds with pinned Zig/cargo-zigbuild versions, a checksum-verified Apple SDK secure file, and SDK-aware cache keys.
  • Drops Intel macOS from the release contract, including its npm package, NuGet RID package, Python wheel, standalone binary, CI leg, and documentation.

Runner tradeoff

Azure release artifact production is Linux-only. The GitHub macOS check (ARM64) job uses a native macos-14 runner because a Linux-hosted cargo check still executes target C build scripts such as zstd-sys; generic Linux cc rejects Apple -arch arguments before Rust checking can complete. Windows PR jobs remain Linux-hosted cross-builds.

Operational notes

Azure release builds require secure file WebUI-MacOSX-SDK.tar.xz and pipeline/library variable WEBUI_APPLE_SDK_SHA256. macOS and Windows artifacts are cross-linked and packaged on Linux; runtime qualification remains a separate step on matching hardware.

Validation

  • GitHub Actions: all PR checks passed before the latest main merge
  • cargo xtask check after merging origin/main and removing Thin LTO
  • dotnet build dotnet/Microsoft.WebUI.sln --configuration Release
  • pnpm install --frozen-lockfile --registry=https://registry.npmjs.org
  • pnpm --filter @microsoft/webui build
  • GitHub/Azure YAML parse and five-target release-contract checks

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…go-xwin env instead

maturin has no built-in --xwin flag; the CargoXwin backend's Windows
cross-build was passing --xwin to maturin build, which maturin's clap
parser rejects with "unexpected argument '--xwin' found". This masked
the earlier missing llvm-lib failure and only surfaced once that
preflight issue was fixed.

The correct mechanism is to export cargo-xwin's own environment (CC/CXX/AR,
linker, and Windows SDK/CRT include/lib paths from cargo xwin env --target
<triple>) onto the maturin process, since maturin invokes cargo internally
and has no xwin integration of its own.

- xtask/src/publish.rs: remove the invalid --xwin maturin arg; add
  cargo_xwin_env()/parse_cargo_xwin_env() to capture and export cargo-xwin's
  environment for the maturin wheel build when using the CargoXwin backend;
  update/add unit tests covering the parser and the backend-flag behavior.
- .github/workflows/pr.yml, .ado/pipelines/azure-pipelines-build.yml: correct
  stale comments that described the old (incorrect) --xwin flag mechanism.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

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.

Pull request overview

This PR consolidates Linux-hosted release builds, adds cross-compilation for Windows and macOS ARM64, and removes Intel macOS artifacts.

Changes:

  • Adds Cargo, cargo-xwin, and cargo-zigbuild backends with pinned macOS tooling.
  • Consolidates CI and Azure release builds into a five-target Linux matrix.
  • Updates packages, documentation, tests, and contracts for Intel macOS removal.

Reviewed changes

Copilot reviewed 21 out of 22 changed files in this pull request and generated 4 comments.

Show a summary per file
File Change / review status
xtask/src/windows_local.rs Enables Linux-hosted Windows cross-builds.
xtask/src/publish.rs Adds cross-build backends and release staging. Critical (2 votes): cargo-zigbuild receives an invalid build argument.
README.md Updates supported platforms and build instructions.
pnpm-lock.yaml Removes the Intel macOS package entry.
packages/webui/src/platform.ts Removes Intel macOS runtime resolution.
packages/webui/README.md Updates npm platform support.
packages/webui/package.json Removes the Intel macOS dependency.
packages/webui-darwin-x64/README.md Removes the unsupported Intel macOS package documentation.
packages/webui-darwin-x64/package.json Removes the unsupported Intel macOS package.
dotnet/src/Microsoft.WebUI/README.md Updates supported .NET platforms.
dotnet/src/Microsoft.WebUI/Microsoft.WebUI.csproj Removes the Intel macOS runtime reference.
dotnet/runtime/README.md Updates runtime package support.
dotnet/runtime/Microsoft.WebUI.Runtime.osx-x64/Microsoft.WebUI.Runtime.osx-x64.csproj Removes the Intel macOS runtime package.
dotnet/Microsoft.WebUI.sln Removes the deleted runtime project.
docs/guide/integrations/python.md Documents the five-wheel matrix. Nit (2 votes): installation text still claims every supported OS provides both x86_64 and ARM64 wheels.
DESIGN.md Updates release architecture and contracts.
crates/webui-python/tests/validate_release_targets.py Validates five wheel targets.
crates/webui-python/tests/test_package.py Tests release-target consistency.
.github/workflows/pr.yml Moves Windows builds to Linux cross-compilation. Moderate (2 votes): macOS validation does not exercise the Python wheel packaging path.
.github/actions/build/action.yml Simplifies shared Linux build setup.
.ado/pipelines/azure-pipelines-cd.yml Updates release artifact publication.
.ado/pipelines/azure-pipelines-build.yml Adds the Linux five-target release matrix. Critical (1 vote): secure-file archive contents are extracted before containment validation, allowing unsafe archive entries to write outside the extraction directory.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file
Suppressed comments (6)

.ado/pipelines/azure-pipelines-build.yml:405

  • This full publish-build invocation also creates the Windows wheel through maturin, but the task does not pass the release commit's SOURCE_DATE_EPOCH. As a result, wheel entry mtimes vary between runs even though the pipeline resolves and uses that epoch for Linux wheels and final packaging. Export SOURCE_DATE_EPOCH: $(sourceDateEpoch) in this task's environment.
          cargo +1.93 xtask publish-build \
            --target "$TARGET_TRIPLE" \
            --profile release \
            --output "$BUILD_ARTIFACT_STAGING_DIRECTORY/$ARTIFACT_NAME"

.ado/pipelines/azure-pipelines-build.yml:468

  • The macOS publish-build leg also runs maturin to produce the release wheel, but unlike the Linux wheel and assembly steps it does not receive SOURCE_DATE_EPOCH. This makes the macOS wheel's archive timestamps depend on the build time and defeats the pipeline's reproducible-artifact setup; pass SOURCE_DATE_EPOCH: $(sourceDateEpoch) in this task's environment.
          cargo +1.93 xtask publish-build \
            --target "$TARGET_TRIPLE" \
            --profile release \
            --output "$BUILD_ARTIFACT_STAGING_DIRECTORY/$ARTIFACT_NAME"

.ado/pipelines/azure-pipelines-build.yml:465

  • The +1.93 selector applies only to the outer cargo xtask process. publish-build then starts maturin, which starts a separate plain cargo for the wheel; because this job never exports RUSTUP_TOOLCHAIN, that nested build uses the agent's default toolchain rather than the pinned one. This makes the Windows/macOS artifacts depend on hosted-agent state and can diverge from the native build. Export RUSTUP_TOOLCHAIN=1.93 (or otherwise pin the cargo used by maturin) in both cross-build legs.
          cargo +1.93 xtask publish-build \

README.md:42

  • The five-wheel contract removes the macOS x86_64 wheel, but docs/guide/installation.md:123-124 still tells users that prebuilt macOS wheels exist for both x86_64 and ARM64. Update that user-facing installation page in this PR so it does not advertise a removed artifact.
`microsoft-webui` is a native PyO3 binding (not `ctypes`) for CPython 3.11+, distributed as prebuilt x86_64/ARM64 wheels for Windows and manylinux plus an ARM64 wheel for macOS, alongside one sdist. It is runtime-only: render `webui build` output, but don't compile templates from Python.

xtask/src/publish.rs:135

  • This new backend documentation says cargo-zigbuild cross-compiles “the two Apple Darwin targets,” but PLATFORMS now contains only aarch64-apple-darwin after Intel macOS was removed. Update the description to refer to the supported Apple target (or target family) so the backend contract is not misstated.
    /// `cargo zigbuild`, cross-compiles the two Apple Darwin targets using
    /// Zig as the C/Obj-C cross linker.
    CargoZigbuild,

xtask/src/publish.rs:97

  • Adding the five-target contract leaves the validate_python_release_artifacts doc comment at line 1868 claiming there are six wheels. Please update that comment while changing the platform list; otherwise the source documentation contradicts the validation behavior and will mislead future edits.
        macos_deployment_target: Some("11.0"),

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

sdk_extract_dir="$AGENT_TEMP_DIRECTORY/apple-sdk"
rm -rf "$sdk_extract_dir"
mkdir -p "$sdk_extract_dir"
tar -xf "$SECURE_FILE_PATH" -C "$sdk_extract_dir"
Comment thread .github/workflows/pr.yml
Comment on lines +111 to +115
cargo check --target ${{ matrix.platform.target }} \
-p microsoft-webui-cli \
-p microsoft-webui-ffi \
-p microsoft-webui-node \
-p microsoft-webui-python
Comment on lines +262 to +263
build matrix. v1 ships five wheels: x86_64 and ARM64 for Windows and manylinux,
plus ARM64 for macOS, alongside one `sdist`.
Comment thread xtask/src/publish.rs
if let Some(subcommand) = backend.subcommand() {
args.push(subcommand);
}
args.push("build");
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