Skip to content

[release/13.4] Remove duplicated profiles block from empty C# AppHost aspire.config.json#17820

Merged
joperezr merged 1 commit into
release/13.4from
backport/pr-17781-to-release/13.4
Jun 2, 2026
Merged

[release/13.4] Remove duplicated profiles block from empty C# AppHost aspire.config.json#17820
joperezr merged 1 commit into
release/13.4from
backport/pr-17781-to-release/13.4

Conversation

@aspire-repo-bot
Copy link
Copy Markdown
Contributor

@aspire-repo-bot aspire-repo-bot Bot commented Jun 2, 2026

Backport of #17781 to release/13.4

/cc @mitchdenny

Customer Impact

Customers running aspire new aspire-empty for a C# (.NET) project on 13.4 get an aspire.config.json whose profiles block duplicates the same content already in apphost.run.json. Reported externally as #17660 (regression vs 13.3.5, where only aspire.config.json was emitted and contained the profiles). The duplication is confusing and gives the impression that the two files could drift; it isn't a runtime failure, but it ships visible noise in every newly-scaffolded empty C# project.

Testing

  • Existing NewCommandTests updated to assert the new shape (aspire.config.json minimal; profiles only in apphost.run.json); 77/77 pass locally.
  • The runtime CI E2E Cli.EndToEnd-EmptyAppHostTemplateTests.CreateAndRunEmptyAppHostProject (scaffold → aspire start → curl dashboard for HTTP 200 → aspire stop) passes on the PR.
  • Dogfood-tested the PR build on macOS: scaffolded plain + --localhost-tld variants (verified file shapes), then aspire start → dashboard bound at the port from apphost.run.json → HTTP 200 → clean aspire stop.

Risk

Very low. Content-only change to the embedded empty-apphost/aspire.config.json template — no code paths altered. DotNetAppHostProject already reads apphost.run.json first and only falls back to aspire.config.json#profiles if the run.json is missing, so the removed block was dead for newly-scaffolded projects. Existing on-disk projects are not modified.

Regression?

Yes. Works in 13.3.5; regressed in 13.4 when #16828 re-added apphost.run.json alongside aspire.config.json (deliberate defense-in-depth for dotnet run apphost.cs compatibility, but it left the profiles block duplicated across both files).

@aspire-repo-bot aspire-repo-bot Bot requested a review from mitchdenny as a code owner June 2, 2026 03:56
Copilot AI review requested due to automatic review settings June 2, 2026 03:56
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 17820

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 17820"

@mitchdenny mitchdenny self-assigned this Jun 2, 2026
@mitchdenny mitchdenny added this to the 13.4.x milestone Jun 2, 2026
…json

