Skip to content

Route staging-identity CLI to its darc feed regardless of version shape#17743

Merged
davidfowl merged 6 commits into
release/13.4from
mitchdenny/add-command-feed-mismatch
May 31, 2026
Merged

Route staging-identity CLI to its darc feed regardless of version shape#17743
davidfowl merged 6 commits into
release/13.4from
mitchdenny/add-command-feed-mismatch

Conversation

@mitchdenny
Copy link
Copy Markdown
Member

@mitchdenny mitchdenny commented May 31, 2026

Problem

On a staging build of Aspire, aspire add <pkg> behaves differently between C# and TypeScript (polyglot) apphosts:

// C#
aspire add foundry
✅ The package Aspire.Hosting.Foundry::13.4.0-preview.1.26280.6 was added successfully.

// TS
aspire add foundry
Select a version of Aspire.Hosting.Foundry:
> 13.3.5-preview.1.26270.6 (based on NuGet.config)
  daily

The TypeScript path never offers the matching staging version because the synthesized staging channel routes Aspire* to the shared dnceng/dotnet9 daily feed instead of the build's own SHA-specific darc-pub-microsoft-aspire-<commit> feed.

Root cause

In PackagingService.CreateStagingChannel, useSharedFeed was derived from the CLI build's version shape:

var useSharedFeed = !hasExplicitFeedOverride && stagingQuality is not PackageChannelQuality.Stable;

A prerelease-shaped staging build (e.g. 13.4.0-preview.1.26280.6) defaults to Both quality → useSharedFeed = true → the shared daily feed (which only carries main-branch daily packages). But darc publishes a per-commit darc-pub-microsoft-aspire-<commit> feed for every officially published release-branch build, prerelease- or stable-shaped. The old comment's assumption that "darc feeds only exist for stable builds" was wrong.

C# apphosts masked the bug because the darc feed is baked into their nuget.config (written from the channel's PackageMappings); polyglot apphosts resolve solely through the channel's feed, so they surfaced it.

Fix

Decouple feed provenance (identity) from version filtering (quality):

  • Add ShouldUseSharedStagingFeed(hasExplicitFeedOverride, stagingQuality, identityChannel): a staging-identity CLI always resolves Aspire* from its own darc feed regardless of version shape. Explicit overrideStagingFeed and non-staging identities keep the prior quality-based routing unchanged, so only the prerelease-shaped staging case flips.
  • Add an injectable cliInformationalVersionProvider constructor seam (mirroring the existing isStableShapedCliVersion seam) so the derived darc feed URL is deterministic and assertable in tests, instead of reading the nondeterministic test-host assembly version.
  • Correct the misleading comments that claimed darc feeds only exist for stable-shaped builds.

Because GetChannelsAsyncCreateStagingChannel is the single source of truth for aspire add search, polyglot restore, and C# nuget.config writing, fixing it here unifies the C# and TypeScript code paths.

Tests

