Skip to content

Commit

Permalink
Merge pull request #5002 from dependabot/jakecoffman/nuget-repo-from-…
Browse files Browse the repository at this point in the history
…private

nuget: fix PR missing commits in message when using private registry
  • Loading branch information
jakecoffman committed Apr 19, 2022
2 parents 8851caa + 01a638f commit ae2a2a3
Show file tree
Hide file tree
Showing 4 changed files with 491 additions and 4 deletions.
57 changes: 56 additions & 1 deletion nuget/lib/dependabot/nuget/metadata_finder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,62 @@ class MetadataFinder < Dependabot::MetadataFinders::Base
def look_up_source
return Source.from_url(dependency_source_url) if dependency_source_url

look_up_source_in_nuspec(dependency_nuspec_file)
src_repo = look_up_source_in_nuspec(dependency_nuspec_file)
return src_repo if src_repo

# Fallback to getting source from the search result's projectUrl or licenseUrl.
# GitHub Packages doesn't support getting the `.nuspec`, switch to getting
# that instead once it is supported.
src_repo_from_project
end

def src_repo_from_project
source = dependency.requirements.find { |r| r&.fetch(:source) }&.fetch(:source)
return unless source

# Query the service index e.g. https://nuget.pkg.github.com/ORG/index.json
response = Excon.get(
source.fetch(:url),
idempotent: true,
**SharedHelpers.excon_defaults(headers: auth_header)
)
return unless response.status == 200

# Extract the query url e.g. https://nuget.pkg.github.com/ORG/query
search_base = extract_search_url(response.body)
return unless search_base

response = Excon.get(
search_base + "?q=#{dependency.name.downcase}&prerelease=true&semVerLevel=2.0.0",
idempotent: true,
**SharedHelpers.excon_defaults(headers: auth_header)
)
return unless response.status == 200

# Find a projectUrl or licenseUrl that look like a source URL
extract_source_repo(response.body)
end

def extract_search_url(body)
JSON.parse(body).
fetch("resources", []).
find { |r| r.fetch("@type") == "SearchQueryService" }&.
fetch("@id")
end

def extract_source_repo(body)
JSON.parse(body).fetch("data", []).each do |search_result|
next unless search_result["id"].downcase == dependency.name.downcase

if search_result.fetch("projectUrl")
source = Source.from_url(search_result.fetch("projectUrl"))
return source unless source.repo.nil?
end
if search_result.fetch("licenseUrl")
source = Source.from_url(search_result.fetch("licenseUrl"))
return source unless source.repo.nil?
end
end
end

def look_up_source_in_nuspec(nuspec)
Expand Down
53 changes: 50 additions & 3 deletions nuget/spec/dependabot/nuget/metadata_finder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,18 @@
context "that requires authentication" do
before do
stub_request(:get, nuget_url).to_return(status: 404)
stub_request(:get, nuget_url).
with(basic_auth: %w(my passw0rd)).
to_return(status: 200, body: nuget_response)
stub_request(:get, "https://www.myget.org/F/exceptionless/api/v3/index.json").to_return(status: 404)
end

it { is_expected.to be_nil }

context "with details in the credentials" do
before do
stub_request(:get, nuget_url).
with(basic_auth: %w(my passw0rd)).
to_return(status: 200, body: nuget_response)
end

