Skip to content

registry: install azure-cli from the official Windows zip - #12161

Merged
jdx merged 2 commits into
jdx:mainfrom
JamBalaya56562:registry/azure-cli-windows-zip
Aug 20, 2026
Merged

jdx merged 2 commits into
jdx:mainfrom
JamBalaya56562:registry/azure-cli-windows-zip

Conversation

@JamBalaya56562

@JamBalaya56562 JamBalaya56562 commented Aug 19, 2026 •

Copy link
Copy Markdown
Contributor

mise use azure-cli produces an az that cannot run on Windows. The tool installs fine, then:

'python' is not recognized as an internal or external command

or, when some unrelated Python happens to be on PATH:

ModuleNotFoundError: No module named 'azure'

Linux and macOS are unaffected.

Why the PyPI package cannot work on Windows

azure-cli declares no console_scripts entry point. Its wheel carries the launchers as plain data scripts instead:

azure_cli-2.89.1.data/scripts/{az, az.bat, az.completion.sh, azps.ps1}

entry_points.txt is absent from the dist-info, so pip and uv have nothing to generate an .exe launcher from — the one artifact that would carry the interpreter path inside it. They copy az.bat verbatim into the bin directory instead, and it resolves the interpreter next to itself:

IF EXIST "%~dp0\python.exe" ( "%~dp0\python.exe" -m azure.cli %* ) ELSE ( python -m azure.cli %* )

%~dp0 is the directory the batch file sits in. That holds inside the venv's Scripts\ and nowhere else. mise points UV_TOOL_BIN_DIR / PIPX_BIN_DIR at <install>/bin, a sibling of the venv rather than part of it, so the IF EXIST fails and the else branch runs whichever python is on PATH.

Unix escapes this because pip rewrites the az script's shebang to the venv interpreter at install time:

