Skip to content

Refine dynamic endpoint allocation#17879

Merged
danegsta merged 6 commits into
mainfrom
danegsta/dynamic-endpoint-evaluation
Jun 3, 2026
Merged

Refine dynamic endpoint allocation#17879
danegsta merged 6 commits into
mainfrom
danegsta/dynamic-endpoint-evaluation

Conversation

@danegsta

@danegsta danegsta commented Jun 3, 2026

Copy link
Copy Markdown
Member

Description

This PR refines dynamic endpoint allocation for proxyless container endpoints so Aspire only falls back to early allocation when waiting would be unsafe. Endpoint resolution now uses the value provider caller and recursive resource dependency discovery to distinguish circular or unknown references from independent references that can remain lazily allocated.

The DCP path now:

  • pre-allocates dependent dynamic proxyless container endpoints before container objects are submitted, so lifecycle callbacks that create a circular reference observe a consistent fallback port
  • keeps safe independent endpoint references lazy until DCP reports the actual allocated container port
  • treats RandomizePorts as an implicit default for proxying persistent endpoints without overriding explicit proxy settings
  • publishes ConnectionStringAvailableEvent for both eager fallback allocation and post-container dynamic allocation, and resets that event de-dupe state when a resource is recreated for restart

User-facing behavior

AppHost endpoint references that are safe to resolve later avoid unnecessary early fallback allocation. Circular, self, and unknown-caller references still resolve during startup when they need to. In isolated/randomized-port runs, persistent endpoints default to proxied behavior unless the app explicitly configured the endpoint as proxyless.

Validation

  • dotnet test --project tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj --no-build --no-launch-profile -- --filter-class "*.DcpExecutorTests" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"
  • dotnet test --project tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj --no-launch-profile -- --filter-method "*.ResourceRestarted_EnvironmentCallbacksApplied" --filter-method "*.EndpointPortsContainerProxylessNoPortTargetPortSetPublishesAllocatedEndpointAfterServiceUpdate" --filter-method "*.EndpointPortsContainerProxylessNoPortTargetPortSetUsesTargetPortFallbackWhenResolvedBeforeContainerCreation" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"
  • Focused EndpointReferenceTests
  • git diff --check

Fixes: N/A

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

Make proxyless container endpoint allocation dependency-aware so safe references can remain lazy while circular or unknown references still allocate early. Preserve explicit proxy settings when randomizing ports and publish connection string availability for dynamic allocation paths.

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

github-actions Bot commented Jun 3, 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 -- 17879

Or

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

Clear the connection-string availability de-dupe state when a resource is recreated for restart so the event can publish again after callbacks are re-evaluated.

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

danegsta commented Jun 3, 2026

Copy link
Copy Markdown
Member Author

PR Testing Report

PR Information

CLI Version Verification

  • Expected Commit: 64d25de
  • Installed Version: 13.5.0-pr.17879.g64d25de7
  • Status: Verified - installed PR CLI version contains the PR head short SHA.

Changes Analyzed

Files Changed

  • src/Aspire.Hosting/ApplicationModel/EndpointReference.cs
  • src/Aspire.Hosting/Dcp/DcpExecutor.cs
  • src/Aspire.Hosting/Dcp/DcpModelUtilities.cs
  • tests/Aspire.Hosting.Tests/Dcp/DcpExecutorTests.cs
  • tests/Aspire.Hosting.Tests/EndpointReferenceTests.cs

Change Categories

  • CLI changes detected
  • Hosting changes detected
  • Dashboard changes detected
  • Template changes detected
  • Client/component changes detected
  • Test changes detected

Test Scenarios Executed

Scenario 1: Independent proxyless container endpoint stays lazy

Objective: Verify a caller-aware reference from an independent executable to a proxyless container endpoint waits for DCP allocation instead of falling back to the endpoint target port.
Coverage Type: Happy path / boundary
Status: Passed

