Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
72 changes: 71 additions & 1 deletion azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ jobs:

- script: |
set ARCH=$(Platform)
set TARGET=msi
set /p CLI_VERSION=<$(System.ArtifactsDirectory)/metadata/version
set

Expand All @@ -228,6 +229,45 @@ jobs:
TargetPath: 'build_scripts/windows/out/'
ArtifactName: msi-$(Platform)

- job: BuildWindowsZIP
displayName: Build Windows ZIP
strategy:
matrix:
x64:
Platform: x64
Comment on lines +235 to +237
Copy link
Member

Choose a reason for hiding this comment

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

I agree we should only release 64-bit ZIP as 32-bit is on its way to deprecation.


dependsOn: ExtractMetadata
condition: succeeded()
pool:
name: ${{ variables.windows_pool }}
steps:
- task: DownloadPipelineArtifact@1
displayName: 'Download Build Artifacts'
inputs:
TargetPath: '$(Build.ArtifactStagingDirectory)/metadata'
artifactName: metadata


- script: |
set ARCH=$(Platform)
set TARGET=zip
set /p CLI_VERSION=<$(System.ArtifactsDirectory)/metadata/version
set

build_scripts/windows/scripts/build.cmd
displayName: 'Build Windows ZIP'

- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
displayName: 'SBOM'
inputs:
BuildDropPath: 'build_scripts/windows/out/'

- task: PublishPipelineArtifact@0
displayName: 'Publish Artifact: ZIP'
inputs:
TargetPath: 'build_scripts/windows/out/'
ArtifactName: zip-$(Platform)

- job: TestMsiInstallation
displayName: Test MSI Installation
strategy:
Expand Down Expand Up @@ -259,6 +299,34 @@ jobs:
inputs:
filePath: build_scripts\windows\scripts\test_msi_installation.ps1

- job: TestZipInstallation
displayName: Test ZIP Installation
dependsOn: BuildWindowsZIP
strategy:
matrix:
x64:
Platform: x64
condition: and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI', 'Manual', 'Schedule'))
pool:
name: ${{ variables.windows_pool }}
steps:
- task: DownloadPipelineArtifact@1
displayName: 'Download Build Artifacts'
inputs:
TargetPath: '$(Build.ArtifactStagingDirectory)/metadata'
artifactName: metadata

- task: DownloadPipelineArtifact@1
displayName: 'Download Build Artifacts'
inputs:
TargetPath: '$(Build.ArtifactStagingDirectory)/zip'
artifactName: zip-$(Platform)

- task: PowerShell@2
displayName: Expand and Load CLI
inputs:
filePath: build_scripts\windows\scripts\test_zip_installation.ps1

- job: BuildDockerImageAlpine
displayName: Build Docker Image Alpine
strategy:
Expand Down Expand Up @@ -302,7 +370,7 @@ jobs:
${{ each arch in parameters.architectures }}:
${{ arch.name }}:
pool: ${{ arch.pool }}
artifactName: docker-${{ arch.name }}
artifactName: docker-${{ arch.value }}
pool:
name: $(pool)
steps:
Expand Down Expand Up @@ -1160,6 +1228,8 @@ jobs:
- VerifyVersions
- BuildWindowsMSI
- TestMsiInstallation
- BuildWindowsZIP
- TestZipInstallation
- BuildDockerImageAlpine
- TestDockerImageAlpine
- BuildDockerImageAzureLinux
Expand Down
12 changes: 12 additions & 0 deletions build_scripts/windows/scripts/az_zip.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
::
:: Microsoft Azure CLI - Windows Installer - Author file components script
:: Copyright (C) Microsoft Corporation. All Rights Reserved.
::

@IF EXIST "%~dp0\..\python.exe" (
SET AZ_INSTALLER=ZIP
"%~dp0\..\python.exe" -IBm azure.cli %*
) ELSE (
echo Failed to load python executable.
exit /b 1
)
70 changes: 45 additions & 25 deletions build_scripts/windows/scripts/build.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@ if "%CLI_VERSION%"=="" (
echo Please set the CLI_VERSION environment variable, e.g. 2.0.13
goto ERROR
)

@REM ARCH can be x86 or x64
if "%ARCH%"=="" (
set ARCH=x86
)
@REM TARGET can be msi or zip
if "%TARGET%"=="" (
set TARGET=msi
)