#!/bin/sh
'''exec' '<install>/azure-cli/bin/python' "$0" "$@"

A .bat has no shebang to rewrite. That asymmetry is the whole bug: Azure/azure-cli#10516 fixed the Unix launcher this way and left az.bat on %~dp0.

Not unique to azure-cli, for what it is worth — of the 29 pipx: packages in the registry, awscli-local ships the same shape (awslocal.bat runs a bare python, without even the IF EXIST fallback). It has no GitHub release to switch to, so it is out of scope here.

Upstream is unlikely to change it. console_scripts was adopted in Azure/azure-cli#1014 and reverted a week later in Azure/azure-cli#1042 ("it imports pkg_resources which takes a significant time of the total 'az' load time (~50%)"), then proposed again and declined in Azure/azure-cli#10900. The objection is obsolete — a wrapper generated by modern pip/uv from a wheel imports only the target module, and pkg_resources is not even installed in the venv — but azure/cli/__main__.py is module-level script code with no callable to point an entry point at, so adopting one now means refactoring the telemetry and timing path. Worth raising upstream separately; not something to wait on here.

Why the zip works

The official Windows zip makes no assumption about where it lives:

azure-cli-2.89.1-x64.zip
├── python.exe        <- bundled interpreter
├── Lib/  Scripts/
└── bin/az.cmd        <- @IF EXIST "%~dp0\..\python.exe" ( ... "%~dp0\..\python.exe" -IBm azure.cli %* )

Purely relative, and bin/ is already where mise's default list_bin_paths looks, so no bin_path is needed. It is also a move from a tier 3 backend to a tier 1 one for the platform that was broken, and the release carries GitHub artifact attestations and SLSA provenance, which mise verifies on install.

Scope

Windows x64 only. The release carries no Linux asset, and the macOS tarball does not bundle python — libexec/bin/az errors with AZ_PYTHON not set outside a Homebrew Cask path. Both keep using pipx:, where they work today, so nothing changes for them. Windows arm64 has no asset either and still falls through to pipx:.

No asset_pattern: autodetection already selects the zip over the two .msi assets on Windows, because score_format_preferences gives a zip +15 there while an .msi is not an archive and scores 0 (asset_matcher.rs:591). Confirmed both by mise lock --platform windows-x64 from Linux and on a real Windows machine.

version_prefix is required — the tags are azure-cli-<version>:

$ mise latest github:Azure/azure-cli
azure-cli-2.89.1
$ mise latest 'github:Azure/azure-cli[version_prefix=azure-cli-]'
2.89.1

Verification

On Windows 11 x64, through the equivalent explicit backend (github:Azure/azure-cli[version_prefix=azure-cli-]):

az --version, via a shim

azure-cli                         2.89.1

core                              2.89.1
telemetry                          1.1.0

Dependencies:
msal                              1.36.0
azure-mgmt-resource               24.0.0

Python location 'C:\Users\<user>\AppData\Local\mise\installs\...\2.89.1\python.exe'
Config directory 'C:\Users\<user>\.azure'
Extensions directory 'C:\Users\<user>\.azure\cliextensions'

Python (Windows) 3.14.6 (tags/v3.14.6:c63aec6, Jun 10 2026, 10:26:10) [MSC v.1944 64 bit (AMD64)]

Legal docs and information: aka.ms/AzureCliLegal

Your CLI is up-to-date.

The Python location is inside the mise install directory: the bundled interpreter, with no dependency on a system Python or a pipx venv. exit 0.

Shims — mise reshim produces az.exe (a mise launcher, not a copy of the script) and it runs. The zip's bin/ holds exactly one file, az.cmd, so .cmd → shim generation works. Verified by isolation: with a pipx-installed azure-cli also present, reshim produced az.exe and azps.exe; moving the pipx install aside left only az.exe, which confirms azps.exe came from the pipx azps.ps1 and az.exe from the zip's az.cmd.

A pinned, non-latest version — 2.88.0 resolves to the azure-cli-2.88.0 tag, and installs to a directory named by the stripped version:

mise github:Azure/azure-cli@2.88.0 [1/3] download azure-cli-2.88.0-x64.zip
mise github:Azure/azure-cli@2.88.0 [2/3] checksum azure-cli-2.88.0-x64.zip
mise github:Azure/azure-cli@2.88.0 [2/3] verify GitHub artifact attestations
mise github:Azure/azure-cli@2.88.0 [2/3] verify SLSA provenance
mise github:Azure/azure-cli@2.88.0 [3/3] extract azure-cli-2.88.0-x64.zip
mise github:Azure/azure-cli@2.88.0 ✓ installed

Other checks

  • mise ls-remote github:Azure/azure-cli returns versions.
  • registry-ci runs on Linux, where this entry still resolves to pipx: — the existing test is unchanged and still exercises that path. The github backend is not reachable from CI, hence the manual Windows run above.
  • taplo fmt --check and taplo check pass; the entry validates against schema/mise-registry-tool.json.
  • On Linux, mise install azure-cli + az --version still works unchanged (2.89.1 via uv).

One upgrade note: the install directory is keyed by the tool's short name, and the manifest records the backend that produced it, so a Windows user with an existing pipx-installed azure-cli may need mise uninstall azure-cli before the zip is used. I could not test that transition end to end.

Popularity

  • GitHub: 4.6k stars, 3.5k forks, latest release azure-cli-2.89.1 (2026-08-12), pushed to daily
  • PyPI: 6.65M downloads last month (1.60M last week)
  • Microsoft's official CLI for Azure. Already in the registry — this PR changes how it is installed on Windows, it does not add a new tool.

AI-assisted — Tool: Claude Code; model: anthropic/claude-opus-5; version: 2.1.235.

Summary by CodeRabbit

  • New Features
    • Added support for installing the Azure CLI on Windows using the official bundled Python ZIP release.
    • Windows ARM64 uses the x64 release asset.
    • Retained the existing PyPI-based installation as a fallback for other platforms.

@coderabbitai

coderabbitai Bot commented Aug 19, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 5235b9e4-e95d-40bc-a3ef-cb64214b1b61

📥 Commits

Reviewing files that changed from the base of the PR and between 810046a and f39e6ed.

📒 Files selected for processing (1)
  • registry/azure.toml

Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

The Azure CLI registry entry adds a Windows GitHub backend for bundled-python ZIP releases. Windows ARM64 uses the x64 asset. The pipx backend remains the fallback for non-Windows platforms.

Changes

Azure CLI backend

Layer / File(s) Summary
Windows backend registration
registry/azure.toml
Adds a Windows GitHub backend for the bundled-python Azure CLI ZIP release. Sets the azure-cli- version prefix and maps Windows ARM64 to the x64 asset. Retains the pipx backend for non-Windows platforms.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: 🔵 Low · up to f39e6

This change routes Windows x64 to the official Azure CLI ZIP with its bundled Python while preserving the existing installation path on other platforms and Windows ARM64. The change is mergeable, but maintainers should explicitly confirm version resolution for both installation sources as a bounded registry integration follow-up.

Suggested reviewers: jdx

Poem

A rabbit sees the Windows ZIP,
Azure versions make a hop.
ARM64 takes the x64 trail,
Pipx waits where Windows fails.
The registry stays neat.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: installing azure-cli from the official Windows ZIP.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Aug 19, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR switches Azure CLI installation on Windows to Microsoft’s official ZIP while retaining the existing pipx backend elsewhere.

  • Selects the GitHub release backend on Windows.
  • Strips the azure-cli- release-tag prefix during version resolution.
  • Uses the x64 ZIP on Windows ARM64, where Windows supports x64 user-mode emulation.
  • Preserves pipx installation on Linux and macOS.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
registry/azure.toml Adds a platform-filtered GitHub backend for the official Windows Azure CLI ZIP, including an ARM64 override, while retaining pipx as the fallback for other platforms.

Reviews (3): Last reviewed commit: "registry(azure-cli): cover Windows ARM64..." | Re-trigger Greptile

@JamBalaya56562
JamBalaya56562 marked this pull request as draft August 19, 2026 09:06
@JamBalaya56562
JamBalaya56562 marked this pull request as ready for review August 19, 2026 10:58
The PyPI package cannot produce a working `az` on Windows. azure-cli ships no
`console_scripts` entry point -- it was adopted in Azure/azure-cli#1014 and
reverted a week later in Azure/azure-cli#1042 over startup cost, and proposed
again and declined in Azure/azure-cli#10900 -- so pip and uv generate no `.exe`
launcher and copy the package's own `az.bat` verbatim. That script resolves the
interpreter next to itself:

    IF EXIST "%~dp0\python.exe" ( "%~dp0\python.exe" -m azure.cli %* )
                                ELSE ( python -m azure.cli %* )

which only holds inside the venv's `Scripts` directory, not in the bin
directory `UV_TOOL_BIN_DIR` / `PIPX_BIN_DIR` point at. The else branch then runs
whichever `python` is on PATH, so `az --version` fails with a missing `python`
or `ModuleNotFoundError: No module named 'azure'`. Unix is unaffected because
pip rewrites the `az` script's shebang to the venv interpreter; a `.bat` has no
shebang to rewrite.

The official Windows zip has no such assumption: it bundles `python.exe` at its
root and its `bin/az.cmd` reaches it with `%~dp0\..\python.exe`, so it works
wherever mise unpacks it, and `bin/` is already where mise looks for binaries.
This also moves the platform that was broken from a tier 3 backend to a tier 1
one.

Windows x64 only. There is no Linux release asset, and the macOS tarball does
not bundle python -- outside a Homebrew Cask path its launcher requires
AZ_PYTHON -- so both keep using pipx, where they work today.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@JamBalaya56562
JamBalaya56562 force-pushed the registry/azure-cli-windows-zip branch from 810046a to 4ff8708 Compare August 19, 2026 10:59

jdx commented Aug 19, 2026

Copy link
Copy Markdown
Owner

Thanks for digging into this. I checked the pipx/Python behavior and Windows ARM64 before deciding.

The Python dependency added in #9678 only puts mise-managed Python on PATH while mise runs pipx.pyz during installation. It does not put the package venv's python.exe on PATH when the installed command runs. Even if the generic dependency Python is found then, it does not contain the venv's azure modules, which explains the ModuleNotFoundError. So the launcher problem described here is real.

I don't think Windows ARM64 should fall through to pipx:, though. The PyPI launcher defect is independent of CPU architecture, so that fallback is known-broken there too.

Microsoft currently publishes only an x64 Windows ZIP, but Windows 11 ARM supports transparent x64 user-mode emulation. This ZIP is a self-contained x64 Python application with no driver component, and mise's aqua backend already treats Windows AMD64 packages as compatible with ARM64 for the same reason.

Please test the x64 ZIP on GitHub's windows-11-arm runner. If it passes, I suggest covering both Windows architectures and explicitly choosing the x64 asset on ARM64:

[[backends]]
full = "github:Azure/azure-cli"
platforms = ["windows"]

[backends.options]
version_prefix = "azure-cli-"

[backends.options.platforms.windows-arm64]
asset_pattern = "azure-cli-{{ version }}-x64.zip"

The ARM64 smoke test should install through mise, execute az --version through the shim, and confirm the bundled python.exe reports AMD64.

If that cannot be validated, please instead scope the pipx:azure-cli fallback to Linux/macOS so Windows ARM64 reports unsupported rather than selecting a backend we know cannot launch correctly.

AI-assisted — Tool: Codex; model: unavailable; version: unavailable.

@JamBalaya56562

Copy link
Copy Markdown
Contributor Author

Tested it on windows-11-arm, and it passes. Taken your shape in f39e6ed.

The runner and the driver are both genuinely ARM64, which matters — an x64 mise under emulation would detect windows-x64 and the run would prove nothing:

PROCESSOR_ARCHITECTURE = ARM64
OSArchitecture         = Arm64
mise.exe PE machine    = 0xAA64 (ARM64)

Config mirroring the proposed entry, since the registry is compiled in:

"github:Azure/azure-cli" = { version = "2.89.1", version_prefix = "azure-cli-", asset_pattern = "azure-cli-{{ version }}-x64.zip" }

Results — install, mise exec, and the shim:

$ mise exec -- az --version
azure-cli                         2.89.1
core                              2.89.1
telemetry                          1.1.0
Python (Windows) 3.14.6 … [MSC v.1944 64 bit (AMD64)]

$ az --version          # through the shim
azure-cli                         2.89.1
Python (Windows) 3.14.6 … [MSC v.1944 64 bit (AMD64)]

On confirming the interpreter is the x64 build, one detail is worth stating exactly, because the obvious check answers a different question:

machine = ARM64                                  # platform.machine() — the host CPU
python.exe PE machine = 0x8664 (x64/AMD64)       # the binary itself

platform.machine() reports the machine, not the image, so it says ARM64 even under emulation. The PE header and the [MSC v.1944 64 bit (AMD64)] build tag are the ones that answer "is this the x64 build", and both say it is.

The registry entry now reads:

[[backends]]
full = "github:Azure/azure-cli"
platforms = ["windows"]

[backends.options]
version_prefix = "azure-cli-"

[backends.options.platforms.windows-arm64]
asset_pattern = "azure-cli-{{ version }}-x64.zip"

codeql is the existing precedent for the shape — it points macos-arm64 at the osx64 asset for the same reason — and flyway for a platform-scoped asset_pattern with {{ version }} in it.

You were right that pipx: was the wrong fallback there. My platforms = ["windows-x64"] left ARM64 falling through to a backend that cannot launch, which is a worse answer than either working or reporting unsupported.

The probe workflow lived on a scratch branch in my fork and is deleted; nothing was added to this PR but the registry file. Two things it turned up that are only about the probe, not about mise: the shim re-invokes mise by name, so mise has to be on PATH and not merely invoked by absolute path, and windows-11-arm had no trouble with the x64 ZIP download or extraction.

@jdx
jdx merged commit 9276059 into jdx:main Aug 20, 2026
31 checks passed
@JamBalaya56562
JamBalaya56562 deleted the registry/azure-cli-windows-zip branch August 20, 2026 04: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.

2 participants