Steps:

  1. Created a fresh aspire-empty file-based C# AppHost from the PR package hive.
  2. Added independent-db as a proxyless container endpoint with target port 18084.
  3. Added independent-client that resolves the endpoint from OnBeforeResourceStarted with Caller = independent-client.
  4. Started the app with aspire start --isolated and waited for all resources to be up.

Evidence:

  • Evidence file: /var/folders/97/44fp_02d4kd90s9p6sy_jwgh0000gn/T/aspire-pr-test-XXXXXX.O3kvUfEtWw/evidence-rerun2/independent-before-start.txt contains 56494.
  • Describe URL for independent-db: [{'name': 'http', 'url': 'http://localhost:56494'}].
  • Resource log: [independent-client] independent_port=56494.

Observations:

  • The observed port was not the configured target/fallback port 18084; it was the DCP-assigned host port.

Scenario 2: Circular/dependent proxyless container endpoint resolves early

Objective: Verify a circular endpoint reference still resolves early to target-port fallback and does not block startup.
Coverage Type: Boundary / circular dependency
Status: Passed

Steps:

  1. Added cycle-db as a proxyless container endpoint with target port 18080.
  2. Made cycle-db wait for cycle-client.
  3. Resolved cycle-db from cycle-client startup with caller context.
  4. Waited for both resources to be up.

Evidence:

  • Evidence file: /var/folders/97/44fp_02d4kd90s9p6sy_jwgh0000gn/T/aspire-pr-test-XXXXXX.O3kvUfEtWw/evidence-rerun2/cycle-before-start.txt contains http://localhost:18080.
  • Describe URL for cycle-db: [{'name': 'http', 'url': 'http://localhost:18080'}].
  • Resource log: [cycle-client] cycle_port=18080.

Observations:

  • The circular reference resolved to the target-port fallback 18080 and startup completed successfully.

Scenario 3: Randomized ports preserve explicit proxy settings

Objective: Verify isolated/randomized-port runs proxy implicit persistent endpoints by default while preserving explicit proxyless configuration.
Coverage Type: Happy path / boundary
Status: Passed

Steps:

  1. Added persistent-implicit with persistent lifetime and endpoint port 18081 without explicit proxy settings.
  2. Added persistent-explicit with persistent lifetime and endpoint port 18082 with isProxied: false.
  3. Started with aspire start --isolated.
  4. Compared describe output and resource logs.

Evidence:

  • persistent-implicit URL: [{'name': 'implicit', 'url': 'tcp://localhost:56479'}]; environment IMPLICIT_PORT=56482.
  • persistent-explicit URL: [{'name': 'explicit', 'url': 'tcp://localhost:18082'}]; environment EXPLICIT_PORT=18082.
  • Logs: [persistent-implicit] implicit_port=56482 / [persistent-explicit] explicit_port=18082.

Observations:

  • The implicit persistent endpoint was randomized/proxied instead of using 18081.
  • The explicit proxyless endpoint kept 18082.

Scenario 4: Resource restart after connection-string event reset path

Objective: Verify restart/recreate still succeeds and re-evaluates endpoint values after the new connection-string availability de-dupe reset is wired into the restart path.
Coverage Type: Restart / recovery
Status: Passed

Steps:

  1. Added restart-client with an endpoint whose port is injected into the executable environment.
  2. Started the AppHost and captured the initial endpoint value.
  3. Ran aspire resource restart-client restart.
  4. Waited for restart-client to return to up state and captured logs/describe output after restart.

Evidence:

  • Before restart: state Running, URL [{'name': 'restart', 'url': 'tcp://localhost:56480'}], RESTART_PORT=56486.
  • After restart: state Running, URL [{'name': 'restart', 'url': 'tcp://localhost:56480'}], RESTART_PORT=56580.
  • Restart command log: /var/folders/97/44fp_02d4kd90s9p6sy_jwgh0000gn/T/aspire-pr-test-XXXXXX.O3kvUfEtWw/scenario-endpoints/restart-client-command-rerun2.txt.
  • Restart resource log line: [restart-client] restart_port=56580

