Skip to content

{Packaging} Migrate Windows MSI build to WiX v7 - #34273

Open
Dennis Ameling (dennisameling) wants to merge 2 commits into
Azure:devfrom
dennisameling:wix-v7-upstream
Open

Dennis Ameling (dennisameling) wants to merge 2 commits into
Azure:devfrom
dennisameling:wix-v7-upstream

Conversation

@dennisameling

@dennisameling Dennis Ameling (dennisameling) commented Oct 25, 2026 •

Copy link
Copy Markdown

🤖 PR Validation — ️✔️ All clear

Breaking Changes Tests Suppressions
️✔️ None ️✔️ 130/130 ️✔️ None

Related command

N/A (Windows MSI packaging)

Description

Close #34272

Migrates the Windows MSI build from WiX 3.10, which is out of community support, to WiX v7. It also removes WiX v3 as a blocker for native Windows arm64 MSIs (#29317).

  • azure-cli.wixproj: now an SDK-style project (WixToolset.Sdk/7.0.0, with the UI and Util extensions as package references). WiX is restored from NuGet, so build.cmd builds with dotnet build and no longer downloads WiX. The .NET Framework 3.5 requirement and the hard-coded VS 2022 MSBuild path are gone too.
  • Product.wxs: converted to the v4+ schema. The authoring is otherwise unchanged: same UpgradeCodes, component GUIDs, install layout, upgrade and downgrade logic, PATH and registry entries, and UI. heat.exe is replaced by WiX's <Files Include="artifacts\cli\**" /> harvesting.
  • azure-pipelines.yml:
    • UseDotNet@2 (.NET 8 SDK) in the MSI build job, as sync-alias.yml already does.
    • The TestMsiInstallation job runs the new test_msi_upgrade.ps1 first. It installs the latest released MSI older than the artifact (2.90.0 for a 2.91.0 build), upgrades it with the artifact MSI, and checks that exactly one Azure CLI install of the artifact version remains.
  • Also updated: the project type GUID in azure-cli.sln (the SDK-style WiX project type) and the prerequisites in build_scripts/windows/README.md.

Important

WiX v7 requires accepting the Open Source Maintenance Fee (OSMF) EULA, and organizations with more than $10k annual revenue are expected to sponsor the project. This PR deliberately doesn't accept it on the team's behalf. Until a pipeline variable AcceptEula is set to wix7 (MSBuild reads it from the environment), the "Build Windows MSI" job fails with WIX7015. If the team prefers not to accept it, the authoring also works with WiX v6 (same OSMF terms, just not enforced) or v5 (no OSMF, but out of support) by changing the SDK version.

Other open points for the team:

  • Can pool-windows-2022 restore WixToolset.* packages from nuget.org, or does it need a feed?
  • Signing: the MSI is unsigned at build time, as before, so downstream signing shouldn't change. A release-pipeline dry run would confirm it.

Does upgrading from existing installs work?

Yes. The UpgradeCodes and the Upgrade, LaunchCondition and InstallExecuteSequence tables are unchanged. The old version is still fully removed before the new one is installed (RemoveExistingProducts before InstallInitialize), so the different component layout that <Files> produces doesn't matter. Downgrades are still blocked.

Verified in CI (fork run, windows-latest), for both x86 and x64:

  1. The runner's preinstalled official CLI (built with WiX v3) was uninstalled.
  2. Official 2.90.0 (WiX 3.10) was installed, then upgraded with this PR's 2.91.0 MSI using test_msi_upgrade.ps1. Exactly one Microsoft Azure CLI (32-bit|64-bit) 2.91.0 entry remained.
  3. test_msi_installation.ps1 passed: version check, az extension add -n account, and az self-test (CLI self-test completed: OK).
  4. Uninstall removed the product, the PATH entry and all installed files.

Comparison with the official 2.91.0 x64 MSI: Upgrade, LaunchCondition, Environment, Registry, Feature and InstallExecuteSequence match. The only differences come from WiX v4+ itself:

  • the PATH broadcast custom action is now per architecture (Wix4BroadcastEnvironmentChange_X64);
  • WixUI_Minimal no longer has a "Print EULA" action;
  • folder-only components get CreateFolder rows.

8.3 short names are still generated, and wix msi validate (ICE) is clean. The MSI is ~13 MB smaller (57 vs 70 MB) because WiX v7 packs the CAB into fewer, larger folders. The compression is the same (LZX:21) and no content is missing.

A pre-existing issue, not caused by this PR: uninstalling leaves the runtime-generated pip\**\__pycache__ files behind (319 files), with WiX v3 and v7 builds alike. pip is shipped as .py sources, so running it creates __pycache__ files the MSI doesn't know about.

Testing Guide

Prerequisites: the .NET SDK 8 or later, and the OSMF EULA accepted (see above).

  1. Build the MSI. This also works on a Windows arm64 machine, since WiX v7 runs natively there.

    set CLI_VERSION=2.91.0
    set ARCH=x64
    set TARGET=msi
    set AcceptEula=wix7
    build_scripts\windows\scripts\build.cmd
  2. Test upgrading from the previous WiX v3-built release, in an elevated Windows PowerShell on a test machine or VM. The script uninstalls any Azure CLI already on the machine, installs the previous release, then upgrades it:

    New-Item -ItemType Directory -Force test\msi, test\metadata
    Copy-Item "build_scripts\windows\out\Microsoft Azure CLI.msi" test\msi\
    Set-Content test\metadata\version 2.91.0
    $env:SYSTEM_ARTIFACTSDIRECTORY = "$PWD\test"; $env:PLATFORM = 'x64'
    build_scripts\windows\scripts\test_msi_upgrade.ps1

    Or by hand:

  3. Then run build_scripts\windows\scripts\test_msi_installation.ps1 with the same environment variables for the existing fresh-install test.

In Azure Pipelines, the TestMsiInstallation job runs both scripts (under its existing condition: CI, manual and scheduled builds).

History Notes

N/A, not customer-facing. Installs and upgrades behave as before.


This checklist is used to make sure that common guidelines for a pull request are followed.

🤖 Generated with Claude Code

WiX v3 is out of support, needs .NET Framework 3.5 and was downloaded
from a blob mirror. Move to WiX v7 as an SDK-style project restored from
NuGet and built with `dotnet build`:

- Convert Product.wxs to the v4+ schema. UpgradeCodes, component GUIDs,
  layout and upgrade logic are unchanged.
- Harvest the CLI folder with the Files element instead of heat.exe.
- Drop the WiX download and the hard-coded MSBuild path from build.cmd.
- Install the .NET 8 SDK in the MSI build job.

WiX v7 requires accepting its OSMF EULA (https://wixtoolset.org/osmf/),
e.g. by setting AcceptEula=wix7. This change doesn't accept it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add test_msi_upgrade.ps1 to the TestMsiInstallation job: it installs the
latest released MSI older than the artifact, upgrades it with the
artifact MSI and checks that exactly one Azure CLI install of the
artifact version remains.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 25, 2026 13:53
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@microsoft-github-policy-service microsoft-github-policy-service Bot added the customer-reported Issues that are reported by GitHub users external to the Azure organization. label Oct 25, 2026
@microsoft-github-policy-service

Copy link
Copy Markdown
Contributor

Thank you for your contribution Dennis Ameling (@dennisameling)! We will review the pull request and get back to you soon.

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.

🔵 Needs a closer look

Team EULA acceptance and production-pipeline validation of NuGet restore and downstream signing remain outstanding.

No open issues 🎉

What changed in this PR

Migrates Azure CLI’s Windows MSI packaging from unsupported WiX v3 to WiX v7, modernizing the build tooling while preserving installer behavior and removing a blocker for native Windows arm64 packaging.

Changes:

  • Replaces downloaded WiX binaries and legacy MSBuild tooling with an SDK-style project built through dotnet build.
  • Converts installer authoring to the v4+ schema and replaces heat.exe with built-in file harvesting.
  • Adds previous-release upgrade testing to CI and documents the new prerequisites and EULA requirement.
File Description
build_scripts/​windows/​scripts/​test_msi_upgrade.ps1 Adds previous-release installation, upgrade, and version checks.
build_scripts/​windows/​scripts/​build.cmd Switches MSI builds to dotnet build and removes legacy WiX setup.
build_scripts/​windows/​README.md Documents .NET SDK and WiX EULA prerequisites.
build_scripts/​windows/​Product.wxs Migrates installer schema, extensions, and file harvesting.
build_scripts/​windows/​azure-cli.wixproj Adopts the WiX v7 SDK and NuGet extension references.
build_scripts/​windows/​azure-cli.sln Updates the WiX project type GUID.
azure-pipelines.yml Installs the .NET SDK and runs the upgrade test.

Review effort: Balanced

@x-engineering-agent

Copy link
Copy Markdown
Contributor

Hi Dennis Ameling (@dennisameling),
Since the current milestone time is less than 7 days, this pr will be reviewed in the next milestone.

@yonzhan

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

act-platform-engineering-squad customer-reported Issues that are reported by GitHub users external to the Azure organization. Installation Packaging

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate the Windows MSI build from WiX v3 to WiX v7

6 participants