mirror of https://github.com/renovatebot/renovate
244 lines
7.2 KiB
TypeScript
244 lines
7.2 KiB
TypeScript
import is from '@sindresorhus/is';
|
|
import JSON5 from 'json5';
|
|
import { getOptions } from '../../../../config/options';
|
|
import type { AllConfig } from '../../../../config/types';
|
|
import { logger } from '../../../../logger';
|
|
import { coersions } from './coersions';
|
|
import type { ParseConfigOptions } from './types';
|
|
import { migrateAndValidateConfig } from './util';
|
|
|
|
function normalizePrefixes(
|
|
env: NodeJS.ProcessEnv,
|
|
prefix: string | undefined,
|
|
): NodeJS.ProcessEnv {
|
|
const result = { ...env };
|
|
if (prefix) {
|
|
for (const [key, val] of Object.entries(result)) {
|
|
if (key.startsWith(prefix)) {
|
|
const newKey = key.replace(prefix, 'RENOVATE_');
|
|
result[newKey] = val;
|
|
delete result[key];
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
export function getEnvName(option: ParseConfigOptions): string {
|
|
if (option.env === false) {
|
|
return '';
|
|
}
|
|
if (option.env) {
|
|
return option.env;
|
|
}
|
|
const nameWithUnderscores = option.name.replace(/([A-Z])/g, '_$1');
|
|
return `RENOVATE_${nameWithUnderscores.toUpperCase()}`;
|
|
}
|
|
|
|
const renameKeys = {
|
|
aliases: 'registryAliases',
|
|
azureAutoComplete: 'platformAutomerge', // migrate: azureAutoComplete
|
|
gitLabAutomerge: 'platformAutomerge', // migrate: gitLabAutomerge
|
|
mergeConfidenceApiBaseUrl: 'mergeConfidenceEndpoint',
|
|
mergeConfidenceSupportedDatasources: 'mergeConfidenceDatasources',
|
|
};
|
|
|
|
function renameEnvKeys(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
|
|
const result = { ...env };
|
|
for (const [from, to] of Object.entries(renameKeys)) {
|
|
const fromKey = getEnvName({ name: from });
|
|
const toKey = getEnvName({ name: to });
|
|
if (env[fromKey]) {
|
|
result[toKey] = env[fromKey];
|
|
delete result[fromKey];
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
const migratedKeysWithValues = [
|
|
{
|
|
oldName: 'recreateClosed',
|
|
newName: 'recreateWhen',
|
|
from: 'true',
|
|
to: 'always',
|
|
},
|
|
{
|
|
oldName: 'recreateClosed',
|
|
newName: 'recreateWhen',
|
|
from: 'false',
|
|
to: 'auto',
|
|
},
|
|
];
|
|
|
|
function massageEnvKeyValues(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
|
|
const result = { ...env };
|
|
for (const { oldName, newName, from, to } of migratedKeysWithValues) {
|
|
const key = getEnvName({ name: oldName });
|
|
if (env[key] !== undefined) {
|
|
if (result[key] === from) {
|
|
delete result[key];
|
|
result[getEnvName({ name: newName })] = to;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// these experimental env vars have been converted into self-hosted config options
|
|
const convertedExperimentalEnvVars = [
|
|
'RENOVATE_X_AUTODISCOVER_REPO_SORT',
|
|
'RENOVATE_X_AUTODISCOVER_REPO_ORDER',
|
|
'RENOVATE_X_DOCKER_MAX_PAGES',
|
|
'RENOVATE_X_DELETE_CONFIG_FILE',
|
|
'RENOVATE_X_S3_ENDPOINT',
|
|
'RENOVATE_X_S3_PATH_STYLE',
|
|
'RENOVATE_X_MERGE_CONFIDENCE_API_BASE_URL',
|
|
'RENOVATE_X_MERGE_CONFIDENCE_SUPPORTED_DATASOURCES',
|
|
];
|
|
|
|
/**
|
|
* Massages the experimental env vars which have been converted to config options
|
|
*
|
|
* e.g. RENOVATE_X_AUTODISCOVER_REPO_SORT -> RENOVATE_AUTODISCOVER_REPO_SORT
|
|
*/
|
|
function massageConvertedExperimentalVars(
|
|
env: NodeJS.ProcessEnv,
|
|
): NodeJS.ProcessEnv {
|
|
const result = { ...env };
|
|
for (const key of convertedExperimentalEnvVars) {
|
|
if (env[key] !== undefined) {
|
|
const newKey = key.replace('RENOVATE_X_', 'RENOVATE_');
|
|
result[newKey] = env[key];
|
|
delete result[key];
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
export async function getConfig(
|
|
inputEnv: NodeJS.ProcessEnv,
|
|
): Promise<AllConfig> {
|
|
let env = inputEnv;
|
|
env = normalizePrefixes(inputEnv, inputEnv.ENV_PREFIX);
|
|
env = massageConvertedExperimentalVars(env);
|
|
env = renameEnvKeys(env);
|
|
// massage the values of migrated configuration keys
|
|
env = massageEnvKeyValues(env);
|
|
|
|
const options = getOptions();
|
|
|
|
let config: AllConfig = {};
|
|
|
|
if (env.RENOVATE_CONFIG) {
|
|
try {
|
|
config = JSON5.parse(env.RENOVATE_CONFIG);
|
|
logger.debug({ config }, 'Detected config in env RENOVATE_CONFIG');
|
|
|
|
config = await migrateAndValidateConfig(config, 'RENOVATE_CONFIG');
|
|
} catch (err) {
|
|
logger.fatal({ err }, 'Could not parse RENOVATE_CONFIG');
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
config.hostRules ||= [];
|
|
|
|
options.forEach((option) => {
|
|
if (option.env !== false) {
|
|
const envName = getEnvName(option);
|
|
const envVal = env[envName];
|
|
if (envVal) {
|
|
if (option.type === 'array' && option.subType === 'object') {
|
|
try {
|
|
const parsed = JSON5.parse(envVal);
|
|
if (is.array(parsed)) {
|
|
config[option.name] = parsed;
|
|
} else {
|
|
logger.debug(
|
|
{ val: envVal, envName },
|
|
'Could not parse object array',
|
|
);
|
|
}
|
|
} catch {
|
|
logger.debug(
|
|
{ val: envVal, envName },
|
|
'Could not parse environment variable',
|
|
);
|
|
}
|
|
} else {
|
|
const coerce = coersions[option.type];
|
|
config[option.name] = coerce(envVal);
|
|
if (option.name === 'dryRun') {
|
|
if ((config[option.name] as string) === 'true') {
|
|
logger.warn(
|
|
'env config dryRun property has been changed to full',
|
|
);
|
|
config[option.name] = 'full';
|
|
} else if ((config[option.name] as string) === 'false') {
|
|
logger.warn(
|
|
'env config dryRun property has been changed to null',
|
|
);
|
|
delete config[option.name];
|
|
} else if ((config[option.name] as string) === 'null') {
|
|
delete config[option.name];
|
|
}
|
|
}
|
|
if (option.name === 'requireConfig') {
|
|
if ((config[option.name] as string) === 'true') {
|
|
logger.warn(
|
|
'env config requireConfig property has been changed to required',
|
|
);
|
|
config[option.name] = 'required';
|
|
} else if ((config[option.name] as string) === 'false') {
|
|
logger.warn(
|
|
'env config requireConfig property has been changed to optional',
|
|
);
|
|
config[option.name] = 'optional';
|
|
}
|
|
}
|
|
if (option.name === 'platformCommit') {
|
|
if ((config[option.name] as string) === 'true') {
|
|
logger.warn(
|
|
'env config platformCommit property has been changed to enabled',
|
|
);
|
|
config[option.name] = 'enabled';
|
|
} else if ((config[option.name] as string) === 'false') {
|
|
logger.warn(
|
|
'env config platformCommit property has been changed to disabled',
|
|
);
|
|
config[option.name] = 'disabled';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
if (env.GITHUB_COM_TOKEN) {
|
|
logger.debug(`Converting GITHUB_COM_TOKEN into a global host rule`);
|
|
config.hostRules.push({
|
|
hostType: 'github',
|
|
matchHost: 'github.com',
|
|
token: env.GITHUB_COM_TOKEN,
|
|
});
|
|
}
|
|
|
|
// These env vars are deprecated and deleted to make sure they're not used
|
|
const unsupportedEnv = [
|
|
'BITBUCKET_TOKEN',
|
|
'BITBUCKET_USERNAME',
|
|
'BITBUCKET_PASSWORD',
|
|
'GITHUB_ENDPOINT',
|
|
'GITHUB_TOKEN',
|
|
'GITLAB_ENDPOINT',
|
|
'GITLAB_TOKEN',
|
|
'VSTS_ENDPOINT',
|
|
'VSTS_TOKEN',
|
|
];
|
|
|
|
unsupportedEnv.forEach((val) => delete env[val]);
|
|
|
|
return config;
|
|
}
|