Observations:

  • The restart command completed successfully and the restarted executable received a newly evaluated endpoint port.
  • Public ConnectionStringAvailableEvent dispatch is not directly observable for a plain executable resource; the smoke validates the restart/re-evaluation path that the de-dupe reset participates in, while the PR's unit tests cover event publication behavior directly.

Summary

Scenario Status Notes
Independent proxyless endpoint stays lazy Passed Caller-aware independent reference resolved to DCP-assigned port instead of target fallback.
Circular proxyless endpoint resolves early Passed Caller-aware circular reference resolved to target-port fallback and startup completed.
Randomized ports preserve explicit proxy settings Passed Implicit persistent endpoint randomized; explicit proxyless endpoint stayed fixed.
Restart after event reset path Passed Resource restart completed and endpoint value was re-evaluated.

Overall Result

PR VERIFIED

Artifacts

  • Install/version info: /var/folders/97/44fp_02d4kd90s9p6sy_jwgh0000gn/T/aspire-pr-test-XXXXXX.O3kvUfEtWw/install-info.txt
  • Smoke AppHost: /var/folders/97/44fp_02d4kd90s9p6sy_jwgh0000gn/T/aspire-pr-test-XXXXXX.O3kvUfEtWw/scenario-endpoints/EndpointSmoke/apphost.cs
  • Build output: /var/folders/97/44fp_02d4kd90s9p6sy_jwgh0000gn/T/aspire-pr-test-XXXXXX.O3kvUfEtWw/scenario-endpoints/build-output-rerun2.txt
  • Start output: /var/folders/97/44fp_02d4kd90s9p6sy_jwgh0000gn/T/aspire-pr-test-XXXXXX.O3kvUfEtWw/scenario-endpoints/start-output-rerun2.json
  • Describe before restart: /var/folders/97/44fp_02d4kd90s9p6sy_jwgh0000gn/T/aspire-pr-test-XXXXXX.O3kvUfEtWw/scenario-endpoints/describe-rerun2-before-restart.json
  • Describe after restart: /var/folders/97/44fp_02d4kd90s9p6sy_jwgh0000gn/T/aspire-pr-test-XXXXXX.O3kvUfEtWw/scenario-endpoints/describe-rerun2-after-restart.json
  • Resource logs: /var/folders/97/44fp_02d4kd90s9p6sy_jwgh0000gn/T/aspire-pr-test-XXXXXX.O3kvUfEtWw/scenario-endpoints/logs-rerun2-*.txt
  • Restart logs: /var/folders/97/44fp_02d4kd90s9p6sy_jwgh0000gn/T/aspire-pr-test-XXXXXX.O3kvUfEtWw/scenario-endpoints/restart-client-command-rerun2.txt, /var/folders/97/44fp_02d4kd90s9p6sy_jwgh0000gn/T/aspire-pr-test-XXXXXX.O3kvUfEtWw/scenario-endpoints/logs-rerun2-restart-client-after-restart.txt
  • Evidence files: /var/folders/97/44fp_02d4kd90s9p6sy_jwgh0000gn/T/aspire-pr-test-XXXXXX.O3kvUfEtWw/evidence-rerun2

Recommendations

  • No issues found in the PR dogfood smoke scenarios.

@danegsta danegsta marked this pull request as ready for review June 3, 2026 19:40
@danegsta danegsta requested a review from mitchdenny as a code owner June 3, 2026 19:40
Copilot AI review requested due to automatic review settings June 3, 2026 19:40

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

Refines Aspire hosting’s dynamic endpoint allocation for proxyless container endpoints, aiming to avoid early fallback allocation unless endpoint resolution cannot safely wait (e.g., circular/unknown/self references), and ensuring endpoint/connection-string availability events are published consistently (including across restarts).

