Skip to content

Enable CLI bundle in C# AppHost templates - #19076

Merged
Damian Edwards (DamianEdwards) merged 2 commits into
mainfrom
damianedwards-update-apphost-cli-bundle-templates
Aug 12, 2026
Merged

Enable CLI bundle in C# AppHost templates#19076
Damian Edwards (DamianEdwards) merged 2 commits into
mainfrom
damianedwards-update-apphost-cli-bundle-templates

Conversation

@DamianEdwards

Copy link
Copy Markdown
Member

Description

New C# AppHosts should use the Aspire CLI bundle by default so they do not emit the opt-in warning and can use features provided by the bundled dashboard and DCP packages.

This updates all C# AppHost project templates, single-file AppHost templates, and the aspire init single-file skeleton to enable AspireUseCliBundle. The bundle smoke tests now verify that generated projects opt in without modifying the generated files.

User-facing usage

Generated AppHost projects now include:

<AspireUseCliBundle>true</AspireUseCliBundle>

Generated single-file AppHosts now include:

#:property AspireUseCliBundle=true

Validation

  • dotnet test --project tests\Aspire.Cli.Tests\Aspire.Cli.Tests.csproj --no-launch-profile -- --filter-method "*.InitCommand_WhenNoSolutionExists_SingleFileSkeletonPinsSdkVersion" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"
  • dotnet build src\Aspire.ProjectTemplates\Aspire.ProjectTemplates.csproj --no-restore
  • dotnet build tests\Aspire.Cli.EndToEnd.Tests\Aspire.Cli.EndToEnd.Tests.csproj --no-restore

Fixes #19074

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 63b77c7f-f8cf-4923-8cd7-abaf1ff27a76
Copilot AI balanced review requested due to automatic review settings August 6, 2026 19:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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.

Note

This error may be related to your runner configuration. You can now configure runners for Copilot code review separately from Copilot cloud agent by creating a copilot-code-review.yml file with your setup steps. Read the docs for details.

@github-actions

Copy link
Copy Markdown
Contributor

🚀 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 -- 19076

Or

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

@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 63b77c7f-f8cf-4923-8cd7-abaf1ff27a76
@github-actions

Copy link
Copy Markdown
Contributor

Tests selector (audit mode)

The full test matrix and all jobs still run in audit mode. The tests and jobs below are what selective CI would run under enforcement.

4 / 100 test projects · 5 jobs, from 13 changed files.

Selected test projects (4 / 100)

Aspire.Cli.EndToEnd.Tests, Aspire.Cli.Tests, Aspire.EndToEnd.Tests, Aspire.Templates.Tests

Selected jobs (5)

cli-starter, deployment-e2e, extension-e2e, polyglot, typescript-api-compat


How these were chosen — grouped by what changed

🧪 tests/Shared/TemplatesTesting/AspireProject.cs (changed test)
2 via the project graph: Aspire.EndToEnd.Tests, Aspire.Templates.Tests

📦 affected project Aspire.Cli
1 test: Aspire.Cli.EndToEnd.Tests

🔧 src/Aspire.ProjectTemplates/templates/aspire-apphost-singlefile/apphost.cs (changed source)
1 directly: Aspire.Templates.Tests

🔧 src/Aspire.ProjectTemplates/templates/aspire-apphost/Aspire.AppHost1.csproj (changed source)
1 directly: Aspire.Templates.Tests

🔧 src/Aspire.ProjectTemplates/templates/aspire-empty/AspireApplication.1.AppHost/AspireApplication.1.AppHost.csproj (changed source)
1 directly: Aspire.Templates.Tests

🔧 src/Aspire.ProjectTemplates/templates/aspire-starter/Aspire-StarterApplication.1.AppHost/Aspire-StarterApplication.1.AppHost.csproj (changed source)
1 directly: Aspire.Templates.Tests

🔧 src/Aspire.ProjectTemplates/templates/aspire-ts-cs-starter/Aspire-StarterApplication.1.AppHost/Aspire-StarterApplication.1.AppHost.csproj (changed source)
1 directly: Aspire.Templates.Tests

🧪 tests/Aspire.Cli.EndToEnd.Tests/BundleSmokeTests.cs (changed test)
1 directly: Aspire.Cli.EndToEnd.Tests

🧪 tests/Aspire.Cli.EndToEnd.Tests/SingleFileAppHostInitDotnetRunTests.cs (changed test)
1 directly: Aspire.Cli.EndToEnd.Tests

🧪 tests/Aspire.Cli.Tests/Commands/InitCommandTests.cs (changed test)
1 directly: Aspire.Cli.Tests

Job reasons

Job Triggered by
cli-starter • affected project Aspire.Cli
• selected test Aspire.Cli.Tests
deployment-e2e src/Aspire.ProjectTemplates/templates/aspire-apphost-singlefile/apphost.cs, src/Aspire.ProjectTemplates/templates/aspire-apphost/Aspire.AppHost1.csproj, src/Aspire.ProjectTemplates/templates/aspire-empty/AspireApplication.1.AppHost/AspireApplication.1.AppHost.csproj, src/Aspire.ProjectTemplates/templates/aspire-starter/Aspire-StarterApplication.1.AppHost/Aspire-StarterApplication.1.AppHost.csproj, src/Aspire.ProjectTemplates/templates/aspire-ts-cs-starter/Aspire-StarterApplication.1.AppHost/Aspire-StarterApplication.1.AppHost.csproj
• affected project Aspire.Cli
extension-e2e src/Aspire.Cli/Commands/InitCommand.cs, src/Aspire.Cli/Templating/Templates/empty-apphost/apphost.cs, tests/Aspire.Cli.EndToEnd.Tests/BundleSmokeTests.cs, tests/Aspire.Cli.EndToEnd.Tests/SingleFileAppHostInitDotnetRunTests.cs, tests/Aspire.Cli.Tests/Commands/InitCommandTests.cs
• affected project Aspire.Cli
polyglot affected project Aspire.Cli
typescript-api-compat affected project Aspire.Cli

Selection computed for commit 8927a29.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

Suppressed comments (1)

tests/Aspire.Cli.EndToEnd.Tests/BundleSmokeTests.cs:76

  • DotNetRunProjectAppHostRestoresAndUsesAspireCliThroughDnx still rewrites the generated project to add AspireUseCliBundle=true (lines 139–147). With the template change, that produces a duplicate property and, more importantly, means the DNX smoke test still masks whether generated projects opt in by default, contrary to the PR description. Remove that rewrite and assert the generated property there as this test now does.
        Assert.Contains("<AspireUseCliBundle>true</AspireUseCliBundle>", appHostProject);

@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@DamianEdwards

Copy link
Copy Markdown
Member Author

PR Testing Report

PR Information

Artifact Version Verification

The PR CLI and package hive were installed with the dogfood command from the PR comment in the repository container runner.

Changes Analyzed

Files Changed

  • src/Aspire.Cli/Commands/InitCommand.cs
  • src/Aspire.Cli/Templating/Templates/empty-apphost/apphost.cs
  • src/Aspire.ProjectTemplates/templates/aspire-apphost-singlefile/apphost.cs
  • src/Aspire.ProjectTemplates/templates/aspire-apphost/Aspire.AppHost1.csproj
  • src/Aspire.ProjectTemplates/templates/aspire-empty/AspireApplication.1.AppHost/AspireApplication.1.AppHost.csproj
  • src/Aspire.ProjectTemplates/templates/aspire-starter/Aspire-StarterApplication.1.AppHost/Aspire-StarterApplication.1.AppHost.csproj
  • src/Aspire.ProjectTemplates/templates/aspire-ts-cs-starter/Aspire-StarterApplication.1.AppHost/Aspire-StarterApplication.1.AppHost.csproj
  • tests/Aspire.Cli.EndToEnd.Tests/BundleSmokeTests.cs
  • tests/Aspire.Cli.EndToEnd.Tests/SingleFileAppHostInitDotnetRunTests.cs
  • tests/Aspire.Cli.Tests/Commands/InitCommandTests.cs
  • tests/Shared/TemplatesTesting/AspireProject.cs
  • tests/Shared/TemplatesTesting/BuildEnvironment.cs
  • tests/Shared/TemplatesTesting/DotNetNewCommand.cs

Change Categories

  • CLI changes detected
  • Hosting integration changes
  • Dashboard changes
  • Template changes
  • Client/component changes
  • VS Code extension changes
  • Test changes
  • CI infrastructure changes

Test Scenarios Executed

Scenario 1: PR artifact identity

Objective: Verify the tested CLI and package hive came from the latest PR commit.

Coverage Type: Artifact integrity

Status: Passed

Evidence:

  • install.log
  • version.txt

Observations:

  • The installer selected workflow run 31543322968.
  • The installed version included the expected short SHA: 8927a298.

Scenario 2: Project-based AppHost templates

Objective: Generate and build every modified project-based C# AppHost template.

Coverage Type: Happy path

Status: Passed

Templates:

  1. aspire-apphost
  2. aspire (the project-template short name for aspire-empty)
  3. aspire-starter
  4. aspire-ts-cs-starter

Assertions:

  • Every generated AppHost project contained exactly one <AspireUseCliBundle>true</AspireUseCliBundle>.
  • Every AppHost restored and built from the PR hive.
  • No build emitted ASPIRE010.

