Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Packaging] Support x86 and x64 MSI builds #26640

Merged
merged 8 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,12 @@ jobs:

- job: BuildWindowsMSI
displayName: Build Windows MSI
strategy:
matrix:
x86:
Platform: x86
x64:
Platform: x64

dependsOn: ExtractMetadata
condition: succeeded()
Expand All @@ -200,7 +206,8 @@ jobs:


- script: |
set /p CLI_VERSION=<$(System.ArtifactsDirectory)/metadata/version
set ARCH=$(Platform)
set CLI_VERSION=<$(System.ArtifactsDirectory)/metadata/version
heaths marked this conversation as resolved.
Show resolved Hide resolved
set

build_scripts/windows/scripts/build.cmd
Expand All @@ -215,10 +222,16 @@ jobs:
displayName: 'Publish Artifact: MSI'
inputs:
TargetPath: 'build_scripts/windows/out/'
ArtifactName: msi
ArtifactName: msi-$(Platform)

- job: TestWindowsMSI
displayName: Test Windows MSI
strategy:
matrix:
x86:
Platform: x86
x64:
Platform: x64

dependsOn: BuildWindowsMSI
condition: and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI', 'Manual', 'Schedule'))
Expand All @@ -235,7 +248,7 @@ jobs:
displayName: 'Download Build Artifacts'
inputs:
TargetPath: '$(Build.ArtifactStagingDirectory)/msi'
artifactName: msi
artifactName: msi-$(Platform)

- task: PowerShell@2
displayName: Install and Load CLI
Expand Down
53 changes: 45 additions & 8 deletions build_scripts/windows/Product.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,55 @@
<?define ProductAuthor = "Microsoft Corporation" ?>
<?define ProductResources = ".\resources\" ?>

<?if $(var.Platform) = "x64" ?>
<?define AzureCliRegistryGuid = "90b6367e-4e15-4313-af33-a0ef459a56fc" ?>
<?define AzureCliSystemPathGuid = "12c8f0dc-0475-4814-93b6-fcbe82e89532" ?>
<?define AzureCliVersionGuid = "4df4882f-4604-4cdc-a0b4-bffc4b8c5967" ?>
<?define ProgramFilesFolder = "ProgramFiles64Folder" ?>
<?define RemoveAzureCLIFolderGuid = "7ce8a521-7429-4ded-9cce-0948e393cc83" ?>
<?define RemoveCLIFolderGuid = "59fb416c-91d0-49aa-a185-d4330c435a93" ?>
<?define UpgradeCode = "90762fec-9554-4729-a107-c6a8ea316698" ?>
heaths marked this conversation as resolved.
Show resolved Hide resolved

<?elseif $(var.Platform) = "x86" ?>
<?define AzureCliRegistryGuid = "BDEEE50E-70D3-4990-BFF9-FCF8114AA701" ?>
<?define AzureCliSystemPathGuid = "3B60CA67-DB92-465A-BC96-3CA6CAEFF41B" ?>
<?define AzureCliVersionGuid = "A5647E93-02B7-4CED-802A-DDD7416E0231" ?>
<?define ProgramFilesFolder = "ProgramFilesFolder" ?>
<?define RemoveAzureCLIFolderGuid = "6AF97701-6A7A-4292-95D6-ED34CD4C97C0" ?>
<?define RemoveCLIFolderGuid = "24DA394D-B03D-4623-A0D9-852DB51EF9F4" ?>
<?define UpgradeCode = "dff82af0-3f95-4ac9-8efd-948604fdb028" ?>

<?else ?>
<?error Unsupported platform "$(var.Platform)" ?>
<?endif ?>

<Product Id="*"
Name="$(var.ProductName)"
Copy link
Member

@jiasli jiasli Jul 19, 2023

Choose a reason for hiding this comment

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

Some programs attach x86 and x64 to the product name. Some don't:

image

  1. Shall we do the same and change $(var.ProductName) to include $(var.Platform) too?
  2. Shall we allow 32-bit and 64-bit MSIs to be installed side-by-side? I don't feel this is necessary as there can be only one active az.cmd on PATH.

Copy link
Member Author

Choose a reason for hiding this comment

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

Shall we do the same and change $(var.ProductName) too?

Sure I can do that.

Shall we allow 32-bit and 64-bit MSIs to be installed side-by-side? I don't feel this is necessary as there can be only one active az.cmd on PATH.

I don't recommend it. 1) what purpose does it serve? These are EXEs where, unlike libraries e.g., DLLs, architecture doesn't typically matter. 32- and 64-bit code can call any architecture of an EXE. It would be a UX problem because,

  1. Depending on the ordering of updates to PATH, customer will call the first or last architecture installed. It's not deterministic.
  2. Every time there's an update, the ~15-20 minute upgrade of 1 MSI will now be doubled.

And all that for what reason? Again, it's an EXE (well, effectively - an executable, more specifically) so architecture doesn't matter. SxS just unnecessarily complicates things in this case.

Copy link
Member

@jiasli jiasli Jul 20, 2023

Choose a reason for hiding this comment

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

Microsoft products usually use (x86) and (x64). Python uses (32-bit) and (64-bit). I an not sure which convention we should follow.

image

Language="1033"
Version="$(var.ProductVersion)"
Manufacturer="$(var.ProductAuthor)"
UpgradeCode="dff82af0-3f95-4ac9-8efd-948604fdb028">
UpgradeCode="$(var.UpgradeCode)">

<Package InstallerVersion="200"
Compressed="yes"
InstallScope="perMachine" />

<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." Schedule="afterInstallExecute" />
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion Property="WIX_UPGRADE_DETECTED" Maximum="$(var.ProductVersion)" IncludeMinimum="no" MigrateFeatures="yes" />
<UpgradeVersion Property="WIX_DOWNGRADE_DETECTED" Minimum="$(var.ProductVersion)" IncludeMinimum="no" OnlyDetect="yes" />
</Upgrade>
<Condition Message="A newer version of [ProductName] is already installed.">NOT WIX_DOWNGRADE_DETECTED</Condition>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallExecute" />
</InstallExecuteSequence>

<!-- New product architectures should upgrade the original x86 product - even of the same version. -->
<?if $(var.UpgradeCode) != "dff82af0-3f95-4ac9-8efd-948604fdb028" ?>
<Upgrade Id="dff82af0-3f95-4ac9-8efd-948604fdb028">
<UpgradeVersion Property="WIX_UPGRADE_DETECTED" Maximum="$(var.ProductVersion)" IncludeMinimum="yes" MigrateFeatures="yes" />
<UpgradeVersion Property="WIX_DOWNGRADE_DETECTED" Minimum="$(var.ProductVersion)" IncludeMinimum="no" OnlyDetect="yes" />
</Upgrade>
heaths marked this conversation as resolved.
Show resolved Hide resolved
<?endif ?>

<Media Id="1" Cabinet="WindowsAzureCLI.cab" EmbedCab="yes" CompressionLevel="high" />

Expand Down Expand Up @@ -61,7 +98,7 @@

<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="$(var.ProgramFilesFolder)">
<Directory Id="SDKFOLDER" Name="Microsoft SDKs">
<Directory Id="AZUREFOLDER" Name="Azure">
<Directory Id="AZURECLIFOLDER" Name="CLI2">
Expand All @@ -78,17 +115,17 @@
<ComponentGroup Id="AzureCliSettingsGroup">
<Component Id="RemoveCLIFolder"
Directory="DynamicCliDir"
Guid="{24DA394D-B03D-4623-A0D9-852DB51EF9F4}">
Guid="$(var.RemoveCLIFolderGuid)">
<RemoveFolder Id="DynamicCliDir" On="uninstall" />
</Component>
<Component Id="RemoveAzureCLIFolder"
Directory="AZURECLIFOLDER"
Guid="{6AF97701-6A7A-4292-95D6-ED34CD4C97C0}">
Guid="$(var.RemoveAzureCLIFolderGuid)">
<RemoveFolder Id="AZURECLIFOLDER" On="uninstall" />
</Component>
<Component Id="AzureCliSystemPath"
Directory="DynamicCliDir"
Guid="{3B60CA67-DB92-465A-BC96-3CA6CAEFF41B}">
Guid="$(var.AzureCliSystemPathGuid)">
<Environment Id="AzureCliAddedToPATH"
Name="PATH"
Value="[DynamicCliDir]wbin"
Expand All @@ -100,7 +137,7 @@
</Component>
<Component Id="AzureCliRegistry"
Directory="DynamicCliDir"
Guid="{BDEEE50E-70D3-4990-BFF9-FCF8114AA701}">
Guid="$(var.AzureCliRegistryGuid)">
<RegistryValue Root="HKCU"
Key="Software\Microsoft\$(var.ProductName)"
Name="installed"
Expand All @@ -110,7 +147,7 @@
</Component>
<Component Id="AzureCliVersion"
Directory="DynamicCliDir"
Guid="{A5647E93-02B7-4CED-802A-DDD7416E0231}">
Guid="$(var.AzureCliVersionGuid)">
<RegistryValue Root="HKLM"
Key="Software\Microsoft\$(var.ProductName)"
Name="version"
Expand Down
6 changes: 6 additions & 0 deletions build_scripts/windows/azure-cli.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9A0DC66D-3186-4EE4-B471-6C0F1DD6E159}.Debug|x86.ActiveCfg = Debug|x86
{9A0DC66D-3186-4EE4-B471-6C0F1DD6E159}.Debug|x86.Build.0 = Debug|x86
{9A0DC66D-3186-4EE4-B471-6C0F1DD6E159}.Release|x86.ActiveCfg = Release|x86
{9A0DC66D-3186-4EE4-B471-6C0F1DD6E159}.Release|x86.Build.0 = Release|x86
{9A0DC66D-3186-4EE4-B471-6C0F1DD6E159}.Debug|x64.ActiveCfg = Debug|x64
{9A0DC66D-3186-4EE4-B471-6C0F1DD6E159}.Debug|x64.Build.0 = Debug|x64
{9A0DC66D-3186-4EE4-B471-6C0F1DD6E159}.Release|x64.ActiveCfg = Release|x64
{9A0DC66D-3186-4EE4-B471-6C0F1DD6E159}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
28 changes: 19 additions & 9 deletions build_scripts/windows/azure-cli.wixproj
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Local WiX -->
<PropertyGroup>
<LocalWixRoot>artifacts\wix\</LocalWixRoot>
<WixToolPath>$(LocalWixRoot)</WixToolPath>
<WixTargetsPath>$(WixToolPath)Wix.targets</WixTargetsPath>
<WixTasksPath>wixtasks.dll</WixTasksPath>
heaths marked this conversation as resolved.
Show resolved Hide resolved
<AzureCliSource>artifacts\cli</AzureCliSource>
<LinkerAdditionalOptions>-fv</LinkerAdditionalOptions>
</PropertyGroup>
<!-- Project -->
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
Expand All @@ -21,6 +12,15 @@
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
</PropertyGroup>
<!-- Local WiX -->
<PropertyGroup>
<LocalWixRoot>artifacts\wix</LocalWixRoot>
<WixToolPath>$(LocalWixRoot)</WixToolPath>
<WixTargetsPath Condition="Exists('$(WixToolPath)\Wix.targets')">$(WixToolPath)\Wix.targets</WixTargetsPath>
<WixTasksPath Condition="Exists('$(WixToolPath)\wixtasks.dll')">wixtasks.dll</WixTasksPath>
heaths marked this conversation as resolved.
Show resolved Hide resolved
heaths marked this conversation as resolved.
Show resolved Hide resolved
heaths marked this conversation as resolved.
Show resolved Hide resolved
<AzureCliSource>artifacts\cli</AzureCliSource>
<LinkerAdditionalOptions>-fv</LinkerAdditionalOptions>
</PropertyGroup>
heaths marked this conversation as resolved.
Show resolved Hide resolved
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>out\$(Configuration)\</OutputPath>
<IntermediateOutputPath>out\obj\$(Configuration)\</IntermediateOutputPath>
Expand All @@ -31,6 +31,16 @@
<IntermediateOutputPath>out\obj\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>AzureCliSource=$(AzureCliSource)</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<OutputPath>out\$(Configuration)\</OutputPath>
<IntermediateOutputPath>out\obj\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>Debug;AzureCliSource=$(AzureCliSource)</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
<OutputPath>out\</OutputPath>
<IntermediateOutputPath>out\obj\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>AzureCliSource=$(AzureCliSource)</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Compile Include="out\azure-cli.wxs">
<Link>azure-cli.wxs</Link>
Expand Down
21 changes: 18 additions & 3 deletions build_scripts/windows/scripts/build.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,22 @@ if "%CLI_VERSION%"=="" (
echo Please set the CLI_VERSION environment variable, e.g. 2.0.13
goto ERROR
)