Changes:

  • Updates endpoint reference resolution to decide when to allocate an endpoint on-demand based on the resolving caller and discovered resource dependencies.
  • Adjusts DCP execution flow to pre-allocate certain dynamic proxyless container endpoints earlier and to dedupe/publish OnConnectionStringAvailable events (resetting dedupe on restart).
  • Changes default proxying behavior for persistent endpoints when RandomizePorts=true, while preserving explicit proxy settings; adds/extends tests for these scenarios.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/Aspire.Hosting.Tests/EndpointReferenceTests.cs Adds unit tests covering on-demand allocation vs waiting behavior based on caller/dependency context.
tests/Aspire.Hosting.Tests/Dcp/DcpExecutorTests.cs Adds coverage for randomized-port proxy defaults and connection-string-available event publication (including restart scenarios).
src/Aspire.Hosting/Dcp/DcpModelUtilities.cs Adds helper to pre-allocate dependent dynamic proxyless container endpoints prior to container submission.
src/Aspire.Hosting/Dcp/DcpExecutor.cs Wires new endpoint allocation publication path, adds connection-string event dedupe/reset logic, and adjusts proxy defaulting under randomized ports.
src/Aspire.Hosting/ApplicationModel/EndpointReference.cs Adds caller/dependency-aware gating for on-demand endpoint allocation before falling back to waiting for allocation.

Comment thread src/Aspire.Hosting/Dcp/DcpModelUtilities.cs
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danegsta danegsta closed this Jun 3, 2026
@danegsta danegsta reopened this Jun 3, 2026
@microsoft-github-policy-service microsoft-github-policy-service Bot added this to the 13.5 milestone Jun 3, 2026
@danegsta danegsta modified the milestones: 13.5, 13.4.x Jun 3, 2026

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

Perfect

Comment thread src/Aspire.Hosting/ApplicationModel/EndpointReference.cs
danegsta and others added 3 commits June 3, 2026 13:51
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Default persistent container reuse tests to normal port behavior while allowing individual tests to opt into randomized ports. Add Redis and RabbitMQ coverage for reuse with randomized ports.

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

danegsta commented Jun 3, 2026

Copy link
Copy Markdown
Member Author

/backport to release/13.4

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

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

@aspire-repo-bot

Copy link
Copy Markdown
Contributor

@danegsta backporting to release/13.4 failed, the patch most likely resulted in conflicts. Please backport manually!

git am output
$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch

Applying: Refine dynamic endpoint allocation
Applying: Reset connection string events on restart
Applying: Use direct dependency scan for DCP preallocation
Applying: Document endpoint allocation wait
Applying: Update persistent container port randomization tests
Using index info to reconstruct a base tree...
M	tests/Aspire.Hosting.RabbitMQ.Tests/RabbitMQFunctionalTests.cs
M	tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs
A	tests/Aspire.Hosting.Tests/Utils/PersistentContainerTestHelpers.cs
Falling back to patching base and 3-way merge...
Auto-merging tests/Aspire.Hosting.RabbitMQ.Tests/RabbitMQFunctionalTests.cs
CONFLICT (content): Merge conflict in tests/Aspire.Hosting.RabbitMQ.Tests/RabbitMQFunctionalTests.cs
Auto-merging tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs
CONFLICT (content): Merge conflict in tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs
CONFLICT (modify/delete): tests/Aspire.Hosting.Tests/Utils/PersistentContainerTestHelpers.cs deleted in HEAD and modified in Update persistent container port randomization tests.  Version Update persistent container port randomization tests of tests/Aspire.Hosting.Tests/Utils/PersistentContainerTestHelpers.cs left in tree.
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0005 Update persistent container port randomization tests
Error: The process '/usr/bin/git' failed with exit code 128

Link to workflow output

