From 517f5ecfb91ce3473da6c87cc0ae0cdddcb92c2c Mon Sep 17 00:00:00 2001 From: Sergio Zharinov Date: Fri, 2 Oct 2020 13:57:52 +0400 Subject: [PATCH] refactor(platform): move optimizeForDisabled, isFork logic to worker layer (#7379) Co-authored-by: Michael Kriese Co-authored-by: Rhys Arkins --- lib/platform/azure/index.spec.ts | 28 +- lib/platform/azure/index.ts | 19 +- .../__snapshots__/index.spec.ts.snap | 304 ++++++++++++++---- lib/platform/bitbucket-server/index.spec.ts | 78 +++-- lib/platform/bitbucket-server/index.ts | 15 +- .../__snapshots__/index.spec.ts.snap | 81 +++-- lib/platform/bitbucket/index.spec.ts | 48 ++- lib/platform/bitbucket/index.ts | 19 +- lib/platform/common.ts | 1 - lib/platform/gitea/index.spec.ts | 33 +- lib/platform/gitea/index.ts | 19 +- .../github/__snapshots__/index.spec.ts.snap | 153 ++++++--- lib/platform/github/index.spec.ts | 44 ++- lib/platform/github/index.ts | 20 +- .../gitlab/__snapshots__/index.spec.ts.snap | 81 +++-- lib/platform/gitlab/index.spec.ts | 62 ++-- lib/platform/gitlab/index.ts | 12 +- lib/workers/repository/init/apis.spec.ts | 40 ++- lib/workers/repository/init/apis.ts | 29 ++ 19 files changed, 686 insertions(+), 400 deletions(-) diff --git a/lib/platform/azure/index.spec.ts b/lib/platform/azure/index.spec.ts index b03401cdd0e80d..0860c238dc8f04 100644 --- a/lib/platform/azure/index.spec.ts +++ b/lib/platform/azure/index.spec.ts @@ -1,6 +1,5 @@ import is from '@sindresorhus/is'; import { PullRequestStatus } from 'azure-devops-node-api/interfaces/GitInterfaces'; -import { REPOSITORY_DISABLED } from '../../constants/error-messages'; import { BranchStatus, PrState } from '../../types'; import * as _git from '../../util/git'; import * as _hostRules from '../../util/host-rules'; @@ -162,14 +161,6 @@ describe('platform/azure', () => { expect(azureApi.gitApi.mock.calls).toMatchSnapshot(); expect(config).toMatchSnapshot(); }); - - it('throws disabled', async () => { - expect.assertions(1); - azureHelper.getFile.mockResolvedValueOnce('{ "enabled": false }'); - await expect( - initRepo({ repository: 'some-repo', optimizeForDisabled: true }) - ).rejects.toThrow(REPOSITORY_DISABLED); - }); }); describe('getRepoForceRebase', () => { @@ -816,4 +807,23 @@ describe('platform/azure', () => { expect(azureApi.gitApi.mock.calls).toMatchSnapshot(); }); }); + describe('getJsonFile()', () => { + it('returns file content', async () => { + const data = { foo: 'bar' }; + azureHelper.getFile.mockResolvedValueOnce(JSON.stringify(data)); + await initRepo({ + repository: 'some-repo', + }); + const res = await azure.getJsonFile('file.json'); + expect(res).toEqual(data); + }); + it('returns null on errors', async () => { + azureHelper.getFile.mockRejectedValueOnce('some error'); + await initRepo({ + repository: 'some-repo', + }); + const res = await azure.getJsonFile('file.json'); + expect(res).toBeNull(); + }); + }); }); diff --git a/lib/platform/azure/index.ts b/lib/platform/azure/index.ts index 6244e98871e024..55411c32f5b818 100644 --- a/lib/platform/azure/index.ts +++ b/lib/platform/azure/index.ts @@ -5,10 +5,7 @@ import { GitPullRequestMergeStrategy, PullRequestStatus, } from 'azure-devops-node-api/interfaces/GitInterfaces'; -import { - REPOSITORY_DISABLED, - REPOSITORY_EMPTY, -} from '../../constants/error-messages'; +import { REPOSITORY_EMPTY } from '../../constants/error-messages'; import { PLATFORM_TYPE_AZURE } from '../../constants/platforms'; import { logger } from '../../logger'; import { BranchStatus, PrState } from '../../types'; @@ -109,7 +106,7 @@ export async function getJsonFile(fileName: string): Promise { config.defaultBranch ); return JSON.parse(json); - } catch (err) /* istanbul ignore next */ { + } catch (err) { return null; } } @@ -117,7 +114,6 @@ export async function getJsonFile(fileName: string): Promise { export async function initRepo({ repository, localDir, - optimizeForDisabled, }: RepoParams): Promise { logger.debug(`initRepo("${repository}")`); config = { repository } as Config; @@ -145,17 +141,6 @@ export async function initRepo({ config.mergeMethod = await azureHelper.getMergeMethod(repo.id, names.project); config.repoForceRebase = false; - if (optimizeForDisabled) { - interface RenovateConfig { - enabled: boolean; - } - - const renovateConfig: RenovateConfig = await getJsonFile('renovate.json'); - if (renovateConfig && renovateConfig.enabled === false) { - throw new Error(REPOSITORY_DISABLED); - } - } - const [projectName, repoName] = repository.split('/'); const opts = hostRules.find({ hostType: defaults.hostType, diff --git a/lib/platform/bitbucket-server/__snapshots__/index.spec.ts.snap b/lib/platform/bitbucket-server/__snapshots__/index.spec.ts.snap index 1b8061e8ce02bc..4b75af9a009e02 100644 --- a/lib/platform/bitbucket-server/__snapshots__/index.spec.ts.snap +++ b/lib/platform/bitbucket-server/__snapshots__/index.spec.ts.snap @@ -1820,6 +1820,129 @@ Array [ ] `; +exports[`platform/bitbucket-server/index endpoint with no path getJsonFile() returns file content 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/rest/api/1.0/projects/SOME/repos/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/rest/api/1.0/projects/SOME/repos/repo/branches/default", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/rest/api/1.0/projects/SOME/repos/repo/browse/file.json?limit=20000", + }, +] +`; + +exports[`platform/bitbucket-server/index endpoint with no path getJsonFile() returns null for long content 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/rest/api/1.0/projects/SOME/repos/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/rest/api/1.0/projects/SOME/repos/repo/branches/default", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/rest/api/1.0/projects/SOME/repos/repo/browse/file.json?limit=20000", + }, +] +`; + +exports[`platform/bitbucket-server/index endpoint with no path getJsonFile() returns null on errors 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/rest/api/1.0/projects/SOME/repos/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/rest/api/1.0/projects/SOME/repos/repo/branches/default", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/rest/api/1.0/projects/SOME/repos/repo/browse/file.json?limit=20000", + }, +] +`; + exports[`platform/bitbucket-server/index endpoint with no path getPr() canRebase 1`] = ` Object { "body": "* Line 1 @@ -2222,18 +2345,6 @@ Object { exports[`platform/bitbucket-server/index endpoint with no path initRepo() does not throw 2`] = ` Array [ - Object { - "headers": Object { - "accept": "application/json", - "accept-encoding": "gzip, deflate", - "authorization": "Basic YWJjOjEyMw==", - "host": "stash.renovatebot.com", - "user-agent": "https://github.com/renovatebot/renovate", - "x-atlassian-token": "no-check", - }, - "method": "GET", - "url": "https://stash.renovatebot.com/rest/api/1.0/projects/SOME/repos/repo/browse/renovate.json?limit=20000", - }, Object { "headers": Object { "accept": "application/json", @@ -2261,23 +2372,6 @@ Array [ ] `; -exports[`platform/bitbucket-server/index endpoint with no path initRepo() throws disabled 1`] = ` -Array [ - Object { - "headers": Object { - "accept": "application/json", - "accept-encoding": "gzip, deflate", - "authorization": "Basic YWJjOjEyMw==", - "host": "stash.renovatebot.com", - "user-agent": "https://github.com/renovatebot/renovate", - "x-atlassian-token": "no-check", - }, - "method": "GET", - "url": "https://stash.renovatebot.com/rest/api/1.0/projects/SOME/repos/repo/browse/renovate.json?limit=20000", - }, -] -`; - exports[`platform/bitbucket-server/index endpoint with no path initRepo() throws empty 1`] = ` Array [ Object { @@ -5567,6 +5661,129 @@ Array [ ] `; +exports[`platform/bitbucket-server/index endpoint with path getJsonFile() returns file content 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/vcs/rest/api/1.0/projects/SOME/repos/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/vcs/rest/api/1.0/projects/SOME/repos/repo/branches/default", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/vcs/rest/api/1.0/projects/SOME/repos/repo/browse/file.json?limit=20000", + }, +] +`; + +exports[`platform/bitbucket-server/index endpoint with path getJsonFile() returns null for long content 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/vcs/rest/api/1.0/projects/SOME/repos/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/vcs/rest/api/1.0/projects/SOME/repos/repo/branches/default", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/vcs/rest/api/1.0/projects/SOME/repos/repo/browse/file.json?limit=20000", + }, +] +`; + +exports[`platform/bitbucket-server/index endpoint with path getJsonFile() returns null on errors 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/vcs/rest/api/1.0/projects/SOME/repos/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/vcs/rest/api/1.0/projects/SOME/repos/repo/branches/default", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "stash.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + "x-atlassian-token": "no-check", + }, + "method": "GET", + "url": "https://stash.renovatebot.com/vcs/rest/api/1.0/projects/SOME/repos/repo/browse/file.json?limit=20000", + }, +] +`; + exports[`platform/bitbucket-server/index endpoint with path getPr() canRebase 1`] = ` Object { "body": "* Line 1 @@ -5969,18 +6186,6 @@ Object { exports[`platform/bitbucket-server/index endpoint with path initRepo() does not throw 2`] = ` Array [ - Object { - "headers": Object { - "accept": "application/json", - "accept-encoding": "gzip, deflate", - "authorization": "Basic YWJjOjEyMw==", - "host": "stash.renovatebot.com", - "user-agent": "https://github.com/renovatebot/renovate", - "x-atlassian-token": "no-check", - }, - "method": "GET", - "url": "https://stash.renovatebot.com/vcs/rest/api/1.0/projects/SOME/repos/repo/browse/renovate.json?limit=20000", - }, Object { "headers": Object { "accept": "application/json", @@ -6008,23 +6213,6 @@ Array [ ] `; -exports[`platform/bitbucket-server/index endpoint with path initRepo() throws disabled 1`] = ` -Array [ - Object { - "headers": Object { - "accept": "application/json", - "accept-encoding": "gzip, deflate", - "authorization": "Basic YWJjOjEyMw==", - "host": "stash.renovatebot.com", - "user-agent": "https://github.com/renovatebot/renovate", - "x-atlassian-token": "no-check", - }, - "method": "GET", - "url": "https://stash.renovatebot.com/vcs/rest/api/1.0/projects/SOME/repos/repo/browse/renovate.json?limit=20000", - }, -] -`; - exports[`platform/bitbucket-server/index endpoint with path initRepo() throws empty 1`] = ` Array [ Object { diff --git a/lib/platform/bitbucket-server/index.spec.ts b/lib/platform/bitbucket-server/index.spec.ts index ca2847e1fc6d4d..6689a5b13240ff 100644 --- a/lib/platform/bitbucket-server/index.spec.ts +++ b/lib/platform/bitbucket-server/index.spec.ts @@ -3,7 +3,6 @@ import * as httpMock from '../../../test/httpMock'; import { getName } from '../../../test/util'; import { REPOSITORY_CHANGED, - REPOSITORY_DISABLED, REPOSITORY_EMPTY, REPOSITORY_NOT_FOUND, } from '../../constants/error-messages'; @@ -167,7 +166,6 @@ describe(getName(__filename), () => { endpoint: 'https://stash.renovatebot.com/vcs/', repository: 'SOME/repo', localDir: '', - optimizeForDisabled: false, ...config, }); return scope; @@ -264,7 +262,6 @@ describe(getName(__filename), () => { endpoint: 'https://stash.renovatebot.com/vcs/', repository: 'SOME/repo', localDir: '', - optimizeForDisabled: false, }) ).toMatchSnapshot(); expect(httpMock.getTrace()).toMatchSnapshot(); @@ -280,20 +277,11 @@ describe(getName(__filename), () => { ) .reply(200, { displayId: 'master', - }) - .get( - `${urlPath}/rest/api/1.0/projects/SOME/repos/repo/browse/renovate.json?limit=20000` - ) - .reply(200, { - isLastPage: false, - lines: [{ text: '{' }], - size: 50000, }); const res = await bitbucket.initRepo({ endpoint: 'https://stash.renovatebot.com/vcs/', repository: 'SOME/repo', localDir: '', - optimizeForDisabled: true, }); expect(res).toMatchSnapshot(); expect(httpMock.getTrace()).toMatchSnapshot(); @@ -314,33 +302,10 @@ describe(getName(__filename), () => { endpoint: 'https://stash.renovatebot.com/vcs/', repository: 'SOME/repo', localDir: '', - optimizeForDisabled: false, }) ).rejects.toThrow(REPOSITORY_EMPTY); expect(httpMock.getTrace()).toMatchSnapshot(); }); - - it('throws disabled', async () => { - expect.assertions(2); - httpMock - .scope(urlHost) - .get( - `${urlPath}/rest/api/1.0/projects/SOME/repos/repo/browse/renovate.json?limit=20000` - ) - .reply(200, { - isLastPage: true, - lines: [{ text: '{ "enabled": false' }, { text: '}' }], - }); - await expect( - bitbucket.initRepo({ - endpoint: 'https://stash.renovatebot.com/vcs/', - repository: 'SOME/repo', - localDir: '', - optimizeForDisabled: true, - }) - ).rejects.toThrow(REPOSITORY_DISABLED); - expect(httpMock.getTrace()).toMatchSnapshot(); - }); }); describe('repoForceRebase()', () => { @@ -1925,6 +1890,49 @@ Followed by some information. expect(httpMock.getTrace()).toMatchSnapshot(); }); }); + + describe('getJsonFile()', () => { + it('returns file content', async () => { + const data = { foo: 'bar' }; + const scope = await initRepo(); + scope + .get( + `${urlPath}/rest/api/1.0/projects/SOME/repos/repo/browse/file.json?limit=20000` + ) + .reply(200, { + isLastPage: true, + lines: [{ text: JSON.stringify(data) }], + }); + const res = await bitbucket.getJsonFile('file.json'); + expect(res).toEqual(data); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + it('returns null for long content', async () => { + const scope = await initRepo(); + scope + .get( + `${urlPath}/rest/api/1.0/projects/SOME/repos/repo/browse/file.json?limit=20000` + ) + .reply(200, { + isLastPage: false, + lines: [{ text: '{' }], + }); + const res = await bitbucket.getJsonFile('file.json'); + expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + it('returns null on errors', async () => { + const scope = await initRepo(); + scope + .get( + `${urlPath}/rest/api/1.0/projects/SOME/repos/repo/browse/file.json?limit=20000` + ) + .replyWithError('some error'); + const res = await bitbucket.getJsonFile('file.json'); + expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + }); }); }); }); diff --git a/lib/platform/bitbucket-server/index.ts b/lib/platform/bitbucket-server/index.ts index d048e4fcf2e534..4d709dab20ef96 100644 --- a/lib/platform/bitbucket-server/index.ts +++ b/lib/platform/bitbucket-server/index.ts @@ -4,7 +4,6 @@ import delay from 'delay'; import type { PartialDeep } from 'type-fest'; import { REPOSITORY_CHANGED, - REPOSITORY_DISABLED, REPOSITORY_EMPTY, REPOSITORY_NOT_FOUND, } from '../../constants/error-messages'; @@ -123,7 +122,7 @@ export async function getJsonFile(fileName: string): Promise { } else { return JSON.parse(body.lines.map((l) => l.text).join('')); } - } catch (err) /* istanbul ignore next */ { + } catch (err) { // no-op } return null; @@ -133,7 +132,6 @@ export async function getJsonFile(fileName: string): Promise { export async function initRepo({ repository, localDir, - optimizeForDisabled, }: RepoParams): Promise { logger.debug( `initRepo("${JSON.stringify({ repository, localDir }, null, 2)}")` @@ -153,17 +151,6 @@ export async function initRepo({ username: opts.username, } as any; - if (optimizeForDisabled) { - interface RenovateConfig { - enabled: boolean; - } - - const renovateConfig: RenovateConfig = await getJsonFile('renovate.json'); - if (renovateConfig && renovateConfig.enabled === false) { - throw new Error(REPOSITORY_DISABLED); - } - } - const { host, pathname } = url.parse(defaults.endpoint); const gitUrl = git.getUrl({ protocol: defaults.endpoint.split(':')[0] as GitProtocol, diff --git a/lib/platform/bitbucket/__snapshots__/index.spec.ts.snap b/lib/platform/bitbucket/__snapshots__/index.spec.ts.snap index 6127836ed45001..7a04b76efda853 100644 --- a/lib/platform/bitbucket/__snapshots__/index.spec.ts.snap +++ b/lib/platform/bitbucket/__snapshots__/index.spec.ts.snap @@ -806,6 +806,60 @@ Array [ ] `; +exports[`platform/bitbucket getJsonFile() returns file content 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/src/master/file.json", + }, +] +`; + +exports[`platform/bitbucket getJsonFile() returns null on errors 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/src/master/file.json", + }, +] +`; + exports[`platform/bitbucket getPr() canRebase 1`] = ` Object { "body": "summary", @@ -1062,33 +1116,6 @@ Object { } `; -exports[`platform/bitbucket initRepo() throws disabled 1`] = ` -Array [ - Object { - "headers": Object { - "accept": "application/json", - "accept-encoding": "gzip, deflate", - "authorization": "Basic YWJjOjEyMw==", - "host": "api.bitbucket.org", - "user-agent": "https://github.com/renovatebot/renovate", - }, - "method": "GET", - "url": "https://api.bitbucket.org/2.0/repositories/some/empty", - }, - Object { - "headers": Object { - "accept": "application/json", - "accept-encoding": "gzip, deflate", - "authorization": "Basic YWJjOjEyMw==", - "host": "api.bitbucket.org", - "user-agent": "https://github.com/renovatebot/renovate", - }, - "method": "GET", - "url": "https://api.bitbucket.org/2.0/repositories/some/empty/src/master/renovate.json", - }, -] -`; - exports[`platform/bitbucket initRepo() works 1`] = ` Object { "defaultBranch": "master", diff --git a/lib/platform/bitbucket/index.spec.ts b/lib/platform/bitbucket/index.spec.ts index 7ff31450521bf0..13cdab170282f2 100644 --- a/lib/platform/bitbucket/index.spec.ts +++ b/lib/platform/bitbucket/index.spec.ts @@ -1,6 +1,5 @@ import nock from 'nock'; import * as httpMock from '../../../test/httpMock'; -import { REPOSITORY_DISABLED } from '../../constants/error-messages'; import { logger as _logger } from '../../logger'; import { BranchStatus, PrState } from '../../types'; import * as _git from '../../util/git'; @@ -82,7 +81,6 @@ describe('platform/bitbucket', () => { await bitbucket.initRepo({ repository: 'some/repo', localDir: '', - optimizeForDisabled: false, ...config, }); @@ -148,34 +146,10 @@ describe('platform/bitbucket', () => { await bitbucket.initRepo({ repository: 'some/repo', localDir: '', - optimizeForDisabled: false, }) ).toMatchSnapshot(); expect(httpMock.getTrace()).toMatchSnapshot(); }); - - it('throws disabled', async () => { - expect.assertions(2); - httpMock - .scope(baseUrl) - .get('/2.0/repositories/some/empty') - .reply(200, { owner: {}, mainbranch: { name: 'master' } }) - .get('/2.0/repositories/some/empty/src/master/renovate.json') - .reply( - 200, - JSON.stringify({ - enabled: false, - }) - ); - await expect( - bitbucket.initRepo({ - repository: 'some/empty', - optimizeForDisabled: true, - localDir: '', - }) - ).rejects.toThrow(REPOSITORY_DISABLED); - expect(httpMock.getTrace()).toMatchSnapshot(); - }); }); describe('getRepoForceRebase()', () => { @@ -816,4 +790,26 @@ describe('platform/bitbucket', () => { expect(await bitbucket.getVulnerabilityAlerts()).toEqual([]); }); }); + + describe('getJsonFile()', () => { + it('returns file content', async () => { + const data = { foo: 'bar' }; + const scope = await initRepoMock(); + scope + .get('/2.0/repositories/some/repo/src/master/file.json') + .reply(200, JSON.stringify(data)); + const res = await bitbucket.getJsonFile('file.json'); + expect(res).toEqual(data); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + it('returns null on errors', async () => { + const scope = await initRepoMock(); + scope + .get('/2.0/repositories/some/repo/src/master/file.json') + .replyWithError('some error'); + const res = await bitbucket.getJsonFile('file.json'); + expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + }); }); diff --git a/lib/platform/bitbucket/index.ts b/lib/platform/bitbucket/index.ts index 1739bdc6fe94b9..651454a3d24303 100644 --- a/lib/platform/bitbucket/index.ts +++ b/lib/platform/bitbucket/index.ts @@ -1,10 +1,7 @@ import URL from 'url'; import is from '@sindresorhus/is'; import parseDiff from 'parse-diff'; -import { - REPOSITORY_DISABLED, - REPOSITORY_NOT_FOUND, -} from '../../constants/error-messages'; +import { REPOSITORY_NOT_FOUND } from '../../constants/error-messages'; import { PLATFORM_TYPE_BITBUCKET } from '../../constants/platforms'; import { logger } from '../../logger'; import { BranchStatus, PrState } from '../../types'; @@ -110,7 +107,7 @@ export async function getJsonFile(fileName: string): Promise { `/2.0/repositories/${config.repository}/src/${config.defaultBranch}/${fileName}` ) ).body; - } catch (err) /* istanbul ignore next */ { + } catch (err) { return null; } } @@ -119,7 +116,6 @@ export async function getJsonFile(fileName: string): Promise { export async function initRepo({ repository, localDir, - optimizeForDisabled, }: RepoParams): Promise { logger.debug(`initRepo("${repository}")`); const opts = hostRules.find({ @@ -141,17 +137,6 @@ export async function initRepo({ ); config.defaultBranch = info.mainbranch; - if (optimizeForDisabled) { - interface RenovateConfig { - enabled: boolean; - } - - const renovateConfig: RenovateConfig = await getJsonFile('renovate.json'); - if (renovateConfig && renovateConfig.enabled === false) { - throw new Error(REPOSITORY_DISABLED); - } - } - Object.assign(config, { owner: info.owner, mergeMethod: info.mergeMethod, diff --git a/lib/platform/common.ts b/lib/platform/common.ts index 74cc54a0aace4e..a858aa15ed656b 100644 --- a/lib/platform/common.ts +++ b/lib/platform/common.ts @@ -34,7 +34,6 @@ export interface RepoResult { export interface RepoParams { localDir: string; - optimizeForDisabled: boolean; repository: string; endpoint?: string; forkMode?: string; diff --git a/lib/platform/gitea/index.spec.ts b/lib/platform/gitea/index.spec.ts index 6741556f879fc0..090bd901a753b3 100644 --- a/lib/platform/gitea/index.spec.ts +++ b/lib/platform/gitea/index.spec.ts @@ -5,7 +5,6 @@ import { REPOSITORY_ARCHIVED, REPOSITORY_BLOCKED, REPOSITORY_CHANGED, - REPOSITORY_DISABLED, REPOSITORY_EMPTY, REPOSITORY_MIRRORED, } from '../../constants/error-messages'; @@ -174,7 +173,6 @@ describe('platform/gitea', () => { return gitea.initRepo({ repository: mockRepo.full_name, localDir: '', - optimizeForDisabled: false, ...config, }); } @@ -242,7 +240,6 @@ describe('platform/gitea', () => { const initRepoCfg: RepoParams = { repository: mockRepo.full_name, localDir: '', - optimizeForDisabled: false, }; it('should propagate API errors', async () => { @@ -251,18 +248,6 @@ describe('platform/gitea', () => { await expect(gitea.initRepo(initRepoCfg)).rejects.toThrow('getRepo()'); }); - it('should abort when disabled and optimizeForDisabled is enabled', async () => { - helper.getRepoContents.mockResolvedValueOnce( - partial({ - contentString: JSON.stringify({ enabled: false }), - }) - ); - - await expect( - initFakeRepo({}, { optimizeForDisabled: true }) - ).rejects.toThrow(REPOSITORY_DISABLED); - }); - it('should abort when repo is archived', async () => { await expect(initFakeRepo({ archived: true })).rejects.toThrow( REPOSITORY_ARCHIVED @@ -1330,4 +1315,22 @@ describe('platform/gitea', () => { expect(await gitea.getVulnerabilityAlerts()).toEqual([]); }); }); + + describe('getJsonFile()', () => { + it('returns file content', async () => { + const data = { foo: 'bar' }; + helper.getRepoContents.mockResolvedValueOnce({ + contentString: JSON.stringify(data), + } as never); + await initFakeRepo({ full_name: 'some/repo' }); + const res = await gitea.getJsonFile('file.json'); + expect(res).toEqual(data); + }); + it('returns null on errors', async () => { + helper.getRepoContents.mockRejectedValueOnce('some error'); + await initFakeRepo({ full_name: 'some/repo' }); + const res = await gitea.getJsonFile('file.json'); + expect(res).toBeNull(); + }); + }); }); diff --git a/lib/platform/gitea/index.ts b/lib/platform/gitea/index.ts index 48cccf31e696a0..7271c41cc5cf9d 100644 --- a/lib/platform/gitea/index.ts +++ b/lib/platform/gitea/index.ts @@ -1,13 +1,10 @@ import URL from 'url'; import is from '@sindresorhus/is'; -import { configFileNames } from '../../config/app-strings'; -import { RenovateConfig } from '../../config/common'; import { REPOSITORY_ACCESS_FORBIDDEN, REPOSITORY_ARCHIVED, REPOSITORY_BLOCKED, REPOSITORY_CHANGED, - REPOSITORY_DISABLED, REPOSITORY_EMPTY, REPOSITORY_MIRRORED, } from '../../constants/error-messages'; @@ -54,7 +51,6 @@ const defaults = { hostType: PLATFORM_TYPE_GITEA, endpoint: 'https://gitea.com/api/v1/', }; -const defaultConfigFile = configFileNames[0]; let config: GiteaRepoConfig = {} as any; let botUserID: number; @@ -221,12 +217,7 @@ const platform: Platform = { } }, - async initRepo({ - repository, - localDir, - optimizeForDisabled, - }: RepoParams): Promise { - let renovateConfig: RenovateConfig; + async initRepo({ repository, localDir }: RepoParams): Promise { let repo: helper.Repo; config = {} as any; @@ -284,14 +275,6 @@ const platform: Platform = { config.defaultBranch = repo.default_branch; logger.debug(`${repository} default branch = ${config.defaultBranch}`); - // Optionally check if Renovate is disabled by attempting to fetch default configuration file - if (optimizeForDisabled) { - renovateConfig = await platform.getJsonFile(defaultConfigFile); - if (renovateConfig && renovateConfig.enabled === false) { - throw new Error(REPOSITORY_DISABLED); - } - } - // Find options for current host and determine Git endpoint const opts = hostRules.find({ hostType: PLATFORM_TYPE_GITEA, diff --git a/lib/platform/github/__snapshots__/index.spec.ts.snap b/lib/platform/github/__snapshots__/index.spec.ts.snap index 6ad946476d21ea..faba36141056d6 100644 --- a/lib/platform/github/__snapshots__/index.spec.ts.snap +++ b/lib/platform/github/__snapshots__/index.spec.ts.snap @@ -2914,6 +2914,108 @@ Array [ ] `; +exports[`platform/github getJsonFile() returns file content 1`] = ` +Array [ + Object { + "graphql": Object { + "query": Object { + "repository": Object { + "__args": Object { + "name": "repo", + "owner": "some", + }, + "defaultBranchRef": Object { + "name": null, + "target": Object { + "oid": null, + }, + }, + "isArchived": null, + "isFork": null, + "mergeCommitAllowed": null, + "nameWithOwner": null, + "rebaseMergeAllowed": null, + "squashMergeAllowed": null, + }, + }, + }, + "headers": Object { + "accept": "application/vnd.github.v3+json", + "accept-encoding": "gzip, deflate", + "authorization": "token abc123", + "content-length": "330", + "content-type": "application/json", + "host": "api.github.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "POST", + "url": "https://api.github.com/graphql", + }, + Object { + "headers": Object { + "accept": "application/vnd.github.v3+json", + "accept-encoding": "gzip, deflate", + "authorization": "token abc123", + "host": "api.github.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.github.com/repos/some/repo/contents/file.json", + }, +] +`; + +exports[`platform/github getJsonFile() returns null on errors 1`] = ` +Array [ + Object { + "graphql": Object { + "query": Object { + "repository": Object { + "__args": Object { + "name": "repo", + "owner": "some", + }, + "defaultBranchRef": Object { + "name": null, + "target": Object { + "oid": null, + }, + }, + "isArchived": null, + "isFork": null, + "mergeCommitAllowed": null, + "nameWithOwner": null, + "rebaseMergeAllowed": null, + "squashMergeAllowed": null, + }, + }, + }, + "headers": Object { + "accept": "application/vnd.github.v3+json", + "accept-encoding": "gzip, deflate", + "authorization": "token abc123", + "content-length": "330", + "content-type": "application/json", + "host": "api.github.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "POST", + "url": "https://api.github.com/graphql", + }, + Object { + "headers": Object { + "accept": "application/vnd.github.v3+json", + "accept-encoding": "gzip, deflate", + "authorization": "token abc123", + "host": "api.github.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.github.com/repos/some/repo/contents/file.json", + }, +] +`; + exports[`platform/github getPr(prNo) should return PR from closed graphql result 1`] = ` Object { "body": "dummy body", @@ -4831,57 +4933,6 @@ Array [ ] `; -exports[`platform/github initRepo should throw err if disabled in renovate.json 1`] = ` -Array [ - Object { - "graphql": Object { - "query": Object { - "repository": Object { - "__args": Object { - "name": "repo", - "owner": "some", - }, - "defaultBranchRef": Object { - "name": null, - "target": Object { - "oid": null, - }, - }, - "isArchived": null, - "isFork": null, - "mergeCommitAllowed": null, - "nameWithOwner": null, - "rebaseMergeAllowed": null, - "squashMergeAllowed": null, - }, - }, - }, - "headers": Object { - "accept": "application/vnd.github.v3+json", - "accept-encoding": "gzip, deflate", - "authorization": "token abc123", - "content-length": "330", - "content-type": "application/json", - "host": "api.github.com", - "user-agent": "https://github.com/renovatebot/renovate", - }, - "method": "POST", - "url": "https://api.github.com/graphql", - }, - Object { - "headers": Object { - "accept": "application/vnd.github.v3+json", - "accept-encoding": "gzip, deflate", - "authorization": "token abc123", - "host": "api.github.com", - "user-agent": "https://github.com/renovatebot/renovate", - }, - "method": "GET", - "url": "https://api.github.com/repos/some/repo/contents/renovate.json", - }, -] -`; - exports[`platform/github initRepo should throw error if archived 1`] = ` Array [ Object { diff --git a/lib/platform/github/index.spec.ts b/lib/platform/github/index.spec.ts index 14193e6c1457a5..d4aa2084c052b0 100644 --- a/lib/platform/github/index.spec.ts +++ b/lib/platform/github/index.spec.ts @@ -2,7 +2,6 @@ import fs from 'fs-extra'; import * as httpMock from '../../../test/httpMock'; import { mocked } from '../../../test/util'; import { - REPOSITORY_DISABLED, REPOSITORY_NOT_FOUND, REPOSITORY_RENAMED, } from '../../constants/error-messages'; @@ -217,21 +216,6 @@ describe('platform/github', () => { } describe('initRepo', () => { - it('should throw err if disabled in renovate.json', async () => { - const scope = httpMock.scope(githubApiHost); - initRepoMock(scope, 'some/repo'); - scope.get('/repos/some/repo/contents/renovate.json').reply(200, { - content: Buffer.from('{"enabled": false}').toString('base64'), - }); - - await expect( - github.initRepo({ - repository: 'some/repo', - optimizeForDisabled: true, - } as any) - ).rejects.toThrow(REPOSITORY_DISABLED); - expect(httpMock.getTrace()).toMatchSnapshot(); - }); it('should rebase', async () => { const scope = httpMock.scope(githubApiHost); initRepoMock(scope, 'some/repo'); @@ -393,7 +377,6 @@ describe('platform/github', () => { }); await expect( github.initRepo({ - includeForks: true, repository: 'some/repo', } as any) ).rejects.toThrow(REPOSITORY_RENAMED); @@ -1993,4 +1976,31 @@ describe('platform/github', () => { expect(httpMock.getTrace()).toMatchSnapshot(); }); }); + + describe('getJsonFile()', () => { + it('returns file content', async () => { + const data = { foo: 'bar' }; + const scope = httpMock.scope(githubApiHost); + initRepoMock(scope, 'some/repo'); + await github.initRepo({ repository: 'some/repo', token: 'token' } as any); + scope.get('/repos/some/repo/contents/file.json').reply(200, { + content: Buffer.from(JSON.stringify(data)).toString('base64'), + }); + const res = await github.getJsonFile('file.json'); + expect(res).toEqual(data); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + it('returns null on errors', async () => { + const scope = httpMock.scope(githubApiHost); + initRepoMock(scope, 'some/repo'); + await github.initRepo({ repository: 'some/repo', token: 'token' } as any); + scope + .get('/repos/some/repo/contents/file.json') + .replyWithError('some error'); + + const res = await github.getJsonFile('file.json'); + expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + }); }); diff --git a/lib/platform/github/index.ts b/lib/platform/github/index.ts index 86a461f69de470..9fb2ac8dcf9c67 100644 --- a/lib/platform/github/index.ts +++ b/lib/platform/github/index.ts @@ -1,7 +1,6 @@ import URL from 'url'; import is from '@sindresorhus/is'; import delay from 'delay'; -import { configFileNames } from '../../config/app-strings'; import { PLATFORM_INTEGRATION_UNAUTHORIZED, REPOSITORY_ACCESS_FORBIDDEN, @@ -58,8 +57,6 @@ import { UserDetails, getUserDetails, getUserEmail } from './user'; const githubApi = new githubHttp.GithubHttp(); -const defaultConfigFile = configFileNames[0]; - let config: LocalRepoConfig = {} as any; const defaults = { @@ -156,7 +153,7 @@ export async function getJsonFile(fileName: string): Promise { 'base64' ).toString() ); - } catch (err) /* istanbul ignore next */ { + } catch (err) { return null; } } @@ -170,9 +167,7 @@ export async function initRepo({ forkMode, forkToken, localDir, - includeForks, renovateUsername, - optimizeForDisabled, }: RepoParams): Promise { logger.debug(`initRepo("${repository}")`); // config is used by the platform api itself, not necessary for the app layer to know @@ -219,13 +214,6 @@ export async function initRepo({ if (!repo.defaultBranchRef?.name) { throw new Error(REPOSITORY_EMPTY); } - // istanbul ignore if - if (repo.isFork && !includeForks) { - const renovateConfig = await getJsonFile(defaultConfigFile); - if (!renovateConfig?.includeForks) { - throw new Error(REPOSITORY_FORKED); - } - } if (repo.nameWithOwner && repo.nameWithOwner !== repository) { logger.debug( { repository, this_repository: repo.nameWithOwner }, @@ -239,12 +227,6 @@ export async function initRepo({ ); throw new Error(REPOSITORY_ARCHIVED); } - if (optimizeForDisabled) { - const renovateConfig = await getJsonFile(defaultConfigFile); - if (renovateConfig?.enabled === false) { - throw new Error(REPOSITORY_DISABLED); - } - } // Use default branch as PR target unless later overridden. config.defaultBranch = repo.defaultBranchRef.name; // Base branch may be configured but defaultBranch is always fixed diff --git a/lib/platform/gitlab/__snapshots__/index.spec.ts.snap b/lib/platform/gitlab/__snapshots__/index.spec.ts.snap index 0b7fe1bd31844f..22c492414088b6 100644 --- a/lib/platform/gitlab/__snapshots__/index.spec.ts.snap +++ b/lib/platform/gitlab/__snapshots__/index.spec.ts.snap @@ -1090,6 +1090,60 @@ Array [ ] `; +exports[`platform/gitlab getJsonFile() returns file content 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer abc123", + "host": "gitlab.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://gitlab.com/api/v4/projects/some%2Frepo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer abc123", + "host": "gitlab.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://gitlab.com/api/v4/projects/some%2Frepo/repository/files/file.json?ref=master", + }, +] +`; + +exports[`platform/gitlab getJsonFile() returns null on errors 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer abc123", + "host": "gitlab.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://gitlab.com/api/v4/projects/some%2Frepo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer abc123", + "host": "gitlab.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://gitlab.com/api/v4/projects/some%2Frepo/repository/files/file.json?ref=master", + }, +] +`; + exports[`platform/gitlab getPr(prNo) returns the PR 1`] = ` Object { "body": "a merge request", @@ -1514,33 +1568,6 @@ Array [ ] `; -exports[`platform/gitlab initRepo should throw error if disabled in renovate.json 1`] = ` -Array [ - Object { - "headers": Object { - "accept": "application/json", - "accept-encoding": "gzip, deflate", - "authorization": "Bearer abc123", - "host": "gitlab.com", - "user-agent": "https://github.com/renovatebot/renovate", - }, - "method": "GET", - "url": "https://gitlab.com/api/v4/projects/some%2Frepo", - }, - Object { - "headers": Object { - "accept": "application/json", - "accept-encoding": "gzip, deflate", - "authorization": "Bearer abc123", - "host": "gitlab.com", - "user-agent": "https://github.com/renovatebot/renovate", - }, - "method": "GET", - "url": "https://gitlab.com/api/v4/projects/some%2Frepo/repository/files/renovate.json?ref=master", - }, -] -`; - exports[`platform/gitlab mergePr(pr) merges the PR 1`] = ` Array [ Object { diff --git a/lib/platform/gitlab/index.spec.ts b/lib/platform/gitlab/index.spec.ts index 0ceea9a67ceb34..bb85f841e427ac 100644 --- a/lib/platform/gitlab/index.spec.ts +++ b/lib/platform/gitlab/index.spec.ts @@ -126,7 +126,6 @@ describe('platform/gitlab', () => { repoParams: RepoParams = { repository: 'some/repo', localDir: '', - optimizeForDisabled: false, }, repoResp = null, scope = httpMock.scope(gitlabApiHost) @@ -145,29 +144,6 @@ describe('platform/gitlab', () => { } describe('initRepo', () => { - it(`should throw error if disabled in renovate.json`, async () => { - httpMock - .scope(gitlabApiHost) - .get('/api/v4/projects/some%2Frepo') - .reply(200, { - default_branch: 'master', - http_url_to_repo: 'https://gitlab.com/some/repo.git', - }) - .get( - '/api/v4/projects/some%2Frepo/repository/files/renovate.json?ref=master' - ) - .reply(200, { - content: Buffer.from('{"enabled": false}').toString('base64'), - }); - await expect( - gitlab.initRepo({ - repository: 'some/repo', - localDir: '', - optimizeForDisabled: true, - }) - ).rejects.toThrow(REPOSITORY_DISABLED); - expect(httpMock.getTrace()).toMatchSnapshot(); - }); it(`should escape all forward slashes in project names`, async () => { httpMock .scope(gitlabApiHost) @@ -176,7 +152,6 @@ describe('platform/gitlab', () => { await gitlab.initRepo({ repository: 'some/repo/project', localDir: '', - optimizeForDisabled: false, }); expect(httpMock.getTrace()).toMatchSnapshot(); }); @@ -189,7 +164,6 @@ describe('platform/gitlab', () => { gitlab.initRepo({ repository: 'some/repo', localDir: '', - optimizeForDisabled: false, }) ).rejects.toThrow('always error'); expect(httpMock.getTrace()).toMatchSnapshot(); @@ -203,7 +177,6 @@ describe('platform/gitlab', () => { gitlab.initRepo({ repository: 'some/repo', localDir: '', - optimizeForDisabled: false, }) ).rejects.toThrow(REPOSITORY_ARCHIVED); expect(httpMock.getTrace()).toMatchSnapshot(); @@ -217,7 +190,6 @@ describe('platform/gitlab', () => { gitlab.initRepo({ repository: 'some/repo', localDir: '', - optimizeForDisabled: false, }) ).rejects.toThrow(REPOSITORY_MIRRORED); expect(httpMock.getTrace()).toMatchSnapshot(); @@ -231,7 +203,6 @@ describe('platform/gitlab', () => { gitlab.initRepo({ repository: 'some/repo', localDir: '', - optimizeForDisabled: false, }) ).rejects.toThrow(REPOSITORY_DISABLED); expect(httpMock.getTrace()).toMatchSnapshot(); @@ -245,7 +216,6 @@ describe('platform/gitlab', () => { gitlab.initRepo({ repository: 'some/repo', localDir: '', - optimizeForDisabled: false, }) ).rejects.toThrow(REPOSITORY_DISABLED); expect(httpMock.getTrace()).toMatchSnapshot(); @@ -259,7 +229,6 @@ describe('platform/gitlab', () => { gitlab.initRepo({ repository: 'some/repo', localDir: '', - optimizeForDisabled: false, }) ).rejects.toThrow(REPOSITORY_EMPTY); expect(httpMock.getTrace()).toMatchSnapshot(); @@ -273,7 +242,6 @@ describe('platform/gitlab', () => { gitlab.initRepo({ repository: 'some/repo', localDir: '', - optimizeForDisabled: false, }) ).rejects.toThrow(REPOSITORY_EMPTY); expect(httpMock.getTrace()).toMatchSnapshot(); @@ -289,7 +257,6 @@ describe('platform/gitlab', () => { await gitlab.initRepo({ repository: 'some/repo/project', localDir: '', - optimizeForDisabled: false, }); expect(httpMock.getTrace()).toMatchSnapshot(); }); @@ -300,7 +267,6 @@ describe('platform/gitlab', () => { { repository: 'some/repo/project', localDir: '', - optimizeForDisabled: false, }, { default_branch: 'master', @@ -317,7 +283,6 @@ describe('platform/gitlab', () => { { repository: 'some/repo/project', localDir: '', - optimizeForDisabled: false, }, { default_branch: 'master', @@ -1146,4 +1111,31 @@ These updates have all been created already. Click a checkbox below to force a r expect(httpMock.getTrace()).toMatchSnapshot(); }); }); + describe('getJsonFile()', () => { + it('returns file content', async () => { + const data = { foo: 'bar' }; + const scope = await initRepo(); + scope + .get( + '/api/v4/projects/some%2Frepo/repository/files/file.json?ref=master' + ) + .reply(200, { + content: Buffer.from(JSON.stringify(data)).toString('base64'), + }); + const res = await gitlab.getJsonFile('file.json'); + expect(res).toEqual(data); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + it('returns null on errors', async () => { + const scope = await initRepo(); + scope + .get( + '/api/v4/projects/some%2Frepo/repository/files/file.json?ref=master' + ) + .replyWithError('some error'); + const res = await gitlab.getJsonFile('file.json'); + expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + }); }); diff --git a/lib/platform/gitlab/index.ts b/lib/platform/gitlab/index.ts index 662cf95a52cc60..e98621ef1e3864 100644 --- a/lib/platform/gitlab/index.ts +++ b/lib/platform/gitlab/index.ts @@ -1,7 +1,6 @@ import URL, { URLSearchParams } from 'url'; import is from '@sindresorhus/is'; import delay from 'delay'; -import { configFileNames } from '../../config/app-strings'; import { PLATFORM_AUTHENTICATION_ERROR, REPOSITORY_ACCESS_FORBIDDEN, @@ -42,14 +41,12 @@ import { GitlabComment, GitlabIssue, MergeMethod, RepoResponse } from './types'; const gitlabApi = new GitlabHttp(); -const defaultConfigFile = configFileNames[0]; let config: { repository: string; localDir: string; email: string; prList: any[]; issueList: GitlabIssue[]; - optimizeForDisabled: boolean; mergeMethod: MergeMethod; defaultBranch: string; } = {} as any; @@ -132,7 +129,7 @@ export async function getJsonFile(fileName: string): Promise { 'base64' ).toString() ); - } catch (err) /* istanbul ignore next */ { + } catch (err) { return null; } } @@ -141,7 +138,6 @@ export async function getJsonFile(fileName: string): Promise { export async function initRepo({ repository, localDir, - optimizeForDisabled, }: RepoParams): Promise { config = {} as any; config.repository = urlEscape(repository); @@ -180,12 +176,6 @@ export async function initRepo({ throw new Error(REPOSITORY_EMPTY); } config.defaultBranch = res.body.default_branch; - if (optimizeForDisabled) { - const renovateConfig = await getJsonFile(defaultConfigFile); - if (renovateConfig && renovateConfig.enabled === false) { - throw new Error(REPOSITORY_DISABLED); - } - } config.mergeMethod = res.body.merge_method || 'merge'; logger.debug(`${repository} default branch = ${config.defaultBranch}`); delete config.prList; diff --git a/lib/workers/repository/init/apis.spec.ts b/lib/workers/repository/init/apis.spec.ts index e20917a7bde961..b373d18549769f 100644 --- a/lib/workers/repository/init/apis.spec.ts +++ b/lib/workers/repository/init/apis.spec.ts @@ -1,8 +1,10 @@ -import { RenovateConfig, getConfig } from '../../../../test/util'; +import { RenovateConfig, getConfig, platform } from '../../../../test/util'; +import { + REPOSITORY_DISABLED, + REPOSITORY_FORKED, +} from '../../../constants/error-messages'; import { initApis } from './apis'; -jest.mock('../../../platform/github'); - describe('workers/repository/init/apis', () => { describe('initApis', () => { let config: RenovateConfig; @@ -11,10 +13,42 @@ describe('workers/repository/init/apis', () => { config.errors = []; config.warnings = []; config.token = 'some-token'; + delete config.optimizeForDisabled; + delete config.includeForks; }); it('runs', async () => { + platform.initRepo.mockResolvedValueOnce({ + defaultBranch: 'master', + isFork: false, + }); const workerPlatformConfig = await initApis(config); expect(workerPlatformConfig).toBeTruthy(); }); + it('throws for disabled', async () => { + platform.initRepo.mockResolvedValueOnce({ + defaultBranch: 'master', + isFork: false, + }); + platform.getJsonFile.mockResolvedValueOnce({ enabled: false }); + await expect( + initApis({ + ...config, + optimizeForDisabled: true, + }) + ).rejects.toThrow(REPOSITORY_DISABLED); + }); + it('throws for forked', async () => { + platform.initRepo.mockResolvedValueOnce({ + defaultBranch: 'master', + isFork: true, + }); + platform.getJsonFile.mockResolvedValueOnce({ includeForks: false }); + await expect( + initApis({ + ...config, + includeForks: false, + }) + ).rejects.toThrow(REPOSITORY_FORKED); + }); }); }); diff --git a/lib/workers/repository/init/apis.ts b/lib/workers/repository/init/apis.ts index 5eb423e511c867..22d948fa163ae6 100644 --- a/lib/workers/repository/init/apis.ts +++ b/lib/workers/repository/init/apis.ts @@ -1,4 +1,9 @@ import { RenovateConfig } from '../../../config'; +import { configFileNames } from '../../../config/app-strings'; +import { + REPOSITORY_DISABLED, + REPOSITORY_FORKED, +} from '../../../constants/error-messages'; import * as npmApi from '../../../datasource/npm'; import { RepoParams, RepoResult, platform } from '../../../platform'; @@ -7,6 +12,28 @@ export type WorkerPlatformConfig = RepoResult & RenovateConfig & Record; +const defaultConfigFile = configFileNames[0]; + +async function validateOptimizeForDisabled( + config: RenovateConfig +): Promise { + if (config.optimizeForDisabled) { + const renovateConfig = await platform.getJsonFile(defaultConfigFile); + if (renovateConfig?.enabled === false) { + throw new Error(REPOSITORY_DISABLED); + } + } +} + +async function validateIncludeForks(config: RenovateConfig): Promise { + if (!config.includeForks && config.isFork) { + const renovateConfig = await platform.getJsonFile(defaultConfigFile); + if (!renovateConfig?.includeForks) { + throw new Error(REPOSITORY_FORKED); + } + } +} + // TODO: fix types async function getPlatformConfig( config: RepoParams @@ -24,6 +51,8 @@ export async function initApis( ): Promise { let config: WorkerPlatformConfig = { ...input } as never; config = await getPlatformConfig(config as never); + await validateOptimizeForDisabled(config); + await validateIncludeForks(config); npmApi.resetMemCache(); npmApi.setNpmrc(config.npmrc); return config;