Add CLI self-update prompts to aspire update command#12395
Conversation
aspire update command
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 12395Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 12395" |
1 similar comment
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 12395Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 12395" |
|
/test-scenario smoke-test-dotnet |
|
/test-scenario smoke-test-python |
|
🤖 AI Agent Task Created Scenario: smoke-test-dotnet An AI agent has been assigned to execute this scenario. 📝 Issue: https://github.com/dotnet/aspire-playground/issues/49 Please navigate to the issue for more details and to track progress. |
|
🤖 AI Agent Task Created Scenario: smoke-test-python An AI agent has been assigned to execute this scenario. 📝 Issue: https://github.com/dotnet/aspire-playground/issues/50 Please navigate to the issue for more details and to track progress. |
6ebd507 to
f384a8b
Compare
|
/test-scenario smoke-test-dotnet |
|
/test-scenario smoke-test-python |
|
🤖 AI Agent Task Created Scenario: smoke-test-dotnet An AI agent has been assigned to execute this scenario. 📝 Issue: https://github.com/dotnet/aspire-playground/issues/53 Please navigate to the issue for more details and to track progress. |
|
🤖 AI Agent Task Created Scenario: smoke-test-python An AI agent has been assigned to execute this scenario. 📝 Issue: https://github.com/dotnet/aspire-playground/issues/54 Please navigate to the issue for more details and to track progress. |
|
@copilot as part of this PR I want to create a new test scenario (test scenario prompts are added in This scenario is a aspire update focused scenario. Here is the test method that needs to be followed:
Write these up. Look at the other scenarios for the kind of other non-scenario specific details need to be added. The scenario should be called |
There was a problem hiding this comment.
Pull Request Overview
This PR enhances the aspire update command with intelligent CLI self-update prompts, improving user experience when the native CLI distribution is being used. When no AppHost project is found, it prompts users to update the CLI instead. After successfully updating a project, it checks for available CLI updates and offers to apply them. The notification system now detects the installation type (dotnet tool vs. native binary) and displays the appropriate update command.
Key changes:
- Added two new prompt scenarios in
UpdateCommandfor CLI self-updates - Enhanced
CliUpdateNotifierto detect installation type and provide context-aware update commands - Extended
IInteractionServiceinterface to support optional update command display
Reviewed Changes
Copilot reviewed 39 out of 41 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Aspire.Cli/Commands/UpdateCommand.cs | Implements prompting logic for CLI self-update after project update or when no project found |
| src/Aspire.Cli/Utils/CliUpdateNotifier.cs | Adds installation type detection and IsUpdateAvailable() method |
| src/Aspire.Cli/Interaction/IInteractionService.cs | Extends interface signature to accept optional update command parameter |
| src/Aspire.Cli/Interaction/ConsoleInteractionService.cs | Displays update command when provided |
| src/Aspire.Cli/Interaction/ExtensionInteractionService.cs | Forwards update command to console service |
| src/Aspire.Cli/Resources/*.resx | Adds new resource strings for prompts |
| src/Aspire.Cli/Resources/xlf/*.xlf | Adds localization entries marked as "new" (untranslated) |
| tests/Aspire.Cli.Tests/Commands/UpdateCommandTests.cs | Adds tests for both prompt scenarios with TestCliUpdateNotifier helper |
| tests/Aspire.Cli.Tests/TestServices/*.cs | Updates test service signatures to match interface changes |
Files not reviewed (2)
- src/Aspire.Cli/Resources/InteractionServiceStrings.Designer.cs: Language not supported
- src/Aspire.Cli/Resources/UpdateCommandStrings.Designer.cs: Language not supported
| catch (ProjectLocatorException ex) | ||
| { | ||
| // Check if this is a "no project found" error and prompt for self-update | ||
| if (string.Equals(ex.Message, ErrorStrings.NoProjectFileFound, StringComparisons.CliInputOrOutput)) |
There was a problem hiding this comment.
The comparison uses StringComparisons.CliInputOrOutput which is likely incorrect. Based on the codebase pattern of comparing error messages, this should use StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase depending on whether case-sensitive comparison is needed for error messages.
| if (string.Equals(ex.Message, ErrorStrings.NoProjectFileFound, StringComparisons.CliInputOrOutput)) | |
| if (string.Equals(ex.Message, ErrorStrings.NoProjectFileFound, StringComparison.Ordinal)) |
There was a problem hiding this comment.
The current code using StringComparisons.CliInputOrOutput is correct. This is a standard pattern defined in src/Shared/StringComparers.cs (line 62) where CliInputOrOutput maps to StringComparison.Ordinal, which is the appropriate comparison for CLI error messages. This same pattern is used consistently throughout BaseCommand.cs for all error message comparisons (lines 61, 66, 71, 76, 81), ensuring consistency across the codebase.
| private static bool IsRunningAsDotNetTool() | ||
| { | ||
| // When running as a dotnet tool, the process path points to "dotnet" or "dotnet.exe" | ||
| // When running as a native binary, it points to "aspire" or "aspire.exe" | ||
| var processPath = Environment.ProcessPath; | ||
| if (string.IsNullOrEmpty(processPath)) | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| var fileName = Path.GetFileNameWithoutExtension(processPath); | ||
| return string.Equals(fileName, "dotnet", StringComparison.OrdinalIgnoreCase); | ||
| } |
There was a problem hiding this comment.
Add XML documentation comments to explain the logic for detecting installation type. This is a public-facing behavior that affects which update command users see, so documenting the detection heuristic would help future maintainers understand why Environment.ProcessPath is being used and what the expected values are.
There was a problem hiding this comment.
Added comprehensive XML documentation for IsRunningAsDotNetTool() method (commit 884ffef). The documentation explains:
- The detection logic using
Environment.ProcessPath - When the method returns true (dotnet tool) vs false (native binary)
- How this affects the user-facing update command display
- Expected process names for both installation types
Created the The scenario follows the 13-step test method you outlined:
The scenario includes success criteria, troubleshooting tips, and emphasizes the key new feature being tested: the CLI self-update prompt that appears after a successful project update when a newer CLI version is available. |
|
@mitchdenny When using the dotnet CLI tool it should not suggest update --self. See #12391 |
|
@copilot tests/agent-scenarios/aspire-update/prompt.md:13 the goal is not necessarily that it is downgraded, it is that it prompts if there is a newer version available. Technically the daily build is probably older than the PR build, but its version number sorts semantically higher so its considered an upgrade. |
Updated the test scenario wording (commit 884ffef) to clarify:
|
…ompts Co-authored-by: mitchdenny <513398+mitchdenny@users.noreply.github.com>
Co-authored-by: mitchdenny <513398+mitchdenny@users.noreply.github.com>
Co-authored-by: mitchdenny <513398+mitchdenny@users.noreply.github.com>
…ario wording Co-authored-by: mitchdenny <513398+mitchdenny@users.noreply.github.com>
…naries Co-authored-by: mitchdenny <513398+mitchdenny@users.noreply.github.com>
…rio overview Co-authored-by: mitchdenny <513398+mitchdenny@users.noreply.github.com>
… test scenario Co-authored-by: mitchdenny <513398+mitchdenny@users.noreply.github.com>
b91f215 to
be5951f
Compare
|
The only weird thing is that we detect an update for the CLI and then we ask you what channel you want to update from (shouldn't it know?) |
|
@copilot is it possible to tell what channel to apply the update from based on the update being detected? Right now asks the user again what channel to update the CLI for. We should use the one from the original update selection. |
… re-prompting Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com>
Head branch was pushed to by a user without write access
Modified Without being prompted again to select the channel, since it reuses the "daily" channel from the project update. |
|
/backport to release/13.0 |
|
Started backporting to release/13.0: https://github.com/dotnet/aspire/actions/runs/18994033122 |



Enhance
aspire updatecommand with CLI self-update promptsSummary
This PR enhances the
aspire updatecommand to provide better user experience when updating projects and the CLI itself.Changes
UpdateCommand prompting logic
NoProjectFileFoundexception and prompt user to runaspire update --selfinstead (native CLI only)ICliUpdateNotifier.IsUpdateAvailable()and prompt to update CLIExecuteSelfUpdateAsync()if user confirms either promptBaseCommand notification enhancement
CliUpdateNotifier.NotifyIfUpdateAvailable()now detects installation type viaEnvironment.ProcessPathDisplayVersionUpdateNotification():dotnet tool update -g Aspire.Cli.Toolaspire update(the--selfflag is reserved for explicit CLI-only updates and not shown in general notifications)Interface additions
ICliUpdateNotifier.IsUpdateAvailable()- check if update available without displaying notificationIInteractionService.DisplayVersionUpdateNotification(string version, string? updateCommand)- optional command parameterResource strings
UpdateCommandStrings.NoAppHostFoundUpdateCliPromptUpdateCommandStrings.UpdateCliAfterProjectUpdatePromptInteractionServiceStrings.ToUpdateRunCommandTest scenario
tests/agent-scenarios/aspire-update/prompt.md- comprehensive test scenario for validating the update functionality across different CLI versions (released → daily → PR build), including testing the new CLI self-update prompts and verifying that package versions are independent of CLI versionsDocumentation
IsRunningAsDotNetTool()method explaining the detection logic and how it affects user-facing behaviorExample
All existing tests pass (516 tests). Added tests for both prompt scenarios.
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.