implement install script and brew cask for linux/macos#7213
implement install script and brew cask for linux/macos#7213hemarina merged 16 commits intoAzure:mainfrom
Conversation
… replaced by new azd exe
There was a problem hiding this comment.
Pull request overview
This PR expands azd update to support additional install methods across platforms, notably Homebrew casks on macOS and shell install script flows on Linux/macOS, while also reworking the Windows MSI update path to use the official install script with a backup/restore safety mechanism.
Changes:
- Add Homebrew cask-aware update logic, including stable↔daily channel switching.
- Add Linux/macOS update path that re-runs
install-azd.shin-place forInstallTypeSh. - Rework Windows MSI update to (1) validate standard per-user MSI install location, (2) backup/restore the running exe safely, and (3) run
install-azd.ps1. - Add/update tests for the new update flows; add new update error code and minor UX/spellcheck tweaks.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| cli/azd/pkg/update/manager.go | Adds brew and install-script update flows; rewires Windows MSI update to use install script + exe backup/restore; adjusts IsPackageManagerInstall. |
| cli/azd/pkg/update/manager_test.go | Adds test coverage for updateViaBrew and updateViaInstallScript. |
| cli/azd/pkg/update/msi_windows.go | Implements Windows-specific backup/restore, standard MSI location validation, and PowerShell install-script invocation args. |
| cli/azd/pkg/update/msi_windows_test.go | Adds Windows-only tests for MSI path checks, install-script args, and restore behavior. |
| cli/azd/pkg/update/msi_unix.go | Provides non-Windows stubs for Windows-only MSI helper functions (build-tagged !windows). |
| cli/azd/pkg/update/errors.go | Adds CodeNonStandardInstall for telemetry/typed error reporting. |
| cli/azd/cmd/update.go | Tweaks success message wording. |
| cli/azd/.vscode/cspell-azd-dictionary.txt | Adds installer-related tokens (ALLUSERS, INSTALLDIR). |
Comments suppressed due to low confidence (1)
cli/azd/pkg/update/manager.go:914
IsPackageManagerInstallno longer treats Homebrew installs as package-manager installs. This impacts auto-update/staging logic (e.g.,main.gouses!update.IsPackageManagerInstall()to decide whether to stage/replace the binary) and can cause azd to overwrite a brew-managed installation. Includeinstaller.InstallTypeBrewhere (or otherwise ensure brew installs are excluded from staging and direct binary replacement).
// IsPackageManagerInstall returns true if azd was installed via a package manager.
func IsPackageManagerInstall() bool {
switch installer.InstalledBy() {
case installer.InstallTypeWinget, installer.InstallTypeChoco:
return true
default:
return false
}
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (2)
cli/azd/pkg/update/manager.go:463
updateViaMSIappears to contain a duplicatedisStandardMSIInstall()guard block (theif err := isStandardMSIInstall(); err != nil {+ comments are repeated). As written, this breaks the function structure and will not compile correctly. Please remove the duplicate block and ensure the guard has exactly oneifwith a single body returning the error.
func (m *Manager) updateViaMSI(ctx context.Context, cfg *UpdateConfig, writer io.Writer) error {
// Verify the install is the standard per-user MSI configuration.
// install-azd.ps1 installs with ALLUSERS=2 to %LOCALAPPDATA%\Programs\Azure Dev CLI.
// If the current install is non-standard, abort and advise the user.
if err := isStandardMSIInstall(); err != nil {
// Verify the install is the standard per-user MSI configuration.
// install-azd.ps1 installs with ALLUSERS=2 to %LOCALAPPDATA%\Programs\Azure Dev CLI.
// If the current install is non-standard, abort and advise the user.
if err := isStandardMSIInstall(); err != nil {
return err
}
cli/azd/pkg/update/manager.go:846
currentExePathcurrently has duplicated comments and duplicated statements (including two identicalreturnstatements inside the sameif err != nilblock, and a secondEvalSymlinksblock after an unconditionalreturn). This creates unreachable code and should fail to compile. Please collapse this function to a single implementation that resolves symlinks once and returns once.
// currentExePath returns the resolved path of the currently running executable.
// currentExePath returns the resolved path of the currently running executable.
func currentExePath() (string, error) {
exePath, err := os.Executable()
if err != nil {
return "", fmt.Errorf("failed to determine current executable path: %w", err)
return "", fmt.Errorf("failed to determine current executable path: %w", err)
}
resolved, err := filepath.EvalSymlinks(exePath)
if err != nil {
return "", fmt.Errorf("failed to resolve executable path: %w", err)
}
return resolved, nil
resolved, err := filepath.EvalSymlinks(exePath)
if err != nil {
return "", fmt.Errorf("failed to resolve executable path: %w", err)
}
return resolved, nil
}
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
cli/azd/pkg/update/manager.go:923
- IsPackageManagerInstall no longer treats Homebrew installs as package-manager installs. This affects the auto-update path in main.go (it checks !update.IsPackageManagerInstall()) and can cause Homebrew users to stage/apply standalone binaries, potentially overwriting a brew-managed cask install or leaving unused staged updates. Consider including InstallTypeBrew here (or introducing a separate helper specifically for auto-update eligibility) so auto-update is skipped for brew-managed installs.
// IsPackageManagerInstall returns true if azd was installed via a package manager.
func IsPackageManagerInstall() bool {
switch installer.InstalledBy() {
case installer.InstallTypeWinget, installer.InstallTypeChoco:
return true
default:
return false
}
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Azure Dev CLI Install InstructionsInstall scriptsMacOS/Linux
bash: pwsh: WindowsPowerShell install MSI install Standalone Binary
MSI
Documentationlearn.microsoft.com documentationtitle: Azure Developer CLI reference
|
- Add Unreleased section to CHANGELOG covering merged PRs from 2026-03-19/20: - feat: AI-assisted error troubleshooting category selection (Azure#7216) - feat: CopilotService gRPC extension framework service (Azure#7172) - fix: lifecycle hooks silently not firing in azd up workflow (Azure#7218) - fix: azd update for Linux/macOS shell script and Homebrew (Azure#7213) - fix: azd update on Windows with backup/restore safety (Azure#7166) - fix: azd up --debug/--no-prompt positional arg error (Azure#7212) - fix: PromptSubscription not respecting AZD_DEMO_MODE (Azure#7193) - fix: preflight role check for B2B/guest users (Azure#7174) - Add AZD_DEMO_MODE note to PromptSubscription in extension-framework.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| currentlyDaily := hasAzdDaily | ||
| currentlyStable := hasAzd |
There was a problem hiding this comment.
These are redundant. Why not use hasAzd or hasAzdDaily directly?
- Add AI-Powered Error Troubleshooting section to error-suggestions.md documenting the new category-based flow (explain/guidance/troubleshoot/skip), the three-step interactive process, and configuration keys introduced in Azure#7216 - Update design/azd-update.md to reflect Homebrew cask support, install script updates for macOS/Linux, and MSI backup/restore improvements from Azure#7213 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* add install script installation for windows * address feedback * address feedback * address feedback, update UI, rename azd to temp and have a copy to be replaced by new azd exe * fix cspell and golang, address feedback * fix golang-run * clean up tests due to feedback * brew * installscript for non windows * fix exit 1 bug when switch channel on non windows for binary download * add tests * address feedback * Update cli/azd/pkg/update/manager.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * address feedback, separate rm and cp commands with sudo --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* add install script installation for windows * address feedback * address feedback * address feedback, update UI, rename azd to temp and have a copy to be replaced by new azd exe * fix cspell and golang, address feedback * fix golang-run * clean up tests due to feedback * brew * installscript for non windows * fix exit 1 bug when switch channel on non windows for binary download * add tests * address feedback * Update cli/azd/pkg/update/manager.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * address feedback, separate rm and cp commands with sudo --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* add install script installation for windows * address feedback * address feedback * address feedback, update UI, rename azd to temp and have a copy to be replaced by new azd exe * fix cspell and golang, address feedback * fix golang-run * clean up tests due to feedback * brew * installscript for non windows * fix exit 1 bug when switch channel on non windows for binary download * add tests * address feedback * Update cli/azd/pkg/update/manager.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * address feedback, separate rm and cp commands with sudo --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* add install script installation for windows * address feedback * address feedback * address feedback, update UI, rename azd to temp and have a copy to be replaced by new azd exe * fix cspell and golang, address feedback * fix golang-run * clean up tests due to feedback * brew * installscript for non windows * fix exit 1 bug when switch channel on non windows for binary download * add tests * address feedback * Update cli/azd/pkg/update/manager.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * address feedback, separate rm and cp commands with sudo --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* add install script installation for windows * address feedback * address feedback * address feedback, update UI, rename azd to temp and have a copy to be replaced by new azd exe * fix cspell and golang, address feedback * fix golang-run * clean up tests due to feedback * brew * installscript for non windows * fix exit 1 bug when switch channel on non windows for binary download * add tests * address feedback * Update cli/azd/pkg/update/manager.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * address feedback, separate rm and cp commands with sudo --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* add install script installation for windows * address feedback * address feedback * address feedback, update UI, rename azd to temp and have a copy to be replaced by new azd exe * fix cspell and golang, address feedback * fix golang-run * clean up tests due to feedback * brew * installscript for non windows * fix exit 1 bug when switch channel on non windows for binary download * add tests * address feedback * Update cli/azd/pkg/update/manager.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * address feedback, separate rm and cp commands with sudo --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Fix #7197
This pull request introduces significant improvements and bug fixes to the update mechanism for the
azdCLI, with a focus on making updates more robust and user-friendly across different installation methods (especially Homebrew and shell script installs), and improving error handling and messaging. The most important changes are grouped below:Homebrew and Shell Script Update Handling:
updateViaBrewmethod to properly handle Homebrew cask installations, including channel switching between stable and daily, and reinstalling as a cask if not already installed as one. This ensures consistent update behavior for Homebrew users. [1] [2]updateViaInstallScriptfor Linux/macOS shell script installs, which downloads and executes the latest install script, supporting channel selection and ensuring updates are applied correctly. [1] [2]Windows MSI Update Improvements:
buildMSIDownloadURLfunction, as MSI updates are now handled via install scripts rather than direct downloads.General Update Robustness and Error Handling:
rm -f && cpwithsudoto avoid "Text file busy" errors, making updates more reliable while the CLI is running.currentExePathfunction to resolve symlinks and provide clearer error messages, ensuring the updater targets the correct binary path.Minor Fixes and Messaging:
Overall, these changes make the update process for
azdmore reliable, especially in edge cases and across different platforms and installation methods.