-
Notifications
You must be signed in to change notification settings - Fork 1.8k
C#: Automatically use configured private registry feeds #18850
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 15 commits
6b2f348
63d5517
11efb55
726123c
0db6a26
6b15f77
a8dde15
9560593
b6c74fe
284f612
51874b8
7a92a72
d564529
92eab47
4448369
7cea2ad
d2b88ae
4d3b024
73ca2eb
be95d33
fe1c098
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -156,7 +156,7 @@ public HashSet<AssemblyLookupLocation> Restore() | |
|
||
var restoredProjects = RestoreSolutions(out var container); | ||
var projects = fileProvider.Projects.Except(restoredProjects); | ||
RestoreProjects(projects, out var containers); | ||
RestoreProjects(projects, explicitFeeds, out var containers); | ||
|
||
var dependencies = containers.Flatten(container); | ||
|
||
|
@@ -260,8 +260,34 @@ private IEnumerable<string> RestoreSolutions(out DependencyContainer dependencie | |
/// Populates dependencies with the relative paths to the assets files generated by the restore. | ||
/// </summary> | ||
/// <param name="projects">A list of paths to project files.</param> | ||
private void RestoreProjects(IEnumerable<string> projects, out ConcurrentBag<DependencyContainer> dependencies) | ||
private void RestoreProjects(IEnumerable<string> projects, HashSet<string>? configuredSources, out ConcurrentBag<DependencyContainer> dependencies) | ||
{ | ||
// Conservatively, we only set this to a non-null value if a Dependabot proxy is enabled. | ||
// This ensures that we continue to get the old behaviour where feeds are taken from | ||
// `nuget.config` files instead of the command-line arguments. | ||
string? extraArgs = null; | ||
|
||
if (this.dependabotProxy is not null) | ||
{ | ||
// If the Dependabot proxy is configured, then our main goal is to make `dotnet` aware | ||
// of the private registry feeds. However, since providing them as command-line arguments | ||
// to `dotnet` ignores other feeds that may be configured, we also need to add the feeds | ||
// we have discovered from analysing `nuget.config` files. | ||
var sources = configuredSources ?? new(); | ||
sources.Add(PublicNugetOrgFeed); | ||
this.dependabotProxy.RegistryURLs.ForEach(url => sources.Add(url)); | ||
|
||
// Add package sources. If any are present, they override all sources specified in | ||
// the configuration file(s). | ||
var feedArgs = new StringBuilder(); | ||
foreach (string source in sources) | ||
{ | ||
feedArgs.Append($" -s {source}"); | ||
} | ||
|
||
extraArgs = feedArgs.ToString(); | ||
} | ||
|
||
var successCount = 0; | ||
var nugetSourceFailures = 0; | ||
ConcurrentBag<DependencyContainer> collectedDependencies = []; | ||
|
@@ -276,7 +302,7 @@ private void RestoreProjects(IEnumerable<string> projects, out ConcurrentBag<Dep | |
foreach (var project in projectGroup) | ||
{ | ||
logger.LogInfo($"Restoring project {project}..."); | ||
var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true, TargetWindows: isWindows)); | ||
var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true, extraArgs, TargetWindows: isWindows)); | ||
assets.AddDependenciesRange(res.AssetsFilePaths); | ||
lock (sync) | ||
{ | ||
|
@@ -674,10 +700,40 @@ private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount, | |
return (timeoutMilliSeconds, tryCount); | ||
} | ||
|
||
/// <summary> | ||
/// Checks that we can connect to all Nuget feeds that are explicitly configured in configuration files. | ||
/// </summary> | ||
/// <param name="explicitFeeds">Outputs the set of explicit feeds.</param> | ||
/// <returns>True if all feeds are reachable or false otherwise.</returns> | ||
private bool CheckFeeds(out HashSet<string> explicitFeeds) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe rename one of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in d2b88ae |
||
{ | ||
logger.LogInfo("Checking Nuget feeds..."); | ||
(explicitFeeds, var allFeeds) = GetAllFeeds(); | ||
HashSet<string> feedsToCheck = explicitFeeds; | ||
|
||
// If private package registries are configured for C#, then check those | ||
// in addition to the ones that are configured in `nuget.config` files. | ||
this.dependabotProxy?.RegistryURLs.ForEach(url => feedsToCheck.Add(url)); | ||
|
||
var allFeedsReachable = this.CheckFeeds(feedsToCheck); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the dependabot proxy is set, we also explicitly add the public nuget org feed as a source - so we should probably check whether that feed is reachable as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have changed this so that the public feed is not manually added when private registries are configured in 4d3b024, since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, there's more subtly to this. So, we didn't previously check that the public feed is reachable anyway. @tamasvajk left a comment saying that we could check that they are reachable, but don't because of authentication requirements(?). I think the real lesson for my changes here is that I should really use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK that also still doesn't quite work with the current logic, because There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the reachability of the public nuget feed wasn't checked before, then maybe there is no need to check it now either. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In any case, it's probably a separate discussion to the changes in this PR. I have also now removed that part of the code that manually added the public feed in be95d33.
That's true. |
||
|
||
var inheritedFeeds = allFeeds.Except(explicitFeeds).ToHashSet(); | ||
if (inheritedFeeds.Count > 0) | ||
{ | ||
logger.LogInfo($"Inherited Nuget feeds (not checked for reachability): {string.Join(", ", inheritedFeeds.OrderBy(f => f))}"); | ||
compilationInfoContainer.CompilationInfos.Add(("Inherited Nuget feed count", inheritedFeeds.Count.ToString())); | ||
} | ||
|
||
return allFeedsReachable; | ||
} | ||
|
||
/// <summary> | ||
/// Checks that we can connect to the specified Nuget feeds. | ||
/// </summary> | ||
/// <param name="feeds">The set of package feeds to check.</param> | ||
/// <returns>True if all feeds are reachable or false otherwise.</returns> | ||
private bool CheckFeeds(HashSet<string> feeds) | ||
{ | ||
logger.LogInfo("Checking that Nuget feeds are reachable..."); | ||
|
||
var excludedFeeds = EnvironmentVariables.GetURLs(EnvironmentVariableNames.ExcludedNugetFeedsFromResponsivenessCheck) | ||
.ToHashSet(); | ||
|
@@ -689,7 +745,7 @@ private bool CheckFeeds(out HashSet<string> explicitFeeds) | |
|
||
var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback: false); | ||
|
||
var allFeedsReachable = explicitFeeds.All(feed => excludedFeeds.Contains(feed) || IsFeedReachable(feed, initialTimeout, tryCount)); | ||
var allFeedsReachable = feeds.All(feed => excludedFeeds.Contains(feed) || IsFeedReachable(feed, initialTimeout, tryCount)); | ||
if (!allFeedsReachable) | ||
{ | ||
logger.LogWarning("Found unreachable Nuget feed in C# analysis with build-mode 'none'. This may cause missing dependencies in the analysis."); | ||
|
@@ -704,14 +760,6 @@ private bool CheckFeeds(out HashSet<string> explicitFeeds) | |
} | ||
compilationInfoContainer.CompilationInfos.Add(("All Nuget feeds reachable", allFeedsReachable ? "1" : "0")); | ||
|
||
|
||
var inheritedFeeds = allFeeds.Except(explicitFeeds).ToHashSet(); | ||
if (inheritedFeeds.Count > 0) | ||
{ | ||
logger.LogInfo($"Inherited Nuget feeds (not checked for reachability): {string.Join(", ", inheritedFeeds.OrderBy(f => f))}"); | ||
compilationInfoContainer.CompilationInfos.Add(("Inherited Nuget feed count", inheritedFeeds.Count.ToString())); | ||
} | ||
|
||
return allFeedsReachable; | ||
} | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.