let(:credentials) do
[{
"type" => "git_source",
Expand All @@ -171,6 +175,49 @@
it { is_expected.to eq("https://github.com/dotnet/core-setup") }
end
end

context "that doesn't support .nuspec routes" do
before do
# registry doesn't support .nuspec route, so returns 404
stub_request(:get, nuget_url).to_return(status: 404)
# fallback begins by getting the search URL from the index
stub_request(:get, "https://www.myget.org/F/exceptionless/api/v3/index.json").
to_return(status: 200, body: fixture("nuspecs", "index.json"))
# next query for the package at the search URL returned
stub_request(:get, "https://azuresearch-usnc.nuget.org/query?prerelease=true&q=microsoft.extensions.dependencymodel&semVerLevel=2.0.0").
to_return(status: 200, body: fixture("nuspecs", "microsoft.extensions.depdencymodel-results.json"))
end

# data was extracted from the projectUrl in the search results
it { is_expected.to eq "https://github.com/dotnet/core-setup" }

context "and it fails to get the index" do
before do
# registry is in a bad state
stub_request(:get, nuget_url).to_return(status: 500)
# it falls back to get search URL from the index, but it fails too
stub_request(:get, "https://www.myget.org/F/exceptionless/api/v3/index.json").
to_return(status: 500, body: "internal server error")
end

it { is_expected.to be_nil }
end

context "and it fails to get the search results" do
before do
# registry doesn't support .nuspec route, so returns 404
stub_request(:get, nuget_url).to_return(status: 404)
# fallback begins by getting the search URL from the index
stub_request(:get, "https://www.myget.org/F/exceptionless/api/v3/index.json").
to_return(status: 200, body: fixture("nuspecs", "index.json"))
# oops, we're a little overloaded
stub_request(:get, "https://azuresearch-usnc.nuget.org/query?prerelease=true&q=microsoft.extensions.dependencymodel&semVerLevel=2.0.0").
to_return(status: 503, body: "")
end

it { is_expected.to be_nil }
end
end
end
end
end
192 changes: 192 additions & 0 deletions nuget/spec/fixtures/nuspecs/index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
{
"version": "3.0.0",
"resources": [
{
"@id": "https://azuresearch-usnc.nuget.org/query",
"@type": "SearchQueryService",
"comment": "Query endpoint of NuGet Search service (primary)"
},
{
"@id": "https://azuresearch-ussc.nuget.org/query",
"@type": "SearchQueryService",
"comment": "Query endpoint of NuGet Search service (secondary)"
},
{
"@id": "https://azuresearch-usnc.nuget.org/autocomplete",
"@type": "SearchAutocompleteService",
"comment": "Autocomplete endpoint of NuGet Search service (primary)"
},
{
"@id": "https://azuresearch-ussc.nuget.org/autocomplete",
"@type": "SearchAutocompleteService",
"comment": "Autocomplete endpoint of NuGet Search service (secondary)"
},
{
"@id": "https://azuresearch-usnc.nuget.org/",
"@type": "SearchGalleryQueryService/3.0.0-rc",
"comment": "Azure Website based Search Service used by Gallery (primary)"
},
{
"@id": "https://azuresearch-ussc.nuget.org/",
"@type": "SearchGalleryQueryService/3.0.0-rc",
"comment": "Azure Website based Search Service used by Gallery (secondary)"
},
{
"@id": "https://api.nuget.org/v3/registration5-semver1/",
"@type": "RegistrationsBaseUrl",
"comment": "Base URL of Azure storage where NuGet package registration info is stored"
},
{
"@id": "https://api.nuget.org/v3-flatcontainer/",
"@type": "PackageBaseAddress/3.0.0",
"comment": "Base URL of where NuGet packages are stored, in the format https://api.nuget.org/v3-flatcontainer/{id-lower}/{version-lower}/{id-lower}.{version-lower}.nupkg"
},
{
"@id": "https://www.nuget.org/api/v2",
"@type": "LegacyGallery"
},
{
"@id": "https://www.nuget.org/api/v2",
"@type": "LegacyGallery/2.0.0"
},
{
"@id": "https://www.nuget.org/api/v2/package",
"@type": "PackagePublish/2.0.0"
},
{
"@id": "https://www.nuget.org/api/v2/symbolpackage",
"@type": "SymbolPackagePublish/4.9.0",
"comment": "The gallery symbol publish endpoint."
},
{
"@id": "https://azuresearch-usnc.nuget.org/query",
"@type": "SearchQueryService/3.0.0-rc",
"comment": "Query endpoint of NuGet Search service (primary) used by RC clients"
},
{
"@id": "https://azuresearch-ussc.nuget.org/query",
"@type": "SearchQueryService/3.0.0-rc",
"comment": "Query endpoint of NuGet Search service (secondary) used by RC clients"
},
{
"@id": "https://azuresearch-usnc.nuget.org/query",
"@type": "SearchQueryService/3.5.0",
"comment": "Query endpoint of NuGet Search service (primary) that supports package type filtering"
},
{
"@id": "https://azuresearch-ussc.nuget.org/query",
"@type": "SearchQueryService/3.5.0",
"comment": "Query endpoint of NuGet Search service (secondary) that supports package type filtering"
},
{
"@id": "https://azuresearch-usnc.nuget.org/autocomplete",
"@type": "SearchAutocompleteService/3.0.0-rc",
"comment": "Autocomplete endpoint of NuGet Search service (primary) used by RC clients"
},
{
"@id": "https://azuresearch-ussc.nuget.org/autocomplete",
"@type": "SearchAutocompleteService/3.0.0-rc",
"comment": "Autocomplete endpoint of NuGet Search service (secondary) used by RC clients"
},
{
"@id": "https://azuresearch-usnc.nuget.org/autocomplete",
"@type": "SearchAutocompleteService/3.5.0",
"comment": "Autocomplete endpoint of NuGet Search service (primary) that supports package type filtering"
},
{
"@id": "https://azuresearch-ussc.nuget.org/autocomplete",
"@type": "SearchAutocompleteService/3.5.0",
"comment": "Autocomplete endpoint of NuGet Search service (secondary) that supports package type filtering"
},
{
"@id": "https://api.nuget.org/v3/registration5-semver1/",
"@type": "RegistrationsBaseUrl/3.0.0-rc",
"comment": "Base URL of Azure storage where NuGet package registration info is stored used by RC clients. This base URL does not include SemVer 2.0.0 packages."
},
{
"@id": "https://www.nuget.org/packages/{id}/{version}/ReportAbuse",
"@type": "ReportAbuseUriTemplate/3.0.0-rc",
"comment": "URI template used by NuGet Client to construct Report Abuse URL for packages used by RC clients"
},
{
"@id": "https://api.nuget.org/v3/registration5-semver1/{id-lower}/index.json",
"@type": "PackageDisplayMetadataUriTemplate/3.0.0-rc",
"comment": "URI template used by NuGet Client to construct display metadata for Packages using ID"
},
{
"@id": "https://api.nuget.org/v3/registration5-semver1/{id-lower}/{version-lower}.json",
"@type": "PackageVersionDisplayMetadataUriTemplate/3.0.0-rc",
"comment": "URI template used by NuGet Client to construct display metadata for Packages using ID, Version"
},
{
"@id": "https://azuresearch-usnc.nuget.org/query",
"@type": "SearchQueryService/3.0.0-beta",
"comment": "Query endpoint of NuGet Search service (primary) used by beta clients"
},
{
"@id": "https://azuresearch-ussc.nuget.org/query",
"@type": "SearchQueryService/3.0.0-beta",
"comment": "Query endpoint of NuGet Search service (secondary) used by beta clients"
},
{
"@id": "https://azuresearch-usnc.nuget.org/autocomplete",
"@type": "SearchAutocompleteService/3.0.0-beta",
"comment": "Autocomplete endpoint of NuGet Search service (primary) used by beta clients"
},
{
"@id": "https://azuresearch-ussc.nuget.org/autocomplete",
"@type": "SearchAutocompleteService/3.0.0-beta",
"comment": "Autocomplete endpoint of NuGet Search service (secondary) used by beta clients"
},
{
"@id": "https://api.nuget.org/v3/registration5-semver1/",
"@type": "RegistrationsBaseUrl/3.0.0-beta",
"comment": "Base URL of Azure storage where NuGet package registration info is stored used by Beta clients. This base URL does not include SemVer 2.0.0 packages."
},
{
"@id": "https://www.nuget.org/packages/{id}/{version}/ReportAbuse",
"@type": "ReportAbuseUriTemplate/3.0.0-beta",
"comment": "URI template used by NuGet Client to construct Report Abuse URL for packages"
},
{
"@id": "https://www.nuget.org/packages/{id}/{version}?_src=template",
"@type": "PackageDetailsUriTemplate/5.1.0",
"comment": "URI template used by NuGet Client to construct details URL for packages"
},
{
"@id": "https://api.nuget.org/v3/registration5-gz-semver1/",
"@type": "RegistrationsBaseUrl/3.4.0",
"comment": "Base URL of Azure storage where NuGet package registration info is stored in GZIP format. This base URL does not include SemVer 2.0.0 packages."
},
{
"@id": "https://api.nuget.org/v3/registration5-gz-semver2/",
"@type": "RegistrationsBaseUrl/3.6.0",
"comment": "Base URL of Azure storage where NuGet package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages."
},
{
"@id": "https://api.nuget.org/v3/registration5-gz-semver2/",
"@type": "RegistrationsBaseUrl/Versioned",
"clientVersion": "4.3.0-alpha",
"comment": "Base URL of Azure storage where NuGet package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages."
},
{
"@id": "https://api.nuget.org/v3-index/repository-signatures/4.7.0/index.json",
"@type": "RepositorySignatures/4.7.0",
"comment": "The endpoint for discovering information about this package source's repository signatures."
},
{
"@id": "https://api.nuget.org/v3-index/repository-signatures/5.0.0/index.json",
"@type": "RepositorySignatures/5.0.0",
"comment": "The endpoint for discovering information about this package source's repository signatures."
},
{
"@id": "https://api.nuget.org/v3/catalog0/index.json",
"@type": "Catalog/3.0.0",
"comment": "Index of the NuGet package catalog."
}
],
"@context": {
"@vocab": "http://schema.nuget.org/services#",
"comment": "http://www.w3.org/2000/01/rdf-schema#comment"
}
}
Loading

0 comments on commit ae2a2a3

Please sign in to comment.