@danegsta danegsta merged commit b98331d into main Jun 3, 2026
658 of 663 checks passed
@danegsta danegsta deleted the danegsta/dynamic-endpoint-evaluation branch June 3, 2026 22:10
@github-actions github-actions Bot modified the milestones: 13.4.x, 13.5 Jun 3, 2026
@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

CLI E2E Tests failed — 111 passed, 2 failed, 2 unknown (commit dd6828a)

❌ Failed Tests

- Test Detail
DeployK8sWithMySql Recording · Job · CLI logs
DeployTypeScriptAppToKubernetes Recording · Job · CLI logs
View all recordings
- Test Detail
AddPackageInteractiveWhileAppHostRunningDetached Recording · Job · CLI logs
AddPackageWhileAppHostRunningDetached Recording · Job · CLI logs
AgentCommands_AllHelpOutputs_AreCorrect Recording · Job · CLI logs
AgentInitCommand_DefaultSelection_InstallsDefaultSkills Recording · Job · CLI logs
AgentInitCommand_MigratesDeprecatedConfig Recording · Job · CLI logs
AgentInit_NonInteractive_BundleOnlySkillsNotInCatalog Recording · Job · CLI logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp Recording · Job · CLI logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_DevLocalhost Recording · Job · CLI logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_Isolated Recording · Job · CLI logs
AllPublishMethodsBuildDockerImages Recording · Job · CLI logs
AspireAddAndStartWorkAgainstLegacyAppHostTs Recording · Job · CLI logs
AspireAddPackageVersionToDirectoryPackagesProps Recording · Job · CLI logs
AspireInitSingleFileAppHostRunsViaDotnetRunAppHost Recording · Job · CLI logs
AspireInit_ExistingAppHostDir_RecreatesNuGetConfigKeepsFiles Recording · Job · CLI logs
AspireInit_SolutionFile_BuildsAgainstChannelHive Recording · Job · CLI logs
AspireStartUpdatesStaleTypeScriptAppHostPath Recording · Job · CLI logs
AspireUpdateRemovesAppHostPackageVersionFromDirectoryPackagesProps Recording · Job · CLI logs
AspireUpdateRemovesOrphanAppHostPackageVersionWhenSdkAlreadyCurrent Recording · Job · CLI logs
Banner_DisplayedOnFirstRun Recording · Job · CLI logs
Banner_DisplayedWithExplicitFlag Recording · Job · CLI logs
Banner_NotDisplayedWithNoLogoFlag Recording · Job · CLI logs
CertificatesClean_RemovesCertificates Recording · Job · CLI logs
CertificatesTrust_WithNoCert_CreatesAndTrustsCertificate Recording · Job · CLI logs
CertificatesTrust_WithUntrustedCert_TrustsCertificate Recording · Job · CLI logs
ConfigSetGet_CreatesNestedJsonFormat Recording · Job · CLI logs
CreateAndRunAspireStarterProject Recording · Job · CLI logs
CreateAndRunAspireStarterProjectWithBundle Recording · Job · CLI logs
CreateAndRunEmptyAppHostProject Recording · Job · CLI logs
CreateAndRunJavaEmptyAppHostProject Recording · Job · CLI logs
CreateAndRunJsReactProject Recording · Job · CLI logs
CreateAndRunPolyglotAppHostWithDevLocalhostUrls Recording · Job · CLI logs
CreateAndRunPythonReactProject Recording · Job · CLI logs
CreateAndRunTypeScriptEmptyAppHostProject Recording · Job · CLI logs
CreateAndRunTypeScriptStarterProject Recording · Job · CLI logs
CreateJavaAppHostWithViteApp Recording · Job · CLI logs
CreateTypeScriptAppHostWithViteApp_UsesConfiguredToolchain Recording · Job · CLI logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces Recording · Job · CLI logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces_DevLocalhost Recording · Job · CLI logs
DashboardRunWithOtelTracesReturnsNoTraces Recording · Job · CLI logs
DashboardRunWithOtelTracesReturnsNoTraces_DevLocalhost Recording · Job · CLI logs
DeployK8sBasicApiService Recording · Job · CLI logs
DeployK8sWithExternalHelmChart Recording · Job · CLI logs
DeployK8sWithGarnet Recording · Job · CLI logs
DeployK8sWithMongoDB Recording · Job · CLI logs
DeployK8sWithMySql Recording · Job · CLI logs
DeployK8sWithPostgres Recording · Job · CLI logs
DeployK8sWithRabbitMQ Recording · Job · CLI logs
DeployK8sWithRedis Recording · Job · CLI logs
DeployK8sWithSqlServer Recording · Job · CLI logs
DeployK8sWithValkey Recording · Job · CLI logs
DeployTypeScriptAppToKubernetes Recording · Job · CLI logs
DescribeCommandResolvesReplicaNames Recording · Job · CLI logs
DescribeCommandShowsRunningResources Recording · Job · CLI logs
DetachFormatJsonProducesValidJson Recording · Job · CLI logs
DetachFormatJsonProducesValidJsonWhenRestartingExistingInstance Recording · Job · CLI logs
DoPublishAndDeployListStepsWork Recording · Job · CLI logs
DocsCommand_RendersInteractiveMarkdownFromLocalSource Recording · Job · CLI logs
DoctorCommand_DetectsDeprecatedAgentConfig Recording · Job · CLI logs
DoctorCommand_TypeScriptAppHostReportsMissingConfiguredToolchain Recording · Job · CLI logs
DoctorCommand_WithSslCertDir_ShowsTrusted Recording · Job · CLI logs
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted Recording · Job · CLI logs
DotNetRunFileBasedAppHostUsesAspireCliBundle Recording · Job · CLI logs
DotNetRunProjectAppHostUsesAspireCliBundle Recording · Job · CLI logs
GatewayWithoutExternalEndpoint_FailsPublishWithGuidance Recording · Job · CLI logs
GeneratedAspireDevScript_StartsWatchMode_WithConfiguredToolchain Recording · Job · CLI logs
GlobalMigration_HandlesCommentsAndTrailingCommas Recording · Job · CLI logs
GlobalMigration_HandlesMalformedLegacyJson Recording · Job · CLI logs
GlobalMigration_PreservesAllValueTypes Recording · Job · CLI logs
GlobalMigration_SkipsWhenNewConfigExists Recording · Job · CLI logs
GlobalSettings_MigratedFromLegacyFormat Recording · Job · CLI logs
IngressWithoutExternalEndpoint_FailsPublishWithGuidance Recording · Job · CLI logs
InitTypeScriptAppHost_AugmentsExistingViteRepoInWorkspaceSubdirectory Recording · Job · CLI logs
InteractiveCSharpInitCreatesExpectedFiles Recording · Job · CLI logs
InvalidAppHostPathWithComments_IsHealedOnRun Recording · Job · CLI logs
JavaScriptHostingApisRunFromTypeScriptAppHost Recording · Job · CLI logs
LatestCliCanStartStableChannelAppHost Recording · Job · CLI logs
LatestCliCanStartStableChannelTypeScriptAppHost Recording · Job · CLI logs
LegacySettingsMigration_AdjustsRelativeAppHostPath Recording · Job · CLI logs
LogsCommandShowsResourceLogs Recording · Job · CLI logs
OtelLogsReturnsStructuredLogsFromStarterApp Recording · Job · CLI logs
OtelLogsReturnsStructuredLogsFromStarterAppIsolated Recording · Job · CLI logs
PersistentContainersPreserveDataAcrossAppHostRuns Recording · Job · CLI logs
PsCommandListsRunningAppHost Recording · Job · CLI logs
PsFormatJsonOutputsOnlyJsonToStdout Recording · Job · CLI logs
PublishJavaScriptPatternsGeneratesExpectedDockerComposeArtifacts Recording · Job · CLI logs
PublishWithConfigureEnvFileUpdatesEnvOutput Recording · Job · CLI logs
PublishWithDockerComposeServiceCallbackSucceeds Recording · Job · CLI logs
PublishWithoutOutputPathUsesAppHostDirectoryDefault Recording · Job · CLI logs
ResourceCommand_FailedExec_ShowsLogPathAndLogHasEntries Recording · Job · CLI logs
ResourceCommand_SetAndDeleteParameterUpdatesDescribeOutput Recording · Job · CLI logs
RestoreGeneratesSdkFiles Recording · Job · CLI logs
RestoreGeneratesSdkFiles_WithConfiguredToolchain Recording · Job · CLI logs
RestoreRefreshesGeneratedSdkAfterAddingIntegration Recording · Job · CLI logs
RestoreSupportsConfigOnlyHelperPackageAndCrossPackageTypes Recording · Job · CLI logs
RunFromParentDirectory_UsesExistingConfigNearAppHost Recording · Job · CLI logs
RunReportsSyntaxErrorsForDotNetAppHost Recording · Job · CLI logs
RunReportsSyntaxErrorsForTypeScriptAppHost Recording · Job · CLI logs
SecretCrudOnDotNetAppHost Recording · Job · CLI logs
SecretCrudOnTypeScriptAppHost Recording · Job · CLI logs
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels Recording · Job · CLI logs
StartAndWaitForTypeScriptSqlServerAppHostWithNativeAssets Recording · Job · CLI logs
StartReportsSyntaxErrorsForDotNetAppHost Recording · Job · CLI logs
StartReportsSyntaxErrorsForTypeScriptAppHost Recording · Job · CLI logs
StopAllAppHostsFromAppHostDirectory Recording · Job · CLI logs
StopJavaPolyglotAppHostUsingApphostDirectory Recording · Job · CLI logs
StopNonInteractiveSingleAppHost Recording · Job · CLI logs
StopTypeScriptPolyglotAppHostUsingApphostDirectory Recording · Job · CLI logs
StopWithNoRunningAppHostExitsSuccessfully Recording · Job · CLI logs
TypeScriptAppHostRunDoesNotDeadlockWhenLazyOptionsInvokeAsyncCallback Recording · Job · CLI logs
TypeScriptAppHostWithVite_AllowsDifferentGuestPkgManager Recording · Job · CLI logs
UnAwaitedChainsCompileWithAutoResolvePromises Recording · Job · CLI logs
UpdateToStable_CSharpEmptyAppHost_KeepsConfigChannel Recording · Job · CLI logs
UpdateToStable_CSharpSingleFileInit_KeepsConfigChannel Recording · Job · CLI logs
UpdateToStable_TypeScriptSingleFileInit_KeepsConfigChannel Recording · Job · CLI logs
UpdateToStable_TypeScript_PreviewsStablePkgsAndKeepsChannel Recording · Job · CLI logs

