Conversation
There was a problem hiding this comment.
Pull request overview
Moves the azd update experience out of the alpha-gated flow and into a preview/beta stage by removing the alpha.update feature toggle, updating user-facing messaging, and expanding telemetry/error-handling for update scenarios.
Changes:
- Removes the
alpha.updatefeature gate and related wiring; update behavior is now always available (with a preview notice on first use). - Adds new update telemetry result codes and updates middleware to skip agentic error analysis for typed
update.UpdateErrors. - Updates documentation to reflect the new feature stage and adds
updateto the feature-stages list.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| cli/azd/resources/alpha_features.yaml | Removes the update alpha feature entry. |
| cli/azd/pkg/update/errors.go | Adds new telemetry result codes for config/invalid-input failures. |
| cli/azd/pkg/update/config.go | Removes alpha feature key and adds HasUpdateConfig helper. |
| cli/azd/main.go | Updates out-of-date banner guidance to conditionally suggest azd update. |
| cli/azd/docs/feature-stages.md | Lists update as Beta. |
| cli/azd/docs/design/azd-update.md | Updates design doc language from alpha-toggle to preview/always-available framing. |
| cli/azd/cmd/version.go | Removes alpha gating and always appends channel suffix in default version output. |
| cli/azd/cmd/version_test.go | Updates tests for new version output behavior. |
| cli/azd/cmd/update.go | Removes auto-enable alpha behavior; adds preview notice and new telemetry codes. |
| cli/azd/cmd/update_test.go | Adds test coverage for update telemetry code constants. |
| cli/azd/cmd/middleware/error.go | Skips agentic error analysis for update.UpdateError. |
| cli/azd/cmd/middleware/error_test.go | Adds tests ensuring UpdateError (and wrapped) is skipped. |
Comments suppressed due to low confidence (2)
cli/azd/main.go:128
- The update hint is now shown only when HasUpdateConfig(userCfg) is true. Since
azd updatemay not persist any updates.* config on a default run, users can repeatedly see platform-specific upgrade text even after usingazd update. Consider keying this decision off an explicit “update feature used/acknowledged” marker (or persisting default update config on first use) rather than the presence of updates.channel/checkIntervalHours.
// Show "azd update" hint if the user has update config set,
// otherwise show the original platform-specific upgrade instructions.
configMgr := config.NewUserConfigManager(config.NewFileConfigManager(config.NewManager()))
userCfg, cfgErr := configMgr.Load()
if cfgErr != nil {
userCfg = config.NewEmptyConfig()
}
if update.HasUpdateConfig(userCfg) {
fmt.Fprintln(
os.Stderr,
output.WithWarningFormat("To update to the latest version, run: azd update"))
} else {
upgradeText := platformUpgradeText()
fmt.Fprintln(
os.Stderr,
output.WithWarningFormat("To update to the latest version, %s", upgradeText))
}
cli/azd/cmd/version.go:87
- channelSuffix() now always returns " (stable)" for non-daily builds, which changes the default
azd versionoutput for stable releases (potentially breaking scripts that parse the exact output). If the goal is to indicate daily builds, consider only appending a suffix for daily builds (or gate the suffix behind an explicit config/flag) to preserve stable output compatibility.
// channelSuffix returns a display suffix like " (stable)" or " (daily)".
// Based on the running binary's version string, not the configured channel.
func (v *versionAction) channelSuffix() string {
// Detect from the binary itself: if the version contains "daily.", it's a daily build.
if _, err := update.ParseDailyBuildNumber(internal.Version); err == nil {
return " (daily)"
}
return " (stable)"
}
| _, hasInterval := cfg.Get(configKeyCheckIntervalHours) | ||
| return hasChannel || hasInterval |
There was a problem hiding this comment.
HasUpdateConfig claims to detect whether the user has any update configuration set, but it only checks updates.channel and updates.checkIntervalHours. Since LoadUpdateConfig also honors updates.autoUpdate, users who have only set updates.autoUpdate will be treated as having no update config (affecting preview notice + update hints). Consider including updates.autoUpdate in this check (or renaming the helper to match what it actually checks).
| _, hasInterval := cfg.Get(configKeyCheckIntervalHours) | |
| return hasChannel || hasInterval | |
| _, hasAutoUpdate := cfg.Get(configKeyAutoUpdate) | |
| _, hasInterval := cfg.Get(configKeyCheckIntervalHours) | |
| return hasChannel || hasAutoUpdate || hasInterval |
| // Show preview notice on first use | ||
| if !update.HasUpdateConfig(userConfig) { | ||
| a.console.MessageUxItem(ctx, &ux.MessageTitle{ | ||
| Title: fmt.Sprintf( | ||
| "azd update is currently in preview. "+ | ||
| "To learn more about feature stages, visit %s.", | ||
| output.WithLinkFormat("https://aka.ms/azd-feature-stages")), | ||
| }) | ||
| } |
There was a problem hiding this comment.
The “preview notice on first use” condition is based on HasUpdateConfig, but this command doesn’t persist any updates.* config when the user runs azd update with default settings. That means the notice will show on every invocation (and the out-of-date banner in main.go will never switch to the azd update hint). Consider persisting a one-time acknowledgement marker (e.g., updates.previewAcknowledged) or writing a default updates.channel=stable on first run after showing the notice.
| // Persist non-channel config flags immediately (auto-update, check-interval) | ||
| configChanged, err := a.persistNonChannelFlags(userConfig) | ||
| if err != nil { | ||
| tracing.SetUsageAttributes(fields.UpdateResult.String(update.CodeConfigFailed)) | ||
| return nil, err | ||
| } |
There was a problem hiding this comment.
This comment mentions persisting “auto-update” flags, but updateFlags/persistNonChannelFlags currently only handle check-interval-hours. Update the comment to reflect the actual persisted flags to avoid confusion during future maintenance.
| ### 8. Feature Stage (Preview) | ||
|
|
||
| - **Toggle off** (default): Zero behavior changes. `azd version` output is the same. Update notification shows the existing platform-specific install instructions. Running `azd update` auto-enables the feature. | ||
| - **Toggle on** (`azd config set alpha.update on`): All update features are active — `azd update` works, `azd version` shows the channel suffix, notifications say "run `azd update`." | ||
| The update feature is currently in preview: | ||
|
|
||
| This lets us roll out to internal users first, gather feedback, and fix issues before broader availability. Once stable, the toggle can be removed and the feature enabled by default. | ||
| - `azd update` works without needing any config toggle | ||
| - On first use, when no `updates.*` configuration exists, a preview notice is displayed. | ||
|
|
There was a problem hiding this comment.
This section describes the feature stage as “Preview”, but cli/azd/docs/feature-stages.md uses the Alpha/Beta/Stable taxonomy (and now lists update as Beta). Also, the telemetry result-code table earlier in this doc doesn’t include the newly introduced update.configFailed and update.invalidInput codes, and the azd version section still refers to a removed feature-toggle state. Please reconcile terminology and update the related sections so the doc matches the new preview/beta behavior.
| // Verify telemetry result codes used in updateAction.Run() are non-empty | ||
| // and follow the expected "update." prefix convention. | ||
| codes := []string{ | ||
| update.CodeSuccess, | ||
| update.CodeAlreadyUpToDate, | ||
| update.CodeVersionCheckFailed, | ||
| update.CodeSkippedCI, | ||
| update.CodePackageManagerFailed, | ||
| update.CodeChannelSwitchDecline, | ||
| update.CodeReplaceFailed, | ||
| update.CodeConfigFailed, | ||
| update.CodeInvalidInput, | ||
| } | ||
|
|
||
| for _, code := range codes { | ||
| assert.NotEmpty(t, code) | ||
| assert.Contains(t, code, "update.") | ||
| } |
There was a problem hiding this comment.
The test comment says these codes follow the "update." prefix convention, but the assertion uses Contains("update.") which would allow non-prefixed values. Prefer asserting strings.HasPrefix(code, "update.") (or assert.Equal("update.", code[:7]) etc.) to match the stated intent.
Azure Dev CLI Install InstructionsInstall scriptsMacOS/Linux
bash: pwsh: WindowsPowerShell install MSI install Standalone Binary
MSI
Documentationlearn.microsoft.com documentationtitle: Azure Developer CLI reference
|
jongio
left a comment
There was a problem hiding this comment.
Reviewed 12 changed files. Clean alpha-to-preview promotion - the gate removal is thorough across all touchpoints.
The copilot bot's inline comments cover the main design gaps. One additional note:
- pkg/update/config.go:151 - HasUpdateConfig has no unit test
| } | ||
|
|
||
| // HasUpdateConfig returns true if the user has any update configuration set. | ||
| func HasUpdateConfig(cfg config.Config) bool { |
There was a problem hiding this comment.
[LOW] No dedicated unit test for this function. A table-driven test covering empty config, channel-only, interval-only, and (once the autoUpdate gap from the other review is addressed) autoUpdate-only would make it easy to verify correctness and prevent regressions.
Discussed offline with @rajeshkamal5050 and @kristenwomack to mark it as preview rather than alpha.
This pull request transitions the
azd updatefeature from an alpha-gated, hidden command to a public preview feature. It removes the dependency on the alpha feature flag, updates user messaging and documentation to reflect the preview status, and ensures telemetry and error handling are robust for the new flow. The code and tests are updated to support this change, and the feature is now listed as Beta in the feature stages documentation.Feature gating and user experience:
Removes all code and documentation references to the
alpha.updatefeature flag, makingazd updatealways available without toggling any config. The command now shows a preview notice on first use instead of auto-enabling an alpha feature. (cli/azd/cmd/update.go,cli/azd/cmd/version.go,cli/azd/main.go,cli/azd/docs/design/azd-update.md,cli/azd/docs/feature-stages.md,cli/azd/pkg/update/config.go) [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14]Updates the version and update notification logic to always reference the preview feature, and to show the
azd updatehint if any update config is set, not based on an alpha feature. (cli/azd/main.go,cli/azd/cmd/version.go) [1] [2]Error handling and telemetry:
update.UpdateErrorto the list of errors that skip further error analysis, and ensures telemetry codes are correctly set for update-related failures. (cli/azd/cmd/middleware/error.go,cli/azd/cmd/middleware/error_test.go,cli/azd/cmd/update.go,cli/azd/cmd/update_test.go) [1] [2] [3] [4] [5] [6] [7] [8] [9]Documentation and tests:
Updates design documentation to describe the preview flow, removes references to the alpha toggle, and marks the update command as Beta in the feature stages table. (
cli/azd/docs/design/azd-update.md,cli/azd/docs/feature-stages.md) [1] [2] [3] [4]Refactors tests to remove alpha feature dependencies and to verify the new preview/always-on behavior. (
cli/azd/cmd/version_test.go,cli/azd/cmd/update_test.go) [1] [2] [3] [4] [5]These changes collectively make the update experience more discoverable and user-friendly while maintaining safe rollout practices via a preview notice.