Skip to content

Forward-port #17528 + #17564 + #17573 from release/13.4 to main + DotNet template identity-channel fix#17597

Closed
mitchdenny wants to merge 4 commits into
mainfrom
mitchdenny/forward-port-template-fixes-to-main
Closed

Forward-port #17528 + #17564 + #17573 from release/13.4 to main + DotNet template identity-channel fix#17597
mitchdenny wants to merge 4 commits into
mainfrom
mitchdenny/forward-port-template-fixes-to-main

Conversation

@mitchdenny
Copy link
Copy Markdown
Member

Forward-ports two CLI fixes from release/13.4 to main.

Fixes #17596.

What's cherry-picked

Commit Original PR Author Summary
3f0998a #17564 @sebastienros Prefer current CLI template version for aspire new
5d0da8b #17573 @danegsta Stabilize PrebuiltAppHostServer staging globalPackagesFolder path

Both PRs are already merged on release/13.4 and need to land on main so daily builds get the same fixes.

Why this matters (#17564)

See #17596 for the full investigation. Short version:

On a clean ~/.aspire, aspire new with a daily-build CLI from main and a DotNet template (C# Blazor / aspire-starter) was resolving Aspire.ProjectTemplates 13.3.5 from nuget.org instead of the expected 13.5.0-preview.1.* from the dotnet9 daily feed. Root cause: TemplateNuGetConfigService.ResolveTemplatePackageAsync restricts the channel search to the Implicit (nuget.org) channel when neither --channel is supplied nor PR hives exist on disk. Folks with stale ~/.aspire/hives/* from past PR installs never saw this — clearing ~/.aspire exposes it.

PR #17564 adds NewCommand.TryGetCurrentCliTemplateVersionPackage, which synthesizes a Aspire.ProjectTemplates package pinned to the CLI's own SDK version for non-stable Explicit channels (daily/staging). A daily 13.5 CLI now lock-steps to 13.5 daily templates regardless of what nuget.org ships.

Why this matters (#17573)

PackagingService creates the staging channel with ConfigureGlobalPackagesFolder=true so each darc/override feed restore lands in an isolated cache (two staging builds of the same release branch ship as 13.4.0 but from different feeds, and NuGet keys by (id,version) only). PrebuiltAppHostServer was wiring that flag into a TemporaryNuGetConfig whose relative .nugetpackages default resolved under the temp config's own directory; BundleNuGetService baked those temp paths into integration-package-probe-manifest.json, and TemporaryNuGetConfig.Dispose then recursively deleted the cache out from under the manifest. On macOS osx-arm64 polyglot staging builds this surfaced as a hang during DI / assembly loading in aspire-managed.

The fix anchors the override at a stable absolute path: <ASPIRE_HOME>/.nugetpackages/<first-8-of-CLI-commit-sha>, matching the existing darc-pub-microsoft-aspire-<hash> feed URL convention in PackagingService.GetStagingFeedUrl.

Validation

Cherry-picks applied cleanly (no conflicts). Both PRs already passed CI on release/13.4. Will rely on this PR's CI run to confirm the forward-port compiles and tests pass on top of current main.

cc @radical @davidfowl @joperezr @sebastienros @danegsta

@mitchdenny mitchdenny requested a review from JamesNK as a code owner May 28, 2026 12:10
Copilot AI review requested due to automatic review settings May 28, 2026 12:10
@mitchdenny mitchdenny requested a review from davidfowl as a code owner May 28, 2026 12:10
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 28, 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 -- 17597

Or

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

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.

Pull request overview

Forward-ports two Aspire CLI fixes from release/13.4 to main: (1) ensuring aspire new prefers templates matching the running CLI/SDK version for explicit prerelease channels, and (2) stabilizing staging-channel NuGet cache paths so temporary nuget.config cleanup doesn’t delete packages that are still referenced by the integration probe manifest.

Changes:

  • Update aspire new template-version resolution to pin to the current CLI/SDK version for explicit prerelease channels (daily/staging), with corresponding channel-resolution test coverage.
  • Stabilize staging globalPackagesFolder to an absolute, persistent per-feed cache under <ASPIRE_HOME>/.nugetpackages/<feed-hash>; add cache-clearing support and tests.
  • Extend supporting utilities (VersionHelper, CliPathHelper, NuGetConfigMerger, TemporaryNuGetConfig) and add/adjust unit tests to lock in the new invariants.
Show a summary per file
File Description
tests/Aspire.Cli.Tests/Utils/VersionHelperTests.cs Adds coverage for “current CLI version match” behavior when a channel is selected vs. no channel/hives.
tests/Aspire.Cli.Tests/Utils/CliPathHelperTests.cs Adds tests for staging feed cache-key hashing (normalization, determinism, length handling).
tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs Asserts staging globalPackagesFolder is absolute, outside temp config dir, and keyed by feed-hash.
tests/Aspire.Cli.Tests/Packaging/TemporaryNuGetConfigTests.cs Verifies explicit globalPackagesFolder override propagation and ignore-when-disabled behavior.
tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs Removes hard-coded SDK version expectation; aligns with VersionHelper.GetDefaultSdkVersion().
tests/Aspire.Cli.Tests/Commands/NewCommandChannelResolutionTests.cs Expands coverage for identity-channel resolution and explicit prerelease/stable channel pinning behavior.
tests/Aspire.Cli.Tests/Commands/CacheCommandTests.cs Adds tests ensuring cache clear removes staging .nugetpackages subdirectories and handles missing roots.
src/Aspire.Cli/Utils/VersionHelper.cs Broadens “exact current CLI match” eligibility to cases where a channel is selected.
src/Aspire.Cli/Utils/CliPathHelper.cs Introduces staging cache root path helper and feed-url hash key computation.
src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs Writes a persistent absolute globalPackagesFolder for staging/source-override temp configs; selects primary feed URL for keying.
src/Aspire.Cli/Packaging/TemporaryNuGetConfig.cs Adds optional globalPackagesFolderValue passthrough to config generation.
src/Aspire.Cli/Packaging/PackageChannel.cs Preserves current CLI/SDK version in prerelease channel searches to support pinning behavior.
src/Aspire.Cli/Packaging/NuGetConfigMerger.cs Adds default .nugetpackages constant and allows callers to supply an explicit globalPackagesFolder value.
src/Aspire.Cli/Commands/NewCommand.cs Adds TryGetCurrentCliTemplateVersionPackage to synthesize/preserve CLI-matching template version for prerelease explicit channels.
src/Aspire.Cli/Commands/CacheCommand.cs Extends cache clear to wipe staging NuGet cache root under ASPIRE_HOME.

Copilot's findings

  • Files reviewed: 15/15 changed files
  • Comments generated: 3

Comment on lines +43 to +48
// Wipe the staging NuGet package cache too. Producers (PrebuiltAppHostServer's
// temporary nuget.config for the staging channel) deposit SHA-keyed package
// caches under <ASPIRE_HOME>/.nugetpackages/<sha>; clearing them lets users
// recover wedged staging restores without filesystem surgery. We hand the parent
// directory to ClearDirectoryContents so each SHA subdirectory is wiped while
// the parent itself stays in place for the next staging restore.
Comment on lines +91 to +94
// Pins that `aspire cache clear` wipes the SHA-keyed staging NuGet package caches under
// <ASPIRE_HOME>/.nugetpackages — produced by PrebuiltAppHostServer's temporary
// nuget.config for the staging channel. Without this, a wedged staging restore can only
// be recovered by manual filesystem surgery.
Comment on lines +114 to +116
// SHA-keyed subdirectories should be gone; the parent stays so the next staging restore
// can populate a fresh cache without recreating the .nugetpackages root.
Assert.False(Directory.Exists(Path.Combine(stagingCacheRoot.FullName, "deadbeef")));
@mitchdenny mitchdenny marked this pull request as draft May 28, 2026 12:18
mitchdenny and others added 3 commits May 28, 2026 22:35
…rce mapping (#17528)

* Bake AspireCliChannel=staging for release-branch builds even when stabilizing

The channel-compute step in build_sign_native.yml was checking
$versionKind -eq 'release' BEFORE the release-branch regex check. A
13.4 staging build runs from a release/* branch with
StabilizePackageVersion=true, which sets DotNetFinalVersionKind=release,
so the wrong arm fired and baked AspireCliChannel=stable into the
binary.

Downstream, aspire init reads CliExecutionContext.IdentityChannel to
pick the channel mappings it writes into the workspace nuget.config.
With identity=stable there's no Aspire.* → staging-feed mapping, so
aspire add tries to resolve packages from nuget.org and either gets
13.3.5 or fails outright (the apphost.cs template pins
#:sdk Aspire.AppHost.Sdk@13.4.0+<sha>, which isn't on nuget.org).

Swap the conditions so the release-branch check runs first. Release-
branch builds are always staging artifacts; only release-shaped
non-release-branch builds (effectively none in practice) get stable.

Fixes #17527

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

* Add aspireCliChannelOverride pipeline parameter for GA ship builds

With release-branch builds now defaulting to 'staging' (so stabilizing
dogfood builds aren't mis-baked as 'stable'), there was no remaining
path to produce a real 'stable' GA ship binary — the same release/*
branch that produces the staging dogfood drops also produces the final
ship build, and the pipeline has no other signal to tell them apart.

Add a runtime pipeline parameter 'aspireCliChannelOverride' (auto |
stable | staging | daily, default auto) to azure-pipelines.yml and
thread it through every build_sign_native.yml invocation. When the
release manager kicks off the official GA ship build, they set this to
'stable' so the distributed binary bakes AspireCliChannel=stable and
aspire init writes the nuget.org-only nuget.config that matches the
promoted package set. Routine stabilizing builds leave it on 'auto'
and continue to bake 'staging'.

The override is validated against the same accepted-channel set that
IdentityChannelReader.IsValidChannel enforces at CLI startup so a typo
fails the pipeline step rather than producing a binary that refuses
to boot. pr-<N> is intentionally excluded from the override set since
PR builds always come from the PullRequest reason arm.

The unofficial pipeline doesn't get the parameter — its test builds
should always derive the channel from branch+reason, and the
template's default 'auto' achieves that.

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

* Route stabilizing staging CLI to SHA-derived darc feed

The staging-channel synthesis in PackagingService defaulted to
PackageChannelQuality.Both for staging-identity CLIs. With Both,
useSharedFeed=true and Aspire.* gets routed to the shared dnceng/dotnet9
daily feed -- which only contains prerelease-tagged 13.4.0-preview.*
packages, not the stable-shaped 13.4.0 packages produced during release
stabilization (StabilizePackageVersion=true).

Net effect on the just-shipped staging build of 13.4: `aspire init`
drops a NuGet.config pointing Aspire.* at dotnet9, then `aspire add yarp`
fails to resolve Aspire.Hosting.Yarp 13.4.0 because dotnet9 doesn't
carry it. The packages actually live in the SHA-derived
darc-pub-microsoft-aspire-<hash> feed.

Fix: when the CLI's identity is staging, derive the synthesized
channel's default quality from the CLI build's version shape:
  - Stable-shaped (no semver prerelease tag) -> Stable, which makes
    useSharedFeed=false and routes Aspire.* to the SHA-derived darc
    feed where stabilizing packages actually live.
  - Prerelease-shaped -> Both (the historical default), since SHA-
    specific darc feeds are only created for stable release-branch
    builds and prerelease staging CLIs must use the shared feed.

The identity-staging branch runs before the requested/configured
branches in the if/else because `init` (and many other commands) calls
GetChannelsAsync(requestedChannelName: "staging") when the running
CLI's identity is staging -- short-circuiting on the requested branch
would re-introduce the bug.

The version-shape predicate is injected via constructor so unit tests
can deterministically exercise both paths regardless of the test-host
assembly's baked InformationalVersion.

Validated end-to-end with a locally-built NAOT `aspire` binary
(`/p:AspireCliChannel=staging`) + overrideStagingFeed pointing at
darc-pub-microsoft-aspire-0f514452: `aspire init` -> `aspire add yarp`
now resolves Aspire.Hosting.Yarp 13.4.0 instead of falling back to
13.3.5.

Refs #17527

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

* Pin PackagingService stable-shape predicate to false in CliTestHelper

The stabilization-check CI job builds the test host with
StabilizePackageVersion=true, which bakes a stable-shaped (no '-')
informational version into Aspire.Cli. PackagingService's new
identity-staging branch then defaults quality to Stable and requires
a SHA suffix in the assembly's InformationalVersion to compute the
darc-pub feed URL. Stabilized test-host assemblies don't carry a
+sha suffix, so CreateStagingChannel returned null and the
UpdateCommand_WhenStagingIdentityRegistersChannel_UsesStagingForUnpinnedProject
test fell back to the default channel instead of staging.

Default CliTestHelper.PackagingServiceFactory to inject
isStableShapedCliVersion: () => false so command-level tests get
deterministic prerelease-shaped behavior (quality=Both → shared
dotnet9 feed) regardless of how the test host was built. Tests
that specifically exercise the stable-shape branch (in
PackagingServiceTests) construct PackagingService directly and
already pass an explicit predicate.

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

* Update eng/pipelines/templates/build_sign_native.yml

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Jose Perez Rodriguez <joperezr@microsoft.com>
* Prefer current CLI template version

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

* Pin aspire new template version to CLI

Ensure CLI-runtime templates selected from explicit package channels use the current bundled CLI/SDK version instead of floating to newer channel packages that can mismatch the bundled AppHost server.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…Folder path (#17573)

* Stabilize PrebuiltAppHostServer staging globalPackagesFolder path

PackagingService creates the staging channel with
ConfigureGlobalPackagesFolder=true so each darc/override feed restore
lands in an isolated cache (two staging builds of the same release
branch ship as 13.4.0 but from different feeds, and NuGet keys by
(id,version) only). PrebuiltAppHostServer was wiring that flag into a
TemporaryNuGetConfig whose default globalPackagesFolder value is the
relative '.nugetpackages' -- NuGet resolved it under the temp config's
own directory, BundleNuGetService baked those temp paths into
integration-package-probe-manifest.json, and TemporaryNuGetConfig.Dispose
then recursively deleted the cache out from under the manifest. On macOS
osx-arm64 polyglot staging builds this surfaced as a hang during DI /
assembly loading in aspire-managed.

Preserve the per-feed cache isolation behavior and anchor the override
at a stable absolute path instead:

  <ASPIRE_HOME>/.nugetpackages/<first-8-of-CLI-commit-sha>

Keying by the truncated commit hash matches the existing
darc-pub-microsoft-aspire-<hash> feed URL convention in
PackagingService.GetStagingFeedUrl, so the cache key and feed key stay
aligned at 8 hex chars. 8 chars is short enough to avoid Windows
MAX_PATH blow-ups on deep integration cache trees while keeping SHA
collisions negligible. The cache lives under ASPIRE_HOME (not the
per-AppHost working directory) so multiple AppHosts on the same machine
running against the same staging build can share a single restore --
the unit of isolation here is the staging build, not the individual
restore command.

Mechanics:
- TemporaryNuGetConfig.CreateAsync now accepts an optional
  globalPackagesFolderValue and propagates it through
  AddGlobalPackagesFolderToConfigAsync into the merger.
- NuGetConfigMerger.AddGlobalPackagesFolderConfiguration takes the
  optional override and falls back to the workspace-relative default
  ('.nugetpackages') for the non-temp workspace-merge path.
- PrebuiltAppHostServer.ResolveStableGlobalPackagesFolder routes both
  temp config branches (channel and package-source-override) through
  the new helper.
- VersionHelper.TryGetCurrentCommitHashShort surfaces the truncated
  SHA from the running CLI's AssemblyInformationalVersion (returns
  null on clean release builds with no '+sha' suffix; callers fall
  back to 'default').
- CliPathHelper centralizes the '<ASPIRE_HOME>/.nugetpackages' path so
  the producer (PrebuiltAppHostServer) and consumer (CacheCommand)
  can't drift.
- CacheCommand.ClearCommand now wipes <ASPIRE_HOME>/.nugetpackages so
  a wedged staging restore is recoverable through the same UX as every
  other CLI cache.

Tests:
- Updated existing PrebuiltAppHostServerTests staging cases to assert
  the globalPackagesFolder value is absolute and lives outside the
  temp config directory.
- New PrebuiltAppHostServerTests case wires a real PackagingService
  with overrideStagingFeed on a stable-shaped CLI and pins the same
  invariant end-to-end.
- New TemporaryNuGetConfigTests for the override propagation and for
  the no-override-when-disabled invariant.
- New CacheCommandTests covering the staging cache wipe and the
  missing-cache no-op path.

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

* Key staging globalPackagesFolder cache by feed URL hash

The staging globalPackagesFolder fix in the previous commit keyed the
\`.nugetpackages\` subdirectory off the CLI's own commit SHA (first 8
hex chars of \`AssemblyInformationalVersionAttribute\`). That handles
two darc-shipped staging builds of the same release branch, but it
breaks the local-dev case where one CLI is repeatedly retargeted at
different \`overrideStagingFeed\` values: the URL changes but the SHA
doesn't, so every override silently shares one cache bucket and the
second restore reuses the first feed's now-stale \`13.4.0\` assemblies.

Switch the cache key to the first 8 hex chars of \`XxHash3\` over the
trimmed, lower-cased resolved feed URL:

- Override branch passes the explicit \`--source\` URL.
- Channel branch passes the channel's \`Aspire*\` mapping source (or
  the first mapping for forward compatibility).

Trim + lower-case before hashing so a stray whitespace from a config
file or a hostname-case change doesn't fragment the cache.
Non-cryptographic hashing is fine here — the key is a directory name,
not a security boundary — and 8 hex chars keep deep integration cache
paths well under Windows MAX_PATH while giving ~4 billion buckets, so
collisions are negligible across the handful of staging feeds any user
ever sees.

Removes the now-unused \`VersionHelper.TryGetCurrentCommitHashShort\`
helper (added in the previous commit, no remaining callers).

Tests:
- New \`CliPathHelperTests.ComputeStagingFeedCacheKey_*\` cover
  determinism, normalization, length defaults, and null/empty input.
- Existing \`PrebuiltAppHostServerTests\` strengthened to assert the
  emitted globalPackagesFolder equals \`<aspireHome>/.nugetpackages/<hash(feed)>\`.

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

* Narrow #17564 CLI-pin fallback to prerelease channels

PR #17564 introduced a new fallback in TryGetCurrentCliTemplateVersionPackage
that pins the template package to the running CLI's SDK version whenever the
selected channel is explicit and not local-build. That preserved the intended
fix for prerelease channels (daily, staging) where the channel feed filters
the running CLI's package out of search results even though the feed can
still restore it.

But it also fired for the stable channel, where the filter does not apply.
For a non-stable-shape CLI (PR build like '13.4.0-pr.X.gY' or a daily-shape
preview) invoked with '--channel stable', it forced an unpublishable version
into the generated apphost.cs, breaking the SmokeTests
LatestCliCanStartStableChannelAppHost and
LatestCliCanStartStableChannelTypeScriptAppHost.

Exclude the stable channel from the new fallback so that case falls through
to the OrderByDescending picker and the user gets the highest shipped stable
package they explicitly asked for. The original prerelease-channel motivation
('Aspire.TypeSystem version mismatch when 13.4 CLI floats templates to a
13.5 daily preview') is preserved unchanged.

Test updates:
 - NewCommandChannelResolutionTests.NewCommand_NoChannelArg_ResolvesTemplateFromIdentityChannel
   gets an expectedVersion theory parameter so the daily case still pins to
   the CLI version while the stable case asserts the highest shipped stable.
 - NewCommandChannelResolutionTests.NewCommand_ExplicitChannelArg_OverridesIdentityChannel
   asserts highest shipped stable (matching the SmokeTest contract).
 - New NewCommand_ExplicitStableChannel_NonStableCliVersion_FallsBackToHighestShippedStable
   regression test covers both daily-shape and PR-shape CLI identities.
 - NewCommandTests.NewCommandWithTypeScriptEmptyTemplatePassesResolvedVersionAndChannelToScaffolding
   reverts to its pre-#17564 assertion of '9.2.0' from the stable feed.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mitchdenny mitchdenny force-pushed the mitchdenny/forward-port-template-fixes-to-main branch from 31b1660 to 58b3c85 Compare May 28, 2026 12:36
@mitchdenny mitchdenny changed the title Forward-port #17564 + #17573 from release/13.4 to main Forward-port #17528 + #17564 + #17573 from release/13.4 to main May 28, 2026
@mitchdenny
Copy link
Copy Markdown
Member Author

Pushed update: prepended cherry-pick of #17528 ("Fix 13.4 staging CLI dropping nuget.config without Aspire package source mapping", @radical). #17573's tests reference the isStableShapedCliVersion ctor parameter on PackagingService that #17528 introduced — that PR was also missing from main, so without it the cherry-pick of #17573 broke the test build (CS1739). Local Aspire.Cli.Tests build is green. Order is now: #17528#17564#17573.

The cherry-picks of #17564 and #17573 alone do not address the
`aspire new` + C# Blazor scenario from #17596 because that path
runs through `TemplateNuGetConfigService.ResolveTemplatePackageAsync`
(DotNet templates), not `NewCommand.ResolveCliTemplateVersionAsync`
(CLI-runtime templates) where #17564's `TryGetCurrentCliTemplateVersionPackage`
synthesis lives.

Teach `ResolveTemplatePackageAsync` to mirror the identity-channel
preference that `ResolveCliTemplateVersionAsync` (NewCommand.cs:376-389)
already does for CLI templates: when no `--channel` is supplied and no
PR hives exist, prefer the channel whose name matches the running CLI's
`CliExecutionContext.IdentityChannel` before falling back to Implicit.

Without this, a daily 13.5 CLI on a clean `~/.aspire` silently restricts
the template search to nuget.org and returns the shipped stable
`Aspire.ProjectTemplates 13.3.5` instead of the matching
`13.5.0-preview.1.*` daily prerelease from the `dotnet9` feed.

The Implicit fallback preserves prior behavior when the identity channel
isn't a registered channel (e.g. a "local" CLI without a corresponding
local-build hive).

See #17596 for full repro.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mitchdenny mitchdenny changed the title Forward-port #17528 + #17564 + #17573 from release/13.4 to main Forward-port #17528 + #17564 + #17573 from release/13.4 to main + DotNet template identity-channel fix May 28, 2026
@mitchdenny
Copy link
Copy Markdown
Member Author

Added new commit 239cf6dd9"Prefer identity channel for DotNet template resolution".

Catching this during review: PR #17564 only modifies NewCommand.cs / PackageChannel.cs / VersionHelper.cs. Its TryGetCurrentCliTemplateVersionPackage synthesis runs inside ResolveCliTemplateVersionAsync, which is only invoked for TemplateRuntime.Cli templates (TypeScript starter etc.). The user-reported scenario in #17596 is aspire new → C# Blazor, which goes through DotNetTemplateFactory.ApplyTemplateAsyncTemplateNuGetConfigService.ResolveTemplatePackageAsync — a path #17564 never touches.

In ResolveTemplatePackageAsync, when --channel is null and no PR hives exist, the channel list was restricted to Implicit (nuget.org) only. On a clean ~/.aspire a daily 13.5 CLI would silently get Aspire.ProjectTemplates 13.3.5 from nuget.org, never seeing the daily 13.5.0-preview.1.* on dotnet9.

The new commit teaches ResolveTemplatePackageAsync to prefer the channel whose name matches CliExecutionContext.IdentityChannel before falling back to Implicit — exactly mirroring ResolveCliTemplateVersionAsync's logic for CLI templates. The Implicit fallback preserves prior behavior when the identity channel isn't a registered channel.

Tests: existing ResolveTemplatePackageAsync_NullRequestedChannel_UsesImplicitChannelOnly renamed to clarify it now covers the no-identity-match fallback; new ResolveTemplatePackageAsync_NullRequestedChannel_PrefersIdentityChannelMatch covers the daily-CLI repro from #17596. Full TemplateNuGetConfigServiceTests suite passes (17/17 local).

@github-actions
Copy link
Copy Markdown
Contributor

CLI E2E Tests unknown — 107 passed, 0 failed, 2 unknown (commit 239cf6d)

View all recordings
Status Test Recording Job Artifacts
AddPackageInteractiveWhileAppHostRunningDetached Recording #78303014983 Logs
AddPackageWhileAppHostRunningDetached Recording #78303014983 Logs
AgentCommands_AllHelpOutputs_AreCorrect Recording #78303014164 Logs
AgentInitCommand_DefaultSelection_InstallsDefaultSkills Recording #78303014164 Logs
AgentInitCommand_MigratesDeprecatedConfig Recording #78303014164 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp Recording #78303014837 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_DevLocalhost Recording #78303014837 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_Isolated Recording #78303014837 Logs
AllPublishMethodsBuildDockerImages Recording #78303014954 Logs
AspireAddAndStartWorkAgainstLegacyAppHostTs Recording #78303015017 Logs
AspireAddPackageVersionToDirectoryPackagesProps Recording #78303013758 Logs
AspireInitSingleFileAppHostRunsViaDotnetRunAppHost Recording #78303013856 Logs
AspireInitWithExistingAppHostDirRecreatesMissingNuGetConfigAndPreservesFiles Recording #78303014844 Logs
AspireInitWithSolutionFileGeneratesAppHostThatBuildsAgainstChannelHive Recording #78303014844 Logs
AspireStartUpdatesStaleTypeScriptAppHostPath Recording #78303014833 Logs
AspireUpdateRemovesAppHostPackageVersionFromDirectoryPackagesProps Recording #78303013758 Logs
AspireUpdateRemovesOrphanAppHostPackageVersionWhenSdkAlreadyCurrent Recording #78303013758 Logs
Banner_DisplayedOnFirstRun Recording #78303014917 Logs
Banner_DisplayedWithExplicitFlag Recording #78303014917 Logs
Banner_NotDisplayedWithNoLogoFlag Recording #78303014917 Logs
CertificatesClean_RemovesCertificates Recording #78303013952 Logs
CertificatesTrust_WithNoCert_CreatesAndTrustsCertificate Recording #78303013952 Logs
CertificatesTrust_WithUntrustedCert_TrustsCertificate Recording #78303013952 Logs
ConfigSetGet_CreatesNestedJsonFormat Recording #78303015026 Logs
CreateAndRunAspireStarterProject Recording #78303014192 Logs
CreateAndRunAspireStarterProjectWithBundle Recording #78303014888 Logs
CreateAndRunEmptyAppHostProject Recording #78303013871 Logs
CreateAndRunJavaEmptyAppHostProject Recording #78303015046 Logs
CreateAndRunJsReactProject Recording #78303015019 Logs
CreateAndRunPythonReactProject Recording #78303013800 Logs
CreateAndRunTypeScriptEmptyAppHostProject Recording #78303014089 Logs
CreateAndRunTypeScriptStarterProject Recording #78303014067 Logs
CreateJavaAppHostWithViteApp Recording #78303013991 Logs
CreateTypeScriptAppHostWithViteApp_AllowsGuestAppPackageManagerToDiffer Recording #78303013867 Logs
CreateTypeScriptAppHostWithViteApp_UsesConfiguredToolchain Recording #78303013867 Logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces Recording #78303014157 Logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces_DevLocalhost Recording #78303014157 Logs
DashboardRunWithOtelTracesReturnsNoTraces Recording #78303014157 Logs
DashboardRunWithOtelTracesReturnsNoTraces_DevLocalhost Recording #78303014157 Logs
DeployK8sBasicApiService Recording #78303015032 Logs
DeployK8sWithExternalHelmChart Recording #78303014270 Logs
DeployK8sWithGarnet Recording #78303015006 Logs
DeployK8sWithMongoDB Recording #78303014011 Logs
DeployK8sWithMySql Recording #78303014495 Logs
DeployK8sWithPostgres Recording #78303014039 Logs
DeployK8sWithRabbitMQ Recording #78303014877 Logs
DeployK8sWithRedis Recording #78303014105 Logs
DeployK8sWithSqlServer Recording #78303014756 Logs
DeployK8sWithValkey Recording #78303014939 Logs
DeployTypeScriptAppToKubernetes Recording #78303015088 Logs
DescribeCommandResolvesReplicaNames Recording #78303014392 Logs
DescribeCommandShowsRunningResources Recording #78303014392 Logs
DetachFormatJsonProducesValidJson Recording #78303015024 Logs
DetachFormatJsonProducesValidJsonWhenRestartingExistingInstance Recording #78303015024 Logs
DoPublishAndDeployListStepsWork Recording #78303014023 Logs
DocsCommand_RendersInteractiveMarkdownFromLocalSource Recording #78303014867 Logs
DoctorCommand_DetectsDeprecatedAgentConfig Recording #78303014164 Logs
DoctorCommand_TypeScriptAppHostReportsMissingConfiguredToolchain Recording #78303014942 Logs
DoctorCommand_WithSslCertDir_ShowsTrusted Recording #78303014942 Logs
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted Recording #78303014942 Logs
GatewayWithoutExternalEndpoint_FailsPublishWithGuidance Recording #78303014943 Logs
GeneratedAspireDevScript_StartsWatchMode_WithConfiguredToolchain Recording #78303013867 Logs
GlobalMigration_HandlesCommentsAndTrailingCommas Recording #78303015026 Logs
GlobalMigration_HandlesMalformedLegacyJson Recording #78303015026 Logs
GlobalMigration_PreservesAllValueTypes Recording #78303015026 Logs
GlobalMigration_SkipsWhenNewConfigExists Recording #78303015026 Logs
GlobalSettings_MigratedFromLegacyFormat Recording #78303015026 Logs
IngressWithoutExternalEndpoint_FailsPublishWithGuidance Recording #78303014943 Logs
InitTypeScriptAppHost_AugmentsExistingViteRepoInWorkspaceSubdirectory Recording #78303013867 Logs
InteractiveCSharpInitCreatesExpectedFiles Recording #78303014646 Logs
InvalidAppHostPathWithComments_IsHealedOnRun Recording #78303014016 Logs
JavaScriptHostingApisRunFromTypeScriptAppHost Recording #78303014954 Logs
LatestCliCanStartStableChannelAppHost Recording #78303014192 Logs
LatestCliCanStartStableChannelTypeScriptAppHost Recording #78303014192 Logs
LegacySettingsMigration_AdjustsRelativeAppHostPath Recording #78303014833 Logs
LogsCommandShowsResourceLogs Recording #78303014117 Logs
OtelLogsReturnsStructuredLogsFromStarterApp Recording #78303015076 Logs
OtelLogsReturnsStructuredLogsFromStarterAppIsolated Recording #78303015076 Logs
PsCommandListsRunningAppHost Recording #78303014956 Logs
PsFormatJsonOutputsOnlyJsonToStdout Recording #78303014956 Logs
PublishJavaScriptPatternsGeneratesExpectedDockerComposeArtifacts Recording #78303014412 Logs
PublishWithConfigureEnvFileUpdatesEnvOutput Recording #78303014412 Logs
PublishWithDockerComposeServiceCallbackSucceeds Recording #78303014412 Logs
PublishWithoutOutputPathUsesAppHostDirectoryDefault Recording #78303014412 Logs
ResourceCommand_FailedExecution_DisplaysAppHostLogPathAndLogContainsEntries Recording #78303015044 Logs
ResourceCommand_SetAndDeleteParameterUpdatesDescribeOutput Recording #78303015044 Logs
RestoreGeneratesSdkFiles Recording #78303014010 Logs
RestoreGeneratesSdkFiles_WithConfiguredToolchain Recording #78303014212 Logs
RestoreRefreshesGeneratedSdkAfterAddingIntegration Recording #78303014212 Logs
RestoreSupportsConfigOnlyHelperPackageAndCrossPackageTypes Recording #78303013957 Logs
RunFromParentDirectory_UsesExistingConfigNearAppHost Recording #78303015105 Logs
RunReportsSyntaxErrorsForDotNetAppHost Recording #78303013775 Logs
RunReportsSyntaxErrorsForTypeScriptAppHost Recording #78303013775 Logs
SecretCrudOnDotNetAppHost Recording #78303013869 Logs
SecretCrudOnTypeScriptAppHost Recording #78303013974 Logs
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels Recording #78303014136 Logs
StartAndWaitForTypeScriptSqlServerAppHostWithNativeAssets Recording #78303014958 Logs
StartReportsSyntaxErrorsForDotNetAppHost Recording #78303013775 Logs
StartReportsSyntaxErrorsForTypeScriptAppHost Recording #78303013775 Logs
StopAllAppHostsFromAppHostDirectory Recording #78303014257 Logs
StopJavaPolyglotAppHostUsingApphostDirectory Recording #78303014532 Logs
StopNonInteractiveSingleAppHost Recording #78303014257 Logs
StopTypeScriptPolyglotAppHostUsingApphostDirectory Recording #78303013842 Logs
StopWithNoRunningAppHostExitsSuccessfully Recording #78303014983 Logs
UnAwaitedChainsCompileWithAutoResolvePromises Recording #78303014212 Logs
UpdateProjectChannelToStable_CSharpEmptyAppHost_PreservesAspireConfigChannel Recording #78303014531 Logs
UpdateProjectChannelToStable_CSharpSingleFileInit_PreservesAspireConfigChannel Recording #78303014531 Logs
UpdateProjectChannelToStable_TypeScriptSingleFileInit_PreservesAspireConfigChannel Recording #78303014531 Logs
UpdateProjectChannelToStable_TypeScript_PreviewsStablePackagesAndPreservesChannel Recording #78303014531 Logs

📹 Recordings uploaded automatically from CI run #26576856038

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.

aspire new on daily main CLI resolves Aspire.ProjectTemplates 13.3.5 from nuget.org instead of daily 13.5 prerelease

4 participants