Evidence:

  • assert-build.log
  • scenarios-8927a298/logs/*AppHost-build.log
  • scenarios-8927a298/logs/*AppHost-restore.log

Scenario 3: Single-file AppHost templates

Objective: Generate and build every modified single-file creation path.

Coverage Type: Happy path

Status: Passed

Paths:

  1. dotnet new aspire-apphost-singlefile
  2. aspire new aspire-empty --language csharp
  3. aspire init --language csharp

Assertions:

  • Line 1 was #:sdk Aspire.AppHost.Sdk@13.6.0-pr.19076.g8927a298.
  • Line 2 was #:property AspireUseCliBundle=true.
  • Every file-based AppHost built successfully.
  • No build emitted ASPIRE010.

Evidence:

  • assert-build.log
  • scenarios-8927a298/logs/dotnet-single-build.log
  • scenarios-8927a298/logs/cli-single-build.log
  • scenarios-8927a298/logs/init-single-build.log

Scenario 4: Runtime bundle behavior

Objective: Start representative project and file-based AppHosts with the PR CLI and verify readiness and shutdown.

Coverage Type: Runtime happy path

Status: Passed

Cases:

  1. Project AppHost via dotnet run --no-launch-profile --project PrAppHost.csproj
  2. Init-created file AppHost via dotnet run apphost.cs

Assertions:

  • The project AppHost displayed Connecting to AppHost, Starting dashboard, and the CLI Ctrl+C readiness message.
  • The file-based AppHost started DCP, displayed the dashboard login endpoint, and reported distributed-application readiness. The non-TTY runner uses the direct presentation path for this command.
  • Neither runtime emitted ASPIRE010.
  • Both stopped successfully through aspire stop --apphost.
  • A final aspire ps reported no running AppHosts.

Evidence:

  • runtime.log
  • final-ps.log
  • scenarios-8927a298/logs/project-apphost-run.log
  • scenarios-8927a298/logs/project-apphost-stop.log
  • scenarios-8927a298/logs/init-single-run.log
  • scenarios-8927a298/logs/init-single-stop.log

Scenario 5: Explicit bundle opt-out

Objective: Verify a user can explicitly disable the bundle and receives the expected migration warning.

Coverage Type: Negative boundary

Status: Passed

Steps:

  1. Generated a fresh aspire-apphost.
  2. Changed the generated property value from true to false.
  3. Restored and built the AppHost from the PR hive.

Expected Outcome: Build succeeds and emits ASPIRE010.

Observed Outcome: Build succeeded with exactly the expected ASPIRE010 warning.

Evidence:

  • negative.log
  • scenarios-8927a298/logs/negative-disabled-build.log

Observations

  • Starter and TypeScript/C# Starter builds emitted the existing NU1903 advisory for Microsoft.OpenApi 2.0.0 (GHSA-v5pm-xwqc-g5wc). This is unrelated to the PR.
  • The checked-in PowerShell container runner assigns $isWindows, which conflicts with PowerShell 7.6's read-only $IsWindows automatic variable because PowerShell variable names are case-insensitive. Running the same script under Windows PowerShell 5.1 worked. This is unrelated to the PR.
  • No product defects were found.

Summary

Scenario Status Notes
PR artifact identity Passed Exact head SHA verified
Four project templates Passed Properties, restore, build, no ASPIRE010
Three single-file paths Passed Directive order, build, no ASPIRE010
Project and file runtime Passed Ready, dashboard/DCP active, stopped cleanly
Explicit opt-out Passed Build succeeded with expected ASPIRE010

Overall Result

PR VERIFIED

No follow-up changes are recommended for PR #19076.

@DamianEdwards
Damian Edwards (DamianEdwards) merged commit 50f5aa9 into main Aug 12, 2026
677 of 680 checks passed
@DamianEdwards
Damian Edwards (DamianEdwards) deleted the damianedwards-update-apphost-cli-bundle-templates branch August 12, 2026 17:56
@DamianEdwards

Copy link
Copy Markdown
Member Author

/backport to release/13.5

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/13.5 (link to workflow run)

@aspire-repo-bot

Copy link
Copy Markdown
Contributor

Pull request created: #1483

Generated by PR Documentation Check · auto · 56.4 AIC · ⌖ 10.3 AIC · ⊞ 19.6K

@aspire-repo-bot

Copy link
Copy Markdown
Contributor

📝 Documentation has been drafted in microsoft/aspire.dev#1483 targeting release/13.5.

Drafted docs updates for the CLI bundle default opt-in in new C# AppHost templates.

  • Updated src/frontend/src/content/docs/get-started/aspire-sdk.mdx to note that new AppHost projects (via aspire new/dotnet new) and single-file AppHosts (via aspire init) now enable AspireUseCliBundle by default, plus added a #:property single-file example.
  • Added a new entry to src/frontend/src/content/docs/whats-new/aspire-13-5.mdx announcing the default opt-in.

Triggered signals: cli_command_file_changed (InitCommand.cs), project_template_changed (apphost.cs and .csproj templates), pr_body_has_user_facing_section, pr_body_has_cli_flag_mention.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update C# templates to opt-in to using the CLI bundle by default

3 participants