Skip to content

Expose resolved environment variables to debug launch producers - #19077

Merged
Adam Ratzman (adamint) merged 33 commits into
microsoft:mainfrom
adamint:adamint/issue-18956-launch-config-context
Aug 13, 2026
Merged

Expose resolved environment variables to debug launch producers#19077
Adam Ratzman (adamint) merged 33 commits into
microsoft:mainfrom
adamint:adamint/issue-18956-launch-config-context

Conversation

@adamint

@adamint Adam Ratzman (adamint) commented Aug 6, 2026

Copy link
Copy Markdown
Member

Description

Debug launch configuration producers can now read environment variables after Aspire has resolved their value providers. This fixes #18956 without exposing a second mutable argument model or moving every existing integration to a new callback shape.

The new LaunchConfigurationCallbackContext contains the launch mode, resource, resolved environment variables, and cancellation token. A new context-based WithDebugSupport overload is additive; the existing synchronous and asynchronous mode-based overloads remain unchanged.

Aspire creates the context after resolving the executable environment and before producing IDE launch metadata. Restarts and replicas therefore receive the values for that executable creation, and environment providers are not evaluated again by the launch producer.

The executable creation path also continues running non-project launch producers, including MAUI, when a project launch-args override keeps execution in process mode.

Security considerations

Resolved environment variables can contain secrets. The callback runs as AppHost/integration code in the existing AppHost process, and the context is not serialized automatically. Producers should copy only values required by the IDE into the returned launch configuration.

Validation

  • 41 debug-support and executable-resource tests passed
  • 5 focused DCP launch-configuration tests passed
  • affected .NET, Go, JavaScript, MAUI, and Python test projects build successfully

Fixes #18956

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

Copilot AI balanced review requested due to automatic review settings August 6, 2026 19:38
@adamint Adam Ratzman (adamint) added the breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. label Aug 6, 2026

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

github-actions Bot commented Aug 7, 2026

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 -- 19077

Or

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

Copilot AI review requested due to automatic review settings August 7, 2026 13:53
@adamint

Copy link
Copy Markdown
Member Author

Self-review notes (posted as a comment since GitHub does not allow reviewing your own PR).

I ran a deep review pass over the full main...HEAD diff. Two items are already fixed in e131354:

  • 2052 lines of agent planning artifacts committed under a new docs/superpowers/ tree that does not exist on main. Removed.
  • Two load-bearing WHY comments deleted from SupportsDebuggingAnnotation.Create while the code they explain is unchanged. Restored.

CI is green (337 passing). The remaining items below are open; the core design and the migration itself look sound.

High

  1. No test asserts that resolved arguments reach the producer. PlainExecutable_LaunchConfigurationProducerReceivesResolvedExecutionConfiguration, ProjectReplicas_CreateFreshLaunchConfigurationContexts and ResourceRestarted_RebuildsExecutionConfigurationAndLaunchContext all assert only context.ExecutionConfiguration.EnvironmentVariablesgit grep ExecutionConfiguration.Arguments -- tests/ returns nothing. The feature's other half is untested, specifically the ordering where WithDebugSupport's own argsCallback (Go/Python entrypoint stripping) runs inside BuildExecutableConfiguration before the producer. A regression that hoisted the producer above BuildExecutableConfiguration, or that dropped the argsCallback contribution, would pass the entire suite.
    Fix: add a test on a resource with .WithArgs("a") + WithDebugSupport(..., argsCallback: ctx => ctx.Args.Add("rewritten")) asserting context.ExecutionConfiguration.Arguments.Select(a => a.Value) matches the executable's Spec.Args tail.

