Skip to content

Commit 2a363ef

Browse files
authored
Polish the tool first-run experience and allow empty multi-select submissions (#8487)
* refactor(tool_first_run): improve user prompts and allow empty selection in multi-select * Fix lll * Bump version and add changelog entry * Add test
1 parent e3f4cba commit 2a363ef

6 files changed

Lines changed: 42 additions & 18 deletions

File tree

cli/azd/CHANGELOG.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
# Release History
22

3-
## 1.26.0-beta.1 (Unreleased)
4-
5-
### Features Added
6-
7-
### Breaking Changes
3+
## 1.25.4 (2026-05-29)
84

95
### Bugs Fixed
106

11-
### Other Changes
7+
- [[#8487]](https://github.com/Azure/azure-dev/pull/8487) Fix the `azd tool` first-run prompt blocking users who deselect all recommended tools, and clarify its setup wording.
128

139
## 1.25.3 (2026-05-28)
1410

cli/azd/cmd/middleware/tool_first_run.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,12 @@ func (m *ToolFirstRunMiddleware) runFirstRunExperience(ctx context.Context) erro
169169
// Tool check banner
170170
// ---------------------------------------------------------------
171171
m.console.Message(ctx, "")
172-
m.console.Message(ctx, output.WithBold("Checking your Azure development tools..."))
172+
m.console.Message(ctx, output.WithBold("Let's get your development environment ready."))
173173
m.console.Message(ctx, "")
174-
m.console.Message(ctx, "Let's make sure your development environment is up to date.")
174+
m.console.Message(
175+
ctx,
176+
"Discover and install Azure development tools such as Azure CLI, GitHub Copilot CLI, and Azure AI extensions.",
177+
)
175178
m.console.Message(ctx, output.WithGrayFormat(
176179
"To skip this check, set %s or run %s.",
177180
output.WithHighLightFormat("AZD_SKIP_FIRST_RUN=true"),
@@ -278,6 +281,8 @@ func (m *ToolFirstRunMiddleware) runFirstRunExperience(ctx context.Context) erro
278281
tracing.SetUsageAttributes(
279282
fields.ToolFirstRunToolsOfferedKey.Int(0),
280283
)
284+
m.console.Message(ctx, output.WithGrayFormat(
285+
"All recommended tools are installed. You're all set!"))
281286
}
282287

283288
tracing.SetUsageAttributes(fields.ToolFirstRunOutcomeKey.String(finalOutcome))
@@ -340,8 +345,11 @@ func (m *ToolFirstRunMiddleware) offerInstall(
340345
multiSelect := uxlib.NewMultiSelect(&uxlib.MultiSelectOptions{
341346
Writer: m.console.Handles().Stdout,
342347
Reader: m.console.Handles().Stdin,
343-
Message: "Select recommended tools to install:",
348+
Message: "Select recommended tools to install",
344349
Choices: choices,
350+
// Allow proceeding without selecting any tools; the "no tools selected"
351+
// path below is a valid completion of the first-run flow.
352+
AllowEmptySelection: new(true),
345353
})
346354

347355
selected, err := multiSelect.Ask(ctx)
@@ -390,7 +398,7 @@ func (m *ToolFirstRunMiddleware) offerInstall(
390398

391399
if len(selected) == 0 {
392400
m.console.Message(ctx, output.WithGrayFormat(
393-
"No tools selected. You can install them later with 'azd tool install'."))
401+
"No tools selected. You can install them later with 'azd tool install'."))
394402
return "", nil
395403
}
396404

cli/azd/pkg/azdext/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ package azdext
66
// Version is the semantic version of the azdext SDK package.
77
// This value mirrors the CLI version in cli/version.txt and is
88
// automatically updated by eng/scripts/Update-CliVersion.ps1.
9-
const Version = "1.26.0-beta.1"
9+
const Version = "1.25.4"

cli/azd/pkg/ux/multi_select.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,17 @@ type MultiSelectOptions struct {
3737
DisplayNumbers *bool
3838
// Whether or not to disable filtering (default: true)
3939
EnableFiltering *bool
40+
// Whether or not to allow submitting with no options selected (default: false)
41+
AllowEmptySelection *bool
4042
}
4143

4244
var DefaultMultiSelectOptions MultiSelectOptions = MultiSelectOptions{
43-
Writer: os.Stdout,
44-
Reader: os.Stdin,
45-
DisplayCount: 6,
46-
EnableFiltering: new(true),
47-
DisplayNumbers: new(false),
45+
Writer: os.Stdout,
46+
Reader: os.Stdin,
47+
DisplayCount: 6,
48+
EnableFiltering: new(true),
49+
DisplayNumbers: new(false),
50+
AllowEmptySelection: new(false),
4851
}
4952

5053
type MultiSelectChoice struct {
@@ -375,10 +378,12 @@ func (p *MultiSelect) validate() {
375378
p.hasValidationError = false
376379
p.validationMessage = ""
377380

381+
allowEmptySelection := p.options.AllowEmptySelection != nil && *p.options.AllowEmptySelection
382+
378383
if len(p.filteredChoices) == 0 {
379384
p.hasValidationError = true
380385
p.validationMessage = "No options found matching the filter"
381-
} else if p.submitted && len(p.selectedChoices) == 0 {
386+
} else if p.submitted && len(p.selectedChoices) == 0 && !allowEmptySelection {
382387
p.hasValidationError = true
383388
p.validationMessage = "At least one option must be selected"
384389
}

cli/azd/pkg/ux/select_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,21 @@ func TestMultiSelect_validate_no_selection(t *testing.T) {
324324
)
325325
}
326326

327+
func TestMultiSelect_validate_no_selection_allowed(t *testing.T) {
328+
ms := NewMultiSelect(&MultiSelectOptions{
329+
Message: "Pick many",
330+
Choices: []*MultiSelectChoice{
331+
{Value: "a", Label: "Alpha"},
332+
},
333+
AllowEmptySelection: new(true),
334+
})
335+
ms.submitted = true
336+
ms.validate()
337+
338+
assert.False(t, ms.hasValidationError)
339+
assert.Empty(t, ms.validationMessage)
340+
}
341+
327342
func TestMultiSelect_validate_with_selection(t *testing.T) {
328343
ms := NewMultiSelect(&MultiSelectOptions{
329344
Message: "Pick many",

cli/version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.26.0-beta.1
1+
1.25.4

0 commit comments

Comments
 (0)