if "%ARCH%"=="x86" (
set PYTHON_ARCH=win32
) else if "%ARCH%"=="x64" (
Expand Down Expand Up @@ -71,20 +76,22 @@ if exist %REPO_ROOT%\privates (
copy %REPO_ROOT%\privates\*.whl %TEMP_SCRATCH_FOLDER%
)

REM ensure wix is available
if exist %WIX_DIR% (
echo Using existing Wix at %WIX_DIR%
)
if not exist %WIX_DIR% (
mkdir %WIX_DIR%
pushd %WIX_DIR%
echo Downloading Wix.
curl --output wix-archive.zip %WIX_DOWNLOAD_URL%
unzip wix-archive.zip
if %errorlevel% neq 0 goto ERROR
del wix-archive.zip
echo Wix downloaded and extracted successfully.
popd
if "%TARGET%" == "msi" (
REM ensure wix is available
if exist %WIX_DIR% (
echo Using existing Wix at %WIX_DIR%
)
if not exist %WIX_DIR% (
mkdir %WIX_DIR%
pushd %WIX_DIR%
echo Downloading Wix.
curl --output wix-archive.zip %WIX_DOWNLOAD_URL%
unzip wix-archive.zip
if %errorlevel% neq 0 goto ERROR
del wix-archive.zip
echo Wix downloaded and extracted successfully.
popd
)
)

REM ensure Python is available
Expand Down Expand Up @@ -122,7 +129,6 @@ set PYTHON_EXE=%PYTHON_DIR%\python.exe
robocopy %PYTHON_DIR% %BUILDING_DIR% /s /NFL /NDL

set CLI_SRC=%REPO_ROOT%\src
%BUILDING_DIR%\python.exe -m pip install --no-warn-script-location --force-reinstall pycparser==2.18
Copy link
Contributor Author

Choose a reason for hiding this comment

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

pycparser==2.19 is installed later.

Copy link
Member

Choose a reason for hiding this comment

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

Where?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

%BUILDING_DIR%\python.exe -m pip install --no-warn-script-location --requirement %CLI_SRC%\azure-cli\requirements.py3.windows.txt

Copy link
Member

Choose a reason for hiding this comment

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

Also see #27196 (comment)

for %%a in (%CLI_SRC%\azure-cli %CLI_SRC%\azure-cli-core %CLI_SRC%\azure-cli-telemetry) do (
pushd %%a
%BUILDING_DIR%\python.exe -m pip install --no-warn-script-location --no-cache-dir --no-deps .
Expand All @@ -137,18 +143,27 @@ if %errorlevel% neq 0 goto ERROR

pushd %BUILDING_DIR%
%BUILDING_DIR%\python.exe %REPO_ROOT%\scripts\compact_aaz.py
if %errorlevel% neq 0 goto ERROR
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Check the error code of last command.
compact_aaz.py may fails because of #27923

%BUILDING_DIR%\python.exe %~dp0\patch_models_v2.py
if %errorlevel% neq 0 goto ERROR
%BUILDING_DIR%\python.exe %REPO_ROOT%\scripts\trim_sdk.py
if %errorlevel% neq 0 goto ERROR
popd

REM Remove pywin32 help file to reduce size.
del %BUILDING_DIR%\Lib\site-packages\PyWin32.chm

echo Creating the wbin (Windows binaries) folder that will be added to the path...
mkdir %BUILDING_DIR%\wbin
copy %REPO_ROOT%\build_scripts\windows\scripts\az.cmd %BUILDING_DIR%\wbin\
copy %REPO_ROOT%\build_scripts\windows\scripts\azps.ps1 %BUILDING_DIR%\wbin\
copy %REPO_ROOT%\build_scripts\windows\scripts\az %BUILDING_DIR%\wbin\
if "%TARGET%"=="msi" (
REM Creating the wbin (Windows binaries) folder that will be added to the path...
Copy link
Contributor Author

@bebound bebound Jan 23, 2024

Choose a reason for hiding this comment

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

If I use echo instead of REM, the (Windows binaries) folder will be parsed and folder was unexpected at this time. error will be raised. It seems there are some special rules when parentheses block is executed.
Repro script:

echo () ok
if 'kk'=='kk' (
    echo () ok2
)
() ok
ok2 was unexpected at this time.

Copy link
Member

Choose a reason for hiding this comment

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

If you truly need to use echo, you may quote the sentence:

echo "Creating the wbin (Windows binaries) folder that will be added to the path..."

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Exactly. (Generally, echo is able to print multiple word without the quote: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/echo)

In this instance, since the line functions more as a comment, so I changed it to REM.

mkdir %BUILDING_DIR%\wbin
copy %REPO_ROOT%\build_scripts\windows\scripts\az_msi.cmd %BUILDING_DIR%\wbin\az.cmd
copy %REPO_ROOT%\build_scripts\windows\scripts\azps.ps1 %BUILDING_DIR%\wbin\
copy %REPO_ROOT%\build_scripts\windows\scripts\az %BUILDING_DIR%\wbin\
) else (
REM Creating the bin folder that will be added to the path...
mkdir %BUILDING_DIR%\bin
copy %REPO_ROOT%\build_scripts\windows\scripts\az_zip.cmd %BUILDING_DIR%\bin\az.cmd
)
if %errorlevel% neq 0 goto ERROR
copy %REPO_ROOT%\build_scripts\windows\resources\CLI_LICENSE.rtf %BUILDING_DIR%
copy %REPO_ROOT%\build_scripts\windows\resources\ThirdPartyNotices.txt %BUILDING_DIR%
Expand All @@ -174,6 +189,7 @@ for /f %%f in ('dir /b /s *.pyc') do (
REM Delete __init__.pyc
del %%~f
) ELSE (
REM pip source code is required when install packages from source code
echo --SKIP !PARENT_DIR! under pip
)
)
Expand All @@ -193,14 +209,18 @@ for /d %%d in ("azure*.dist-info") do (
)
popd

if %errorlevel% neq 0 goto ERROR

echo Building MSI...
msbuild /t:rebuild /p:Configuration=Release /p:Platform=%ARCH% %REPO_ROOT%\build_scripts\windows\azure-cli.wixproj
if "%TARGET%"=="msi" (
echo Building MSI...
msbuild /t:rebuild /p:Configuration=Release /p:Platform=%ARCH% %REPO_ROOT%\build_scripts\windows\azure-cli.wixproj
) else (
echo Building ZIP...
"%ProgramFiles%\7-Zip\7z.exe" a -tzip "%OUTPUT_DIR%\Microsoft Azure CLI.zip" "%BUILDING_DIR%\*"
)

if %errorlevel% neq 0 goto ERROR

echo %OUTPUT_DIR%
echo Output Dir: %OUTPUT_DIR%

goto END

Expand Down
27 changes: 27 additions & 0 deletions build_scripts/windows/scripts/test_zip_installation.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
Set-PSDebug -Trace 1

Write-Output "Extracting zip to $env:SYSTEM_ARTIFACTSDIRECTORY\zip\"
& "C:\Program Files\7-Zip\7z.exe" x -o"$env:SYSTEM_ARTIFACTSDIRECTORY\zip\Azure CLI" "$env:SYSTEM_ARTIFACTSDIRECTORY\zip\Microsoft Azure CLI.zip"

$az_full_path = "$env:SYSTEM_ARTIFACTSDIRECTORY\zip\Azure CLI\bin\az.cmd"

& $az_full_path --version

$installed_version=& $az_full_path version --query '\"azure-cli\"' -o tsv
Write-Output "Installed version: $installed_version"

$artifact_version=Get-Content $env:SYSTEM_ARTIFACTSDIRECTORY\metadata\version
Write-Output "Artifact version: $artifact_version"

if ($installed_version -ne $artifact_version){
Write-Output "The installed version doesn't match the artifact version."
Exit 1
}

# Test bundled pip with extension installation
& $az_full_path extension add -n account
& $az_full_path self-test
4 changes: 4 additions & 0 deletions src/azure-cli/azure/cli/command_modules/util/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ def upgrade_version(cmd, update_all=None, yes=None, allow_preview=None): # pyli
"or run 'pip install --upgrade azure-cli' in this container")
elif installer == 'MSI':
_upgrade_on_windows()
elif installer == 'ZIP':
zip_url = 'https://aka.ms/installazurecliwindowszipx64'
logger.warning("Please download the latest ZIP from %s, delete the old installation folder and extract the "
"new version to the same location", zip_url)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

When extracting a folder with the same name, the default action is to merge, which can lead to unexpected issues.
Deleting the old folder is required.

else:
logger.warning(UPGRADE_MSG)
if exit_code:
Expand Down