diff --git a/lib/datasource/nuget/index.spec.ts b/lib/datasource/nuget/index.spec.ts index cca611cc4c96ec7958d45ae3ee8b7fd25a339953..3170f4c73c0ea7842f6da5b8b85d726061ca167c 100644 --- a/lib/datasource/nuget/index.spec.ts +++ b/lib/datasource/nuget/index.spec.ts @@ -3,7 +3,7 @@ import { getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; import * as _hostRules from '../../util/host-rules'; import { id as versioning } from '../../versioning/nuget'; -import { id as datasource } from '.'; +import { id as datasource, parseRegistryUrl } from '.'; const hostRules: any = _hostRules; @@ -129,6 +129,44 @@ const configV3Multiple = { }; describe('datasource/nuget', () => { + describe('parseRegistryUrl', () => { + beforeEach(() => { + jest.resetAllMocks(); + }); + + it('extracts feed version from registry URL hash (v3)', () => { + const parsed = parseRegistryUrl('https://my-registry#protocolVersion=3'); + + expect(parsed.feedUrl).toEqual('https://my-registry/'); + expect(parsed.protocolVersion).toEqual(3); + }); + + it('extracts feed version from registry URL hash (v2)', () => { + const parsed = parseRegistryUrl('https://my-registry#protocolVersion=2'); + + expect(parsed.feedUrl).toEqual('https://my-registry/'); + expect(parsed.protocolVersion).toEqual(2); + }); + + it('defaults to v2', () => { + const parsed = parseRegistryUrl('https://my-registry'); + + expect(parsed.feedUrl).toEqual('https://my-registry/'); + expect(parsed.protocolVersion).toEqual(2); + }); + + it('returns null for unparseable', () => { + const parsed = parseRegistryUrl( + 'https://test:malfor%5Med@test.example.com' + ); + + expect(parsed.feedUrl).toEqual( + 'https://test:malfor%5Med@test.example.com' + ); + expect(parsed.protocolVersion).toBeNull(); + }); + }); + describe('getReleases', () => { beforeEach(() => { jest.resetAllMocks(); diff --git a/lib/datasource/nuget/index.ts b/lib/datasource/nuget/index.ts index 215a9e0df031a4e927852670b124fef05d6e3eea..0b9ebb79369ab0dbf0ead86acea0194990307ae4 100644 --- a/lib/datasource/nuget/index.ts +++ b/lib/datasource/nuget/index.ts @@ -11,7 +11,7 @@ export const defaultRegistryUrls = [v3.getDefaultFeed()]; export const defaultVersioning = nugetVersioning.id; export const registryStrategy = 'merge'; -function parseRegistryUrl( +export function parseRegistryUrl( registryUrl: string ): { feedUrl: string; protocolVersion: number } { try { diff --git a/lib/manager/nuget/__snapshots__/artifacts.spec.ts.snap b/lib/manager/nuget/__snapshots__/artifacts.spec.ts.snap index 648131471c83dee79901bea61e566741e7f10d71..24488ed845f3cbc46224fde72f1a0786b198c8e8 100644 --- a/lib/manager/nuget/__snapshots__/artifacts.spec.ts.snap +++ b/lib/manager/nuget/__snapshots__/artifacts.spec.ts.snap @@ -28,7 +28,7 @@ exports[`updateArtifacts aborts if no lock file found 1`] = `Array []`; exports[`updateArtifacts authenticates at registries 1`] = ` Array [ Object { - "cmd": "dotnet nuget add source https://my-registry.example.org --configfile others/nuget/not-so-random/nuget.config --name myRegistry --username some-username --password some-password --store-password-in-clear-text", + "cmd": "dotnet nuget add source https://my-registry.example.org/ --configfile others/nuget/not-so-random/nuget.config --name myRegistry --username some-username --password some-password --store-password-in-clear-text", "options": Object { "cwd": "/tmp/github/some/repo", "encoding": "utf-8", @@ -104,6 +104,47 @@ Array [ ] `; +exports[`updateArtifacts strips protocol version from feed url 1`] = ` +Array [ + Object { + "cmd": "dotnet nuget add source https://my-registry.example.org/ --configfile others/nuget/not-so-random/nuget.config --name myRegistry", + "options": Object { + "cwd": "/tmp/github/some/repo", + "encoding": "utf-8", + "env": Object { + "HOME": "/home/user", + "HTTPS_PROXY": "https://example.com", + "HTTP_PROXY": "http://example.com", + "LANG": "en_US.UTF-8", + "LC_ALL": "en_US", + "NO_PROXY": "localhost", + "PATH": "/tmp/path", + }, + "maxBuffer": 10485760, + "timeout": 900000, + }, + }, + Object { + "cmd": "dotnet restore project.csproj --force-evaluate --configfile others/nuget/not-so-random/nuget.config", + "options": Object { + "cwd": "/tmp/github/some/repo", + "encoding": "utf-8", + "env": Object { + "HOME": "/home/user", + "HTTPS_PROXY": "https://example.com", + "HTTP_PROXY": "http://example.com", + "LANG": "en_US.UTF-8", + "LC_ALL": "en_US", + "NO_PROXY": "localhost", + "PATH": "/tmp/path", + }, + "maxBuffer": 10485760, + "timeout": 900000, + }, + }, +] +`; + exports[`updateArtifacts supports docker mode 1`] = ` Array [ Object { diff --git a/lib/manager/nuget/artifacts.spec.ts b/lib/manager/nuget/artifacts.spec.ts index 549be8a5fdb909e1acb32dd84d3017d1bb40113a..1daf2149b6b6b931959e0cd0626ad86057a5617e 100644 --- a/lib/manager/nuget/artifacts.spec.ts +++ b/lib/manager/nuget/artifacts.spec.ts @@ -227,4 +227,26 @@ describe('updateArtifacts', () => { ).not.toBeNull(); expect(execSnapshots).toMatchSnapshot(); }); + it('strips protocol version from feed url', async () => { + const execSnapshots = mockExecAll(exec); + fs.getSiblingFileName.mockReturnValueOnce('packages.lock.json'); + fs.readLocalFile.mockResolvedValueOnce('Current packages.lock.json' as any); + fs.readLocalFile.mockResolvedValueOnce('New packages.lock.json' as any); + getConfiguredRegistries.mockResolvedValueOnce([ + { + name: 'myRegistry', + url: 'https://my-registry.example.org#protocolVersion=3', + }, + ] as never); + hostRules.find.mockImplementationOnce(() => ({})); + expect( + await nuget.updateArtifacts({ + packageFileName: 'project.csproj', + updatedDeps: ['dep'], + newPackageFileContent: '{}', + config, + }) + ).not.toBeNull(); + expect(execSnapshots).toMatchSnapshot(); + }); }); diff --git a/lib/manager/nuget/artifacts.ts b/lib/manager/nuget/artifacts.ts index 6795a2b48851bf9e2b2eb4cd61d3ecb493b441a5..9dbe7e6adaeab122e471425abc4fb2a6fc0e6860 100644 --- a/lib/manager/nuget/artifacts.ts +++ b/lib/manager/nuget/artifacts.ts @@ -1,6 +1,6 @@ import { join } from 'path'; import { TEMPORARY_ERROR } from '../../constants/error-messages'; -import { id } from '../../datasource/nuget'; +import { id, parseRegistryUrl } from '../../datasource/nuget'; import { logger } from '../../logger'; import { ExecOptions, exec } from '../../util/exec'; import { @@ -37,7 +37,8 @@ async function addSourceCmds( hostType: id, url: registry.url, }); - let addSourceCmd = `dotnet nuget add source ${registry.url} --configfile ${nugetConfigFile}`; + const registryInfo = parseRegistryUrl(registry.url); + let addSourceCmd = `dotnet nuget add source ${registryInfo.feedUrl} --configfile ${nugetConfigFile}`; if (registry.name) { // Add name for registry, if known. addSourceCmd += ` --name ${registry.name}`;