diff --git a/docs/usage/config-validation.md b/docs/usage/config-validation.md index 7871cc5367d072b2f7378779069c64b3058eff0a..88ee2cab3d03fa6b35fe6dd44cb2278b128f1d0b 100644 --- a/docs/usage/config-validation.md +++ b/docs/usage/config-validation.md @@ -18,5 +18,8 @@ INFO: Validating renovate.json INFO: Config validated successfully ``` +The validator program fails with a non-zero exit code if there are any validation warnings or errors. +You can pass the `--strict` flag to make it fail if a scanned config needs migration. + You can configure a [pre-commit](https://pre-commit.com) hook to validate your configuration automatically. Please check out the [`renovatebot/pre-commit-hooks` repository](https://github.com/renovatebot/pre-commit-hooks) for more information. diff --git a/lib/config-validator.ts b/lib/config-validator.ts index 07bf4bbe4cda03999a72e8b2d550e834607c8f0e..cccdb1a4f426b9a1e26cef37a5b9fb6a4ae59a4f 100644 --- a/lib/config-validator.ts +++ b/lib/config-validator.ts @@ -19,6 +19,7 @@ let returnVal = 0; async function validate( desc: string, config: RenovateConfig, + strict: boolean, isPreset = false ): Promise<void> { const { isMigrated, migratedConfig } = migrateConfig(config); @@ -30,6 +31,9 @@ async function validate( }, 'Config migration necessary' ); + if (strict) { + returnVal = 1; + } } const massagedConfig = massageConfig(migratedConfig); const res = await validateConfig(massagedConfig, isPreset); @@ -55,6 +59,11 @@ type PackageJson = { }; (async () => { + const strictArgIndex = process.argv.indexOf('--strict'); + const strict = strictArgIndex >= 0; + if (strict) { + process.argv.splice(strictArgIndex); + } if (process.argv.length > 2) { for (const file of process.argv.slice(2)) { try { @@ -66,7 +75,7 @@ type PackageJson = { const parsedContent = await getParsedContent(file); try { logger.info(`Validating ${file}`); - await validate(file, parsedContent); + await validate(file, parsedContent, strict); } catch (err) { logger.warn({ file, err }, 'File is not valid Renovate config'); returnVal = 1; @@ -87,7 +96,7 @@ type PackageJson = { const parsedContent = await getParsedContent(file); try { logger.info(`Validating ${file}`); - await validate(file, parsedContent); + await validate(file, parsedContent, strict); } catch (err) { logger.warn({ file, err }, 'File is not valid Renovate config'); returnVal = 1; @@ -103,12 +112,17 @@ type PackageJson = { ) as PackageJson; if (pkgJson.renovate) { logger.info(`Validating package.json > renovate`); - await validate('package.json > renovate', pkgJson.renovate); + await validate('package.json > renovate', pkgJson.renovate, strict); } if (pkgJson['renovate-config']) { logger.info(`Validating package.json > renovate-config`); for (const presetConfig of Object.values(pkgJson['renovate-config'])) { - await validate('package.json > renovate-config', presetConfig, true); + await validate( + 'package.json > renovate-config', + presetConfig, + strict, + true + ); } } } catch (err) { @@ -120,7 +134,7 @@ type PackageJson = { const file = process.env.RENOVATE_CONFIG_FILE ?? 'config.js'; logger.info(`Validating ${file}`); try { - await validate(file, fileConfig); + await validate(file, fileConfig, strict); } catch (err) { logger.error({ file, err }, 'File is not valid Renovate config'); returnVal = 1;