Full PackagingServiceTests suite: 70/70 passing. Notable additions:

  • Prerelease-shaped staging identity → asserts the resolved Aspire* source is the darc-pub-microsoft-aspire-<hash> feed (not dotnet9), ConfigureGlobalPackagesFolder == true, PinnedVersion == null (the bug repro). Verified it fails before the fix (resolves dotnet9) and passes after (resolves darc).
  • Stable-shaped staging identity → darc feed with Stable quality (guards Staging build of CLI bakes channel as stable, causing aspire init to drop nuget.config without staging feed (resolves wrong Aspire package versions) #17527).
  • Staging identity + overrideStagingFeed → override wins.
  • A PR/daily/staging/stable decision-table theory, an underivable-feed warning test, identity/quality symmetry asserts, and override-mechanism tests covering identity/version overrides, invalid-identity fallback, override precedence, build-metadata hyphen handling, the one-time warning, and the cached unavailable-reason path.

Notes

  • Targets release/13.4.
  • Side effects of the flip for prerelease staging are consistent with stable-shaped staging, which already used the darc feed: ConfigureGlobalPackagesFolder becomes true, and the CLI-version pin (only applied on the shared feed) is no longer applied since the darc feed carries only the matching build.

Relationship to #17744

#17744 reports an adjacent — but distinct — staging symptom that this PR does not fix:

  • That repro is a stable-shaped staging CLI (13.4.0+<hash>) with channel: staging. Its debug log shows Resolved 'staging' channel: feed=<staging Aspire feed>, quality=Stable — i.e. the staging channel is already routed to the darc feed (the stable-shaped path this PR leaves unchanged). So the feed-provenance fix here has no effect on that run.
  • Its symptom is that aspire add persists/reports the search-selected version (13.3.5-preview.1.26270.6, which came from the default based on NuGet.config channel) instead of the version restore actually resolved (13.4.0-preview.1.26280.4). The restore log proves 13.3.5-preview.1.26270.6 exists on no configured feed (NuGet bumped up to the next available version), so that value is the stale catalog/default-channel candidate, not a darc-feed hit.

That is a search-vs-restore version reconciliation gap (the persisted version should reflect what restore resolved), which is independent of which feed the staging channel points at. This PR is a prerequisite (the staging channel must point at the correct darc feed) but is not sufficient to close #17744; that should be tracked/fixed separately.

Validating staging feed routing locally

To make #17744 verifiable without an official build, this PR adds two PackagingService-scoped diagnostic overrides so a locally built CLI (which bakes a local identity and an unstamped version, and therefore never synthesizes a staging channel) can be made to behave exactly like a staging build for the purpose of staging feed-routing:

  • overrideCliIdentityChannel — forces the identity used for staging-feed routing decisions only (validated via IdentityChannelReader.IsValidChannel; invalid values are ignored). It does not change the global identity used for hive/packages-directory lookups, so the blast radius stays limited to feed provenance.
  • overrideCliInformationalVersion — forces the informational version that both the SHA derivation and the stable-shape/quality predicate read (e.g. 13.4.0-preview.1.26280.6+<commit>).

Both overrides are required to reach the darc path from a local build, and a one-time warning is emitted whenever either is active so a normal CLI invocation can't silently resolve packages from an overridden identity/feed. The full recipe (build locally, set channel: staging, set the two env vars, run aspire add <pkg> --debug, confirm the resolved darc feed) is documented in docs/cli-staging-validation.md.

A follow-up to lift the informational-version seam onto CliExecutionContext on main is tracked in #17750.

Helper scripts for staging/stable validation

To make the recipe one command — and to support a full interactive flow against an easy-to-get build — this PR also adds eng/scripts/debug-staging.{sh,ps1} and eng/scripts/debug-stable.{sh,ps1} (sharing a debug-aspire-channel core). Both target identity staging and the SHA-specific darc-pub-microsoft-aspire-<sha8> feed, differing only in version shape/quality:

Script Version shape Expected quality Scenario
debug-staging prerelease Both #17744
debug-stable stable Stable #17527

Modes:

  • default — runs aspire add <pkg> --debug in a throwaway dir and asserts the darc feed resolves (exit non-zero otherwise).
  • --print-env / -PrintEnv — emits export/$env: lines to apply to the current shell so every aspire command behaves like the simulated build.
  • --shell / -Shell — opens an interactive subshell with the overrides applied and the target CLI first on PATH, for a full aspire new/add/run flow; overrides vanish on exit. The subshell also points NUGET_PACKAGES at a per-SHA isolated cache (<temp>/aspire-debug-nuget/<sha8>) so simulated-staging restores can't contaminate (or be contaminated by) the global package cache.

--pr <N> installs that PR's full-bundle build first and targets it, so you can validate against a real installed CLI (not just a local source build). The interactive recipe and a per-identity validation matrix are documented in docs/cli-staging-validation.md, linked from docs/contributing.md.

The synthesized `staging` package channel derived its feed from the CLI
build's version shape: a prerelease-shaped staging build (e.g.
13.4.0-preview.1.26280.6) routed Aspire.* to the shared dnceng/dotnet9
daily feed instead of its SHA-specific darc-pub-microsoft-aspire-<commit>
feed. C# apphosts masked this because the darc feed is baked into their
nuget.config, but polyglot (TypeScript) apphosts resolve solely through the
channel's feed, so `aspire add <pkg>` offered the wrong versions.

Decouple feed provenance (identity) from version filtering (quality):