Medium

  1. Process-mode restart argument coverage was deleted, not extended. ResourceRestarted_EnvironmentCallbacksApplied was repurposed into ResourceRestarted_RebuildsExecutionConfigurationAndLaunchContext. Adding a debug session flips the project to IDE execution, so the old Assert.Single(exe1.Spec.Args!, a => a == "--no-build") / exe2 assertions are gone from the whole file (grep -n "no-build" DcpExecutorTests.cs → no matches). Process-mode restart arg re-application has lost its only regression guard.
    Fix: restore the original test unchanged and add the IDE-mode test as a separate [Fact].

  2. Undocumented behavioral contract change for a throwing project producer (ExecutableCreator.cs:214). On main, a throwing project producer on a ProjectResource ran inside PrepareProjectExecutablesAsync, aborting PrepareObjectsAsync and failing the whole app model before anything started. It now throws from CreateObjectAsync (the && !isProjectLaunchConfiguration filter excludes it from the Process fallback), so only that resource fails and the rest of the app starts. Not listed under "Breaking changes" and untested — DotnetProjectExecutable_ProjectLaunchConfigurationFailure_Fails... covers the plain-executable case and Project_NonProjectLaunchConfig_AnnotatorThrows_FallsBackToProcess covers azure-functions.
    Fix: add a test for AddProject(...).WithDebugSupport(throwingProducer, KnownLaunchConfigurationTypes.Project) and call the change out in the description.

  3. ProjectLaunchArgsOverrideAnnotation guard applies too broadly (ExecutableCreator.cs:95). The new !HasProjectLaunchArgsOverride(er.ModelResource) guard applies to all executables, but the compensating "set ExecutionType = Process and annotate a project launch configuration" only exists in PrepareProjectExecutables (line 266). The annotation is public (ASPIREPROJECTS001), so a non-ProjectResource carrying it plus WithDebugSupport is prepared by PreparePlainExecutables with ExecutionType = IDE, then skips the producer entirely — DCP gets an IDE executable with an empty launch-configurations annotation. On main the producer ran in that case.
    Fix: force spec.ExecutionType = ExecutionType.Process when HasProjectLaunchArgsOverride is true and debug support is present, or scope the guard to er.ModelResource is ProjectResource.

  4. ExecutionConfiguration is required but unconstructable by public callers (LaunchConfigurationCallbackContext.cs:39). The only implementation of IExecutionConfigurationResult is internal sealed ExecutionConfigurationResult; the PR's own helper reaches it via InternalsVisibleTo. Public callers of CreateLaunchConfigurationAsync — previously a one-liner — must now run a full ExecutionConfigurationBuilder...BuildAsync() pass just to inspect a launch configuration, which is the duplicate-evaluation problem Expose the resolved environment variables to the WithDebugSupport launch configuration callback #18956 set out to remove.
    Fix: make ExecutionConfiguration optional with an empty default, or add a public factory (ExecutionConfigurationResult.Empty / LaunchConfigurationCallbackContext.CreateForInspection(resource, mode)).

Low

  1. !ReferenceEquals(resource, context.Resource) is bait-and-switch hostile (DebugSupportExtensions.cs:104). Repo convention explicitly notes resources may be swapped during model transformations and prescribes ResourceNameComparer. Fix: compare by name, or document that reference identity is required.

  2. Configuration exception masks the more actionable error (DebugSupportExtensions.cs:114). ExceptionDispatchInfo.Throw(configurationException) runs before the TryGetLastAnnotation<SupportsDebuggingAnnotation> check, so a resource that never called WithDebugSupport surfaces an unrelated configuration exception instead of "does not declare debug launch support". The removed overload's ArgumentNullException.ThrowIfNull(mode) also has no replacement (required string Mode does not stop Mode = null!). Fix: move the annotation lookup above the rethrow.

  3. Redundant clause (ExecutableCreator.cs:96): !er.ModelResource.HasAnnotationOfType<ForceProcessExecutionAnnotation>()SupportsDebugging already returns false for that annotation (DebugSupportExtensions.cs:55). Duplicated invariants drift.

  4. Task/ValueTask footgun validation removed without replacement (ResourceBuilderExtensions.cs:4770). The deleted sync overload rejected Task/ValueTask-typed TLaunchConfiguration (plus two tests, also deleted). async context => SomeAsync(context) still infers TLaunchConfiguration = Task<X> and serializes the Task object into the DCP annotation. Fix: keep a cheap typeof(TLaunchConfiguration) check with the same diagnostic.

  5. Stale comment (ExecutableCreator.cs:400): // ... see ToSnapshot() for details. — nothing in src/ reads Executable.LaunchConfigurationsAnnotation via TryGetProjectLaunchConfiguration (it is defined at Executable.cs:316 and never called outside tests). This PR deleted the sibling copy of the comment, leaving only this misleading one.

  6. Non-atomic counter in a concurrent fake (RecordingDcpObjectFactory.cs:12): CreateDcpObjectsCallCount++ is a read-modify-write on a fake handed to CreateObjectAsync, a concurrent path. Latent rather than flaky today (single-resource use only). Fix: Interlocked.Increment.

  7. Pre-existing, worth fixing here (DcpExecutorTests.cs:691): ProjectResourceRestarted_RebuildsArgumentsForIdeAfterTransientProducerFailure asserts ExecutionType.Process after producer failure, but a ProjectResource prepared for IDE execution never gets run --project <path> in projectArgs (only file-based apps do), so the fallback runs dotnet --apphost — a broken command line. The new test codifies that state without asserting the command is runnable.

Public API assessment

Shape is right: replacing the two Func<string, …> overloads with a single Func<LaunchConfigurationCallbackContext, Task<T>> is the correct evolvable design and removes the overload-resolution trap the deleted IsValueTask guard existed to catch. Breaking-change bookkeeping checks out — only WithDebugSupport(Func<string,T>,…) was in the shipped baseline and it has exactly one matching CP0002 suppression; the async overload and CreateLaunchConfigurationAsync(mode, ct) were added post-release. All in-tree call sites are migrated and there are no extension/ consumers.

Two smaller points: LaunchConfigurationCallbackContext uses required/init properties while every other Aspire callback context (EnvironmentCallbackContext, CommandLineArgsCallbackContext) uses primary-constructor parameters with get-only properties — worth a deliberate decision rather than drift. And it carries neither [AspireExport] nor [AspireExportIgnore], while EnvironmentCallbackContext is [AspireExport] and WithDebugSupport is [AspireExportIgnore]; confirm the ATS scanner's intended default.

Coverage assessment

Well covered: fresh context per replica and per restart; ExecutionType reset to IDE after a transient producer failure; execution-configuration failure short-circuiting the producer; cancellation not swallowed into a Process fallback; Resource/ExecutionContext/Logger/CancellationToken identity vs EnvironmentCallbackContext; null-task, null-result and wrapped-producer-exception diagnostics.

Flaky-pattern check is clean — ConcurrentQueue for cross-thread collection, Interlocked for counters, no hardcoded ports, no log-text readiness waits, no shared CTS across phases, no Directory.SetCurrentDirectory, no Assert.DoesNotContain. Only exception is item 11.

Gaps: items 1–4 above, plus AdditionalConfigurationData (certificate trust / HTTPS cert data) being reachable through the context but untested. No deployment, CLI, dashboard or extension surfaces are touched, so no E2E coverage is owed.

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.

Review details

  • Files reviewed: 25/25 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

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.

Two findings from a review of the launch-configuration lifecycle move: one behavior regression for MAUI resources, and one leftover async signature.

  • 1 correctness/behavior issue (ProjectLaunchArgsOverrideAnnotation guard disables the MAUI producer)
  • 1 API-shape cleanup (PrepareObjectsAsync is no longer asynchronous)

Comment thread src/Aspire.Hosting/Dcp/ExecutableCreator.cs Outdated
Comment thread src/Aspire.Hosting/Dcp/ExecutableCreator.cs Outdated
Copilot AI review requested due to automatic review settings August 7, 2026 20:01
Adam Ratzman added 8 commits August 7, 2026 16:03
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0f29216a-bf33-40a3-9f37-3863b3d1a79e
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0f29216a-bf33-40a3-9f37-3863b3d1a79e
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0f29216a-bf33-40a3-9f37-3863b3d1a79e
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0f29216a-bf33-40a3-9f37-3863b3d1a79e
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0f29216a-bf33-40a3-9f37-3863b3d1a79e
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0f29216a-bf33-40a3-9f37-3863b3d1a79e
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0f29216a-bf33-40a3-9f37-3863b3d1a79e
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0f29216a-bf33-40a3-9f37-3863b3d1a79e
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3253974d-4f18-486f-863c-281a607656d4
Copilot AI review requested due to automatic review settings August 11, 2026 08:43

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.

Review details

Suppressed comments (2)

src/Aspire.Hosting/Dcp/ExecutableCreator.cs:204

  • For a project with ProjectLaunchArgsOverrideAnnotation, the debug args callback is now intentionally skipped, but RewritesArgumentsForDebugging remains true because an argsCallback was registered. A failing supported non-project producer therefore bypasses this catch and aborts startup even though the override left a valid process command. Allow the process fallback when a project launch-args override is present (and add the faulting-producer case to the new MAUI regression test).
            catch (Exception exception) when (
                !isProjectLaunchConfiguration
                && !supportsDebuggingAnnotation.RewritesArgumentsForDebugging)

src/Aspire.Hosting/ResourceBuilderExtensions.cs:4858

  • This new public overload throws ArgumentNullException for builder and launchConfigurationProducer, but its XML documentation omits that exception. Public Aspire APIs must document thrown exceptions.
    /// <returns>The <see cref="IResourceBuilder{T}"/>.</returns>
  • Files reviewed: 17/17 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Supplying an argsCallback sets RewritesArgumentsForDebugging, and the
exception filter in ExecutableCreator deliberately excludes those resources
from the process fallback that plain debuggable executables get. Falling back
there could start a resource with half-applied debug arguments, so a producer
fault has to fail the resource instead: the exception escapes
ExecutableCreator, DcpExecutor reports the resource as failed to start, and no
Executable is ever created.

Every existing producer-fault test omits argsCallback, so that rule had no
coverage. Adds a theory over both producer overloads asserting the producer
runs once, the args callback never runs, and no Executable is created.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: f1bd51d5-cb9f-4370-a07b-c94416baad61
Copilot AI review requested due to automatic review settings August 11, 2026 20:46

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.

Review details

  • Files reviewed: 17/17 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 12, 2026 02:25

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.

Review details

  • Files reviewed: 17/17 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@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.

@adamint Adam Ratzman (adamint) modified the milestones: 13.5, 13.6 Aug 13, 2026
Copilot AI review requested due to automatic review settings August 13, 2026 03:34

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.

Review details

  • Files reviewed: 17/17 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@IEvangelist David Pine (IEvangelist) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

1 correctness issue found.

Comment thread src/Aspire.Hosting/ApplicationModel/DebugSupportExtensions.cs
@IEvangelist

Copy link
Copy Markdown
Member

PR Testing Report

PR Information

Artifact Version Verification

Changes Analyzed

Change Categories

  • Hosting (core) changes
  • CLI changes
  • Dashboard changes
  • Template changes
  • Client/Component changes
  • VS Code extension changes
  • Test changes
  • CI infrastructure changes

Summary of changes

  • New experimental public type LaunchConfigurationCallbackContext (ASPIREEXTENSION001) exposing Mode, Resource, EnvironmentVariables, and CancellationToken — immutable, no public constructor.
  • New additive context-based WithDebugSupport overload (Func<LaunchConfigurationCallbackContext, Task<TLaunchConfiguration>>); existing sync and (mode, ct) async overloads preserved and now delegate to the context path.
  • DebugSupportExtensions.CreateLaunchConfigurationAsync is now internal and context-based, rejecting a context whose Resource differs from the target.
  • ExecutableCreator.PrepareObjectsAsync → synchronous PrepareObjects; launch-config production moved into CreateObjectAsync, which now passes the resolved environment variables to the producer.
  • Project-launch-args-override behavior changed so non-project producers (including MAUI) still contribute launch metadata while execution stays in Process mode; project-type producer failures now rethrow.

Key testing consideration

The new behavior fires on the IDE/debug executable-creation path. A plain aspire start/run from the CLI launches resources in process mode, so the debug producers don't visibly fire — the CLI run is therefore a no-regression check for the refactored executable-creation path. The actual feature behavior is validated by the unit tests that exercise the DCP executor and debug-support plumbing directly.

Test Scenarios Executed

Scenario 1: Feature validation — core hosting unit tests (PR source)

Objective: Validate the new context, the new overload, env-var flow, restart/replica reuse, and MAUI process-mode-override behavior.
Coverage Type: Feature / unit
Status: ✅ Passed — total: 292, failed: 0, skipped: 1

Command:
dotnet test tests/Aspire.Hosting.Tests --filter-class *.DcpExecutorTests --filter-class *.DebugSupportExtensionsTests --filter-class *.ExecutableResourceBuilderExtensionTests --filter-not-trait quarantined=true --filter-not-trait outerloop=true

Notable tests covered:

  • DcpExecutorTests.PlainExecutable_LaunchConfigurationProducerReceivesResolvedEnvironmentVariables — producer receives resolved DEBUG_VALUE=resolved-1; environment callback invoked exactly once (no re-evaluation); Mode/Resource/CancellationToken correct.
  • DcpExecutorTests.MauiProjectWithLaunchArgsOverrideAndSupportedLaunchConfiguration_StillAppliesMauiLaunchConfiguration (both sync and context overloads) — non-project MAUI producer still applies under a project-launch-args override.
  • DebugSupportExtensionsTests.LaunchConfigurationCallbackContextExposesOnlyLaunchProducerInputs — context has no public ctor, exactly 4 read-only properties.
  • Sync/async overload equivalence and the updated async-producer guard message (ExecutableResourceBuilderExtensionTests).

Observations: The 1 skipped test is PlainExecutableCertificateDirectoriesPath_...OnLinux — a Linux-only test correctly skipped on Windows and unrelated to this PR.

Scenario 2: Feature validation — Dotnet "project" producer tests (PR source)

Objective: Validate the project launch-config producer path with the new callback context.
Coverage Type: Feature / unit
Status: ✅ Passed — total: 2, failed: 0, skipped: 0

Command:
dotnet test tests/Aspire.Hosting.Dotnet.Tests --filter-method *.AddDotnetProject_DebugAnnotator_ProducesProjectLaunchConfiguration --filter-method *.AddDotnetProject_LaunchConfiguration_ResolvesEffectiveLaunchProfile

Scenario 3: No-regression smoke — aspire start/restart/stop (dogfood CLI)

Objective: Confirm the refactored executable-creation path (PrepareObjects, new ApplyLaunchConfigurationAsync signature) doesn't regress normal orchestration.
Coverage Type: Happy path + restart
Status: ✅ Passed