📹 Recordings uploaded automatically from CI run #26914128242

@danegsta

danegsta commented Jun 5, 2026

Copy link
Copy Markdown
Member Author

/backport to release/13.4

@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

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

radical added a commit that referenced this pull request Jun 9, 2026
…ilename globs match nested paths

Three automated PRs in the last 14d fired more tests than they needed to:

  #17672, #17263  [Automated] Update ATS API Surface Area
  #17534          Move repository skills to .agents

They each touched only api/*.txt or only README/skill markdown, but were
firing trigger_all or selective:integrations — burning the full ~25min
CI critical path. Audit-replay over 161 merged PRs found them, plus a
latent C# glob bug where bare-filename patterns silently ignored
nested matches.

Root causes — two independent bugs:

1. The category-trigger rescue logic in RescueCategoryTriggerFiles built
   a synthetic union of all category triggerPaths without consulting
   per-category excludePaths. An ignored file that textually matched some
   category's glob but was excluded from that category got rescued back
   to active and then hit fallback_unmatched (worse than staying
   ignored). For src/Aspire.Hosting.Foundry/api/*.txt this meant ATS-only
   PRs fired integrations even after `**/api/*.txt` was added to
   ignorePaths.

2. The four glob analyzers (CriticalFileDetector, IgnorePathFilter,
   CategoryMapper.CompiledCategory, ProjectMappingResolver.CompiledMapping)
   handed user-facing patterns directly to FileSystemGlobbing.Matcher.
   The Matcher anchors bare-filename patterns at the repo root, so
   `Directory.Build.props` matched only the root file, not
   `src/Directory.Build.props` or `tests/Directory.Build.props`. The
   Python audit-replay evaluator (eval_rules.py) already documented and
   applied a "prepend **/ to bare-filename patterns" rule; the C#
   analyzers did not, so the two evaluators silently disagreed on
   ~5 patterns across ignorePaths, triggerAllPaths, and sourceToTestMappings.

