Skip to content
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

feat(nuget): adds package source mapping and generate cached NuGet.config without CLI commands #25052

Merged
merged 35 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
69ed150
refactor(nuget): Create cached nuget config file without calling CLI …
wterpstra Oct 4, 2023
2118bb0
feat(nuget): Adds support for package source mapping (#17562)
wterpstra Oct 5, 2023
713d6c3
chore: improve logging
wterpstra Oct 5, 2023
3a10bad
fix: fixed packageSource xml element name
wterpstra Oct 5, 2023
0d56ab3
fix: remove wrong import
wterpstra Oct 5, 2023
0098f3b
fix: tests
wterpstra Oct 5, 2023
04c203b
Merge branch 'main' into feature/nugetpackagesourcemapping
wterpstra Oct 9, 2023
b0005b6
Update lib/modules/manager/nuget/config-formatter.ts
wterpstra Oct 16, 2023
56871c9
Update lib/modules/manager/nuget/config-formatter.ts
wterpstra Oct 16, 2023
9879ad8
Update lib/modules/manager/nuget/config-formatter.ts
wterpstra Oct 16, 2023
2535ed9
fix(nuget): rename packageFileName variable back to packageFile
wterpstra Oct 16, 2023
d5a24ae
Update lib/modules/manager/nuget/config-formatter.spec.ts
wterpstra Oct 16, 2023
1e53007
Update lib/modules/manager/nuget/config-formatter.spec.ts
wterpstra Oct 16, 2023
5dd2836
Update lib/modules/manager/nuget/config-formatter.spec.ts
wterpstra Oct 16, 2023
46e82aa
Update lib/modules/manager/nuget/config-formatter.spec.ts
wterpstra Oct 16, 2023
3f895dd
Update lib/modules/manager/nuget/config-formatter.ts
wterpstra Oct 16, 2023
9c6a2db
Update lib/modules/manager/nuget/config-formatter.ts
wterpstra Oct 16, 2023
cac753b
Update lib/modules/manager/nuget/config-formatter.ts
wterpstra Oct 16, 2023
af25de1
Update lib/modules/manager/nuget/config-formatter.ts
wterpstra Oct 16, 2023
9ce9ca8
Update lib/modules/manager/nuget/config-formatter.spec.ts
wterpstra Oct 16, 2023
5350051
refactor(nuget): work around regex lookahead limitation of RE2
wterpstra Oct 16, 2023
b3aba72
refactor(nuget): clear hostrules instead of mocking for config-format…
wterpstra Oct 16, 2023
f39bb6b
Update lib/modules/manager/nuget/config-formatter.spec.ts
wterpstra Oct 16, 2023
5eb0b5c
Update lib/modules/manager/nuget/config-formatter.spec.ts
wterpstra Oct 16, 2023
4f1c12c
Update lib/modules/manager/nuget/config-formatter.spec.ts
wterpstra Oct 16, 2023
1e4f8c8
Update lib/modules/manager/nuget/config-formatter.spec.ts
wterpstra Oct 16, 2023
cb0762f
Update lib/modules/manager/nuget/config-formatter.spec.ts
wterpstra Oct 16, 2023
51af981
Update lib/modules/manager/nuget/config-formatter.spec.ts
wterpstra Oct 16, 2023
7aff3ce
Update lib/modules/manager/nuget/config-formatter.spec.ts
wterpstra Oct 16, 2023
9a7875d
Update lib/modules/manager/nuget/config-formatter.spec.ts
wterpstra Oct 16, 2023
5dfbd5c
Update lib/modules/manager/nuget/config-formatter.spec.ts
wterpstra Oct 16, 2023
a36882e
Update lib/modules/manager/nuget/config-formatter.spec.ts
wterpstra Oct 16, 2023
1324dc2
fix: adds test for reading packageSourceMapping from nuget config file
wterpstra Oct 16, 2023
ad0be30
fix: also test for nuget url
wterpstra Oct 16, 2023
a156209
test(nuget): include unnamed package source in config-formatter tests
wterpstra Oct 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
114 changes: 1 addition & 113 deletions lib/modules/manager/nuget/artifacts.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import { env, fs, git, mocked, scm } from '../../../../test/util';
import { GlobalConfig } from '../../../config/global';
import type { RepoGlobalConfig } from '../../../config/types';
import * as docker from '../../../util/exec/docker';
import * as _hostRules from '../../../util/host-rules';
import type { UpdateArtifactsConfig } from '../types';
import type { Registry } from './types';
import * as util from './util';
import * as nuget from '.';

Expand All @@ -17,8 +15,7 @@ jest.mock('../../../util/host-rules', () => mockDeep());
jest.mock('../../../util/git');
jest.mock('./util');

const { getConfiguredRegistries, getDefaultRegistries } = mocked(util);
const hostRules = mocked(_hostRules);
const { getDefaultRegistries } = mocked(util);

process.env.CONTAINERBASE = 'true';

Expand Down Expand Up @@ -404,113 +401,4 @@ describe('modules/manager/nuget/artifacts', () => {
]);
expect(execSnapshots).toBeEmptyArray();
});

