Skip to content

C#: Support replaces-base via the DependabotProxy. - #22494

Open
michaelnebel wants to merge 8 commits into
github:mainfrom
michaelnebel:csharp/replaces-base
Open

C#: Support replaces-base via the DependabotProxy.#22494
michaelnebel wants to merge 8 commits into
github:mainfrom
michaelnebel:csharp/replaces-base

Conversation

@michaelnebel

@michaelnebel michaelnebel commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

In this PR we add support using the replace-base flag for private registries. If any private registries are configured to replace base, then we use these registries as NuGet feed sources instead of the default public nuget.org in fallback scenarios all scenarios - even if the public NuGet feed is mentioned in nuget.config files (unless it is explicitly configured as a fallback feed as well).

As an add on for this PR, we also prevent the fallback that doesn't provide feeds via the command line when restoring packages manually, if private registries are configured (to make the logic consistent with other similar paths).

DCA looks good.

@github-actions github-actions Bot added the C# label Sep 2, 2026
@michaelnebel
michaelnebel force-pushed the csharp/replaces-base branch 4 times, most recently from e4e0207 to 9d030bd Compare September 3, 2026 13:58
@michaelnebel
michaelnebel requested a balanced review from Copilot September 4, 2026 08:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Feed-check opt-out behavior is regressed, and one fallback path can still retain nuget.org.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Balanced
Findings: 1 Medium severity

New issues introduced by this change (1)
Severity Finding
Medium severity csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​FeedManager.cs — This now probes the default feeds even when `CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK=fal…
What changed in this PR

Adds replaces-base support for private NuGet registries used during buildless C# dependency restoration.

Changes:

  • Parses and exposes replacement-base registry URLs.
  • Uses replacement registries for default and fallback feeds.
  • Adds unit coverage and a change note.
File Description
csharp/​ql/​lib/​change-notes/​2026-09-03-replaces-base.md Documents the new behavior.
csharp/​extractor/​Semmle.Extraction.Tests/​FeedManager.cs Tests default and fallback feed selection.
csharp/​extractor/​Semmle.Extraction.Tests/​DependabotProxy.cs Tests replaces-base parsing.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​PackagesConfigRestorer.cs Uses reachable default feeds during restoration.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​IDependabotProxy.cs Exposes replacement-base registry URLs.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​FeedManager.cs Selects replacement registries as default feeds.
csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​DependabotProxy.cs Parses and stores registry replacement metadata.
Suppressed comments (1)

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FeedManager.cs:315

  • The replacement is only applied through GetReachableFallbackNugetFeeds, but NugetPackageRestorer.DownloadMissingPackages calls that path only when feed responsiveness checks are enabled; its disabled branch uses AllFeeds, which can still contain inherited nuget.org. Thus replaces-base: true does not actually replace the public base feed in fallback downloads when the supported responsiveness opt-out is used. Please separate construction of the configured fallback set from reachability filtering and use that set in both branches.
                fallbackFeeds.UnionWith(defaultFeeds);
                logger.LogInfo($"No fallback NuGet feeds specified. Adding default feeds: {string.Join(", ", defaultFeeds.OrderBy(f => f))}");

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FeedManager.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The responsiveness-check opt-out path can still use public NuGet.org despite a configured replacement registry.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Balanced
Findings: 2 Medium severity

New issues introduced by this change (1)
Severity Finding
Medium severity csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​FeedManager.csDefaultFeeds is substituted only on the responsiveness-checking path. When…
Pre-existing issues (1)
Severity Finding
Medium severity csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​FeedManager.cs — This now probes the default feeds even when `CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK=fal… View comment

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Public NuGet endpoint variants such as the supported v2 URL are not replaced.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Balanced
Findings: 2 Medium severity