The fix:

- Rescue now passes config.Categories directly to CategoryMapper so
  CompiledCategory.Matches honors per-category excludes. A file is
  rescued only when at least one category would actually fire on it.
- New PatternNormalization.NormalizeGlob prepends `**/` to any pattern
  without a path separator. Every glob entry point applies it: the four
  analyzers above plus ProjectMappingResolver's regex compiler.
- Rules: integrations.excludePaths gains `tests/Aspire.Acquisition.Tests/**`,
  `tests/Infrastructure.Tests/**`, `**/*.md`, `**/api/*.txt`. The same
  `**/api/*.txt` exclude is added to every category so an ignored ATS
  file can't be rescued back by any category. ignorePaths gains
  `**/api/*.txt`. Acquisition mapping's source list gains the missing
  self-mapping `tests/Aspire.Acquisition.Tests/**` (Templates and
  Infrastructure mappings already had this; Acquisition was an oversight
  exposed only after the new exclude was added).

Verification:

- Audit replay over 161 merged PRs: 4 outcomes change (#17263, #17534,
  #17549, #17672 all move to `skip`); zero regressions; zero
  fallback_unmatched.
- New AuditFixtureTests xUnit [Theory] replays 28 hand-validated PRs
  against the live audit rules. Each row is a separate test, so any
  future rule edit that changes a row's outcome shows up as a visible
  CI failure. Coverage includes templates (#16447), CLI native build
  (#17567), extension multi-category (#17881/17698/17772), Hosting-core
  trigger_all (#17879), polyglot (#17948), and the regression canaries
  for previous fallback_unmatched cases.
- Per-component regression tests pin both bugs: two new tests in
  EndToEndEvaluationTests for rescue+excludes; two more for
  bare-filename matching at nested paths.
- Three pre-existing analyzer tests had asserted the buggy bare-filename
  behavior as expected (e.g. `*.md` not matching `docs/guide.md`).
  Updated with comments explaining the user-intent rule.
- Full TestSelector namespace: 290 tests, all pass. No collateral damage
  on the wider Infrastructure.Tests suite (5 pre-existing baseline
  failures unchanged).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mitchdenny pushed a commit to mitchdenny/aspire that referenced this pull request Jun 9, 2026
* Refine dynamic endpoint allocation

Make proxyless container endpoint allocation dependency-aware so safe references can remain lazy while circular or unknown references still allocate early. Preserve explicit proxy settings when randomizing ports and publish connection string availability for dynamic allocation paths.

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

* Reset connection string events on restart

Clear the connection-string availability de-dupe state when a resource is recreated for restart so the event can publish again after callbacks are re-evaluated.

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

* Use direct dependency scan for DCP preallocation

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

* Document endpoint allocation wait

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

* Update persistent container port randomization tests

Default persistent container reuse tests to normal port behavior while allowing individual tests to opt into randomized ports. Add Redis and RabbitMQ coverage for reuse with randomized ports.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

3 participants