From 530e8cb0364840ab4083c5f20518cd172a377652 Mon Sep 17 00:00:00 2001 From: praveshtora <pravesh.tora@gmail.com> Date: Sun, 14 Jul 2019 11:15:39 +0530 Subject: [PATCH] =?UTF-8?q?feat:=20check=20for=20disabled=20renovate.json?= =?UTF-8?q?=20before=20cloning=20in=20platfo=E2=80=A6=20(#3965)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/config/definitions.js | 9 ++++ lib/platform/github/index.ts | 23 ++++++++++ lib/platform/gitlab/index.ts | 26 ++++++++++++ renovate-schema.json | 5 +++ test/platform/github/index.spec.ts | 27 ++++++++++++ test/platform/gitlab/index.spec.ts | 52 +++++++++++++++++++++-- website/docs/self-hosted-configuration.md | 2 + 7 files changed, 140 insertions(+), 4 deletions(-) diff --git a/lib/config/definitions.js b/lib/config/definitions.js index 28ccdc25b3..909f67ccf5 100644 --- a/lib/config/definitions.js +++ b/lib/config/definitions.js @@ -165,6 +165,15 @@ const options = [ default: true, admin: true, }, + { + name: 'optimizeForDisabled', + description: + 'Set to true to first check for disabling in config before cloning', + stage: 'repository', + type: 'boolean', + default: false, + admin: true, + }, // Master Issue { name: 'masterIssue', diff --git a/lib/platform/github/index.ts b/lib/platform/github/index.ts index eb54fd4d7e..c90bdde9f9 100644 --- a/lib/platform/github/index.ts +++ b/lib/platform/github/index.ts @@ -147,6 +147,7 @@ export async function initRepo({ localDir, includeForks, renovateUsername, + optimizeForDisabled, }: { endpoint: string; repository: string; @@ -156,6 +157,7 @@ export async function initRepo({ localDir: string; includeForks: boolean; renovateUsername: string; + optimizeForDisabled: boolean; }) { logger.debug(`initRepo("${repository}")`); logger.info('Authenticated as user: ' + renovateUsername); @@ -218,6 +220,24 @@ export async function initRepo({ ); throw new Error('archived'); } + if (optimizeForDisabled) { + let renovateConfig; + try { + renovateConfig = JSON.parse( + Buffer.from( + (await api.get( + `repos/${config.repository}/contents/${defaultConfigFile}` + )).body.content, + 'base64' + ).toString() + ); + } catch (err) { + // Do nothing + } + if (renovateConfig && renovateConfig.enabled === false) { + throw new Error('disabled'); + } + } platformConfig.privateRepo = res.body.private === true; platformConfig.isFork = res.body.fork === true; const owner = res.body.owner.login; @@ -255,6 +275,9 @@ export async function initRepo({ if (err.message === 'fork') { throw err; } + if (err.message === 'disabled') { + throw err; + } if (err.message === 'Response code 451 (Unavailable for Legal Reasons)') { throw new Error('forbidden'); } diff --git a/lib/platform/gitlab/index.ts b/lib/platform/gitlab/index.ts index 7976b1142b..4dd429a43e 100644 --- a/lib/platform/gitlab/index.ts +++ b/lib/platform/gitlab/index.ts @@ -5,7 +5,9 @@ import { api } from './gl-got-wrapper'; import * as hostRules from '../../util/host-rules'; import GitStorage from '../git/storage'; import { PlatformConfig } from '../common'; +import { configFileNames } from '../../config/app-strings'; +const defaultConfigFile = configFileNames[0]; let config: { storage: GitStorage; repository: string; @@ -15,6 +17,7 @@ let config: { email: string; prList: any[]; issueList: any[]; + optimizeForDisabled: boolean; } = {} as any; const defaults = { @@ -90,9 +93,11 @@ export function cleanRepo() { export async function initRepo({ repository, localDir, + optimizeForDisabled, }: { repository: string; localDir: string; + optimizeForDisabled: boolean; }) { config = {} as any; config.repository = urlEscape(repository); @@ -116,6 +121,24 @@ export async function initRepo({ if (res.body.default_branch === null) { throw new Error('empty'); } + if (optimizeForDisabled) { + let renovateConfig; + try { + renovateConfig = JSON.parse( + Buffer.from( + (await api.get( + `projects/${config.repository}/repository/files/${defaultConfigFile}?ref=${res.body.default_branch}` + )).body.content, + 'base64' + ).toString() + ); + } catch (err) { + // Do nothing + } + if (renovateConfig && renovateConfig.enabled === false) { + throw new Error('disabled'); + } + } config.defaultBranch = res.body.default_branch; config.baseBranch = config.defaultBranch; platformConfig.isFork = !!res.body.forked_from_project; @@ -164,6 +187,9 @@ export async function initRepo({ if (err.statusCode === 404) { throw new Error('not-found'); } + if (err.message === 'disabled') { + throw err; + } logger.info({ err }, 'Unknown GitLab initRepo error'); throw err; } diff --git a/renovate-schema.json b/renovate-schema.json index 88d7094a7e..52868c23f5 100644 --- a/renovate-schema.json +++ b/renovate-schema.json @@ -101,6 +101,11 @@ "type": "boolean", "default": true }, + "optimizeForDisabled": { + "description": "Set to true to first check for disabling in config before cloning", + "type": "boolean", + "default": false + }, "masterIssue": { "description": "Whether to create a \"Master Issue\" within the repository.", "type": "boolean", diff --git a/test/platform/github/index.spec.ts b/test/platform/github/index.spec.ts index 8bb25bce85..92e886f0d2 100644 --- a/test/platform/github/index.spec.ts +++ b/test/platform/github/index.spec.ts @@ -192,6 +192,33 @@ describe('platform/github', () => { } describe('initRepo', () => { + it('should throw err if disabled in renovate.json', async () => { + // repo info + api.get.mockImplementationOnce( + () => + ({ + body: { + owner: { + login: 'theowner', + }, + }, + } as any) + ); + api.get.mockImplementationOnce( + () => + ({ + body: { + content: Buffer.from('{"enabled": false}').toString('base64'), + }, + } as any) + ); + await expect( + github.initRepo({ + repository: 'some/repo', + optimizeForDisabled: true, + } as any) + ).rejects.toThrow('disabled'); + }); it('should rebase', async () => { function squashInitRepo(args: any) { // repo info diff --git a/test/platform/gitlab/index.spec.ts b/test/platform/gitlab/index.spec.ts index 104212f266..022c93c81d 100644 --- a/test/platform/gitlab/index.spec.ts +++ b/test/platform/gitlab/index.spec.ts @@ -147,6 +147,7 @@ describe('platform/gitlab', () => { }, } as any) ); + // getBranchCommit // user api.get.mockImplementationOnce( () => @@ -162,10 +163,37 @@ describe('platform/gitlab', () => { return gitlab.initRepo({ repository: 'some/repo', localDir: '', + optimizeForDisabled: false, }); } describe('initRepo', () => { + it(`should throw error if disabled in renovate.json`, async () => { + api.get.mockImplementationOnce( + () => + ({ + body: { + default_branch: 'master', + http_url_to_repo: 'https://gitlab.com/some/repo.git', + }, + } as any) + ); + api.get.mockImplementationOnce( + () => + ({ + body: { + content: Buffer.from('{"enabled": false}').toString('base64'), + }, + } as any) + ); + await expect( + gitlab.initRepo({ + repository: 'some/repo', + localDir: '', + optimizeForDisabled: true, + }) + ).rejects.toThrow(Error('disabled')); + }); it(`should escape all forward slashes in project names`, async () => { api.get.mockReturnValue({ body: [] } as any); await initRepo({ repository: 'some/repo/project', token: 'some-token' }); @@ -176,25 +204,41 @@ describe('platform/gitlab', () => { throw new Error('always error'); }); await expect( - gitlab.initRepo({ repository: 'some/repo', localDir: '' }) + gitlab.initRepo({ + repository: 'some/repo', + localDir: '', + optimizeForDisabled: false, + }) ).rejects.toThrow(Error('always error')); }); it('should throw an error if repository is archived', async () => { api.get.mockReturnValue({ body: { archived: true } } as any); await expect( - gitlab.initRepo({ repository: 'some/repo', localDir: '' }) + gitlab.initRepo({ + repository: 'some/repo', + localDir: '', + optimizeForDisabled: false, + }) ).rejects.toThrow(Error('archived')); }); it('should throw an error if repository is a mirror', async () => { api.get.mockReturnValue({ body: { mirror: true } } as any); await expect( - gitlab.initRepo({ repository: 'some/repo', localDir: '' }) + gitlab.initRepo({ + repository: 'some/repo', + localDir: '', + optimizeForDisabled: false, + }) ).rejects.toThrow(Error('mirror')); }); it('should throw an error if repository is empty', async () => { api.get.mockReturnValue({ body: { default_branch: null } } as any); await expect( - gitlab.initRepo({ repository: 'some/repo', localDir: '' }) + gitlab.initRepo({ + repository: 'some/repo', + localDir: '', + optimizeForDisabled: false, + }) ).rejects.toThrow(Error('empty')); }); it('should fall back if http_url_to_repo is empty', async () => { diff --git a/website/docs/self-hosted-configuration.md b/website/docs/self-hosted-configuration.md index 53d2bc5b03..a33cd7a386 100644 --- a/website/docs/self-hosted-configuration.md +++ b/website/docs/self-hosted-configuration.md @@ -64,6 +64,8 @@ Set this to `false` if (a) you configure Renovate entirely on the bot side (i.e. ## onboardingConfig +## optimizeForDisabled + ## password ## persistRepoData -- GitLab