New issues introduced by this change (1)
Severity Finding
Medium severity csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​FeedManager.cs — This only recognizes the canonical v3 URL, so a configured public NuGet source such as…
Pre-existing issues (1)
Severity Finding
Medium severity csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​FeedManager.csDefaultFeeds is substituted only on the responsiveness-checking path. When… View comment
Issues resolved since last review (1)
Severity Finding
Medium severity csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​FeedManager.cs — This now probes the default feeds even when `CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK=fal… View resolved comment

Comment thread csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FeedManager.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The release note inaccurately describes the replacement behavior as fallback-only.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Balanced
Findings: 1 Low severity

New issues introduced by this change (1)
Severity Finding
Low severity csharp/​ql/​lib/​change-notes/​2026-09-03-replaces-base.md — The release note describes the replacement as fallback-only, but GetFeeds now replaces NuGet.org…
Issues resolved since last review (2)
Severity Finding
Medium severity csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​FeedManager.cs — This only recognizes the canonical v3 URL, so a configured public NuGet source such as… View resolved comment
Medium severity csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​FeedManager.csDefaultFeeds is substituted only on the responsiveness-checking path. When… View resolved comment

Comment thread csharp/ql/lib/change-notes/2026-09-03-replaces-base.md Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The implementation is coherent and the remaining documentation and regression-test gaps are minor.

Review tier: Balanced
Findings: 1 Medium severity · 1 Low severity

New issues introduced by this change (2)
Severity Finding
Medium severity csharp/​extractor/​Semmle.Extraction.Tests/​FeedManager.cs — The replacement test still supplies the canonical v3 endpoint in both inputs, so the newly…
Low severity csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​FeedManager.cs — This makes the fallback default conditional on replaces-base, but the public XML documentation…
Issues resolved since last review (1)
Severity Finding
Low severity csharp/​ql/​lib/​change-notes/​2026-09-03-replaces-base.md — The release note describes the replacement as fallback-only, but GetFeeds now replaces NuGet.org… View resolved comment

Comment thread csharp/extractor/Semmle.Extraction.Tests/FeedManager.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

A trailing semicolon after the nested class declaration causes a compilation error.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Balanced
Findings: 1 Low severity

Pre-existing issues (1)
Severity Finding
Low severity csharp/​extractor/​Semmle.Extraction.CSharp.DependencyFetching/​FeedManager.cs — This makes the fallback default conditional on replaces-base, but the public XML documentation… View comment
Issues resolved since last review (1)
Severity Finding
Medium severity csharp/​extractor/​Semmle.Extraction.Tests/​FeedManager.cs — The replacement test still supplies the canonical v3 endpoint in both inputs, so the newly… View resolved comment

@michaelnebel
michaelnebel marked this pull request as ready for review September 7, 2026 13:08
@michaelnebel
michaelnebel requested a review from a team as a code owner September 7, 2026 13:08
@michaelnebel
michaelnebel requested a review from mbg September 7, 2026 13:08

@mbg mbg left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your work on this!

I have had a look over the changes here with a wider systems point of view, but I haven't looked at how the changes may affect other parts of the extractor that haven't directly changed here.

I have left a few detailed comments on the code. As an additional, high-level point, I think it would be good to add more comments in a few places to annotate the implementation with the intended behaviour / reasoning for various checks.

Comment on lines +44 to +50
private ImmutableHashSet<string>? registryURLs;
public ImmutableHashSet<string> RegistryURLs =>
registryURLs ??= registryMapping.Keys.ToImmutableHashSet();

private ImmutableHashSet<string>? registryBaseURLs;
public ImmutableHashSet<string> RegistryBaseURLs =>
registryBaseURLs ??= registryMapping.Where(kvp => kvp.Value).Select(kvp => kvp.Key).ToImmutableHashSet();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be good to add docs comments for RegistryURLs and RegistryBaseURLs so that it is easier to understand what they represent without needing to read the implementation.

Comment on lines +20 to +28
/// <summary>
/// The type of the package registry.
/// </summary>
public string Type { get; init; } = "";

/// <summary>
/// The URL of the package registry.
/// </summary>
public string URL { get; init; } = "";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can treat these fields as required, so if it would help avoid unexpected results elsewhere, it might be better not to initialise them to the empty string.

Comment on lines 311 to 312
var fallbackFeeds = EnvironmentVariables.GetURLs(EnvironmentVariableNames.FallbackNugetFeeds).ToHashSet();
if (fallbackFeeds.Count == 0)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's possible to set the environment variable for the fallback feeds in Default Setup, but I would still treat both those and the ones from the private registry configurations as explicit, user-provided configuration. Therefore, it might make sense to compute fallbackFeeds.UnionWith(defaultFeeds); even if there are fallback feeds configured in the environment variable. Alternatively, it might be good to at least visibly log that we are ignoring anything that doesn't come from the environment variable, when it is configured.

}

[Fact]
public void TestDefaultFeeds1()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Here and elsewhere, the method names don't communicate what the corresponding tests are testing very well. It would be good to rename them to communicate the objectives more clearly, or add suitable comments to describe the goals of each test.

---
category: minorAnalysis
---
* In `build-mode: none`, private NuGet registries configured with `replaces-base: true` in the organization-level private registry configuration now replace `nuget.org` sources whenever dependencies are downloaded, including sources discovered from NuGet configuration.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to write "In Default Setup" rather than "In build-mode: none", since the private registry functionality is only available in Default Setup.

Also, while "replaces-base": true is the relevant property in the JSON, it might be better to talk about the UI instead. E.g. [..] private NuGet registries that have the "Replaces base" option in the organization-level private registry configuration enabled now replace [..]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants