diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index b1b8a67bd311bc..04eb5a9ac6f512 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -79,9 +79,9 @@ If you want Renovate to run on only a subset of those, use the `autodiscoverFilt ## autodiscoverFilter You can use this option to filter the list of repositories that the Renovate bot account can access through `autodiscover`. -It takes a [minimatch](https://www.npmjs.com/package/minimatch) glob-style pattern. +It takes a [minimatch](https://www.npmjs.com/package/minimatch) glob-style or regex pattern. -e.g. +**Minimatch**: ```json { @@ -89,6 +89,24 @@ e.g. } ``` +**Regex**: + +All text inside the start and end `/` will be treated as a regular expression. + +```json +{ + "autodiscoverFilter": "/project/.*/" +} +``` + +You can negate the regex by putting a `!` in front: + +```json +{ + "autodiscoverFilter": "!/project/.*/" +} +``` + ## baseDir By default Renovate uses a temporary directory like `/tmp/renovate` to store its data. diff --git a/lib/workers/global/autodiscover.spec.ts b/lib/workers/global/autodiscover.spec.ts index 076d179cc3fa9c..deaf9af9f80682 100644 --- a/lib/workers/global/autodiscover.spec.ts +++ b/lib/workers/global/autodiscover.spec.ts @@ -72,4 +72,42 @@ describe('workers/global/autodiscover', () => { const res = await autodiscoverRepositories(config); expect(res).toEqual(config); }); + it('filters autodiscovered github repos with regex', async () => { + config.autodiscover = true; + config.autodiscoverFilter = '/project/re*./'; + config.platform = PlatformId.Github; + hostRules.find = jest.fn(() => ({ + token: 'abc', + })); + ghApi.getRepos = jest.fn(() => + Promise.resolve(['project/repo', 'project/another-repo']) + ); + const res = await autodiscoverRepositories(config); + expect(res.repositories).toEqual(['project/repo']); + }); + it('filters autodiscovered github repos with regex negation', async () => { + config.autodiscover = true; + config.autodiscoverFilter = '!/project/re*./'; + config.platform = PlatformId.Github; + hostRules.find = jest.fn(() => ({ + token: 'abc', + })); + ghApi.getRepos = jest.fn(() => + Promise.resolve(['project/repo', 'project/another-repo']) + ); + const res = await autodiscoverRepositories(config); + expect(res.repositories).toEqual(['project/another-repo']); + }); + it('fail if regex pattern is not valid', async () => { + config.autodiscover = true; + config.autodiscoverFilter = '/project/re**./'; + config.platform = PlatformId.Github; + hostRules.find = jest.fn(() => ({ + token: 'abc', + })); + ghApi.getRepos = jest.fn(() => + Promise.resolve(['project/repo', 'project/another-repo']) + ); + await expect(autodiscoverRepositories(config)).rejects.toThrow(); + }); }); diff --git a/lib/workers/global/autodiscover.ts b/lib/workers/global/autodiscover.ts index 03b66b293acdf0..3a4c7747c6d6cf 100644 --- a/lib/workers/global/autodiscover.ts +++ b/lib/workers/global/autodiscover.ts @@ -3,6 +3,7 @@ import minimatch from 'minimatch'; import type { AllConfig } from '../../config/types'; import { logger } from '../../logger'; import { platform } from '../../platform'; +import { configRegexPredicate, isConfigRegex } from '../../util/regex'; // istanbul ignore next function repoName(value: string | { repository: string }): string { @@ -30,7 +31,19 @@ export async function autodiscoverRepositories( return config; } if (config.autodiscoverFilter) { - discovered = discovered.filter(minimatch.filter(config.autodiscoverFilter)); + if (isConfigRegex(config.autodiscoverFilter)) { + const autodiscoveryPred = configRegexPredicate(config.autodiscoverFilter); + if (!autodiscoveryPred) { + throw new Error( + `Failed to parse regex pattern "${config.autodiscoverFilter}"` + ); + } + discovered = discovered.filter(autodiscoveryPred); + } else { + discovered = discovered.filter( + minimatch.filter(config.autodiscoverFilter) + ); + } if (!discovered.length) { // Soft fail (no error thrown) if no accessible repositories match the filter logger.debug('None of the discovered repositories matched the filter');