Skip to content
Snippets Groups Projects
Unverified Commit a45e5efc authored by Florian Greinacher's avatar Florian Greinacher Committed by GitHub
Browse files

feat(NuGet): add support for specificying protocol version in r… (#5746)

Closes #5165
parent 148d5498
No related branches found
No related tags found
No related merge requests found
...@@ -40,6 +40,18 @@ Renovate by default performs all lookups on `https://api.nuget.org/v3/index.json ...@@ -40,6 +40,18 @@ Renovate by default performs all lookups on `https://api.nuget.org/v3/index.json
If this example we defined 3 nuget feeds. Packages resolving will process feeds consequentially. It means that if package will be resolved in second feed renovate won't look in last one. If this example we defined 3 nuget feeds. Packages resolving will process feeds consequentially. It means that if package will be resolved in second feed renovate won't look in last one.
### Protocol versions
NuGet supports two protocol versions, `v2` and `v3`, which NuGet client and server need to agree on. Renovate as a NuGet client supports both versions and will use `v2` unless the configured feed URL ends with `index.json` (which mirrors the behavior of the official NuGet client). If you have `v3` feed that does not match this pattern (e.g. JFrog Artifactory) you need to help Renovate by appending `#protocolVersion=3` to the registry URL:
```json
"nuget": {
"registryUrls": [
"http://myV3feed#protocolVersion=3"
]
}
```
## Authenticated feeds ## Authenticated feeds
Credentials for authenticated/private feeds can be provided via host rules in the configuration options (file or command line parameter). Credentials for authenticated/private feeds can be provided via host rules in the configuration options (file or command line parameter).
......
...@@ -107,6 +107,17 @@ describe('datasource/nuget', () => { ...@@ -107,6 +107,17 @@ describe('datasource/nuget', () => {
).toBeNull(); ).toBeNull();
}); });
it('extracts feed version from registry URL hash', async () => {
const config = {
lookupName: 'nunit',
registryUrls: ['https://my-registry#protocolVersion=3'],
};
await nuget.getPkgReleases({
...config,
});
expect(got.mock.calls[0][0]).toEqual('https://my-registry/');
});
it('queries the default nuget feed if no registries are supplied', async () => { it('queries the default nuget feed if no registries are supplied', async () => {
await nuget.getPkgReleases({ await nuget.getPkgReleases({
...configNoRegistryUrls, ...configNoRegistryUrls,
......
...@@ -6,17 +6,24 @@ import { GetReleasesConfig, ReleaseResult } from '../common'; ...@@ -6,17 +6,24 @@ import { GetReleasesConfig, ReleaseResult } from '../common';
export { id } from './common'; export { id } from './common';
function detectFeedVersion(url: string): 2 | 3 | null { function parseRegistryUrl(
registryUrl: string
): { feedUrl: string; protocolVersion: number } {
try { try {
const parsecUrl = urlApi.parse(url); const parsedUrl = urlApi.parse(registryUrl);
// Official client does it in the same way let protocolVersion = 2;
if (parsecUrl.pathname.endsWith('.json')) { const protolVersionRegExp = /#protocolVersion=(2|3)/;
return 3; const protocolVersionMatch = protolVersionRegExp.exec(parsedUrl.hash);
if (protocolVersionMatch) {
parsedUrl.hash = '';
protocolVersion = Number.parseInt(protocolVersionMatch[1], 10);
} else if (parsedUrl.pathname.endsWith('.json')) {
protocolVersion = 3;
} }
return 2; return { feedUrl: urlApi.format(parsedUrl), protocolVersion };
} catch (e) { } catch (e) {
logger.debug({ e }, `nuget registry failure: can't parse ${url}`); logger.debug({ e }, `nuget registry failure: can't parse ${registryUrl}`);
return null; return { feedUrl: registryUrl, protocolVersion: null };
} }
} }
...@@ -27,13 +34,13 @@ export async function getPkgReleases({ ...@@ -27,13 +34,13 @@ export async function getPkgReleases({
logger.trace(`nuget.getPkgReleases(${lookupName})`); logger.trace(`nuget.getPkgReleases(${lookupName})`);
let dep: ReleaseResult = null; let dep: ReleaseResult = null;
for (const feed of registryUrls || [v3.getDefaultFeed()]) { for (const feed of registryUrls || [v3.getDefaultFeed()]) {
const feedVersion = detectFeedVersion(feed); const { feedUrl, protocolVersion } = parseRegistryUrl(feed);
if (feedVersion === 2) { if (protocolVersion === 2) {
dep = await v2.getPkgReleases(feed, lookupName); dep = await v2.getPkgReleases(feedUrl, lookupName);
} else if (feedVersion === 3) { } else if (protocolVersion === 3) {
const queryUrl = await v3.getQueryUrl(feed); const queryUrl = await v3.getQueryUrl(feedUrl);
if (queryUrl !== null) { if (queryUrl !== null) {
dep = await v3.getPkgReleases(feed, queryUrl, lookupName); dep = await v3.getPkgReleases(feedUrl, queryUrl, lookupName);
} }
} }
if (dep != null) { if (dep != null) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment