diff --git a/lib/config/validation-helpers/match-base-branches.spec.ts b/lib/config/validation-helpers/match-base-branches.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..4386718ed7a409265ad3de0d4649ab8803d57251 --- /dev/null +++ b/lib/config/validation-helpers/match-base-branches.spec.ts @@ -0,0 +1,26 @@ +import { check } from './match-base-branches'; + +describe('config/validation-helpers/match-base-branches', () => { + it('returns error when baseBranches is not defined', () => { + const res = check({ + resolvedRule: { matchBaseBranches: ['develop'], addLabels: ['develop'] }, + currentPath: 'packageRules[0]', + }); + expect(res).toEqual([ + { + topic: 'Configuration Error', + message: + 'packageRules[0]: You must configure baseBranches inorder to use them inside matchBaseBranches.', + }, + ]); + }); + + it('returns empty array for valid configuration', () => { + const res = check({ + resolvedRule: { matchBaseBranches: ['develop'], addLabels: ['develop'] }, + currentPath: 'packageRules[0]', + baseBranches: ['develop', 'main'], + }); + expect(res).toBeEmptyArray(); + }); +}); diff --git a/lib/config/validation-helpers/match-base-branches.ts b/lib/config/validation-helpers/match-base-branches.ts new file mode 100644 index 0000000000000000000000000000000000000000..e64017b2e7f312cb489995121c767d3cc5d4e774 --- /dev/null +++ b/lib/config/validation-helpers/match-base-branches.ts @@ -0,0 +1,24 @@ +import is from '@sindresorhus/is'; +import type { ValidationMessage } from '../types'; +import type { CheckBaseBranchesArgs } from './types'; + +/** + * Only if type condition or context condition violated then errors array will be mutated to store metadata + */ +export function check({ + resolvedRule, + currentPath, + baseBranches, +}: CheckBaseBranchesArgs): ValidationMessage[] { + const warnings: ValidationMessage[] = []; + if (Array.isArray(resolvedRule.matchBaseBranches)) { + if (!is.nonEmptyArray(baseBranches)) { + warnings.push({ + topic: 'Configuration Error', + message: `${currentPath}: You must configure baseBranches inorder to use them inside matchBaseBranches.`, + }); + } + } + + return warnings; +} diff --git a/lib/config/validation-helpers/types.ts b/lib/config/validation-helpers/types.ts index 68e10825820310b09145efcd0da8a1f4b996d788..873f0398212607142f5cd297f4ed0ed3221d5607 100644 --- a/lib/config/validation-helpers/types.ts +++ b/lib/config/validation-helpers/types.ts @@ -9,3 +9,9 @@ export interface CheckMatcherArgs { val: unknown; currentPath: string; } + +export interface CheckBaseBranchesArgs { + resolvedRule: PackageRule; + currentPath: string; + baseBranches?: string[]; +} diff --git a/lib/config/validation.spec.ts b/lib/config/validation.spec.ts index f0bfcda1f90fe288a6b9d7e67f7279018eea6439..39e6d11cea7ad167f01b97788e31860c5f006328 100644 --- a/lib/config/validation.spec.ts +++ b/lib/config/validation.spec.ts @@ -208,6 +208,41 @@ describe('config/validation', () => { expect(errors).toHaveLength(1); }); + it('validates matchBaseBranches', async () => { + const config = { + baseBranches: ['foo'], + packageRules: [ + { + matchBaseBranches: ['foo'], + addLabels: ['foo'], + }, + ], + }; + const { errors, warnings } = await configValidation.validateConfig( + 'repo', + config, + ); + expect(errors).toHaveLength(0); + expect(warnings).toHaveLength(0); + }); + + it('catches invalid matchBaseBranches when baseBranches is not defined', async () => { + const config = { + packageRules: [ + { + matchBaseBranches: ['foo'], + addLabels: ['foo'], + }, + ], + }; + const { errors, warnings } = await configValidation.validateConfig( + 'repo', + config, + ); + expect(errors).toHaveLength(0); + expect(warnings).toHaveLength(1); + }); + it('catches invalid matchCurrentVersion regex', async () => { const config = { packageRules: [ diff --git a/lib/config/validation.ts b/lib/config/validation.ts index f7050c2ac7925fa26c39d218a241be39c3931055..cbc87d6da6f5cf277a3b6439298f528d4ad25dde 100644 --- a/lib/config/validation.ts +++ b/lib/config/validation.ts @@ -35,6 +35,7 @@ import { allowedStatusCheckStrings, } from './types'; import * as managerValidator from './validation-helpers/managers'; +import * as matchBaseBranchesValidator from './validation-helpers/match-base-branches'; import * as regexOrGlobValidator from './validation-helpers/regex-glob-matchers'; const options = getOptions(); @@ -440,6 +441,13 @@ export async function validateConfig( errors.push( ...managerValidator.check({ resolvedRule, currentPath }), ); + warnings.push( + ...matchBaseBranchesValidator.check({ + resolvedRule, + currentPath: `${currentPath}[${subIndex}]`, + baseBranches: config.baseBranches!, + }), + ); const selectorLength = Object.keys(resolvedRule).filter( (ruleKey) => selectors.includes(ruleKey), ).length;