Fix CLI stop command description to include resource stopping#14372
Merged
Fix CLI stop command description to include resource stopping#14372
Conversation
Updated description from "Stop a running Aspire apphost." to "Stop a running apphost or the specified resource." in the resx file and all XLF localization files. Co-authored-by: JamesNK <303201+JamesNK@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix CLI stop command description for clarity
Fix CLI stop command description to include resource stopping
Feb 6, 2026
Contributor
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 14372Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 14372" |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes an incomplete description for the CLI stop command. The description previously stated "Stop a running Aspire apphost." but failed to mention that the command also accepts an optional resource argument to stop a specific resource instead of the entire apphost. The updated description now reads "Stop a running apphost or the specified resource." to accurately reflect the command's dual functionality.
Changes:
- Updated the command description in
StopCommandStrings.resxsource file - Updated the
<source>elements in all 13 XLF localization files to match the new description
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/Aspire.Cli/Resources/StopCommandStrings.resx | Updated main resource file with corrected command description |
| src/Aspire.Cli/Resources/xlf/StopCommandStrings.cs.xlf | Updated source element in Czech localization file |
| src/Aspire.Cli/Resources/xlf/StopCommandStrings.de.xlf | Updated source element in German localization file |
| src/Aspire.Cli/Resources/xlf/StopCommandStrings.es.xlf | Updated source element in Spanish localization file |
| src/Aspire.Cli/Resources/xlf/StopCommandStrings.fr.xlf | Updated source element in French localization file |
| src/Aspire.Cli/Resources/xlf/StopCommandStrings.it.xlf | Updated source element in Italian localization file |
| src/Aspire.Cli/Resources/xlf/StopCommandStrings.ja.xlf | Updated source element in Japanese localization file |
| src/Aspire.Cli/Resources/xlf/StopCommandStrings.ko.xlf | Updated source element in Korean localization file |
| src/Aspire.Cli/Resources/xlf/StopCommandStrings.pl.xlf | Updated source element in Polish localization file |
| src/Aspire.Cli/Resources/xlf/StopCommandStrings.pt-BR.xlf | Updated source element in Brazilian Portuguese localization file |
| src/Aspire.Cli/Resources/xlf/StopCommandStrings.ru.xlf | Updated source element in Russian localization file |
| src/Aspire.Cli/Resources/xlf/StopCommandStrings.tr.xlf | Updated source element in Turkish localization file |
| src/Aspire.Cli/Resources/xlf/StopCommandStrings.zh-Hans.xlf | Updated source element in Simplified Chinese localization file |
| src/Aspire.Cli/Resources/xlf/StopCommandStrings.zh-Hant.xlf | Updated source element in Traditional Chinese localization file |
davidfowl
approved these changes
Feb 6, 2026
tmat
added a commit
that referenced
this pull request
Mar 5, 2026
* [automated] Disable Aspire.Cli.Tests.Commands.RunCommandTests.RunCommand_SkipsBuild_WhenExtensionDevKitCapabilityIsAvailable (#14322)
* [automated] Disable Aspire.Cli.Tests.Commands.RunCommandTests.RunCommand_SkipsBuild_WhenExtensionDevKitCapabilityIsAvailable
* Update tests/Aspire.Cli.Tests/Commands/RunCommandTests.cs
---------
Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: David Fowler <davidfowl@gmail.com>
* [Automated] Update AI Foundry Models (#14246)
Co-authored-by: sebastienros <sebastienros@users.noreply.github.com>
* Make `EndpointReferenceExpression.GetValueAsync()` context aware (#14278)
* Refactor endpoint resolution logic so that `EndpointReferenceExpression.GetValueAsync()` can be context aware.
To make this work, DCP now always allocates a `DefaultAspireContainerNetwork` endpoint when a container is created alongside the existing `LocalhostNetwork` endpoint.
* PR Review + fix broken test.
* Fix `WithEnvironmentTests.EnvironmentVariableExpressions()`
* - Fix Broken Tests
- Add some DebuggerDisplay attributes to `ValueSnapshot`, and `NetworkEndpointSnapshotList` to make debugging easier
- Explcitly use `*.dev.internal` alias for container networks
- Don't allocate endpoints on custom networks
* Fix test changed by previous commit removing support for custom networks.
* One more failing test
* Remove redundant comment.
* [main] Update dependencies from microsoft/dcp (#14323)
* Update dependencies from https://github.com/microsoft/dcp build 0.22.3
On relative base path root
Microsoft.DeveloperControlPlane.darwin-amd64 , Microsoft.DeveloperControlPlane.darwin-arm64 , Microsoft.DeveloperControlPlane.linux-amd64 , Microsoft.DeveloperControlPlane.linux-arm64 , Microsoft.DeveloperControlPlane.linux-musl-amd64 , Microsoft.DeveloperControlPlane.windows-amd64 , Microsoft.DeveloperControlPlane.windows-arm64 From Version 0.22.2 -> To Version 0.22.3
* Quarantine the tunnel test
---------
Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
Co-authored-by: Karol Zadora-Przylecki <karolz@microsoft.com>
* CLI fixes: MCP error message and help display (#14328)
* Update MCP error to suggest 'aspire run --detach'
* Add test assertions for --detach in MCP error message
* Show help when aspire is invoked without arguments
* Return InvalidCommand exit code for consistency with other parent commands
* Add tests for parent command exit codes to prevent regression
* Updated AppService as stable for Aspire 13.2. (#14316)
Co-authored-by: Shilpi Rachna <shilpir@microsoft.com>
* Change GetHostAddressExpression from explicit interface implementation to public method (#14319)
* Initial plan
* Change GetHostAddressExpression implementations to public methods
Co-authored-by: eerhardt <8291187+eerhardt@users.noreply.github.com>
* Add Experimental attribute to GetHostAddressExpression methods
Co-authored-by: eerhardt <8291187+eerhardt@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: eerhardt <8291187+eerhardt@users.noreply.github.com>
* Add E2E deployment test for React + ASP.NET Core to Azure App Service (#14326)
* Add E2E deployment test for React + ASP.NET Core to Azure App Service
This adds a new deployment test that:
- Creates a project using the Starter App (ASP.NET Core/React) template
- Deploys to Azure App Service (instead of Container Apps)
- Verifies the deployed endpoints are accessible
The test follows the established patterns from AcaStarterDeploymentTests
and PythonFastApiDeploymentTests.
* Fix prompt sequence for React template
The React template (aspire-ts-cs-starter) has different prompts than the
Blazor starter template:
- Does NOT have a 'test project' prompt
- Output path prompt includes the default path
Updated to match the working JsReactTemplateTests pattern.
* Increase deployment timeouts to 30 min and fix cleanup workflow
- Increase pipeline wait timeout from 10-20 min to 30 min across all deployment tests
- Increase overall test timeout to 40 min to accommodate longer deployments
- Fix cleanup workflow to target both e2e-* (current) and rg-aspire-* (legacy) prefixes
* Add endpoint verification retry logic to deployment tests
Each endpoint is now retried up to 18 times (10 second intervals) for a total
of ~3 minutes before failing. This handles cases where deployed apps need
time to become responsive after deployment completes.
* Fix deployment test command to link to actual workflow run
Move the 'starting' comment from deployment-test-command.yml to
deployment-tests.yml where it has direct access to github.run_id.
The notify-start job only runs when pr_number is provided, matching
the existing post_pr_comment job pattern.
* Add Azure quota requirements to deployment test README
Document the required Azure subscription quotas for running deployment
E2E tests, including Container Apps managed environments (150+) and
App Service PremiumV3 vCPUs (10+). Also updated timeout documentation
and cleanup commands.
* Add Python FastAPI to Azure App Service deployment test
New test case AppServicePythonDeploymentTests that deploys the
FastAPI/React template to Azure App Service instead of Container Apps.
This mirrors PythonFastApiDeploymentTests but targets App Service.
* Enhance PR comment to show passed/failed tests separately
- Query individual matrix job results to determine per-test outcomes
- Display passed, failed, and cancelled tests in separate sections
- Show summary counts (X passed, Y failed, Z cancelled)
- Include recordings only for tests that have them
* Add Azure resource deployment E2E tests (Phase 1)
Add 7 new E2E deployment tests for Azure resources using aspire init:
Simple/Low-cost resources:
- AzureStorageDeploymentTests - Azure Storage Account
- AzureKeyVaultDeploymentTests - Azure Key Vault
- AzureAppConfigDeploymentTests - Azure App Configuration
- AzureLogAnalyticsDeploymentTests - Azure Log Analytics Workspace
- AzureContainerRegistryDeploymentTests - Azure Container Registry
Messaging resources:
- AzureServiceBusDeploymentTests - Azure Service Bus
- AzureEventHubsDeploymentTests - Azure Event Hubs
Each test:
1. Uses 'aspire init' to create a single-file AppHost
2. Adds the Azure hosting package via 'aspire add'
3. Injects resource code into apphost.cs
4. Deploys to Azure using 'aspire deploy'
5. Verifies the resource was created
6. Cleans up the resource group
* Fix duplicate heading in deployment tests README
* Fix Azure location for deployment tests - use westus3
The subscription has quota limits in eastus (only 1 Container App environment).
We have expanded quota in westus3, so change the workflow to deploy there.
* Fix Azure resource tests to handle NuGet.config prompt
The aspire init command now prompts for 'Create NuGet.config for selected channels?'
before creating the AppHost. Updated all 7 Azure resource tests to:
1. Handle the new NuGet.config prompt (press Enter for Yes)
2. Remove language selection handling (only appears with polyglot enabled)
* Fix aspire init pattern matching for CI environment
In CI, aspire init:
1. Auto-creates NuGet.config without prompting (no interactive prompt)
2. Shows 'Aspire initialization complete' instead of 'Created apphost.cs'
Updated all 7 Azure resource tests to:
- Wait for 'Aspire initialization complete' pattern
- Remove the NuGet.config prompt handling (not needed in CI)
* Handle NuGet.config prompt that may or may not appear in CI
The NuGet.config prompt behavior is inconsistent in CI - sometimes it appears
interactively, sometimes it auto-accepts. Updated tests to:
1. Wait 5 seconds after running aspire init
2. Press Enter (dismisses prompt if present, no-op if auto-accepted)
3. Then wait for 'Aspire initialization complete'
This handles both interactive and non-interactive cases.
* Add Azure Container App Environment for role assignment support
Azure resources that require role assignments (Storage, KeyVault, AppConfig,
ServiceBus, EventHubs) need a managed identity principal. The Container App
Environment provides this. Updated 5 failing tests to include:
builder.AddAzureContainerAppEnvironment("env")
This provides the principal required for provisioning role assignments.
* Add Aspire.Hosting.Azure.ContainerApps package for CAE support
AddAzureContainerAppEnvironment() requires the ContainerApps hosting package.
Updated 5 tests to add this package before adding the specific Azure resource
package. Flow is now:
1. aspire init
2. aspire add Aspire.Hosting.Azure.ContainerApps
3. aspire add Aspire.Hosting.Azure.{Resource}
4. modify apphost.cs to use AddAzureContainerAppEnvironment + AddAzure{Resource}
* Fix aspire add integration selection prompt handling
Add pattern searcher for 'Select an integration to add:' prompt
and wait for it before pressing Enter to select the first match.
This handles the fuzzy matching that shows multiple options.
* Fix aspire add prompt handling - use combined pattern searcher
aspire add may show either:
- Integration selection prompt if multiple matches
- Version selection prompt if unique match
The combined searcher waits for either prompt type.
* Fix aspire add to handle TWO prompts for ContainerApps
aspire add Aspire.Hosting.Azure.ContainerApps triggers:
1. Integration selection prompt (matches multiple Azure packages)
2. Version selection prompt (in CI)
Need to wait for and handle both prompts sequentially.
* Address code review feedback
- Use discard pattern (_) instead of unused variable for AddAzureContainerAppEnvironment
- Update README.md Test Structure section to include new Azure resource test files
* Skip App Service deployment tests due to infrastructure timeouts
App Service provisioning takes longer than 30 minutes, causing test
timeouts. Skipped until infrastructure issues are resolved.
---------
Co-authored-by: Mitch Denny <mitch@mitchdeny.com>
* Localized file check-in by OneLocBuild Task: Build definition ID 1309: Build ID 2895128 (#14332)
* Lazy index docs in MCP tools and report progress (#14341)
* Hide "Show/Hide Hidden Resources" menu item when viewing single resource logs (#14288)
* Upload CLI E2E recordings as dedicated artifacts (#14355)
- Add step in run-tests.yml to copy .cast files and upload as
'cli-e2e-recordings-{TestName}' artifacts
- Simplify cli-e2e-recording-comment.yml to filter by artifact name prefix
- Removes need for hardcoded test class name list
Co-authored-by: Mitch Denny <mitch@mitchdeny.com>
* Refactor resource MCP refresh (#14353)
* Add Kubernetes/Helm E2E test for CLI publishing (#14352)
* Add Kubernetes/Helm E2E test for CLI publishing
- Add KubernetesPublishTests.cs to correct project (Aspire.Cli.EndToEnd.Tests)
- Delete orphaned tests/Aspire.Cli.EndToEndTests folder (misnamed, no csproj)
* Address PR feedback: improve test reliability and cleanup
- Add .WithDimensions(160, 48) to terminal builder for consistency
- Make KinD/Helm versions configurable via environment variables
- Use unique cluster names (GUID-based) for parallel test execution
- Add kubectl wait --for=condition=Ready for proper pod verification
- Wrap test in try/finally with best-effort cleanup via Process API
- Improve comment explaining port override rationale
* Pass CancellationToken to WaitForExitAsync in cleanup
---------
Co-authored-by: Mitch Denny <mitch@mitchdeny.com>
* Refactor CLI telemetry MCP tools to use dashboard APIs (#14337)
* Add initial Aspire.Hosting.Azure.Network integration (#13108)
* Add initial Aspire.Hosting.Azure.Network integration
This is the first round of supporting Azure virtual networks in Aspire. Currently it supports:
Creating a virtual network
Creating subnets
Creating private endpoints to Storage blobs and queues
Future PRs will enable:
More private endpoint support. This is just the core / first resource.
Being able to add NAT Gateways and public IPs.
This pull request introduces a new Azure Virtual Network end-to-end sample to the repository, demonstrating how to configure a virtual network, subnets, private endpoints, and secure storage access for containerized applications. It also adds support for Azure Network and Private DNS provisioning packages, and makes minor improvements to existing storage modules.
* Get some stuff working
* Don't add VNet resources in run mode.
Add a delegation annotation so things like ACA can delegate subnets.
* Initial support for private endpoints.
* Add Azure.Provisioning.PrivateDns and update to latest
* Remove unncessary workaround
* Finish implementing private endpoints.
Gets AzureStorageEndToEnd working with a vnet and private endpoints.
* Make new Aspire.Hosting.Azure APIs experimental
* Add unit tests.
Remove NatGateway (for now). This will come in a separate PR.
Clean up some code.
* More clean up
* Move to a new playground app specific to VNets
* Fix AddSubnet API
* Rename AddAzurePrivateEndpoint and hang it off of AzureSubnetResource.
* Don't add PrivateEndpointTargetAnnotation in run mode. Also walk the hierarchy until you reach the root resource.
* Add WithSubnet API for ACA environments and improve delegation naming
- Add IAzureDelegatedSubnetResource interface and DelegatedSubnetAnnotation to Aspire.Hosting.Azure
- Implement IAzureDelegatedSubnetResource on AzureContainerAppEnvironmentResource
- Add WithSubnet<T> extension method in Network package for configuring subnet delegation
- Update ACA Bicep generation to read DelegatedSubnetAnnotation and configure VnetConfiguration
- Use serviceName for delegation name in Bicep output (e.g., 'Microsoft.App/environments')
- Mark new public APIs with [Experimental("ASPIREAZURE003")]
- Add unit test verifying ACA and VNet Bicep output with subnet delegation
* Separate and reuse Private DNS Zones across private endpoints
- Add AzurePrivateDnsZoneResource for shared DNS Zone management
- Add AzurePrivateDnsZoneVNetLinkResource for VNet-to-zone linking
- DNS Zones are cached at builder level and reused per zone name
- VNet Links tracked on DNS Zone to avoid duplicates
- PE Bicep now references existing DNS Zone instead of creating inline
- Add tests for DNS Zone reuse scenarios
- Add InternalsVisibleTo for test access to internal types
* Address PR feedback
* Only export env values with FromSpec (#14356)
* Localized file check-in by OneLocBuild Task: Build definition ID 1309: Build ID 2896470 (#14349)
* Localized file check-in by OneLocBuild Task: Build definition ID 1309: Build ID 2895925
* Localized file check-in by OneLocBuild Task: Build definition ID 1309: Build ID 2895925
* Localized file check-in by OneLocBuild Task: Build definition ID 1309: Build ID 2895925
* Localized file check-in by OneLocBuild Task: Build definition ID 1309: Build ID 2895925
* Localized file check-in by OneLocBuild Task: Build definition ID 1309: Build ID 2895925
* Localized file check-in by OneLocBuild Task: Build definition ID 1309: Build ID 2895925
* Localized file check-in by OneLocBuild Task: Build definition ID 1309: Build ID 2895925
* Localized file check-in by OneLocBuild Task: Build definition ID 1309: Build ID 2896434
* Localized file check-in by OneLocBuild Task: Build definition ID 1309: Build ID 2896434
* Localized file check-in by OneLocBuild Task: Build definition ID 1309: Build ID 2896434
* Allow subnet addressprefix to be a parameter. (#14358)
* Allow subnet addressprefix to be a parameter.
Follow-up feedback from #13108
* Add parameter to virtual network
* Fix typo in documentation for pnpm configuration (#14359)
* Suppress banner display for `aspire --version` (#14350)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: radical <1472+radical@users.noreply.github.com>
Co-authored-by: James Newton-King <james@newtonking.com>
* Add AKS starter deployment E2E test (#14351)
* Add AKS starter deployment E2E test (Phase 1)
This adds a new end-to-end deployment test that validates Azure Kubernetes Service (AKS) infrastructure creation:
- Creates resource group, ACR, and AKS cluster
- Configures kubectl credentials
- Verifies cluster connectivity
- Cleans up resources after test
Phase 1 focuses on infrastructure only - Aspire deployment will be added in subsequent phases.
* Fix AKS test: register required resource providers
Add step to register Microsoft.ContainerService and Microsoft.ContainerRegistry
resource providers before attempting to create AKS resources. This fixes the
MissingSubscriptionRegistration error when the subscription hasn't been
configured for AKS usage.
* Fix AKS test: use Standard_B2s_v2 VM size
The subscription in westus3 doesn't have access to Standard_B2s, only
the v2 series VMs. Changed to Standard_B2s_v2 which is available.
* Fix AKS test: use Standard_D2s_v3 VM size
The subscription has zero quota for B-series VMs in westus3. Changed to
Standard_D2s_v3 which is a widely-available D-series VM with typical quota.
* Add Phase 2 & 3: Aspire project creation, Helm chart generation, and AKS deployment
Phase 2 additions:
- Create Aspire starter project using 'aspire new'
- Add Aspire.Hosting.Kubernetes package via 'aspire add'
- Modify AppHost.cs to call AddKubernetesEnvironment() with ACR config
- Login to ACR for Docker image push
- Run 'aspire publish' to generate Helm charts and push images
Phase 3 additions:
- Deploy Helm chart to AKS using 'helm install'
- Verify pods are running with kubectl
- Verify deployments are healthy
This completes the full end-to-end flow: AKS cluster creation -> Aspire project
creation -> Helm chart generation -> Deployment to Kubernetes
* Fix Kubernetes deployment: Add container build/push step
Changes:
- Remove invalid ContainerRegistry property from AddKubernetesEnvironment
- Add pragma warning disable for experimental ASPIREPIPELINES001
- Add container build step using dotnet publish /t:PublishContainer
- Push container images to ACR before Helm deployment
- Override Helm image values with ACR image references
The Kubernetes publisher generates Helm charts but doesn't build containers.
We need to build and push containers separately using dotnet publish.
* Fix duplicate Service ports in Kubernetes publisher
When multiple endpoints resolve to the same port number, the Service
manifest generator was creating duplicate port entries, which Kubernetes
rejects as invalid. This fix deduplicates ports by (port, protocol)
before adding them to the Service spec.
Fixes the error:
Service 'xxx-service' is invalid: spec.ports[1]: Duplicate value
* Add explicit AKS-ACR attachment verification step
Added Step 6 to explicitly run 'az aks update --attach-acr' after AKS
cluster creation to ensure the AcrPull role assignment has properly
propagated. This addresses potential image pull permission issues where
AKS cannot pull images from the attached ACR.
Also renumbered all subsequent steps to maintain proper ordering.
* Fix AKS image pull: correct Helm value paths and add ACR check
* Fix duplicate Service/container ports: compare underlying values not Helm expressions
* Re-enable AppService deployment tests
* Add endpoint verification via kubectl port-forward to AKS test
* Wait for pods to be ready before port-forward verification
* Use retry loop for health endpoint verification and log HTTP status codes
* Use real app endpoints: /weatherforecast and / instead of /health
* Improve comments explaining duplicate port dedup rationale
* Refactor cleanup to async pattern matching other deployment tests
* Fix duplicate K8s ports: skip DefaultHttpsEndpoint in ProcessEndpoints
The Kubernetes publisher was generating duplicate Service/container ports
(both 8080/TCP) for ProjectResources with default http+https endpoints.
The root cause is that GenerateDefaultProjectEndpointMapping assigns the
same default port 8080 to every endpoint with None target port.
The proper fix mirrors the core framework's SetBothPortsEnvVariables()
behavior: skip the DefaultHttpsEndpoint (which the container won't listen
on — TLS termination happens at ingress/service mesh). The https endpoint
still gets an EndpointMapping (for service discovery) but reuses the http
endpoint's HelmValue, so no duplicate K8s port is generated.
Added Aspire.Hosting.Kubernetes to InternalsVisibleTo to access
ProjectResource.DefaultHttpsEndpoint. The downstream dedup in ToService()
and WithContainerPorts() remains as defense-in-depth.
Fixes https://github.com/dotnet/aspire/issues/14029
* Add AKS + Redis E2E deployment test
Validates the Aspire starter template with Redis cache enabled deploys
correctly to AKS. Exercises the full pipeline: webfrontend → apiservice
→ Redis by hitting the /weather page (SSR, uses Redis output caching).
Key differences from the base AKS test:
- Selects 'Yes' for Redis Cache in aspire new prompts
- Redis uses public container image (no ACR push needed)
- Verifies /weather page content (confirms Redis integration works)
* Fix ACR name collision between parallel AKS tests
Both AKS tests generated the same ACR name from RunId+RunAttempt.
Use different prefixes (acrs/acrr) to ensure uniqueness.
* Fix Redis Helm deployment: provide missing cross-resource secret value
Work around K8s publisher bug where cross-resource secret references create
Helm value paths under the consuming resource instead of referencing the
owning resource's secret. The webfrontend template expects
secrets.webfrontend.cache_password but values.yaml only has
secrets.cache.REDIS_PASSWORD. Provide the missing value via --set.
---------
Co-authored-by: Mitch Denny <mitch@mitchdeny.com>
* Improve Aspire skill frontmatter for better AI agent routing (#14364)
* Add AutoVerify to tests (#14357)
- when a Verify test fails, it auto-accepts the changes, so you can see the diff
- It fails the test (throwException: true)
- It doesn't do this on "build servers"
- https://github.com/VerifyTests/DiffEngine/blob/fef0776f63f0cfa1ac070f16d0925dee89faf9de/src/DiffEngine/BuildServerDetector.cs is the checks for what is considered a "build server"
* Add FileLoggerProvider for CLI log persistence and clean error messages (#14335)
- Add Channel-based async FileLoggerProvider writing to ~/.aspire/logs/
- Add --debug-level (-v) option for console log verbosity
- Show 'See logs at {path}' instead of raw stack traces on console
- Centralize child process option forwarding via RootCommand.GetChildProcessArgs()
- Suppress Microsoft.Hosting.Lifetime logs from file logger
- Log backchannel socket errors at Debug level when AppHost has exited
- Add log cleanup to 'aspire cache clear'
- Make CliExecutionContext.LogFilePath a required constructor parameter
Fixes #13787
* Fix CLI stop command description to include resource stopping (#14372)
* Initial plan
* Fix CLI stop command description to mention resource stopping
Updated description from "Stop a running Aspire apphost." to
"Stop a running apphost or the specified resource." in the resx
file and all XLF localization files.
Co-authored-by: JamesNK <303201+JamesNK@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: JamesNK <303201+JamesNK@users.noreply.github.com>
* Add deployed compute resources and endpoints to pipeline deployment summary (#14367)
* Initial plan
* Add deployed compute resources and endpoints to pipeline deployment summary
For both Azure Container Apps and Azure App Service deployments, the pipeline
summary now includes each compute resource name and its public endpoint URL
(or "No public endpoints" if none are configured). This makes it immediately
visible to users whether their services are publicly accessible after deployment.
Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com>
* Remove emoji from summary keys and add Docker Compose endpoint summary
Remove the emoji prefix (🖥️) from pipeline summary keys in
AzureContainerAppResource and AzureAppServiceWebSiteResource.
Add ctx.Summary.Add() calls to DockerComposeServiceResource.PrintEndpointsAsync()
so Docker Compose deployments also show compute resources and their endpoints
(or "No public endpoints") in the deployment summary.
Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com>
* Address PR review feedback: move endpoint check inside step lambda and simplify App Service
Move the anyPublicEndpoints check inside the step Action lambda in
AzureContainerAppResource so endpoints are evaluated at execution time,
not step creation time (addresses @eerhardt's feedback).
For AzureAppServiceWebSiteResource, remove the conditional entirely since
App Service always has a public endpoint at its .azurewebsites.net URL.
This restores the original always-show-URL behavior, avoids unnecessary
async resolution when there are no public endpoints, and addresses both
@eerhardt's and Copilot code review's feedback.
Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com>
* Implement IAzurePrivateEndpointTarget on more Azure resources (#14360)
* Implement IAzurePrivateEndpointTarget on more Azure resources
Follow up to #13108
Contributes to #13750
* Fix tests
* Fix Redis private dns zone name.
* Fixing package signature verification (#14380)
* Fix package signature verification and publishing commands to use dotnet.cmd
* Add .NET 10 SDK installation and update package verification commands
* Improve error handling in NuGet package verification and publishing steps
* Update dependencies from https://github.com/microsoft/dcp build 0.22.4 (#14381)
On relative base path root
Microsoft.DeveloperControlPlane.darwin-amd64 , Microsoft.DeveloperControlPlane.darwin-arm64 , Microsoft.DeveloperControlPlane.linux-amd64 , Microsoft.DeveloperControlPlane.linux-arm64 , Microsoft.DeveloperControlPlane.linux-musl-amd64 , Microsoft.DeveloperControlPlane.windows-amd64 , Microsoft.DeveloperControlPlane.windows-arm64 From Version 0.22.3 -> To Version 0.22.4
Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
* Fix aspire doctor to only warn about multiple dev certs when any is untrusted (#14379)
* Fix aspire doctor to only warn about multiple dev certs when any is untrusted
Previously, aspire doctor always showed a warning when multiple dev
certificates were found, even if all were trusted. This changes the
behavior so that:
- Multiple certs, all trusted: Pass (no warning)
- Multiple certs, some untrusted: Warning
- Multiple certs, none trusted: Warning
The certificate evaluation logic was extracted into a testable static
method (EvaluateCertificateResults) and 10 unit tests were added to
cover all scenarios.
* Address PR review feedback
- Remove unreachable else-if branch (trustedCount > 1 when certInfos.Count <= 1 is impossible; this was pre-existing dead code)
- Use MinimumCertificateVersionSupportingContainerTrust constant in tests instead of hard-coded version numbers
* Add dashboard URL to pipeline summary for ACA and App Service deployments (#14377)
* Initial plan
* Add ACA and AppService dashboard summary links to pipeline summary
Co-authored-by: eerhardt <8291187+eerhardt@users.noreply.github.com>
* Change dashboard summary emoji from 🔗 to 📊
Co-authored-by: eerhardt <8291187+eerhardt@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: eerhardt <8291187+eerhardt@users.noreply.github.com>
* Add self-contained bundle infrastructure for polyglot apphost (#14105)
* Add self-contained bundle infrastructure for polyglot AppHosts
* Add --debug flag to failing E2E tests for diagnostics
* Retry CI - PDB file lock was transient
* Make localhive install aspire.exe
* Fix local hive packages location
* Hande previous local hive layout
* Update clie2e test
* Fix LogsCommandTests: output to terminal, add ps verification
Root cause: aspire logs apiservice > logs.txt 2>&1 captured stderr
(dotnet runtime warnings) and Spectre.Console spinner output instead
of actual log content. The grep for [apiservice] found nothing, timing
out after 10 seconds.
Changes:
- Add aspire ps step to verify AppHost is discoverable before logs
- Output aspire logs directly to terminal instead of file redirect
- Search for [apiservice] in terminal buffer (30s timeout)
- Search for 'logs' key in JSON output instead of 'resourceName'
- Remove intermediate file-based verification steps (wc/head/grep)
- Align with PsCommandTests pattern (proven to work in CI)
* Fix LogsCommandTests: don't assert on log content in snapshot mode
The aspire logs command in snapshot mode (without --follow) returns empty
output even when the AppHost is running and resources are producing logs.
This is a known limitation of the current implementation where
GetResourceLogsAsync/GetAllAsync returns no buffered logs.
The test now verifies:
- aspire ps finds the running AppHost (content check)
- aspire logs apiservice completes successfully (exit code check)
- aspire logs --format json returns valid JSON with 'logs' key (content check)
- aspire stop completes successfully (content check)
* Add CLI and AppHost SDK version logging to LogsCommandTests
Log aspire --version and the AppHost csproj SDK version during the
test for diagnostics. This helps verify whether a version mismatch
between the CLI and AppHost is causing empty logs output.
* Add diagnostic logging to aspire logs pipeline and E2E test
* Upgrade diagnostic logging to Information level for AppHost log visibility
* Add stderr diagnostics in ResourceLoggerState.GetAllAsync to trace console logs path
* Fix LogsCommandTests: increase template search timeout, remove diagnostic logging
* Add file-based diagnostics to trace empty aspire logs root cause
* Fix aspire logs returning empty output
DCP-sourced logs were only stored in the backlog when Dashboard
subscribers were actively watching the resource. Without subscribers,
AddLog silently dropped DCP logs, and GetAllAsync could not retrieve
them since DCP snapshot streams return empty when a follow-mode stream
is already consuming logs.
Fix: Always store all log entries (both DCP and in-memory) in the
backlog regardless of subscriber status. This ensures aspire logs
can retrieve accumulated logs at any time. The WatchAsync replay
of in-memory entries on first subscription is no longer needed since
the backlog already contains everything.
* Restore log content assertions in LogsCommandTests
* Add diagnostic logging to trace empty aspire logs on CI
TEMP: File-based diagnostic logging at three key points:
- RPC target: resource name, resolved names, logger keys
- ResourceLoggerState.GetAllAsync: backlog count, in-memory count
- DcpExecutor.GetAllLogsAsync: resource map keys, lookup result
The test dumps these diag files from /tmp after running aspire logs.
This logging will be removed once the root cause is identified.
* TEMP: Disable unrelated CI jobs, keep only CLI E2E tests
Speeds up inner loop for debugging LogsCommandTests.
Disabled: integrations, templates, endtoend, polyglot, extension tests.
Disabled: macOS and Windows setup jobs.
Will be reverted once LogsCommandTests is fixed.
* Fix aspire logs: temporarily subscribe to trigger DCP log stream
When GetAllAsync finds an empty backlog, it means no subscriber has
triggered StartLogStream in DCP yet. Fix by temporarily subscribing
to the OnNewLog event (which triggers SubscribersChanged -> StartLogStream),
waiting 5s for log entries to arrive, then returning collected entries.
This ensures 'aspire logs' works in snapshot mode even when no dashboard
or other viewer has opened the resource's console logs.
* Add more diag logging, wait 30s before logs, add unfiltered logs call, WatchAsync fallback fix
* Switch logs test to webfrontend (apiservice has no console output), keep diag logging
* Add direct dotnet run diag + ResourceLogSource stream-level diag for apiservice
* Add fd comparison and DCP log dir diagnostics for apiservice vs webfrontend
* Fix aspire logs for executables: always start log streams, revert diagnostics
DCP does not reliably serve executable logs via snapshot (follow=false)
requests. Fix by always starting follow-mode log streams for executables
when logs become available, regardless of subscriber state. This populates
the backlog so snapshot reads return data.
Also add a WatchAsync fallback in GetAllAsync as a safety net: if no logs
are found from the backlog or DCP snapshot, temporarily subscribe to
trigger the log stream and collect whatever arrives within 10 seconds.
Revert all temporary CI workflow changes and diagnostic logging.
* Add resource status and dashboard diagnostics to LogsCommandTests
* Fix dashboard binary name mismatch, revert DcpExecutor/ResourceLoggerService workarounds
The AssemblyName change to 'aspire-dashboard' in Aspire.Dashboard.csproj
renamed the output binary, but three MSBuild files still referenced the
old name 'Aspire.Dashboard'. On Linux (case-sensitive), the dashboard
failed to launch, which prevented DCP from capturing executable logs.
Updated:
- eng/dashboardpack/Sdk.targets
- eng/dashboardpack/UnixFilePermissions.xml
- src/Aspire.Hosting.AppHost/build/Aspire.Hosting.AppHost.in.targets
Reverted the DcpExecutor and ResourceLoggerService workarounds as they
are no longer needed with the dashboard launching correctly.
* Restore build_bundle job in tests.yml for polyglot validation
The build_bundle job was lost when tests.yml was reverted to main during
debugging. The polyglot validation workflow requires the aspire-bundle
artifact which is produced by build-bundle.yml.
* Centralize dashboard binary name into single MSBuild property
Define AspireDashboardBinaryName in Directory.Build.props as the single
source of truth. Use it in the Dashboard csproj and AppHost.in.targets.
Add comments to NuGet-shipped files (Sdk.targets, UnixFilePermissions.xml)
and BundleDiscovery.cs pointing to the source of truth.
Add EnsureDashboardBinaryNameIsConsistentAcrossFiles test that validates
all 5 files reference the same binary name, preventing the silent name
mismatch that caused the LogsCommandTests CI failure.
* Fix EnsureDashboardBinaryNameIsConsistentAcrossFiles assertion
The DoesNotContain assertion was too broad - searching for
'aspire-dashboard') matched unrelated content in the targets file.
Narrowed it to check specifically that NormalizePath doesn't use
a hardcoded name.
* Remove DotNetSdkBasedAppHostServerProject and merge DevAppHostServerProject into base class
- Delete DotNetSdkBasedAppHostServerProject (SDK-based package reference mode)
- Merge DevAppHostServerProject into DotNetBasedAppHostServerProject (now sealed)
- Update AppHostServerProjectFactory to remove SDK fallback path
- Remove SDK-specific tests and snapshot
- Update stale comments in PrebuiltAppHostServer
* Remove unused sdkVersion parameter from CreateProjectFilesAsync
* Auto-detect Aspire repo root and improve factory fallback
- Priority 1: Dev mode if ASPIRE_REPO_ROOT is set or CLI runs from
Aspire source repo (detected via .git + Aspire.slnx)
- Priority 2: PrebuiltAppHostServer if bundle layout is available
- Fallback: Throw explaining both options are needed
* Import repo Directory.Packages.props and fix dashboard binary name
- Generate Directory.Packages.props in project model path that imports
the repo's central package management, enabling version-less PackageReferences
- Remove hardcoded StreamJsonRpc/Google.Protobuf versions (now from CPM)
- Add AspireDashboardBinaryName property to fix empty dashboard DLL path
* Revert dashboard assembly name changes, set ASPNETCORE_ENVIRONMENT=Development in dev mode
Revert all changes that renamed the dashboard binary from Aspire.Dashboard
to aspire-dashboard. The assembly name returns to its default (project name).
Set ASPNETCORE_ENVIRONMENT=Development on the AppHost server process in dev
mode so the dashboard can resolve static web assets from the debug build
via the .staticwebassets.runtime.json manifest.
* Fix dashboard startup in bundle mode for .NET csproj app hosts
Remove ConfigureLayoutEnvironment from DotNetAppHostProject. .NET csproj
app hosts resolve DCP and Dashboard paths through NuGet assembly metadata,
so setting ASPIRE_DASHBOARD_PATH/ASPIRE_DCP_PATH env vars from the bundle
layout is unnecessary and was causing the dashboard to fail (the env var
pointed to a directory, but the hosting code expected an executable path).
Polyglot/guest app hosts (PrebuiltAppHostServer) still correctly set these
env vars since they don't have NuGet packages.
Add BundleSmokeTests E2E test that creates a starter app with the full
bundle installed and verifies the dashboard is actually reachable via curl
(not just that the URL appears on screen).
* Install bundle to ~/.aspire instead of ~/.aspire/bundle
Align PR bundle install scripts with the release install script layout.
The CLI binary and all components (runtime, dashboard, dcp, aspire-server)
are siblings in ~/.aspire/, so auto-discovery works without needing
ASPIRE_LAYOUT_PATH. This also avoids conflicts with the CLI-only install
at ~/.aspire/bin/.
* Use aspire CLI commands in BundleSmokeTests instead of grep
- Use 'aspire ps --format json' for dashboard URL extraction instead of
grep -oP which is not available on macOS (BSD grep lacks -P flag)
- Use 'aspire stop' for graceful cleanup instead of manual PID management
- Add -L to curl to follow 302 redirect from dashboard base URL
* Fix NullReferenceException in ResourceSnapshotMapper when collection properties are null
When resource snapshots are deserialized from the backchannel RPC, collection
properties (Urls, Volumes, HealthReports, EnvironmentVariables, Properties,
Relationships, Commands) can be null despite having default values in the class
definition. This caused 'aspire resources --format Json' to throw a
NullReferenceException.
Add null-coalescing (?? []) to all collection property accesses in
MapToResourceJson() and a null-check before calling
ResourceSource.GetSourceModel() with Properties.
* Fix 'aspire new' with --non-interactive failing for templates with prompts
GetTemplates() did not pass the nonInteractive flag to GetTemplatesCore(),
so templates like aspire-apphost-singlefile always used the interactive code
path with prompts. When --non-interactive was set, the prompt methods threw
InvalidOperationException ('Interactive input is not supported').
Inject ICliHostEnvironment into DotNetTemplateFactory and derive the
GetTemplates().
* Move bundle CLI to bin/ subdir for consistent install path
- LayoutDiscovery.TryDiscoverRelativeLayout() now checks parent dir
for bundle components (CLI at bin/aspire, components at ../)
- Bundle install scripts move CLI to bin/ after extraction
- PATH uses ~/.aspire/bin (same as CLI-only install)
* Fix bundle script CDN caching: use commit SHA instead of branch ref
The install script is fetched from raw.githubusercontent.com which has
CDN caching. Using the branch ref can serve stale content after a push.
Use .head.sha instead of .head.ref to ensure the latest script is used.
Also add both ~/.aspire/bin and ~/.aspire to PATH for backwards
compatibility during the transition.
* Add diagnostics to BundleSmokeTests for dashboardUrl:null debugging
* Fix bundle install: set PR channel for template version compatibility
The bundle install script was not setting the global channel to 'pr-{N}',
unlike the CLI-only install script. This caused 'aspire new' to use
stable 13.1.0 templates which lack GetDashboardUrlsAsync RPC method,
resulting in dashboardUrl:null in detach mode.
Also removes diagnostic output from BundleSmokeTests.
* Add NuGet hive install to bundle scripts for PR template compatibility
The bundle install scripts were missing NuGet hive package installation,
which the CLI-only install scripts already do. Without the hive, setting
channel to 'pr-{N}' fails because the PR channel packages don't exist.
Now both bash and PowerShell bundle scripts download built-nugets and
built-nugets-for-{rid} artifacts and install them to the hive directory
at ~/.aspire/hives/pr-{N}/packages, matching the CLI-only behavior.
* Extract XML doc files alongside DLLs in NuGetHelper LayoutCommand
When creating the flat DLL layout for the AppHost server, also copy
the .xml documentation file for each runtime assembly if it exists.
This enables IntelliSense and MCP context for polyglot AppHosts.
* Unquarantine TypeScriptPolyglotTests
* Update bundle spec and fix TypeScriptPolyglotTests version selection
- Update docs/specs/bundle.md to reflect current install layout (~/.aspire/bin/ + sibling components)
- Fix TypeScriptPolyglotTests: navigate down to pr-{N} channel in aspire add version prompt
* Clean up: use IConfiguration in AssemblyLoader, remove IL3000 suppression, remove debug flags from E2E tests
* Restore IL3000 suppression - needed for single-file bundle publish
* Make PrebuiltAppHostServer channel-aware
- Resolve configured channel (local settings.json → global config fallback)
- Filter NuGet sources to resolved channel instead of all explicit channels
- Return channel name in PrepareResult so it flows to settings.json
- Remove DownArrow workaround in TypeScriptPolyglotTests (channel auto-resolves)
* Fix TypeScriptPolyglotTests: accept version prompt after channel auto-resolve
* Fix TypeScriptPolyglotTests: wait for version string, not prompt title
Spectre.Console briefly renders the channel name before redrawing with
the actual version. Waiting for the prompt title caused Enter to be sent
during the redraw window, where it was swallowed. Instead, wait for the
version string (e.g. 'pr.14105') which only appears after the prompt is
fully rendered.
* Add delay before Enter on version prompt in TypeScriptPolyglotTests
Spectre.Console selection prompts need a brief delay after rendering
before they accept input. Without this, Enter is sent before the
prompt's input handler is ready and gets discarded. This follows the
same pattern used in AgentCommandTests.
* Auto-select single-item version prompts in aspire add
When the version selection has only one channel or one version,
auto-select it instead of showing a single-item Spectre prompt.
This improves UX and fixes the flaky TypeScript E2E test where
two back-to-back single-item prompts caused Enter to be lost.
* Remove accidentally committed cast file
* Remove debug artifacts from CI investigation
* Fix inaccurate README content for CreateLayout and install scripts
- Fix option name: --version → --bundle-version
- Fix example version: 9.2.0 → 13.2.0
- Fix build script syntax: build.sh --restore --build -bundle → build.sh -bundle
- Fix package sizes: CLI ~25 MB, bundle ~200 MB compressed
- Fix runtime download: actually downloads SDK, extracts runtimes + dev-certs
- Fix output structure: remove incorrect DLL names, add dotnet muxer
- Remove overly specific internal file names from layout diagram
---------
Co-authored-by: Sebastien Ros <sebastienros@gmail.com>
* AKS E2E tests: Redis variant, port fix, and reliability improvements (#14371)
* Add AKS starter deployment E2E test (Phase 1)
This adds a new end-to-end deployment test that validates Azure Kubernetes Service (AKS) infrastructure creation:
- Creates resource group, ACR, and AKS cluster
- Configures kubectl credentials
- Verifies cluster connectivity
- Cleans up resources after test
Phase 1 focuses on infrastructure only - Aspire deployment will be added in subsequent phases.
* Fix AKS test: register required resource providers
Add step to register Microsoft.ContainerService and Microsoft.ContainerRegistry
resource providers before attempting to create AKS resources. This fixes the
MissingSubscriptionRegistration error when the subscription hasn't been
configured for AKS usage.
* Fix AKS test: use Standard_B2s_v2 VM size
The subscription in westus3 doesn't have access to Standard_B2s, only
the v2 series VMs. Changed to Standard_B2s_v2 which is available.
* Fix AKS test: use Standard_D2s_v3 VM size
The subscription has zero quota for B-series VMs in westus3. Changed to
Standard_D2s_v3 which is a widely-available D-series VM with typical quota.
* Add Phase 2 & 3: Aspire project creation, Helm chart generation, and AKS deployment
Phase 2 additions:
- Create Aspire starter project using 'aspire new'
- Add Aspire.Hosting.Kubernetes package via 'aspire add'
- Modify AppHost.cs to call AddKubernetesEnvironment() with ACR config
- Login to ACR for Docker image push
- Run 'aspire publish' to generate Helm charts and push images
Phase 3 additions:
- Deploy Helm chart to AKS using 'helm install'
- Verify pods are running with kubectl
- Verify deployments are healthy
This completes the full end-to-end flow: AKS cluster creation -> Aspire project
creation -> Helm chart generation -> Deployment to Kubernetes
* Fix Kubernetes deployment: Add container build/push step
Changes:
- Remove invalid ContainerRegistry property from AddKubernetesEnvironment
- Add pragma warning disable for experimental ASPIREPIPELINES001
- Add container build step using dotnet publish /t:PublishContainer
- Push container images to ACR before Helm deployment
- Override Helm image values with ACR image references
The Kubernetes publisher generates Helm charts but doesn't build containers.
We need to build and push containers separately using dotnet publish.
* Fix duplicate Service ports in Kubernetes publisher
When multiple endpoints resolve to the same port number, the Service
manifest generator was creating duplicate port entries, which Kubernetes
rejects as invalid. This fix deduplicates ports by (port, protocol)
before adding them to the Service spec.
Fixes the error:
Service 'xxx-service' is invalid: spec.ports[1]: Duplicate value
* Add explicit AKS-ACR attachment verification step
Added Step 6 to explicitly run 'az aks update --attach-acr' after AKS
cluster creation to ensure the AcrPull role assignment has properly
propagated. This addresses potential image pull permission issues where
AKS cannot pull images from the attached ACR.
Also renumbered all subsequent steps to maintain proper ordering.
* Fix AKS image pull: correct Helm value paths and add ACR check
* Fix duplicate Service/container ports: compare underlying values not Helm expressions
* Re-enable AppService deployment tests
* Add endpoint verification via kubectl port-forward to AKS test
* Wait for pods to be ready before port-forward verification
* Use retry loop for health endpoint verification and log HTTP status codes
* Use real app endpoints: /weatherforecast and / instead of /health
* Improve comments explaining duplicate port dedup rationale
* Refactor cleanup to async pattern matching other deployment tests
* Fix duplicate K8s ports: skip DefaultHttpsEndpoint in ProcessEndpoints
The Kubernetes publisher was generating duplicate Service/container ports
(both 8080/TCP) for ProjectResources with default http+https endpoints.
The root cause is that GenerateDefaultProjectEndpointMapping assigns the
same default port 8080 to every endpoint with None target port.
The proper fix mirrors the core framework's SetBothPortsEnvVariables()
behavior: skip the DefaultHttpsEndpoint (which the container won't listen
on — TLS termination happens at ingress/service mesh). The https endpoint
still gets an EndpointMapping (for service discovery) but reuses the http
endpoint's HelmValue, so no duplicate K8s port is generated.
Added Aspire.Hosting.Kubernetes to InternalsVisibleTo to access
ProjectResource.DefaultHttpsEndpoint. The downstream dedup in ToService()
and WithContainerPorts() remains as defense-in-depth.
Fixes https://github.com/dotnet/aspire/issues/14029
* Add AKS + Redis E2E deployment test
Validates the Aspire starter template with Redis cache enabled deploys
correctly to AKS. Exercises the full pipeline: webfrontend → apiservice
→ Redis by hitting the /weather page (SSR, uses Redis output caching).
Key differences from the base AKS test:
- Selects 'Yes' for Redis Cache in aspire new prompts
- Redis uses public container image (no ACR push needed)
- Verifies /weather page content (confirms Redis integration works)
* Fix ACR name collision between parallel AKS tests
Both AKS tests generated the same ACR name from RunId+RunAttempt.
Use different prefixes (acrs/acrr) to ensure uniqueness.
* Fix Redis Helm deployment: provide missing cross-resource secret value
Work around K8s publisher bug where cross-resource secret references create
Helm value paths under the consuming resource instead of referencing the
owning resource's secret. The webfrontend template expects
secrets.webfrontend.cache_password but values.yaml only has
secrets.cache.REDIS_PASSWORD. Provide the missing value via --set.
* Move ACR login before AKS creation to avoid OIDC token expiration
The OIDC federated token expires after ~5 minutes, but AKS cluster
creation takes 10-15 minutes. By the time the test reaches az acr login,
the assertion is stale. Moving ACR auth to right after ACR creation
ensures the OIDC token is still fresh, and Docker credentials persist
in ~/.docker/config.json for later use.
* Add pod diagnostics for Redis test: accept kubectl wait failure gracefully
The kubectl wait step was blocking the test when Redis pods failed to
start. Now accepts either OK or ERR exit, captures pod logs for
diagnostics, and continues to verify what we can.
* Wait only for project resource pods, skip Redis (K8s publisher bug #14370)
Redis container crashes with 'cannot open redis-server: No such file'
due to incorrect container command generated by the K8s publisher.
The webfrontend handles Redis being unavailable gracefully. Wait only
for apiservice and webfrontend pods using label selectors, and capture
Redis pod logs for diagnostics.
* Remove redundant weather page grep check (Blazor SSR streaming issue)
The curl -sf /weather | grep 'Weather' step fails because Blazor SSR
streaming rendering returns incomplete initial HTML via curl. The
/weather endpoint already returns 200 (verified in previous step),
which is sufficient to confirm the full pipeline works.
* Add --max-time 10 to /weather curl (Blazor SSR streaming keeps connection open)
Blazor SSR streaming rendering keeps the HTTP connection open to stream
updates to the browser. curl waits indefinitely for the response to
complete, causing the WaitForSuccessPrompt to time out. Adding --max-time
ensures curl returns after receiving the initial 200 status code.
* Fix /weather curl: capture status code in variable to handle SSR streaming
curl --max-time exits with code 28 (timeout) even when HTTP 200 was
received, because Blazor SSR streaming keeps the connection open. This
causes the && chain to fail, so echo/break never execute. Fix by using
semicolons and capturing the status code in a variable, then checking
it explicitly with [ "$S" = "200" ].
* Fix K8s publisher: set ExecutionContext on CommandLineArgsCallbackContext
The K8s publisher was not setting ExecutionContext when creating the
CommandLineArgsCallbackContext in ProcessArgumentsAsync, causing it to
default to Run mode. This made Redis's WithArgs callback produce
individual args instead of a single -c shell command string, resulting
in '/bin/sh redis-server' (open as script) instead of
'/bin/sh -c "redis-server ..."' (execute as command).
Matches the Docker Compose publisher which correctly sets
ExecutionContext = executionContext.
Also updates the Redis E2E test to wait for all pods (including cache)
and verify Redis responds to PING.
* Avoid leaking Redis password in test logs
Expand $REDIS_PASSWORD inside the container shell instead of extracting
it from the K8s secret on the host. Also use --no-auth-warning to
suppress redis-cli's password-on-command-line warning.
* Replace kubectl exec redis-cli with pod status check to avoid container name issue
* Set REDIS_PASSWORD in helm install to prevent redis-server --requirepass with empty arg
* Fix Helm secret path: use parameter name (cache_password) not env var key (REDIS_PASSWORD)
The K8s publisher AllocateParameter creates Helm expressions using the parameter
name (cache-password -> cache_password), but AddValuesToHelmSectionAsync writes
values using the env var key (REDIS_PASSWORD). The template references
.Values.secrets.cache.cache_password but values.yaml has REDIS_PASSWORD, so the
password is always empty and Redis crashes with 'requirepass' having no argument.
* Use dynamically generated GUID for Redis password instead of hardcoded value
* Pass same Redis password to webfrontend so it can authenticate to Redis cache
---------
Co-authored-by: Mitch Denny <mitch@mitchdeny.com>
* Update Hex1b packages to 0.78.0 and add dependency-update skill (#14400)
* Add dependency-update skill for external NuGet package updates
- SKILL.md: Agent instructions for version lookup, changelog review,
user confirmation, and pipeline orchestration
- migrate-package.sh: Companion script to trigger and monitor the
dotnet-migrate-package Azure DevOps pipeline (def 931)
- AGENTS.md: Register new skill in Available Skills section
* Rewrite migrate-package script as single-file C# app
Replace migrate-package.sh with MigratePackage.cs using:
- Azure.Identity (AzureCliCredential) for authentication
- Azure DevOps .NET SDK (PipelinesHttpClient) for pipeline
triggering via RunPipelineAsync and polling via GetRunAsync
- Auto-detection of Microsoft corp tenant for token acquisition
Add .editorconfig and Directory.Packages.props overrides to
allow standalone #:package directives within the repo's CPM.
* Update Hex1b packages to 0.75.0 and add Hex1b.Tool
- Hex1b: 0.48.0 → 0.75.0
- Hex1b.McpServer: 0.48.0 → 0.75.0
- Hex1b.Tool: added at 0.75.0 (new dotnet tool)
All three packages imported via dotnet-migrate-package pipeline:
- Hex1b: Run 2898644 (succeeded)
- Hex1b.McpServer: Run 2898645 (succeeded)
- Hex1b.Tool: Run 2898650 (succeeded)
* Update .github/skills/dependency-update/MigratePackage.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update Hex1b.McpServer and Hex1b.Tool to 0.77.0
* Update Hex1b packages to 0.78.0
---------
Co-authored-by: Mitch Denny <mitch@mitchdeny.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Re-enable container tunnel tests (#14412)
Latest DCP insertion should have fixed this.
Fixes https://github.com/dotnet/aspire/issues/14325
* Ensure DCP path is valid (#14415)
* Add ATS API surface tracking workflow (#14418)
* Add ATS API surface tracking workflow with SqlServer example
Add generate-ats-diffs.yml workflow that:
- Runs aspire sdk dump --ci for each Aspire.Hosting.* project with [AspireExport] attributes
- Saves output as .ats.txt files in each project's api/ directory
- Dynamically discovers integration projects (excludes Analyzers, CodeGeneration, RemoteHost)
- Auto-creates PR with NO-MERGE label (matching generate-api-diffs.yml pattern)
Include SqlServer .ats.txt as an example of the generated output.
Add workflow to CI exclusion list.
* Fix review issues in generate-ats-diffs workflow
- Fix subdirectory discovery: walk up from matched file to find nearest
.csproj instead of assuming flat project layout
- Fix silent failures: remove set +e and continue-on-error, track
failures per project, exit non-zero if any fail, exit immediately
if core dump fails
- Fix inefficiency: build CLI once in a separate step, use --no-build
in the loop
* Add AspireExport coverage for Aspire.Hosting.Azure.Storage (#14420)
* Add AspireExport coverage for Aspire.Hosting.Azure.Storage
Add [AspireExport] attributes to 15 public extension methods and
[AspireExportIgnore] to 2 incompatible methods in AzureStorageExtensions.cs,
enabling polyglot (TypeScript) app host support for Azure Storage.
Exported methods:
- addAzureStorage, runAsEmulator
- withDataBindMount, withDataVolume
- withBlobPort, withQueuePort, withTablePort, withApiVersionCheck
- addBlobs, addDataLake, addTables, addQueues
- addBlobContainer, addDataLakeFileSystem, addQueue
Ignored methods:
- AddBlobContainer(AzureBlobStorageResource) - obsolete
- WithRoleAssignments - params StorageBuiltInRole[] not ATS-compatible
Includes TypeScript validation app host in playground/polyglot.
* Remove .aspire/ folders from playground/polyglot tracking
Remove the gitignore un-ignore rule for playground/polyglot/**/.aspire/
so these machine-specific settings (channels, SDK versions, local paths)
are not tracked. The global .aspire/ ignore rule now applies uniformly.
* Fix review
* Fix Spectre markup escaping bugs across CLI commands (#14422)
* Add failing tests for unescaped Spectre markup in CLI output
* Fix Spectre markup escaping bugs across CLI commands
- ConsoleInteractionService: Escape appHostHostingVersion, RequiredCapability
in DisplayIncompatibleVersionError, and newerVersion/updateCommand in
DisplayVersionUpdateNotification
- RunCommand: Remove double-escaping of ex.Message before DisplayError
(lines 355,362,371), escape resource/endpoint names in Markup (line 313),
escape log file paths in DisplayMessage (lines 366,375,850)
- LogsCommand: Escape logLine.ResourceName in MarkupLine (line 337)
- TelemetryLogsCommand/TelemetrySpansCommand: Escape resourceName in
MarkupLine (lines 261,267)
- Add tests: DisplayError double-escape verification, DisplayMessage with
escaped/unescaped paths, DisplaySubtleMessage default escaping,
choice prompt with bracket-containing Azure subscription names
* Fix Spectre markup escaping: escape link targets and CLI version string
- RunCommand: escape endpoint URL in link= attribute (IPv6 [::1] URLs crash Spectre)
- ConsoleInteractionService: escape cliInformationalVersion (brackets in build metadata crash Spectre)
- Verified: LogsCommand double-escaping is NOT a bug (both approaches produce identical markup)
* Remove tests that don't exercise actual Spectre escaping
* Fix DisplayIncompatibleVersionError showing capability name instead of hosting version
* Add NAT Gateway and Public IP Address support to Azure Virtual Network (#14413)
* Add NAT Gateway and Public IP Address support to Azure Virtual Network
Add AzureNatGatewayResource and AzurePublicIPAddressResource as standalone
top-level Azure provisioning resources. A NAT Gateway provides deterministic
outbound IP addresses for subnet resources.
Key design decisions:
- NAT Gateway is a standalone resource (builder.AddNatGateway), not a VNet child
- A Public IP Address is auto-created inline in the NAT Gateway bicep module
when no explicit PIP is provided via WithPublicIPAddress()
- AzurePublicIPAddressResource is a public reusable type for explicit PIP scenarios
- Cross-module references use BicepOutputReference + AsProvisioningParameter
- Advanced config (idle timeout, zones) available via ConfigureInfrastructure
New public API:
- AzureNatGatewayResource (.Id, .NameOutput)
- AzurePublicIPAddressResource (.Id, .NameOutput)
- AddNatGateway() extension on IDistributedApplicationBuilder
- AddPublicIPAddress() extension on IDistributedApplicationBuilder
- WithPublicIPAddress() extension on IResourceBuilder<AzureNatGatewayResource>
- WithNatGateway() extension on IResourceBuilder<AzureSubnetResource>
* Address PR feedback
Add Tag to auto-created Public IP Address.
* Add Network Security Group (NSG) support for Azure Virtual Networks (#14383)
## Description
Adds Network Security Group (NSG) support for Azure Virtual Networks, enabling fine-grained network traffic control for subnets. Includes both a **shorthand API** for the common case and an **explicit API** for full control.
### Shorthand API (recommended for most users)
Fluent methods on subnet builders that auto-create an NSG, auto-increment priority, and auto-generate rule names:
```csharp
var subnet = vnet.AddSubnet("web", "10.0.1.0/24")
.AllowInbound(port: "443", from: "AzureLoadBalancer", protocol: SecurityRuleProtocol.Tcp)
.DenyInbound(from: "VirtualNetwork")
.DenyInbound(from: "Internet");
```
### Explicit API (for full control)
Create standalone NSG resources with explicit `AzureSecurityRule` objects:
```csharp
var nsg = builder.AddNetworkSecurityGroup("web-nsg")
.WithSecurityRule(new AzureSecurityRule
{
Name = "allow-https",
Priority = 100,
Direction = SecurityRuleDirection.Inbound,
Access = SecurityRuleAccess.Allow,
Protocol = SecurityRuleProtocol.Tcp,
DestinationPortRange = "443"
});
var subnet = vnet.AddSubnet("web-subnet", "10.0.1.0/24")
.WithNetworkSecurityGroup(nsg);
```
### New public APIs
**Types:**
- `AzureNetworkSecurityGroupResource` — standalone `AzureProvisioningResource` with its own bicep module, `Id` and `NameOutput` outputs, and `AddAsExistingResource` support
- `AzureSecurityRule` — data class for rule configuration. `SourcePortRange`, `SourceAddressPrefix`, and `DestinationAddressPrefix` default to `"*"` to reduce verbosity
**Extension methods on `IDistributedApplicationBuilder`:**
- `AddNetworkSecurityGroup(name)` — creates a top-level NSG resource
**Extension methods on `IResourceBuilder<AzureNetworkSecurityGroupResource>`:**
- `WithSecurityRule(rule)` — adds a security rule (rejects duplicate names)
**Extension methods on `IResourceBuilder<AzureSubnetResource>`:**
- `WithNetworkSecurityGroup(nsg)` — associates an explicit NSG with a subnet
- `AllowInbound(port, from, to, protocol, priority, name)` — shorthand allow inbound rule
- `DenyInbound(...)` — shorthand deny inbound rule
- `AllowOutbound(...)` — shorthand allow outbound rule
- `DenyOutbound(...)` — shorthand deny outbound rule
### Key design decisions
- **NSG is a standalone `AzureProvisioningResource`** — generates its own bicep module (not inline in the VNet module). Subnets reference the NSG via cross-module parameter (`param nsg_outputs_id string`)
- **NSG is a top-level resource** (not a child of VNet), matching Azure's actual resource model
- **Shorthand methods auto-create an implicit NSG** named `{subnet}-nsg` when no NSG is assigned. Calling `WithNetworkSecurityGroup` after shorthand methods throws `InvalidOperationException` to prevent silent rule loss
- **Priority auto-increments** by 100 (100, 200, 300...) from the max existing priority
- **Rule names auto-generate** from access/direction/port/source (e.g., `allow-inbound-443-AzureLoadBalancer`)
- **Sensible defaults on `AzureSecurityRule`** — `SourcePortRange`, `SourceAddressPrefix`, `DestinationAddressPrefix` all default to `"*"`, reducing the common 10-line rule to ~5 required properties
- **A single NSG can be shared across multiple subnets**
- **Duplicate rule names** within an NSG are rejected with `ArgumentException`
* Bump the microsoft_docker_images group across 3 directories with 1 update (#14431)
Bumps the microsoft_docker_images group with 1 update in the /playground/withdockerfile/WithDockerfile.AppHost/qots directory: cbl-mariner/base/core.
Bumps the microsoft_docker_images group with 1 update in the /playground/publishers/Publishers.AppHost/qots directory: cbl-mariner/base/core.
Bumps the microsoft_docker_images group with 1 update in the /playground/withdockerfile/WithDockerfile.AppHost directory: cbl-mariner/base/core.
Updates `cbl-mariner/base/core` from 2.0.20251206 to 2.0.20260102
Updates `cbl-mariner/base/core` from 2.0.20251206 to 2.0.20260102
Updates `cbl-mariner/base/core` from 2.0.20251206 to 2.0.20260102
Co-authored-by: Dependabot <adodependabot@microsoft.com>
* Make aspire.exe a self-extracting binary for polyglot scenarios (#14398)
* Self-extracting bundle: trailer format, lazy extraction, setup command, build integration
- Add BundleTrailer (src/Shared/) with read/write/extract helpers for the
32-byte trailer appended to native AOT CLI binaries
- Change IAppHostServerProjectFactory.Create() → CreateAsync() and update
all 8 call sites (GuestAppHostProject, SdkGenerateCommand, SdkDumpCommand,
ScaffoldingService, AppHostServerSession)
- Add EnsureBundleAsync in AppHostServerProjectFactory that lazily extracts
the embedded tar.gz payload on first polyglot command (run/publish/add)
- Add 'aspire setup' command for explicit extraction with --install-path
and --force options
- Add --embed-in-cli option to CreateLayout tool that appends tar.gz
payload + trailer to the native CLI binary
- Update Bundle.proj to pass --embed-in-cli pointing to the layout CLI binary
* Add version check, update --self extraction, tests, and README docs
- Version marker file (.aspire-bundle-version) written after extraction;
EnsureBundleAsync and SetupCommand skip extraction when version matches
- update --self proactively extracts embedded payload after replacing binary
- 10 unit tests for BundleTrailer: roundtrip, payload slicing, version
marker, and tar.gz extraction with strip-components
- README documents self-extracting binary install path
* Centralize bundle extraction into BundleService, simplify update, update CI
- Extract IBundleService/BundleService with th…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What it looks like at the moment:
Description
The
stopcommand description says "Stop a running Aspire apphost." but the command also accepts an optionalresourceargument to stop a specific resource. Updated to "Stop a running apphost or the specified resource."StopCommandStrings.resxsource string<source>elements in all 13 XLF localization filesChecklist
<remarks />and<code />elements on your triple slash comments?aspire.devissue:Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.