From a60841daaa66e9d10abe7f81c41d0e5fd996cd1c Mon Sep 17 00:00:00 2001 From: Gabriel Ladzaretti Date: Tue, 31 Dec 2024 12:34:32 +0200 Subject: [PATCH 1/4] reusable env getConfig --- lib/workers/global/config/parse/env.spec.ts | 6 +- lib/workers/global/config/parse/env.ts | 171 +++++++++++--------- 2 files changed, 96 insertions(+), 81 deletions(-) diff --git a/lib/workers/global/config/parse/env.spec.ts b/lib/workers/global/config/parse/env.spec.ts index 3961e8d3dd61cc..0dae85326e49c5 100644 --- a/lib/workers/global/config/parse/env.spec.ts +++ b/lib/workers/global/config/parse/env.spec.ts @@ -306,7 +306,11 @@ describe('workers/global/config/parse/env', () => { it('crashes', async () => { const envParam: NodeJS.ProcessEnv = { RENOVATE_CONFIG: '!@#' }; - await env.getConfig(envParam); + processExit.mockImplementationOnce(() => { + throw new Error('terminate function to simulate process.exit call'); + }); + + await expect(env.getConfig(envParam)).toReject(); expect(processExit).toHaveBeenCalledWith(1); }); diff --git a/lib/workers/global/config/parse/env.ts b/lib/workers/global/config/parse/env.ts index 3467b1ec1ada8b..6e46c9a735dbf2 100644 --- a/lib/workers/global/config/parse/env.ts +++ b/lib/workers/global/config/parse/env.ts @@ -118,9 +118,9 @@ function massageConvertedExperimentalVars( export async function getConfig( inputEnv: NodeJS.ProcessEnv, + configEnvKey = 'RENOVATE_CONFIG', ): Promise { - let env = inputEnv; - env = normalizePrefixes(inputEnv, inputEnv.ENV_PREFIX); + let env = normalizePrefixes(inputEnv, inputEnv.ENV_PREFIX); env = massageConvertedExperimentalVars(env); env = renameEnvKeys(env); // massage the values of migrated configuration keys @@ -128,92 +128,82 @@ export async function getConfig( const options = getOptions(); - let config: AllConfig = {}; + const config = await parseAndValidateOrExit(env, configEnvKey); - if (env.RENOVATE_CONFIG) { - try { - config = JSON5.parse(env.RENOVATE_CONFIG); - logger.debug({ config }, 'Detected config in env RENOVATE_CONFIG'); + config.hostRules ??= []; - config = await migrateAndValidateConfig(config, 'RENOVATE_CONFIG'); - } catch (err) { - logger.fatal({ err }, 'Could not parse RENOVATE_CONFIG'); - process.exit(1); + for (const option of options) { + if (option.env === false) { + continue; } - } - config.hostRules ??= []; + const envName = getEnvName(option); + const envVal = env[envName]; + if (!envVal) { + continue; + } - 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', - ); - } + if (option.type === 'array' && option.subType === 'object') { + try { + const parsed = JSON5.parse(envVal); + if (is.array(parsed)) { + config[option.name] = parsed; } 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'; - } - } + 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`); @@ -237,7 +227,28 @@ export async function getConfig( 'VSTS_TOKEN', ]; - unsupportedEnv.forEach((val) => delete env[val]); + for (const val of unsupportedEnv) { + delete env[val]; + } return config; } + +async function parseAndValidateOrExit( + env: NodeJS.ProcessEnv, + configEnvKey: string, +): Promise { + if (!env[configEnvKey]) { + return {}; + } + + try { + const config = JSON5.parse(env[configEnvKey]); + logger.debug({ config }, `Detected config in env ${configEnvKey}`); + + return await migrateAndValidateConfig(config, `${configEnvKey}`); + } catch (err) { + logger.fatal({ err }, `Could not parse ${configEnvKey}`); + process.exit(1); + } +} From aacf6f784cc26ce5d644da07175b3bbc85ca60d2 Mon Sep 17 00:00:00 2001 From: Gabriel Ladzaretti Date: Tue, 31 Dec 2024 14:13:58 +0200 Subject: [PATCH 2/4] use util parseJson fn --- lib/workers/global/config/parse/env.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/workers/global/config/parse/env.ts b/lib/workers/global/config/parse/env.ts index 6e46c9a735dbf2..a64919ea73194e 100644 --- a/lib/workers/global/config/parse/env.ts +++ b/lib/workers/global/config/parse/env.ts @@ -3,6 +3,7 @@ import JSON5 from 'json5'; import { getOptions } from '../../../../config/options'; import type { AllConfig } from '../../../../config/types'; import { logger } from '../../../../logger'; +import { parseJson } from '../../../../util/common'; import { coersions } from './coersions'; import type { ParseConfigOptions } from './types'; import { migrateAndValidateConfig } from './util'; @@ -243,7 +244,7 @@ async function parseAndValidateOrExit( } try { - const config = JSON5.parse(env[configEnvKey]); + const config = parseJson(env[configEnvKey], '.json5') as AllConfig; logger.debug({ config }, `Detected config in env ${configEnvKey}`); return await migrateAndValidateConfig(config, `${configEnvKey}`); From 14960a6818631185765aab5c4d394138639161d2 Mon Sep 17 00:00:00 2001 From: Gabriel-Ladzaretti <97394622+Gabriel-Ladzaretti@users.noreply.github.com> Date: Tue, 31 Dec 2024 14:52:13 +0200 Subject: [PATCH 3/4] Update lib/workers/global/config/parse/env.ts Co-authored-by: Michael Kriese --- lib/workers/global/config/parse/env.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/workers/global/config/parse/env.ts b/lib/workers/global/config/parse/env.ts index a64919ea73194e..30ad03c01cd43a 100644 --- a/lib/workers/global/config/parse/env.ts +++ b/lib/workers/global/config/parse/env.ts @@ -244,7 +244,7 @@ async function parseAndValidateOrExit( } try { - const config = parseJson(env[configEnvKey], '.json5') as AllConfig; + const config = parseJson(env[configEnvKey], `${configEnvKey}.env.json5`) as AllConfig; logger.debug({ config }, `Detected config in env ${configEnvKey}`); return await migrateAndValidateConfig(config, `${configEnvKey}`); From c24dd9b36087345d12d537597b58e4967b190de8 Mon Sep 17 00:00:00 2001 From: Gabriel Ladzaretti Date: Tue, 31 Dec 2024 14:58:46 +0200 Subject: [PATCH 4/4] prettier fix --- lib/workers/global/config/parse/env.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/workers/global/config/parse/env.ts b/lib/workers/global/config/parse/env.ts index 30ad03c01cd43a..a5543bb1983549 100644 --- a/lib/workers/global/config/parse/env.ts +++ b/lib/workers/global/config/parse/env.ts @@ -244,7 +244,10 @@ async function parseAndValidateOrExit( } try { - const config = parseJson(env[configEnvKey], `${configEnvKey}.env.json5`) as AllConfig; + const config = parseJson( + env[configEnvKey], + `${configEnvKey}.env.json5`, + ) as AllConfig; logger.debug({ config }, `Detected config in env ${configEnvKey}`); return await migrateAndValidateConfig(config, `${configEnvKey}`);