- Add `ShouldUseSharedStagingFeed(...)`: a staging-identity CLI always uses
  its own darc feed, any version shape. Override feeds and non-staging
  identities keep the prior quality-based routing.
- Add an injectable `cliInformationalVersionProvider` constructor seam so the
  derived darc feed URL is deterministic and assertable in tests.
- Correct the comments that incorrectly claimed darc feeds only exist for
  stable-shaped builds.

Add tests covering prerelease-shaped staging -> darc, stable-shaped staging
-> darc, and override-wins. The prerelease repro fails before the fix
(resolves dotnet9) and passes after (resolves darc).

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

github-actions Bot commented May 31, 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 -- 17743

Or

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

@mitchdenny mitchdenny changed the base branch from main to release/13.4 May 31, 2026 03:26
mitchdenny and others added 3 commits May 31, 2026 13:50
Adds a decision-table theory across PR/daily/staging/stable channel
configurations, drops the override-feed crutch from the staging-identity
tests so they assert the real darc feed via an injected version seam, adds
coverage for the underivable-feed warning path, and adds symmetry asserts
for the stable-shaped staging case.

Also logs a one-time warning in CreateStagingChannel when a staging channel
is permitted but no staging feed URL can be derived, so the channel is
omitted visibly instead of silently.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds two PackagingService-scoped diagnostic config overrides so a locally
built CLI (baked identity 'local', unstamped version) can simulate a staging
build and validate end-to-end that 'aspire add' resolves Aspire.* from the
correct SHA-specific darc-pub-microsoft-aspire-<sha> feed:

- overrideCliIdentityChannel: forces the identity used for staging-feed
  routing decisions only (validated via IdentityChannelReader.IsValidChannel;
  invalid values ignored). Does not change the global identity used for
  hive/packages-directory lookups, keeping blast radius limited.
- overrideCliInformationalVersion: forces the version that both the SHA
  derivation and the stable-shape/quality predicate read.

All staging-feed decision points now route through GetEffectiveIdentityChannel.
A one-time warning is emitted whenever either override is active. Adds
docs/cli-staging-validation.md with the local-validation recipe and nine
PackagingServiceTests covering the override permutations.

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

Add eng/scripts/debug-staging.{sh,ps1} and debug-stable.{sh,ps1} (plus the
shared debug-aspire-channel core) that make an easy-to-get build (an installed
PR build or a local build) resolve Aspire.* packages exactly like an official
staging or stable release-branch build, so the feed-routing fix can be
validated end-to-end.

Each script targets identity 'staging' and the SHA-specific
darc-pub-microsoft-aspire-<sha8> feed, differing only in version shape/quality
(staging => prerelease/Both, #17744; stable => stable/Stable, #17527). Modes:

- default: one-shot 'aspire add --debug' that asserts the darc feed resolves.
- --print-env / -PrintEnv: emit export/$env lines to apply to the current shell.
- --shell / -Shell: interactive subshell with overrides applied and the target
  CLI first on PATH, for a full 'aspire new'/'add'/run flow; overrides vanish on exit.

Extend docs/cli-staging-validation.md with the helper-script usage, the
interactive PR-build recipe, and a validation matrix; link it from
docs/contributing.md.

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

Re-running the failed jobs in the CI workflow for this pull request because 5 jobs were identified as retry-safe transient failures in the CI run attempt.
GitHub was asked to rerun all failed jobs for that attempt, and the rerun is being tracked in the rerun attempt.
The job links below point to the failed attempt jobs that matched the retry-safe transient failure rules.

Matched test failure patterns (1 test)
  • Aspire.Cli.EndToEnd.Tests.JavaScriptPublishTests.AllPublishMethodsBuildDockerImages — MCR registry rate limiting (HTTP 403)

When dropping into the interactive subshell (--shell / -Shell), point
NUGET_PACKAGES at an isolated, per-sha directory so packages restored from
the simulated staging darc feed can never contaminate the developer's real
global package cache. Also commit the staging-override NOTE clarifying the
overrides route to but do not create a feed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mitchdenny mitchdenny marked this pull request as ready for review May 31, 2026 09:10
Copilot AI review requested due to automatic review settings May 31, 2026 09:10
The staging identity now always routes to its build's SHA-specific
darc-pub-microsoft-aspire-<sha> feed regardless of version shape, so the
feed must be derivable from the CLI's +<commit> informational version. The
test host assembly has no commit metadata, so the staging channel could not
be synthesized and the test regressed. Stamp a staging-shaped informational
version via the overrideCliInformationalVersion config so the derivation
matches a real staging build.

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

Re-running the failed jobs in the CI workflow for this pull request because 1 job was identified as retry-safe transient failures in the CI run attempt.
GitHub was asked to rerun all failed jobs for that attempt, and the rerun is being tracked in the rerun attempt.
The job links below point to the failed attempt jobs that matched the retry-safe transient failure rules.

Matched test failure patterns (1 test)
  • Aspire.Cli.EndToEnd.Tests.KubernetesDeployWithValkeyTests.DeployK8sWithValkey — Unable to access container registry during publish

@github-actions
Copy link
Copy Markdown
Contributor

CLI E2E Tests failed — 109 passed, 1 failed, 2 unknown (commit ca752ee)

❌ Failed Tests

Status Test Recording Job Artifacts
DeployK8sWithValkey Recording #78716274148 Logs
View all recordings
Status Test Recording Job Artifacts
AddPackageInteractiveWhileAppHostRunningDetached Recording #78716274742 Logs
AddPackageWhileAppHostRunningDetached Recording #78716274742 Logs
AgentCommands_AllHelpOutputs_AreCorrect Recording #78716274455 Logs
AgentInitCommand_DefaultSelection_InstallsDefaultSkills Recording #78716274455 Logs
AgentInitCommand_MigratesDeprecatedConfig Recording #78716274455 Logs
AgentInitCommand_NonInteractive_BundleOnlySkillsBeyondCliCatalog_AreInstallable Recording #78716274455 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp Recording #78716274271 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_DevLocalhost Recording #78716274271 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_Isolated Recording #78716274271 Logs
AllPublishMethodsBuildDockerImages Recording #78716274492 Logs
AspireAddAndStartWorkAgainstLegacyAppHostTs Recording #78716274704 Logs
AspireAddPackageVersionToDirectoryPackagesProps Recording #78716274759 Logs
AspireInitSingleFileAppHostRunsViaDotnetRunAppHost Recording #78716274467 Logs
AspireInitWithExistingAppHostDirRecreatesMissingNuGetConfigAndPreservesFiles Recording #78716274460 Logs
AspireInitWithSolutionFileGeneratesAppHostThatBuildsAgainstChannelHive Recording #78716274460 Logs
AspireStartUpdatesStaleTypeScriptAppHostPath Recording #78716274774 Logs
AspireUpdateRemovesAppHostPackageVersionFromDirectoryPackagesProps Recording #78716274759 Logs
AspireUpdateRemovesOrphanAppHostPackageVersionWhenSdkAlreadyCurrent Recording #78716274759 Logs
Banner_DisplayedOnFirstRun Recording #78716274481 Logs
Banner_DisplayedWithExplicitFlag Recording #78716274481 Logs
Banner_NotDisplayedWithNoLogoFlag Recording #78716274481 Logs
CertificatesClean_RemovesCertificates Recording #78716274677 Logs
CertificatesTrust_WithNoCert_CreatesAndTrustsCertificate Recording #78716274677 Logs
CertificatesTrust_WithUntrustedCert_TrustsCertificate Recording #78716274677 Logs
ConfigSetGet_CreatesNestedJsonFormat Recording #78716274698 Logs
CreateAndRunAspireStarterProject Recording #78716274794 Logs
CreateAndRunAspireStarterProjectWithBundle Recording #78716274358 Logs
CreateAndRunEmptyAppHostProject Recording #78716274684 Logs
CreateAndRunJavaEmptyAppHostProject Recording #78716274307 Logs
CreateAndRunJsReactProject Recording #78716274611 Logs
CreateAndRunPolyglotAppHostWithDevLocalhostUrls Recording #78716274794 Logs
CreateAndRunPythonReactProject Recording #78716274585 Logs
CreateAndRunTypeScriptEmptyAppHostProject Recording #78716274443 Logs
CreateAndRunTypeScriptStarterProject Recording #78716274674 Logs
CreateJavaAppHostWithViteApp Recording #78716274822 Logs
CreateTypeScriptAppHostWithViteApp_AllowsGuestAppPackageManagerToDiffer Recording #78716274558 Logs
CreateTypeScriptAppHostWithViteApp_UsesConfiguredToolchain Recording #78716274558 Logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces Recording #78716274485 Logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces_DevLocalhost Recording #78716274485 Logs
DashboardRunWithOtelTracesReturnsNoTraces Recording #78716274485 Logs
DashboardRunWithOtelTracesReturnsNoTraces_DevLocalhost Recording #78716274485 Logs
DeployK8sBasicApiService Recording #78716274638 Logs
DeployK8sWithExternalHelmChart Recording #78716274465 Logs
DeployK8sWithGarnet Recording #78716274378 Logs
DeployK8sWithMongoDB Recording #78716274590 Logs
DeployK8sWithMySql Recording #78716274540 Logs
DeployK8sWithPostgres Recording #78716274725 Logs
DeployK8sWithRabbitMQ Recording #78716274390 Logs
DeployK8sWithRedis Recording #78716274576 Logs
DeployK8sWithSqlServer Recording #78716274325 Logs
DeployK8sWithValkey Recording #78716274148 Logs
DeployTypeScriptAppToKubernetes Recording #78716274362 Logs
DescribeCommandResolvesReplicaNames Recording #78716274615 Logs
DescribeCommandShowsRunningResources Recording #78716274615 Logs
DetachFormatJsonProducesValidJson Recording #78716274515 Logs
DetachFormatJsonProducesValidJsonWhenRestartingExistingInstance Recording #78716274515 Logs
DoPublishAndDeployListStepsWork Recording #78716274853 Logs
DocsCommand_RendersInteractiveMarkdownFromLocalSource Recording #78716274789 Logs
DoctorCommand_DetectsDeprecatedAgentConfig Recording #78716274455 Logs
DoctorCommand_TypeScriptAppHostReportsMissingConfiguredToolchain Recording #78716274614 Logs
DoctorCommand_WithSslCertDir_ShowsTrusted Recording #78716274614 Logs
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted Recording #78716274614 Logs
GatewayWithoutExternalEndpoint_FailsPublishWithGuidance Recording #78716274289 Logs
GeneratedAspireDevScript_StartsWatchMode_WithConfiguredToolchain Recording #78716274558 Logs
GlobalMigration_HandlesCommentsAndTrailingCommas Recording #78716274698 Logs
GlobalMigration_HandlesMalformedLegacyJson Recording #78716274698 Logs
GlobalMigration_PreservesAllValueTypes Recording #78716274698 Logs
GlobalMigration_SkipsWhenNewConfigExists Recording #78716274698 Logs
GlobalSettings_MigratedFromLegacyFormat Recording #78716274698 Logs
IngressWithoutExternalEndpoint_FailsPublishWithGuidance Recording #78716274289 Logs
InitTypeScriptAppHost_AugmentsExistingViteRepoInWorkspaceSubdirectory Recording #78716274558 Logs
InteractiveCSharpInitCreatesExpectedFiles Recording #78716274740 Logs
InvalidAppHostPathWithComments_IsHealedOnRun Recording #78716274786 Logs
JavaScriptHostingApisRunFromTypeScriptAppHost Recording #78716274492 Logs
LatestCliCanStartStableChannelAppHost Recording #78716274794 Logs
LatestCliCanStartStableChannelTypeScriptAppHost Recording #78716274794 Logs
LegacySettingsMigration_AdjustsRelativeAppHostPath Recording #78716274774 Logs
LogsCommandShowsResourceLogs Recording #78716274522 Logs
OtelLogsReturnsStructuredLogsFromStarterApp Recording #78716274780 Logs
OtelLogsReturnsStructuredLogsFromStarterAppIsolated Recording #78716274780 Logs
PsCommandListsRunningAppHost Recording #78716274379 Logs
PsFormatJsonOutputsOnlyJsonToStdout Recording #78716274379 Logs
PublishJavaScriptPatternsGeneratesExpectedDockerComposeArtifacts Recording #78716274683 Logs
PublishWithConfigureEnvFileUpdatesEnvOutput Recording #78716274683 Logs
PublishWithDockerComposeServiceCallbackSucceeds Recording #78716274683 Logs
PublishWithoutOutputPathUsesAppHostDirectoryDefault Recording #78716274683 Logs
ResourceCommand_FailedExecution_DisplaysAppHostLogPathAndLogContainsEntries Recording #78716274787 Logs
ResourceCommand_SetAndDeleteParameterUpdatesDescribeOutput Recording #78716274787 Logs
RestoreGeneratesSdkFiles Recording #78716274300 Logs
RestoreGeneratesSdkFiles_WithConfiguredToolchain Recording #78716274730 Logs
RestoreRefreshesGeneratedSdkAfterAddingIntegration Recording #78716274730 Logs
RestoreSupportsConfigOnlyHelperPackageAndCrossPackageTypes Recording #78716274357 Logs
RunFromParentDirectory_UsesExistingConfigNearAppHost Recording #78716274559 Logs
RunReportsSyntaxErrorsForDotNetAppHost Recording #78716274374 Logs
RunReportsSyntaxErrorsForTypeScriptAppHost Recording #78716274374 Logs
SecretCrudOnDotNetAppHost Recording #78716274695 Logs
SecretCrudOnTypeScriptAppHost Recording #78716274696 Logs
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels Recording #78716274399 Logs
StartAndWaitForTypeScriptSqlServerAppHostWithNativeAssets Recording #78716274488 Logs
StartReportsSyntaxErrorsForDotNetAppHost Recording #78716274374 Logs
StartReportsSyntaxErrorsForTypeScriptAppHost Recording #78716274374 Logs
StopAllAppHostsFromAppHostDirectory Recording #78716274701 Logs
StopJavaPolyglotAppHostUsingApphostDirectory Recording #78716274646 Logs
StopNonInteractiveSingleAppHost Recording #78716274701 Logs
StopTypeScriptPolyglotAppHostUsingApphostDirectory Recording #78716274426 Logs
StopWithNoRunningAppHostExitsSuccessfully Recording #78716274742 Logs
TypeScriptAppHostRunDoesNotDeadlockWhenLazyOptionsInvokeAsyncCallback Recording #78716274443 Logs
UnAwaitedChainsCompileWithAutoResolvePromises Recording #78716274730 Logs
UpdateProjectChannelToStable_CSharpEmptyAppHost_PreservesAspireConfigChannel Recording #78716274391 Logs
UpdateProjectChannelToStable_CSharpSingleFileInit_PreservesAspireConfigChannel Recording #78716274391 Logs
UpdateProjectChannelToStable_TypeScriptSingleFileInit_PreservesAspireConfigChannel Recording #78716274391 Logs
UpdateProjectChannelToStable_TypeScript_PreviewsStablePackagesAndPreservesChannel Recording #78716274391 Logs

📹 Recordings uploaded automatically from CI run #26708726647

@davidfowl davidfowl merged commit e138509 into release/13.4 May 31, 2026
616 of 619 checks passed
@davidfowl davidfowl deleted the mitchdenny/add-command-feed-mismatch branch May 31, 2026 18:43
@microsoft-github-policy-service microsoft-github-policy-service Bot added this to the 13.4 milestone May 31, 2026
@aspire-repo-bot
Copy link
Copy Markdown
Contributor

✅ No documentation update needed.

docs_optional → bug_fix_restores_documented_behavior

Triggered signals (1): pr_body_has_cli_flag_mention — fires on --debug (as in aspire add <pkg> --debug) mentioned in the PR body's contributor validation recipe. This refers to the existing --log-level Debug option already documented in aspire-add.mdx via the option-log-level.md include; no new flag was introduced.

Why no docs PR is needed: The PR is a bug fix that makes aspire add for polyglot (TypeScript) apphosts behave consistently with C# apphosts in staging builds — routing Aspire.* package resolution to the per-build darc-pub-microsoft-aspire- feed. The intended behavior was always documented (aspire add adds packages from configured sources); the bug was that polyglot apphosts used the wrong feed. The two new diagnostic env vars (overrideCliIdentityChannel, overrideCliInformationalVersion) are contributor-only tools that emit a one-time warning and are documented in the aspire repo's docs/cli-staging-validation.md, not intended for aspire.dev.

mitchdenny added a commit that referenced this pull request Jun 1, 2026
Polyglot apphosts (TS/Python/Go) deliberately don't carry a persistent
NuGet.config — that file is a .NET-ism. Restore is done via on-the-fly
`TemporaryNuGetConfig`s built from `aspire.config.json#channel` (see
`PrebuiltAppHostServer.CreatePackageSourceOverrideNuGetConfigAsync`).

The IntegrationPackageSearchService was unconditionally including the
Implicit channel whenever the apphost had a pin, even for polyglot. Because
polyglot has no project-local NuGet.config, Implicit's `dotnet package
search` ran against the user's ambient (typically nuget.org) and surfaced
stale/wrong-feed versions alongside the pinned channel's versions. This
produced the spurious 'select version' prompt the user reported on TS
apphosts pinned to staging (#17743), and also added 'staging' / 'daily'
rows to stable packages like azure-appcontainers.

Fix: when a polyglot apphost has a pin, search ONLY the pinned channel.
The pinned channel materializes its own TemporaryNuGetConfig from its PSM
mappings, so it's correctly scoped. This matches C# end-to-end: C#'s
`GetConfiguredChannel` returns null, so IPSS runs Implicit against the C#
template's project-local NuGet.config (which IS correctly scoped because
the C# template writes one).

Trade-off knowingly accepted: a stable-pinned polyglot apphost cannot
reach prerelease-only packages (e.g. Foundry). This matches C# behavior —
a stable-pinned C# project also wouldn't see them.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
pull Bot pushed a commit to tooniez/aspire that referenced this pull request Jun 2, 2026
Brings 43 release-branch commits forward onto main now that 13.4.0 has shipped.
This PR replaces the original automated merge (microsoft#17804) which had to be closed so
that conflict resolution and post-merge cleanups could be made on a non-protected
branch.

Conflict resolution summary (33 files):

* Equivalent backports (took main's commit identity): ChannelUpdateWorkflowTests,
  LoggingHelpersTests, the four extension test files, AspireEditorCommandProvider,
  appHostDiscovery.

* Release-only forwards (preserved): microsoft#17732 / microsoft#17756 Foundry hosted-agent protocol
  selection and cross-compute-environment endpoint references, microsoft#17573 stabilize
  PrebuiltAppHostServer staging globalPackagesFolder path, microsoft#17743 staging-identity
  CLI darc feed routing.

* Main-only forwards (preserved): microsoft#17506 Show discovered AppHosts in Aspire pane,
  microsoft#17547 Localize Aspire skills metadata errors, microsoft#17801 VS Code v1.12.0, microsoft#17297
  Aspire CLI npm package release integration, microsoft#17576 TerminalRun IAsyncDisposable,
  microsoft#17721 / microsoft#17723 VS Code telemetry, microsoft#17671 ATS baseline fix (re-applied manually
  on top of Foundry source taken from release).

* Hybrid (manually spliced): docs/contributing.md - kept main's restructured
  layout and inserted release's staging-validation paragraph; HostedAgentBuilder-
  Extension - took release base then re-applied microsoft#17671 asHostedAgent rename;
  UpdateCommandTests - took main and injected microsoft#17743's
  OverrideCliInformationalVersionConfigKey block.

Post-merge cleanups included in this PR:

* eng/Versions.props: revert StabilizePackageVersion to false (was flipped to
  true on release/13.4 by microsoft#17520 for shipping 13.4.0; main must stay in preview
  mode).

* .github/workflows/generate-api-diffs.yml: retarget back to main (was pointed
  at release/13.4 by microsoft#17696 release prep).

* .github/workflows/backmerge-release.yml: update from release/13.3 to
  release/13.4 (was stale - missed the 13.4 release-time bump).

* .github/workflows/milestone-assignment.yml: audited - already correct
  (main -> 13.5, release/13.4 -> 13.4.x); no change.

This merge commit must be preserved - do not squash on merge.

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