it('authenticates at registries', async () => {
const execSnapshots = mockExecAll();
fs.getSiblingFileName.mockReturnValueOnce('packages.lock.json');
git.getFiles.mockResolvedValueOnce({
'packages.lock.json': 'Current packages.lock.json',
});
fs.getLocalFiles.mockResolvedValueOnce({
'packages.lock.json': 'New packages.lock.json',
});
getConfiguredRegistries.mockResolvedValueOnce([
{
name: 'myRegistry',
url: 'https://my-registry.example.org',
},
{
name: 'myRegistry2',
url: 'https://my-registry2.example.org',
},
] satisfies Registry[]);
hostRules.find.mockImplementation((search) => {
if (search.hostType === 'nuget') {
if (search.url === 'https://my-registry.example.org') {
return {
username: 'some-username',
password: 'some-password',
};
} else {
return {
password: 'some-password',
};
}
}
return {};
});
expect(
await nuget.updateArtifacts({
packageFileName: 'project.csproj',
updatedDeps: [{ depName: 'dep' }],
newPackageFileContent: '{}',
config,
})
).toEqual([
{
file: {
contents: 'New packages.lock.json',
path: 'packages.lock.json',
type: 'addition',
},
},
]);
expect(execSnapshots).toMatchObject([
{
cmd:
'dotnet nuget add source https://my-registry.example.org/ --configfile /tmp/renovate/cache/__renovate-private-cache/nuget/nuget.config ' +
'--name myRegistry --username some-username --password some-password --store-password-in-clear-text',
},
{
cmd:
'dotnet nuget add source https://my-registry2.example.org/ --configfile /tmp/renovate/cache/__renovate-private-cache/nuget/nuget.config ' +
'--name myRegistry2 --password some-password --store-password-in-clear-text',
},
{
cmd: 'dotnet restore project.csproj --force-evaluate --configfile /tmp/renovate/cache/__renovate-private-cache/nuget/nuget.config',
},
]);
});

it('strips protocol version from feed url', async () => {
const execSnapshots = mockExecAll();
fs.getSiblingFileName.mockReturnValueOnce('packages.lock.json');
git.getFiles.mockResolvedValueOnce({
'packages.lock.json': 'Current packages.lock.json',
});
fs.getLocalFiles.mockResolvedValueOnce({
'packages.lock.json': 'New packages.lock.json',
});
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: [{ depName: 'dep' }],
newPackageFileContent: '{}',
config,
})
).toEqual([
{
file: {
contents: 'New packages.lock.json',
path: 'packages.lock.json',
type: 'addition',
},
},
]);
expect(execSnapshots).toMatchObject([
{
cmd: 'dotnet nuget add source https://my-registry.example.org/ --configfile /tmp/renovate/cache/__renovate-private-cache/nuget/nuget.config --name myRegistry',
},
{
cmd: 'dotnet restore project.csproj --force-evaluate --configfile /tmp/renovate/cache/__renovate-private-cache/nuget/nuget.config',
},
]);
});
});
64 changes: 18 additions & 46 deletions lib/modules/manager/nuget/artifacts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,57 +13,34 @@ import {
writeLocalFile,
} from '../../../util/fs';
import { getFiles } from '../../../util/git';
import * as hostRules from '../../../util/host-rules';
import { regEx } from '../../../util/regex';
import { NugetDatasource } from '../../datasource/nuget';
import { parseRegistryUrl } from '../../datasource/nuget/common';
import type {
UpdateArtifact,
UpdateArtifactsConfig,
UpdateArtifactsResult,
} from '../types';
import { createNuGetConfigXml } from './config-formatter';
import {
MSBUILD_CENTRAL_FILE,
NUGET_CENTRAL_FILE,
getDependentPackageFiles,
} from './package-tree';
import { getConfiguredRegistries, getDefaultRegistries } from './util';

async function addSourceCmds(
packageFileName: string,
_config: UpdateArtifactsConfig,
nugetConfigFile: string
): Promise<string[]> {
async function createCachedNuGetConfigFile(
nugetCacheDir: string,
packageFileName: string
): Promise<string> {
const registries =
(await getConfiguredRegistries(packageFileName)) ?? getDefaultRegistries();
const result: string[] = [];
for (const registry of registries) {
const { password, username } = hostRules.find({
hostType: NugetDatasource.id,
url: registry.url,
});
const registryInfo = parseRegistryUrl(registry.url);
let addSourceCmd = `dotnet nuget add source ${quote(
registryInfo.feedUrl
)} --configfile ${quote(nugetConfigFile)}`;
if (registry.name) {
// Add name for registry, if known.
addSourceCmd += ` --name ${quote(registry.name)}`;
}
// Add registry credentials from host rules, if configured.
if (username) {
// Add username from host rules, if configured.
addSourceCmd += ` --username ${quote(username)}`;
}
if (password) {
// Add password from host rules, if configured.
addSourceCmd += ` --password ${quote(
password
)} --store-password-in-clear-text`;
}
result.push(addSourceCmd);
}
return result;

const contents = createNuGetConfigXml(registries);

const cachedNugetConfigFile = join(nugetCacheDir, `nuget.config`);
await ensureDir(nugetCacheDir);
await outputCacheFile(cachedNugetConfigFile, contents);

return cachedNugetConfigFile;
}

async function runDotnetRestore(
Expand All @@ -73,6 +50,11 @@ async function runDotnetRestore(
): Promise<void> {
const nugetCacheDir = join(privateCacheDir(), 'nuget');

const nugetConfigFile = await createCachedNuGetConfigFile(
nugetCacheDir,
packageFileName
);

const execOptions: ExecOptions = {
docker: {},
extraEnv: {
Expand All @@ -84,17 +66,7 @@ async function runDotnetRestore(
],
};

const nugetConfigFile = join(nugetCacheDir, `nuget.config`);

await ensureDir(nugetCacheDir);

await outputCacheFile(
nugetConfigFile,
`<?xml version="1.0" encoding="utf-8"?>\n<configuration>\n</configuration>\n`
);

const cmds = [
...(await addSourceCmds(packageFileName, config, nugetConfigFile)),
...dependentPackageFileNames.map(
(fileName) =>
`dotnet restore ${quote(
Expand Down