@@ -1614,21 +1614,22 @@ public async Task PrepareAsync_RestoreFailure_WithManyPackages_TruncatesPackageL
16141614 }
16151615
16161616 [ Fact ]
1617- public async Task PrepareAsync_WithProjectReferencesAndExplicitChannelButNoOverride_UsesAdditionalSourcesNotRestoreConfigFile ( )
1617+ public async Task PrepareAsync_WithProjectReferencesAndExplicitChannelButNoOverride_UsesNuGetConfigForChannelMappings ( )
16181618 {
1619- // Regression for finding #1 of the 2026-05-19 post-merge review: a project-ref restore
1620- // with an explicit channel pin (daily/staging/pr-*) and NO --source must not replace the
1621- // user's ambient nuget.config via <RestoreConfigFile>. The channel sources flow through
1622- // additively via <RestoreAdditionalProjectSources> so private/internal feeds the user
1623- // has configured in nuget.config remain reachable for non-Aspire transitives.
1619+ // Regression for https://github.com/microsoft/aspire/issues/17629: a project-ref restore
1620+ // with an explicit channel pin and no --source needs the channel's package source mappings,
1621+ // not only its feed URLs, otherwise ambient packageSourceMapping can route Aspire* packages
1622+ // away from the staging/DARC feed.
16241623 using var workspace = TemporaryWorkspace . Create ( outputHelper ) ;
1625- const string channelSource = "https://pkgs.dev.azure.com/fake /v3/index.json" ;
1624+ const string channelSource = "https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-microsoft-aspire-abcdef12/nuget /v3/index.json" ;
16261625 XDocument ? generatedProject = null ;
1626+ XDocument ? generatedRestoreConfig = null ;
1627+ bool restoreConfigFileExistedDuringBuild = false ;
16271628
16281629 var aspireConfigPath = Path . Combine ( workspace . WorkspaceRoot . FullName , AspireConfigFile . FileName ) ;
16291630 await File . WriteAllTextAsync ( aspireConfigPath , """
16301631 {
1631- "channel": "daily "
1632+ "channel": "staging "
16321633 }
16331634 """ ) ;
16341635
@@ -1641,20 +1642,32 @@ await File.WriteAllTextAsync(aspireConfigPath, """
16411642 BuildAsyncCallback = ( projectFilePath , _ , _ , _ ) =>
16421643 {
16431644 generatedProject = XDocument . Load ( projectFilePath . FullName ) ;
1645+ var ns = generatedProject . Root ! . GetDefaultNamespace ( ) ;
1646+ var restoreConfigFile = generatedProject . Descendants ( ns + "RestoreConfigFile" ) . FirstOrDefault ( ) ? . Value ;
1647+ restoreConfigFileExistedDuringBuild = restoreConfigFile is not null && File . Exists ( restoreConfigFile ) ;
1648+ if ( restoreConfigFile is not null )
1649+ {
1650+ generatedRestoreConfig = XDocument . Load ( restoreConfigFile ) ;
1651+ }
1652+
16441653 WriteClosureInputs ( projectFilePath . Directory ! , closureFiles , [ "MyIntegration" ] ) ;
16451654 return 0 ;
16461655 }
16471656 } ;
16481657
1649- var dailyChannel = PackageChannel . CreateExplicitChannel (
1650- name : "daily " ,
1658+ var stagingChannel = PackageChannel . CreateExplicitChannel (
1659+ name : "staging " ,
16511660 quality : PackageChannelQuality . Both ,
1652- mappings : [ new PackageMapping ( "Aspire*" , channelSource ) ] ,
1661+ mappings :
1662+ [
1663+ new PackageMapping ( "Aspire*" , channelSource ) ,
1664+ new PackageMapping ( PackageMapping . AllPackages , NuGetOrgSource )
1665+ ] ,
16531666 nuGetPackageCache : new FakeNuGetPackageCache ( ) ,
16541667 features : new TestFeatures ( ) ) ;
16551668 var packagingService = new TestPackagingService
16561669 {
1657- GetChannelsAsyncCallback = _ => Task . FromResult < IEnumerable < PackageChannel > > ( [ dailyChannel ] )
1670+ GetChannelsAsyncCallback = _ => Task . FromResult < IEnumerable < PackageChannel > > ( [ stagingChannel ] )
16581671 } ;
16591672
16601673 var nugetService = new BundleNuGetService (
@@ -1688,11 +1701,13 @@ await File.WriteAllTextAsync(aspireConfigPath, """
16881701 Assert . NotNull ( generatedProject ) ;
16891702
16901703 var ns = generatedProject ! . Root ! . GetDefaultNamespace ( ) ;
1691- Assert . Null ( generatedProject . Descendants ( ns + "RestoreConfigFile" ) . FirstOrDefault ( ) ) ;
1692-
1693- var restoreSources = generatedProject . Descendants ( ns + "RestoreAdditionalProjectSources" ) . FirstOrDefault ( ) ? . Value ;
1694- Assert . NotNull ( restoreSources ) ;
1695- Assert . Contains ( channelSource , restoreSources ! ) ;
1704+ var restoreConfigFile = generatedProject . Descendants ( ns + "RestoreConfigFile" ) . FirstOrDefault ( ) ? . Value ;
1705+ Assert . NotNull ( restoreConfigFile ) ;
1706+ Assert . True ( restoreConfigFileExistedDuringBuild ) ;
1707+ Assert . NotNull ( generatedRestoreConfig ) ;
1708+ Assert . Equal ( [ "Aspire*" ] , GetPackagePatternsForSource ( generatedRestoreConfig ! , channelSource ) ) ;
1709+ Assert . Equal ( [ PackageMapping . AllPackages ] , GetPackagePatternsForSource ( generatedRestoreConfig ! , NuGetOrgSource ) ) ;
1710+ Assert . Null ( generatedProject . Descendants ( ns + "RestoreAdditionalProjectSources" ) . FirstOrDefault ( ) ) ;
16961711
16971712 // Aspire package versions remain in their original (non-pinned) form when no override
16981713 // is in play; the exact-version pinning only fires when a single source is selected.
0 commit comments