The embedded CLI template src/Aspire.Cli/Templating/Templates/empty-apphost/aspire.config.json
shipped a profiles block that duplicated apphost.run.json. The canonical template in
src/Aspire.ProjectTemplates/templates/aspire-apphost-singlefile/aspire.config.json
intentionally has no profiles (per Damian's design): aspire run / dotnet run apphost.cs
honor apphost.run.json when present, so aspire.config.json for the C# Empty template
should only carry { "appHost": { "path": "apphost.cs" } }.

Updated NewCommandTests to:
- assert that aspire.config.json has no profiles block and pins appHost.path = apphost.cs
- assert that apphost.run.json carries the launch URLs (plain localhost and dev.localhost variants)
- drop the now-unused AssertHttpsApplicationUrlMatches helper

Fixes #17660

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mitchdenny mitchdenny force-pushed the backport/pr-17781-to-release/13.4 branch from 29c7ec8 to 714fa58 Compare June 2, 2026 05:02
@mitchdenny
Copy link
Copy Markdown
Member

Force-pushed the backport branch after rebasing onto current release/13.4 head (753568500).

The previous CI failures (Kubernetes deploy tests + ChannelUpdateWorkflowTests) were caused by the branch being out of date: it was based on 3cbbeb234, which predates #17819 (the 13.4.0 → 13.4.1 version bump). The Garnet K8s test log showed the smoking gun:

error: NU1102: Unable to find package Aspire.StackExchange.Redis with version (>= 13.4.0)
[Nearest version: 13.4.0-pr.17820.g29c7ec81]

NuGet treats the prerelease 13.4.0-pr.XXX as less than 13.4.0 in semver ordering, so the constraint failed even with --prerelease. After #17819 merged, all new release/13.4 branches build at 13.4.1-pr.XXX and the constraint resolves cleanly.

After the rebase the diff is unchanged (32+/-43 in empty-apphost/aspire.config.json and NewCommandTests.cs).

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

CLI E2E Tests unknown — 110 passed, 0 failed, 2 unknown (commit 714fa58)

View all recordings
Status Test Recording Job Artifacts
AddPackageInteractiveWhileAppHostRunningDetached Recording #79004403649 Logs
AddPackageWhileAppHostRunningDetached Recording #79004403649 Logs
AgentCommands_AllHelpOutputs_AreCorrect Recording #79004403066 Logs
AgentInitCommand_DefaultSelection_InstallsDefaultSkills Recording #79004403066 Logs
AgentInitCommand_MigratesDeprecatedConfig Recording #79004403066 Logs
AgentInitCommand_NonInteractive_BundleOnlySkillsBeyondCliCatalog_AreInstallable Recording #79004403066 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp Recording #79004403486 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_DevLocalhost Recording #79004403486 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_Isolated Recording #79004403486 Logs
AllPublishMethodsBuildDockerImages Recording #79004403362 Logs
AspireAddAndStartWorkAgainstLegacyAppHostTs Recording #79004403167 Logs
AspireAddPackageVersionToDirectoryPackagesProps Recording #79004403502 Logs
AspireInitSingleFileAppHostRunsViaDotnetRunAppHost Recording #79004402977 Logs
AspireInitWithExistingAppHostDirRecreatesMissingNuGetConfigAndPreservesFiles Recording #79004403565 Logs
AspireInitWithSolutionFileGeneratesAppHostThatBuildsAgainstChannelHive Recording #79004403565 Logs
AspireStartUpdatesStaleTypeScriptAppHostPath Recording #79004403002 Logs
AspireUpdateRemovesAppHostPackageVersionFromDirectoryPackagesProps Recording #79004403502 Logs
AspireUpdateRemovesOrphanAppHostPackageVersionWhenSdkAlreadyCurrent Recording #79004403502 Logs
Banner_DisplayedOnFirstRun Recording #79004403416 Logs
Banner_DisplayedWithExplicitFlag Recording #79004403416 Logs
Banner_NotDisplayedWithNoLogoFlag Recording #79004403416 Logs
CertificatesClean_RemovesCertificates Recording #79004403058 Logs
CertificatesTrust_WithNoCert_CreatesAndTrustsCertificate Recording #79004403058 Logs
CertificatesTrust_WithUntrustedCert_TrustsCertificate Recording #79004403058 Logs
ConfigSetGet_CreatesNestedJsonFormat Recording #79004403708 Logs
CreateAndRunAspireStarterProject Recording #79004403443 Logs
CreateAndRunAspireStarterProjectWithBundle Recording #79004403514 Logs
CreateAndRunEmptyAppHostProject Recording #79004403573 Logs
CreateAndRunJavaEmptyAppHostProject Recording #79004403500 Logs
CreateAndRunJsReactProject Recording #79004403541 Logs
CreateAndRunPolyglotAppHostWithDevLocalhostUrls Recording #79004403443 Logs
CreateAndRunPythonReactProject Recording #79004403262 Logs
CreateAndRunTypeScriptEmptyAppHostProject Recording #79004403622 Logs
CreateAndRunTypeScriptStarterProject Recording #79004403414 Logs
CreateJavaAppHostWithViteApp Recording #79004403119 Logs
CreateTypeScriptAppHostWithViteApp_AllowsGuestAppPackageManagerToDiffer Recording #79004403137 Logs
CreateTypeScriptAppHostWithViteApp_UsesConfiguredToolchain Recording #79004403137 Logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces Recording #79004403006 Logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces_DevLocalhost Recording #79004403006 Logs
DashboardRunWithOtelTracesReturnsNoTraces Recording #79004403006 Logs
DashboardRunWithOtelTracesReturnsNoTraces_DevLocalhost Recording #79004403006 Logs
DeployK8sBasicApiService Recording #79004403086 Logs
DeployK8sWithExternalHelmChart Recording #79004403478 Logs
DeployK8sWithGarnet Recording #79004403679 Logs
DeployK8sWithMongoDB Recording #79004403299 Logs
DeployK8sWithMySql Recording #79004403701 Logs
DeployK8sWithPostgres Recording #79004403179 Logs
DeployK8sWithRabbitMQ Recording #79004403440 Logs
DeployK8sWithRedis Recording #79004403598 Logs
DeployK8sWithSqlServer Recording #79004403222 Logs
DeployK8sWithValkey Recording #79004403191 Logs
DeployTypeScriptAppToKubernetes Recording #79004403056 Logs
DescribeCommandResolvesReplicaNames Recording #79004403671 Logs
DescribeCommandShowsRunningResources Recording #79004403671 Logs
DetachFormatJsonProducesValidJson Recording #79004403394 Logs
DetachFormatJsonProducesValidJsonWhenRestartingExistingInstance Recording #79004403394 Logs
DoPublishAndDeployListStepsWork Recording #79004403033 Logs
DocsCommand_RendersInteractiveMarkdownFromLocalSource Recording #79004403333 Logs
DoctorCommand_DetectsDeprecatedAgentConfig Recording #79004403066 Logs
DoctorCommand_TypeScriptAppHostReportsMissingConfiguredToolchain Recording #79004403127 Logs
DoctorCommand_WithSslCertDir_ShowsTrusted Recording #79004403127 Logs
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted Recording #79004403127 Logs
GatewayWithoutExternalEndpoint_FailsPublishWithGuidance Recording #79004403515 Logs
GeneratedAspireDevScript_StartsWatchMode_WithConfiguredToolchain Recording #79004403137 Logs
GlobalMigration_HandlesCommentsAndTrailingCommas Recording #79004403708 Logs
GlobalMigration_HandlesMalformedLegacyJson Recording #79004403708 Logs
GlobalMigration_PreservesAllValueTypes Recording #79004403708 Logs
GlobalMigration_SkipsWhenNewConfigExists Recording #79004403708 Logs
GlobalSettings_MigratedFromLegacyFormat Recording #79004403708 Logs
IngressWithoutExternalEndpoint_FailsPublishWithGuidance Recording #79004403515 Logs
InitTypeScriptAppHost_AugmentsExistingViteRepoInWorkspaceSubdirectory Recording #79004403137 Logs
InteractiveCSharpInitCreatesExpectedFiles Recording #79004403280 Logs
InvalidAppHostPathWithComments_IsHealedOnRun Recording #79004403334 Logs
JavaScriptHostingApisRunFromTypeScriptAppHost Recording #79004403362 Logs
LatestCliCanStartStableChannelAppHost Recording #79004403443 Logs
LatestCliCanStartStableChannelTypeScriptAppHost Recording #79004403443 Logs
LegacySettingsMigration_AdjustsRelativeAppHostPath Recording #79004403002 Logs
LogsCommandShowsResourceLogs Recording #79004403458 Logs
OtelLogsReturnsStructuredLogsFromStarterApp Recording #79004403538 Logs
OtelLogsReturnsStructuredLogsFromStarterAppIsolated Recording #79004403538 Logs
PsCommandListsRunningAppHost Recording #79004403659 Logs
PsFormatJsonOutputsOnlyJsonToStdout Recording #79004403659 Logs
PublishJavaScriptPatternsGeneratesExpectedDockerComposeArtifacts Recording #79004403582 Logs
PublishWithConfigureEnvFileUpdatesEnvOutput Recording #79004403582 Logs
PublishWithDockerComposeServiceCallbackSucceeds Recording #79004403582 Logs
PublishWithoutOutputPathUsesAppHostDirectoryDefault Recording #79004403582 Logs
ResourceCommand_FailedExecution_DisplaysAppHostLogPathAndLogContainsEntries Recording #79004403150 Logs
ResourceCommand_SetAndDeleteParameterUpdatesDescribeOutput Recording #79004403150 Logs
RestoreGeneratesSdkFiles Recording #79004403363 Logs
RestoreGeneratesSdkFiles_WithConfiguredToolchain Recording #79004403151 Logs
RestoreRefreshesGeneratedSdkAfterAddingIntegration Recording #79004403151 Logs
RestoreSupportsConfigOnlyHelperPackageAndCrossPackageTypes Recording #79004403043 Logs
RunFromParentDirectory_UsesExistingConfigNearAppHost Recording #79004403662 Logs
RunReportsSyntaxErrorsForDotNetAppHost Recording #79004403255 Logs
RunReportsSyntaxErrorsForTypeScriptAppHost Recording #79004403255 Logs
SecretCrudOnDotNetAppHost Recording #79004403004 Logs
SecretCrudOnTypeScriptAppHost Recording #79004403278 Logs
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels Recording #79004403408 Logs
StartAndWaitForTypeScriptSqlServerAppHostWithNativeAssets Recording #79004403115 Logs
StartReportsSyntaxErrorsForDotNetAppHost Recording #79004403255 Logs
StartReportsSyntaxErrorsForTypeScriptAppHost Recording #79004403255 Logs
StopAllAppHostsFromAppHostDirectory Recording #79004403457 Logs
StopJavaPolyglotAppHostUsingApphostDirectory Recording #79004403338 Logs
StopNonInteractiveSingleAppHost Recording #79004403457 Logs
StopTypeScriptPolyglotAppHostUsingApphostDirectory Recording #79004403081 Logs
StopWithNoRunningAppHostExitsSuccessfully Recording #79004403649 Logs
TypeScriptAppHostRunDoesNotDeadlockWhenLazyOptionsInvokeAsyncCallback Recording #79004403622 Logs
UnAwaitedChainsCompileWithAutoResolvePromises Recording #79004403151 Logs
UpdateProjectChannelToStable_CSharpEmptyAppHost_PreservesAspireConfigChannel Recording #79004403266 Logs
UpdateProjectChannelToStable_CSharpSingleFileInit_PreservesAspireConfigChannel Recording #79004403266 Logs
UpdateProjectChannelToStable_TypeScriptSingleFileInit_PreservesAspireConfigChannel Recording #79004403266 Logs
UpdateProjectChannelToStable_TypeScript_PreviewsStablePackagesAndPreservesChannel Recording #79004403266 Logs

📹 Recordings uploaded automatically from CI run #26799540403

@joperezr
Copy link
Copy Markdown
Member

joperezr commented Jun 2, 2026

IIRC, last time we looked at the run json file was because we had accidentally broken dotnet run on an apphost.cs single file. I'll go ahead and merge this but can we please do a validation once we have a build ready to ensure that works well after this?

@joperezr joperezr merged commit b4653b3 into release/13.4 Jun 2, 2026
311 checks passed
@joperezr joperezr deleted the backport/pr-17781-to-release/13.4 branch June 2, 2026 18:52
@microsoft-github-policy-service microsoft-github-policy-service Bot removed this from the 13.4.x milestone Jun 2, 2026
aspire-repo-bot Bot added a commit to microsoft/aspire.dev that referenced this pull request Jun 2, 2026
… AppHost

The C# empty AppHost template (aspire new aspire-empty) in Aspire 13.4
was generating a duplicate profiles block in aspire.config.json that
was also present in apphost.run.json. This regression is fixed in
microsoft/aspire#17820: launch profiles now live exclusively in
apphost.run.json and aspire.config.json is minimal (AppHost path only).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@aspire-repo-bot
Copy link
Copy Markdown
Contributor Author

Pull request created: #1192

Generated by PR Documentation Check

@aspire-repo-bot
Copy link
Copy Markdown
Contributor Author

📝 Documentation has been drafted in microsoft/aspire.dev#1192 targeting release/13.4.

Updated src/frontend/src/content/docs/whats-new/aspire-13-4.mdx to add a specific bullet in the CLI improvements section documenting that the C# empty AppHost template (aspire new aspire-empty) no longer emits a duplicate profiles block in aspire.config.json — launch profiles now live exclusively in apphost.run.json. This was a user-visible regression introduced in 13.4.

Note

This draft PR needs human review before merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants