From dad3863e8aa5f6ec7369f76d7e29970cc63d4263 Mon Sep 17 00:00:00 2001 From: Oleg Krivtsov Date: Wed, 22 Dec 2021 14:38:49 +0700 Subject: [PATCH] fix(config): detect missing RENOVATE_CONFIG_FILE (#13196) Co-authored-by: Michael Kriese --- .../__fixtures__/config-ref-error.js-invalid | 4 ++++ lib/workers/global/config/parse/file.spec.ts | 24 +++++++++++++++++++ lib/workers/global/config/parse/file.ts | 15 ++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 lib/workers/global/config/parse/__fixtures__/config-ref-error.js-invalid diff --git a/lib/workers/global/config/parse/__fixtures__/config-ref-error.js-invalid b/lib/workers/global/config/parse/__fixtures__/config-ref-error.js-invalid new file mode 100644 index 00000000000000..156a4ee7474d7f --- /dev/null +++ b/lib/workers/global/config/parse/__fixtures__/config-ref-error.js-invalid @@ -0,0 +1,4 @@ +// @ts-ignore +module.exports = { + endpoint: CI_API_V4_URL +}; diff --git a/lib/workers/global/config/parse/file.spec.ts b/lib/workers/global/config/parse/file.spec.ts index a0826752160183..f69792d891a069 100644 --- a/lib/workers/global/config/parse/file.spec.ts +++ b/lib/workers/global/config/parse/file.spec.ts @@ -1,4 +1,5 @@ import fs from 'fs'; +import fsExtra from 'fs-extra'; import { DirectoryResult, dir } from 'tmp-promise'; import upath from 'upath'; import { logger } from '../../../../logger'; @@ -92,6 +93,29 @@ describe('workers/global/config/parse/file', () => { expect(mockProcessExit).toHaveBeenCalledWith(1); }); + it('fatal error and exit if config.js contains unresolved env var', async () => { + const mockProcessExit = jest + .spyOn(process, 'exit') + .mockImplementation(() => undefined as never); + + const configFile = upath.resolve( + __dirname, + './__fixtures__/config-ref-error.js-invalid' + ); + const tmpDir = tmp.path; + await fsExtra.ensureDir(tmpDir); + + const tmpConfigFile = upath.resolve(tmpDir, 'config-ref-error.js'); + await fsExtra.copy(configFile, tmpConfigFile); + + await file.getConfig({ RENOVATE_CONFIG_FILE: tmpConfigFile }); + + expect(logger.fatal).toHaveBeenCalledWith( + `Error parsing config file due to unresolved variable(s): CI_API_V4_URL is not defined` + ); + expect(mockProcessExit).toHaveBeenCalledWith(1); + }); + it.each([ ['invalid config file type', './file.txt'], ['missing config file type', './file'], diff --git a/lib/workers/global/config/parse/file.ts b/lib/workers/global/config/parse/file.ts index 90bd2aa809038e..fa2076c3c1be4b 100644 --- a/lib/workers/global/config/parse/file.ts +++ b/lib/workers/global/config/parse/file.ts @@ -1,4 +1,5 @@ import is from '@sindresorhus/is'; +import * as fs from 'fs-extra'; import { load } from 'js-yaml'; import JSON5 from 'json5'; import upath from 'upath'; @@ -36,6 +37,15 @@ export async function getConfig(env: NodeJS.ProcessEnv): Promise { if (!upath.isAbsolute(configFile)) { configFile = `${process.cwd()}/${configFile}`; } + + if (env.RENOVATE_CONFIG_FILE && !(await fs.pathExists(configFile))) { + logger.fatal( + { configFile }, + `Custom config file specified in RENOVATE_CONFIG_FILE must exist` + ); + process.exit(1); + } + logger.debug('Checking for config file in ' + configFile); let config: AllConfig = {}; try { @@ -45,6 +55,11 @@ export async function getConfig(env: NodeJS.ProcessEnv): Promise { if (err instanceof SyntaxError || err instanceof TypeError) { logger.fatal(`Could not parse config file \n ${err.stack}`); process.exit(1); + } else if (err instanceof ReferenceError) { + logger.fatal( + `Error parsing config file due to unresolved variable(s): ${err.message}` + ); + process.exit(1); } else if (err.message === 'Unsupported file type') { logger.fatal(err.message); process.exit(1);