From 4b6de0f485912f67a1b79d61267a492e82bbcf29 Mon Sep 17 00:00:00 2001
From: Nick Oliver <github@pixnbits.org>
Date: Sat, 16 Mar 2019 22:49:39 -0700
Subject: [PATCH] feat(autodiscover): add autodiscoverFilter option (#3394)

adds a `autodiscoverFilter` option which can be a [minimatch](https://www.npmjs.com/package/minimatch) glob-style pattern for filtering `autodiscover`ed repositories. Ex: `project/*`

Closes #3341
---
 lib/config/definitions.js                 |  7 +++++++
 lib/workers/global/autodiscover.js        | 11 +++++++++-
 test/workers/global/autodiscover.spec.js  | 25 +++++++++++++++++++++++
 website/docs/self-hosted-configuration.md |  6 +++++-
 4 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/lib/config/definitions.js b/lib/config/definitions.js
index a40f8b686d..338b195df9 100644
--- a/lib/config/definitions.js
+++ b/lib/config/definitions.js
@@ -287,6 +287,13 @@ const options = [
     type: 'boolean',
     default: false,
   },
+  {
+    name: 'autodiscoverFilter',
+    description: 'Filter the list of autodiscovered repositories',
+    stage: 'global',
+    type: 'string',
+    default: null,
+  },
   {
     name: 'repositories',
     description: 'List of Repositories',
diff --git a/lib/workers/global/autodiscover.js b/lib/workers/global/autodiscover.js
index 3480958f46..92eaf2d020 100644
--- a/lib/workers/global/autodiscover.js
+++ b/lib/workers/global/autodiscover.js
@@ -1,4 +1,5 @@
 const is = require('@sindresorhus/is');
+const minimatch = require('minimatch');
 const { getPlatformApi } = require('../../platform');
 const hostRules = require('../../util/host-rules');
 
@@ -12,7 +13,7 @@ async function autodiscoverRepositories(config) {
   }
   const credentials = hostRules.find(config, {});
   // Autodiscover list of repositories
-  const discovered = await getPlatformApi(config.platform).getRepos(
+  let discovered = await getPlatformApi(config.platform).getRepos(
     credentials.token,
     credentials.endpoint
   );
@@ -23,6 +24,14 @@ async function autodiscoverRepositories(config) {
     );
     return config;
   }
+  if (config.autodiscoverFilter) {
+    discovered = discovered.filter(minimatch.filter(config.autodiscoverFilter));
+    if (!discovered.length) {
+      // Soft fail (no error thrown) if no accessible repositories match the filter
+      logger.info('None of the discovered repositories matched the filter');
+      return config;
+    }
+  }
   logger.info(`Discovered ${discovered.length} repositories`);
   // istanbul ignore if
   if (config.repositories && config.repositories.length) {
diff --git a/test/workers/global/autodiscover.spec.js b/test/workers/global/autodiscover.spec.js
index ab85dce180..c123c2bca1 100644
--- a/test/workers/global/autodiscover.spec.js
+++ b/test/workers/global/autodiscover.spec.js
@@ -34,4 +34,29 @@ describe('lib/workers/global/autodiscover', () => {
     const res = await autodiscoverRepositories(config);
     expect(res.repositories).toHaveLength(2);
   });
+  it('filters autodiscovered github repos', async () => {
+    config.autodiscover = true;
+    config.autodiscoverFilter = 'project/re*';
+    config.platform = 'github';
+    hostRules.find = jest.fn(() => ({
+      token: 'abc',
+    }));
+    ghApi.getRepos = jest.fn(() => ['project/repo', 'project/another-repo']);
+    const res = await autodiscoverRepositories(config);
+    expect(res.repositories).toEqual(['project/repo']);
+  });
+  it('filters autodiscovered github repos but nothing matches', async () => {
+    config.autodiscover = true;
+    config.autodiscoverFilter = 'project/re*';
+    config.platform = 'github';
+    hostRules.find = jest.fn(() => ({
+      token: 'abc',
+    }));
+    ghApi.getRepos = jest.fn(() => [
+      'another-project/repo',
+      'another-project/another-repo',
+    ]);
+    const res = await autodiscoverRepositories(config);
+    expect(res).toEqual(config);
+  });
 });
diff --git a/website/docs/self-hosted-configuration.md b/website/docs/self-hosted-configuration.md
index d20359d08d..57d4d082e0 100644
--- a/website/docs/self-hosted-configuration.md
+++ b/website/docs/self-hosted-configuration.md
@@ -9,7 +9,11 @@ The below configuration options are applicable only if you are running your own
 
 ## autodiscover
 
-Be cautious when using this option - it will run Renovate over _every_ repository that the bot account has access to.
+Be cautious when using this option - it will run Renovate over _every_ repository that the bot account has access to. To filter this list, use `autodiscoverFilter`.
+
+## autodiscoverFilter
+
+A [minimatch](https://www.npmjs.com/package/minimatch) glob-style pattern for filtering `autodiscover`ed repositories. Ex: `project/*`
 
 ## binarySource
 
-- 
GitLab