Use pinned CLI version for staging channel in shared feed mode#14469
Use pinned CLI version for staging channel in shared feed mode#14469joperezr merged 6 commits intodotnet:release/13.2from
Conversation
…is set dotnet package search only returns the latest version per package ID, so when the shared dotnet9 feed has both 13.2 and 13.3 prerelease packages, only 13.3 is returned. The stagingVersionPrefix filter then discards it, resulting in "no templates found". When VersionPrefix is set on a channel, pass --exact-match to get all versions from the feed, enabling the prefix filter to find the correct version line. Also update ParsePackageSearchResults to handle the "version" JSON field used by --exact-match (vs "latestVersion" in normal search).
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 14469Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 14469" |
There was a problem hiding this comment.
Pull request overview
This PR fixes staging channel template discovery when a feed contains multiple version lines by enabling dotnet package search --exact-match whenever a channel VersionPrefix is configured, and updating parsing to handle the JSON shape returned by exact-match search.
Changes:
- Plumb an
exactMatchflag through the NuGet package cache and dotnet CLI runner, and add--exact-matchwhen appropriate. - Update
ParsePackageSearchResultsto read eitherlatestVersionorversionfrom search results. - Update/fix tests and add new staging channel coverage for version-prefix filtering scenarios.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Aspire.Cli.Tests/Utils/CliUpdateNotificationServiceTests.cs | Fixes a comment typo and updates INuGetPackageCache test stub signatures to include exactMatch. |
| tests/Aspire.Cli.Tests/TestServices/TestDotNetCliRunner.cs | Extends the test runner’s package-search callback/signature to accept exactMatch. |
| tests/Aspire.Cli.Tests/TestServices/FakeNuGetPackageCache.cs | Updates fake cache interface methods to accept exactMatch. |
| tests/Aspire.Cli.Tests/Templating/DotNetTemplateFactoryTests.cs | Updates fakes/stubs for the new cache/runner signatures. |
| tests/Aspire.Cli.Tests/Projects/ProjectUpdaterTests.cs | Updates SearchPackagesAsyncCallback lambdas to match the new signature. |
| tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs | Updates fake cache methods to accept exactMatch. |
| tests/Aspire.Cli.Tests/Packaging/PackagingServiceTests.cs | Adds tests validating staging VersionPrefix filtering across mixed version lines; updates fake cache signatures. |
| tests/Aspire.Cli.Tests/Packaging/PackageChannelTests.cs | Updates fake cache signatures to accept exactMatch. |
| tests/Aspire.Cli.Tests/Packaging/NuGetConfigMergerTests.cs | Updates fake cache signatures to accept exactMatch. |
| tests/Aspire.Cli.Tests/Packaging/NuGetConfigMergerSnapshotTests.cs | Updates fake cache signatures to accept exactMatch. |
| tests/Aspire.Cli.Tests/NuGet/NuGetPackageCacheTests.cs | Updates SearchPackagesAsyncCallback lambdas to match the new signature. |
| tests/Aspire.Cli.Tests/Mcp/MockPackagingService.cs | Updates mock cache signatures to accept exactMatch. |
| tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs | Updates package-search callback lambdas and fake cache methods for new signatures. |
| tests/Aspire.Cli.Tests/Commands/InitCommandTests.cs | Updates package-search callback lambdas and fake cache methods for new signatures. |
| tests/Aspire.Cli.Tests/Commands/AddCommandTests.cs | Updates package-search callback lambdas to match the new signature. |
| src/Shared/PackageUpdateHelpers.cs | Makes parsing resilient to latestVersion vs version property differences. |
| src/Aspire.Cli/Packaging/PackageChannel.cs | Enables exact-match searches for template packages when VersionPrefix is set. |
| src/Aspire.Cli/NuGet/NuGetPackageCache.cs | Adds exactMatch support to cache lookups and passes it through to the CLI runner; adjusts cache key/paging behavior. |
| src/Aspire.Cli/NuGet/BundleNuGetPackageCache.cs | Updates interface signatures to accept exactMatch (but currently doesn’t use it). |
| src/Aspire.Cli/DotNet/DotNetCliRunner.cs | Adds --exact-match to dotnet package search and includes it in the disk cache key. |
|
Found an issue with this approach. |
When the staging channel is configured with Prerelease quality and no explicit feed override, packages are now pinned to the CLI's own version instead of searching NuGet. This avoids the dotnet package search limitation where only the latest version per package ID is returned, which caused version mismatches when the shared feed contains packages from multiple version lines (e.g. 13.2.x and 13.3.x). New config flag stagingPinToCliVersion (boolean) controls this behavior. When enabled alongside overrideStagingQuality=Prerelease: - Templates (aspire new): synthetic result with CLI version - Integrations (aspire add): discovers packages then overrides version - Specific packages (aspire update): synthetic result with CLI version Also cleans up reverted exact-match parameter plumbing from interfaces and test fakes.
|
/azp run dotnet.aspire |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Summary
When the staging channel is configured with
overrideStagingQuality=Prereleaseand no explicit feed override, the staging channel now uses the shareddotnet9daily feed instead of constructing SHA-specificdarc-pub-*feeds (which only exist for stable-quality builds). Additionally, a newstagingPinToCliVersionconfig flag pins all package versions to the CLI's own assembly version, bypassingdotnet package searchentirely.Problem
The staging channel normally builds SHA-specific feeds (
darc-pub-dotnet-aspire-{hash}), but these are only created for stable-quality DARC builds. When builds aren't marked stable yet, the packages are only available on the shareddotnet9daily feed. Even after switching to the shared feed,dotnet package searchonly returns the latest version per package ID per source — so when the feed contains both 13.2.x (staging) and 13.3.x (daily) packages, staging users would always get 13.3.x versions, which is wrong.Solution
Two complementary features controlled by config flags:
1. Shared Feed Mode
When
overrideStagingQualityis set toPrerelease(orBoth) andoverrideStagingFeedis not set, the staging channel uses the shareddotnet9feed URL and setsconfigureGlobalPackagesFolder: false(no package isolation needed).2. Pinned Version Mode (
stagingPinToCliVersion)When
stagingPinToCliVersion=trueis additionally set, all package versions are pinned to the CLI's own assembly version (with+buildmetadatastripped):aspire new): Returns a syntheticAspire.ProjectTemplatespackage with the CLI's version — no NuGet search at allaspire add): Still searches the feed to discover package IDs, but overrides the version on all resultsaspire update): Returns a synthetic package with the pinned versionaspire update --self): Unaffected — usesCliDownloader(URL-based), not NuGet searchConfiguration
Changes
Production code
PackagingService.cs—CreateStagingChannel()computesuseSharedFeedandpinnedVersion; newGetStagingPinnedVersion()helperPackageChannel.cs—pinnedVersionconstructor parameter with short-circuits inGetTemplatePackagesAsync,GetIntegrationPackagesAsync, andGetPackagesAsyncDotNetCliRunner.cs,NuGetPackageCache.cs,BundleNuGetPackageCache.cs— Cleanup of previously reverted exact-match plumbingSchemas
aspire-global-settings.schema.jsonandaspire-settings.schema.json— AddedoverrideStagingFeed,overrideStagingQuality, andstagingPinToCliVersionpropertiesTests
exactMatchparameters across 14 test fake implementations