if "%ARCH%"=="" (
set ARCH=x86
)
if "%ARCH%"=="x86" (
set PYTHON_ARCH=win32
) else if "%ARCH%"=="x64" (
set PYTHON_ARCH=amd64
) else (
echo Please set ARCH to "x86" or "x64"
goto ERROR
)
set PYTHON_VERSION=3.10.10

set WIX_DOWNLOAD_URL="https://azurecliprod.blob.core.windows.net/msi/wix310-binaries-mirror.zip"
set PYTHON_DOWNLOAD_URL="https://www.python.org/ftp/python/%PYTHON_VERSION%/python-%PYTHON_VERSION%-embed-win32.zip"
set PYTHON_DOWNLOAD_URL="https://www.python.org/ftp/python/%PYTHON_VERSION%/python-%PYTHON_VERSION%-embed-%PYTHON_ARCH%.zip"

REM https://pip.pypa.io/en/stable/installation/#get-pip-py
set GET_PIP_DOWNLOAD_URL="https://bootstrap.pypa.io/get-pip.py"
Expand All @@ -34,7 +46,10 @@ set BUILDING_DIR=%ARTIFACTS_DIR%\cli
set WIX_DIR=%ARTIFACTS_DIR%\wix
set PYTHON_DIR=%ARTIFACTS_DIR%\Python

set REPO_ROOT=%~dp0..\..\..
REM Get the absolute directory since we pushd into different levels of subdirectories.
PUSHD %~dp0..\..\..
SET REPO_ROOT=%CD%
POPD
heaths marked this conversation as resolved.
Show resolved Hide resolved

REM reset working folders
if exist %BUILDING_DIR% rmdir /s /q %BUILDING_DIR%
Expand Down Expand Up @@ -181,7 +196,7 @@ popd
if %errorlevel% neq 0 goto ERROR

echo Building MSI...
msbuild /t:rebuild /p:Configuration=Release %REPO_ROOT%\build_scripts\windows\azure-cli.wixproj
msbuild /t:rebuild /p:Configuration=Release /p:Platform=%ARCH% %REPO_ROOT%\build_scripts\windows\azure-cli.wixproj

if %errorlevel% neq 0 goto ERROR

Expand Down