Steps & evidence:

  1. aspire new aspire-starter (projects only: --use-redis-cache false, --test-framework None, --localhost-tld false, --suppress-agent-init) from the PR hive — created ApiService, Web, AppHost, ServiceDefaults.
  2. aspire start --apphost ... — AppHost started (dashboard https://localhost:17065, PID 70528).
  3. aspire describeapiservice and webfrontend both Running / Healthy.
  4. aspire resource webfrontend restart — restarted successfully; re-describe still Running / Healthy (validates restart re-applies launch config).
  5. Dashboard probe — GET https://localhost:17065/ returned 302 → /login (dashboard up).
  6. aspire stop — stopped cleanly.

Unhappy-Path Coverage

Case Where validated Result
Resource without debug support DebugSupportExtensionsTests.CreateLaunchConfigurationThrowsWhenTheResourceHasNoDebugSupport InvalidOperationException ("does not declare debug launch support")
project launch type without project metadata ...ThrowsWhenTheResourceHasNoProjectMetadata InvalidOperationException ("has no project metadata")
Producer returns null ...ThrowsWhenTheProducerReturnsNull InvalidOperationException ("returned null", names resource)
Task/ValueTask-returning sync producer bound to sync overload ExecutableResourceBuilderExtensionTests.WithDebugSupportRejects{ATask,AValueTask}ReturningSynchronousProducer ArgumentException with updated guidance message

Scope Notes

  • Go / JavaScript (Bun+Node) / Python / MAUI producer test projects were not rebuilt separately: their diffs are mechanical signature adaptations (LaunchConfigurationAnnotator(exe, mode, ct)(exe, context)), and the one substantive per-language behavior change (MAUI under a process-mode override) is already covered in DcpExecutorTests above. Running them would require Go/Node/Bun/Python runtimes and MAUI workloads for little additional signal.
  • Container mode was unavailable (Docker Desktop not running); all scenarios ran locally. The starter used no container resources, so this did not limit the smoke test.

Summary

Scenario Status Notes
Core hosting unit tests (292) ✅ Passed 0 failed, 1 Linux-only skip
Dotnet project producer tests (2) ✅ Passed 0 failed
CLI start/restart/stop smoke ✅ Passed Both projects Running/Healthy; dashboard up

Overall Result

✅ PR VERIFIED

  • 294 unit tests passed (0 failed, 1 expected Linux-only skip) across the core DCP executor, debug-support, and Dotnet project-producer paths — directly exercising the new LaunchConfigurationCallbackContext, the additive context-based WithDebugSupport overload, the resolved-environment flow (evaluated once), and the MAUI process-mode-override behavior.
  • Dogfood CLI (13.6.0-pr.19077.g629c3ea1, matching head) shows no regression in normal AppHost orchestration, including restart.

Recommendations

  • None blocking. Feature and no-regression behavior verified. IDE-attached debug behavior (VS/VS Code actually consuming the resolved environment variables) is inherently outside CLI scope and is covered here by the DCP executor unit tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 1b9961b8-65d7-4919-82a9-05b90a62a1b7

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.

Review details

Suppressed comments (1)

src/Aspire.Hosting/ApplicationModel/DebugSupportExtensions.cs:117

  • The method still promises to create “the launch configuration that this resource sends to the IDE,” but a context-based producer receives an empty environment here while executable creation supplies resolved values. A producer that depends on EnvironmentVariables can therefore throw or return different metadata through this public inspection API. Please either expose a way to inspect with caller-supplied resolved values, or explicitly change the method’s summary/return contract to say the result is only a synthetic configuration and may differ from what is sent.
    /// This inspection API does not resolve the resource's environment variables. A producer that accepts a
    /// <see cref="LaunchConfigurationCallbackContext"/> receives an empty
    /// <see cref="LaunchConfigurationCallbackContext.EnvironmentVariables"/> collection. Aspire invokes that producer
    /// separately with resolved values when it creates the executable.
  • Files reviewed: 17/17 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ CI Failure Analysis: Possible Flaky Test(s)

The CI build failed due to test failure(s) that appear unrelated to the PR changes. These may be flaky tests.

Suspected flaky test(s):

  • Aspire.Templates.Tests.XUnit_V2_NewUpAndBuildSupportProjectTemplatesTests.CanNewAndBuild(templateName: "aspire-xunit", extraTestCreationArgs: "--xunit-version v2", sdk: Net8, tfm: Net9, error: "The current .NET SDK does not support targeting .N"...) in job Tests / Templates-XUnit_V2_NewUpAndBuildSupportProjectTemplatesTests (windows-latest)
    • Error: System.Threading.Tasks.TaskCanceledException : Command execution timed out after 300 secs: 'D:\a\aspire\aspire\artifacts\bin\dotnet-8\dotnet.exe new aspire-apphost -o "new_build_aspire_xunit_xc1vzq1o_5xw.AppHost" -f net9.0 --debug:custom-hive "C:\Users\runneradmin\AppData\Local\Temp\templates-$c2e3646d\templates"' ---- System.Threading.Tasks.TaskCanceledException : A task was canceled.
    • Stack Trace (first frames):
      at Aspire.Templates.Tests.ToolCommand.ExecuteAsync(String[] args) in /_/tests/Shared/TemplatesTesting/ToolCommand.cs:line 95
         at Aspire.Templates.Tests.AspireProject.CreateNewTemplateProjectAsync(...) in /_/tests/Shared/TemplatesTesting/AspireProject.cs:line 123
         at Aspire.Templates.Tests.NewUpAndBuildSupportProjectTemplatesBase.CanNewAndBuildActual(...) in /_/tests/Aspire.Templates.Tests/NewUpAndBuildSupportProjectTemplatesTests.cs:line 35
      
    • Why likely flaky: 300-second timeout while invoking dotnet new to scaffold a template project is a classic CI-runner-under-load timing issue rather than a code defect. The test/template code is not touched by this PR, and the accompanying '.NET SDK does not support targeting .NET 9.0' annotation reflects a template test parameter matrix expectation (verifying an error condition), not an actual regression caused by the PR.

Suggested actions:

  • Re-run the failed CI jobs to confirm if the failure is intermittent
  • If the test continues to fail, consider quarantining it using /quarantine-test <test name> <issue URL>
  • Search existing issues to see if this test is already known to be flaky

You can re-run the failed jobs from the workflow run page.

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

Labels

breaking-change Issue or PR that represents a breaking API or functional change over a prerelease.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose the resolved environment variables to the WithDebugSupport launch configuration callback

4 participants