mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-11 06:26:26 +00:00
refactor: encapsulate hostRulesFromEnv (#12277)
This commit is contained in:
parent
a0b8b52a75
commit
42fd18d101
4 changed files with 184 additions and 54 deletions
|
@ -0,0 +1,55 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`workers/global/config/parse/host-rules-from-env regression test for #10937 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"hostType": "git-tags",
|
||||
"matchHost": "gitlab.example-domain.net",
|
||||
"password": "some-password",
|
||||
"username": "some-user",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`workers/global/config/parse/host-rules-from-env supports datasource env token 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"hostType": "pypi",
|
||||
"token": "some-token",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`workers/global/config/parse/host-rules-from-env supports docker username/password 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"hostType": "docker",
|
||||
"password": "some-password",
|
||||
"username": "some-username",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`workers/global/config/parse/host-rules-from-env supports domain and host names with case insensitivity 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"hostType": "github-tags",
|
||||
"matchHost": "github.com",
|
||||
"token": "some-token",
|
||||
},
|
||||
Object {
|
||||
"hostType": "pypi",
|
||||
"matchHost": "my.custom.host",
|
||||
"password": "some-password",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`workers/global/config/parse/host-rules-from-env supports password-only 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"hostType": "npm",
|
||||
"password": "some-password",
|
||||
},
|
||||
]
|
||||
`;
|
|
@ -3,9 +3,8 @@ import is from '@sindresorhus/is';
|
|||
import { getOptions } from '../../../../config/options';
|
||||
import type { AllConfig, RenovateOptions } from '../../../../config/types';
|
||||
import { PlatformId } from '../../../../constants';
|
||||
import { getDatasourceList } from '../../../../datasource';
|
||||
import { logger } from '../../../../logger';
|
||||
import type { HostRule } from '../../../../types';
|
||||
import { hostRulesFromEnv } from './host-rules-from-env';
|
||||
|
||||
function normalizePrefixes(
|
||||
env: NodeJS.ProcessEnv,
|
||||
|
@ -120,58 +119,7 @@ export function getConfig(inputEnv: NodeJS.ProcessEnv): AllConfig {
|
|||
});
|
||||
}
|
||||
|
||||
const datasources = new Set(getDatasourceList());
|
||||
const fields = ['token', 'username', 'password'];
|
||||
|
||||
const hostRules: HostRule[] = [];
|
||||
|
||||
const npmEnvPrefixes = ['npm_config_', 'npm_lifecycle_', 'npm_package_'];
|
||||
|
||||
for (const envName of Object.keys(env).sort()) {
|
||||
if (npmEnvPrefixes.some((prefix) => envName.startsWith(prefix))) {
|
||||
logger.trace('Ignoring npm env: ' + envName);
|
||||
continue; // eslint-disable-line no-continue
|
||||
}
|
||||
// Double underscore __ is used in place of hyphen -
|
||||
const splitEnv = envName.toLowerCase().replace(/__/g, '-').split('_');
|
||||
const hostType = splitEnv.shift();
|
||||
if (datasources.has(hostType)) {
|
||||
const suffix = splitEnv.pop();
|
||||
if (fields.includes(suffix)) {
|
||||
let matchHost: string;
|
||||
const rule: HostRule = {};
|
||||
rule[suffix] = env[envName];
|
||||
if (splitEnv.length === 0) {
|
||||
// host-less rule
|
||||
} else if (splitEnv.length === 1) {
|
||||
logger.warn(`Cannot parse ${envName} env`);
|
||||
continue; // eslint-disable-line no-continue
|
||||
} else {
|
||||
matchHost = splitEnv.join('.');
|
||||
}
|
||||
const existingRule = hostRules.find(
|
||||
(hr) => hr.hostType === hostType && hr.matchHost === matchHost
|
||||
);
|
||||
logger.debug(`Converting ${envName} into a global host rule`);
|
||||
if (existingRule) {
|
||||
// Add current field to existing rule
|
||||
existingRule[suffix] = env[envName];
|
||||
} else {
|
||||
// Create a new rule
|
||||
const newRule: HostRule = {
|
||||
hostType,
|
||||
};
|
||||
if (matchHost) {
|
||||
newRule.matchHost = matchHost;
|
||||
}
|
||||
newRule[suffix] = env[envName];
|
||||
hostRules.push(newRule);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
config.hostRules = [...config.hostRules, ...hostRules];
|
||||
config.hostRules = [...config.hostRules, ...hostRulesFromEnv(env)];
|
||||
|
||||
// These env vars are deprecated and deleted to make sure they're not used
|
||||
const unsupportedEnv = [
|
||||
|
|
70
lib/workers/global/config/parse/host-rules-from-env.spec.ts
Normal file
70
lib/workers/global/config/parse/host-rules-from-env.spec.ts
Normal file
|
@ -0,0 +1,70 @@
|
|||
import { hostRulesFromEnv } from './host-rules-from-env';
|
||||
|
||||
describe('workers/global/config/parse/host-rules-from-env', () => {
|
||||
it('supports docker username/password', () => {
|
||||
const envParam: NodeJS.ProcessEnv = {
|
||||
DOCKER_USERNAME: 'some-username',
|
||||
DOCKER_PASSWORD: 'some-password',
|
||||
};
|
||||
expect(hostRulesFromEnv(envParam)).toMatchSnapshot([
|
||||
{
|
||||
hostType: 'docker',
|
||||
password: 'some-password',
|
||||
username: 'some-username',
|
||||
},
|
||||
]);
|
||||
});
|
||||
it('supports password-only', () => {
|
||||
const envParam: NodeJS.ProcessEnv = {
|
||||
NPM_PASSWORD: 'some-password',
|
||||
};
|
||||
expect(hostRulesFromEnv(envParam)).toMatchSnapshot([
|
||||
{ hostType: 'npm', password: 'some-password' },
|
||||
]);
|
||||
});
|
||||
it('supports domain and host names with case insensitivity', () => {
|
||||
const envParam: NodeJS.ProcessEnv = {
|
||||
GITHUB__TAGS_GITHUB_COM_TOKEN: 'some-token',
|
||||
pypi_my_CUSTOM_HOST_passWORD: 'some-password',
|
||||
};
|
||||
|
||||
expect(hostRulesFromEnv(envParam)).toMatchSnapshot([
|
||||
{ matchHost: 'github.com', token: 'some-token' },
|
||||
{ matchHost: 'my.custom.host', password: 'some-password' },
|
||||
]);
|
||||
});
|
||||
it('regression test for #10937', () => {
|
||||
const envParam: NodeJS.ProcessEnv = {
|
||||
GIT__TAGS_GITLAB_EXAMPLE__DOMAIN_NET_USERNAME: 'some-user',
|
||||
GIT__TAGS_GITLAB_EXAMPLE__DOMAIN_NET_PASSWORD: 'some-password',
|
||||
};
|
||||
expect(hostRulesFromEnv(envParam)).toMatchSnapshot([
|
||||
{
|
||||
hostType: 'git-tags',
|
||||
matchHost: 'gitlab.example-domain.net',
|
||||
password: 'some-password',
|
||||
username: 'some-user',
|
||||
},
|
||||
]);
|
||||
});
|
||||
it('supports datasource env token', () => {
|
||||
const envParam: NodeJS.ProcessEnv = {
|
||||
PYPI_TOKEN: 'some-token',
|
||||
};
|
||||
expect(hostRulesFromEnv(envParam)).toMatchSnapshot([
|
||||
{ hostType: 'pypi', token: 'some-token' },
|
||||
]);
|
||||
});
|
||||
it('rejects incomplete datasource env token', () => {
|
||||
const envParam: NodeJS.ProcessEnv = {
|
||||
PYPI_FOO_TOKEN: 'some-token',
|
||||
};
|
||||
expect(hostRulesFromEnv(envParam)).toHaveLength(0);
|
||||
});
|
||||
it('rejects npm env', () => {
|
||||
const envParam: NodeJS.ProcessEnv = {
|
||||
npm_package_devDependencies__types_registry_auth_token: '4.2.0',
|
||||
};
|
||||
expect(hostRulesFromEnv(envParam)).toHaveLength(0);
|
||||
});
|
||||
});
|
57
lib/workers/global/config/parse/host-rules-from-env.ts
Normal file
57
lib/workers/global/config/parse/host-rules-from-env.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
import { getDatasourceList } from '../../../../datasource';
|
||||
import { logger } from '../../../../logger';
|
||||
import type { HostRule } from '../../../../types';
|
||||
|
||||
export function hostRulesFromEnv(env: NodeJS.ProcessEnv): HostRule[] {
|
||||
const datasources = new Set(getDatasourceList());
|
||||
const fields = ['token', 'username', 'password'];
|
||||
|
||||
const hostRules: HostRule[] = [];
|
||||
|
||||
const npmEnvPrefixes = ['npm_config_', 'npm_lifecycle_', 'npm_package_'];
|
||||
|
||||
for (const envName of Object.keys(env).sort()) {
|
||||
if (npmEnvPrefixes.some((prefix) => envName.startsWith(prefix))) {
|
||||
logger.trace('Ignoring npm env: ' + envName);
|
||||
continue; // eslint-disable-line no-continue
|
||||
}
|
||||
// Double underscore __ is used in place of hyphen -
|
||||
const splitEnv = envName.toLowerCase().replace(/__/g, '-').split('_');
|
||||
const hostType = splitEnv.shift();
|
||||
if (datasources.has(hostType)) {
|
||||
const suffix = splitEnv.pop();
|
||||
if (fields.includes(suffix)) {
|
||||
let matchHost: string;
|
||||
const rule: HostRule = {};
|
||||
rule[suffix] = env[envName];
|
||||
if (splitEnv.length === 0) {
|
||||
// host-less rule
|
||||
} else if (splitEnv.length === 1) {
|
||||
logger.warn(`Cannot parse ${envName} env`);
|
||||
continue; // eslint-disable-line no-continue
|
||||
} else {
|
||||
matchHost = splitEnv.join('.');
|
||||
}
|
||||
const existingRule = hostRules.find(
|
||||
(hr) => hr.hostType === hostType && hr.matchHost === matchHost
|
||||
);
|
||||
logger.debug(`Converting ${envName} into a global host rule`);
|
||||
if (existingRule) {
|
||||
// Add current field to existing rule
|
||||
existingRule[suffix] = env[envName];
|
||||
} else {
|
||||
// Create a new rule
|
||||
const newRule: HostRule = {
|
||||
hostType,
|
||||
};
|
||||
if (matchHost) {
|
||||
newRule.matchHost = matchHost;
|
||||
}
|
||||
newRule[suffix] = env[envName];
|
||||
hostRules.push(newRule);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return hostRules;
|
||||
}
|
Loading…
Reference in a new issue