diff --git a/lib/platform/github/index.js b/lib/platform/github/index.js index 2529b4b97bc31d6f5cb5dae7397b9903a58cecb1..b84dde8f394983543c670f6ae6a7b72b5c08c02d 100644 --- a/lib/platform/github/index.js +++ b/lib/platform/github/index.js @@ -106,6 +106,7 @@ async function initRepo(repoName, token, endpoint) { logger.info({ err, res }, 'Unknown GitHub initRepo error'); throw err; } + await Promise.all([getPrList(), getFileList()]); return platformConfig; } @@ -155,11 +156,13 @@ async function getBranchProtection(branchName) { return res.body; } -function setBaseBranch(branchName) { +async function setBaseBranch(branchName) { if (branchName) { logger.debug(`Setting baseBranch to ${branchName}`); config.baseBranch = branchName; delete config.baseCommitSHA; + delete config.fileList; + await getFileList(branchName); } } @@ -672,7 +675,12 @@ async function mergePr(prNo, branchName) { // Generic File operations async function getFile(filePath, branchName) { - logger.trace(`getFile(filePath=${filePath}, branchName=${branchName})`); + logger.debug(`getFile(filePath=${filePath}, branchName=${branchName})`); + if (!branchName || branchName === config.baseBranch) { + if (!config.fileList.includes(filePath)) { + return null; + } + } try { const res = await get( `repos/${config.repoName}/contents/${filePath}?ref=${branchName || @@ -685,6 +693,7 @@ async function getFile(filePath, branchName) { } catch (error) { if (error.statusCode === 404) { // If file not found, then return null JSON + logger.warn({ filePath, branchName }, 'getFile 404'); return null; } // Propagate if it's any other error diff --git a/test/platform/github/__snapshots__/index.spec.js.snap b/test/platform/github/__snapshots__/index.spec.js.snap index b7f69cc2e808edf6e64587713554c0d24956ef2d..7eedf8da843aba20b32db8a68044a9a5636ddc85 100644 --- a/test/platform/github/__snapshots__/index.spec.js.snap +++ b/test/platform/github/__snapshots__/index.spec.js.snap @@ -46,6 +46,15 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], Array [ "repos/some/repo/git/refs/heads/thebranchname", ], @@ -62,6 +71,15 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], Array [ "repos/some/repo/git/refs/heads/thebranchname", ], @@ -78,6 +96,15 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], Array [ "repos/some/repo/git/refs/heads/thebranchname", ], @@ -94,6 +121,15 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], Array [ "repos/some/repo/git/refs/heads/thebranchname", ], @@ -110,6 +146,15 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], Array [ "repos/some/repo/git/refs/heads/thebranchname", ], @@ -126,6 +171,15 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], Array [ "repos/some/repo/git/refs/heads/thebranchname", ], @@ -142,6 +196,15 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], Array [ "repos/some/repo/git/refs/heads/master", ], @@ -217,6 +280,15 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], Array [ "repos/some/repo/git/refs/heads/master", ], @@ -397,6 +469,9 @@ Array [ "paginate": true, }, ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], ] `; @@ -409,7 +484,7 @@ Array [ ] `; -exports[`platform/github getFile(filePatch, branchName) should return null if GitHub returns a 404 1`] = ` +exports[`platform/github getFile() should return null if GitHub returns a 404 1`] = ` Array [ Array [ "repos/some/repo", @@ -419,13 +494,22 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], Array [ "repos/some/repo/contents/package.json?ref=master", ], ] `; -exports[`platform/github getFile(filePatch, branchName) should return null if getFile returns nothing 1`] = ` +exports[`platform/github getFile() should return null if getFile returns nothing 1`] = ` Array [ Array [ "repos/some/repo", @@ -435,13 +519,22 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], Array [ "repos/some/repo/contents/package.json?ref=master", ], ] `; -exports[`platform/github getFile(filePatch, branchName) should return the encoded file content 1`] = ` +exports[`platform/github getFile() should return the encoded file content 1`] = ` Array [ Array [ "repos/some/repo", @@ -451,6 +544,15 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], Array [ "repos/some/repo/contents/package.json?ref=master", ], @@ -597,6 +699,15 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], ] `; @@ -617,6 +728,15 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], ] `; @@ -637,6 +757,15 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], ] `; @@ -685,6 +814,15 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], ] `; @@ -724,6 +862,15 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], Array [ "repos/some/repo/git/refs/heads/thebranchname", ], @@ -767,6 +914,15 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], ] `; @@ -802,6 +958,15 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], Array [ "repos/some/repo/git/refs/heads/thebranchname", ], @@ -839,6 +1004,15 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], ] `; @@ -860,6 +1034,18 @@ Array [ }, }, ], + Array [ + "repos/some/repo/pulls?per_page=100&state=all", + Object { + "paginate": true, + }, + ], + Array [ + "repos/some/repo/git/trees/master?recursive=true", + ], + Array [ + "repos/some/repo/git/trees/some-branch?recursive=true", + ], ] `; diff --git a/test/platform/github/index.spec.js b/test/platform/github/index.spec.js index a0da3268a2a2e728d09315b748e6a1a0a8799dd6..08bcb1bc30e8f00820f649a42fe4b126abcaae33 100644 --- a/test/platform/github/index.spec.js +++ b/test/platform/github/index.spec.js @@ -63,6 +63,21 @@ describe('platform/github', () => { allow_merge_commit: true, }, })); + // getPrList + get.mockImplementationOnce(() => ({ + body: [], + })); + // getFileList + get.mockImplementationOnce(() => ({ + body: { + tree: [ + { + type: 'blob', + path: 'package.json', + }, + ], + }, + })); return github.initRepo(...args); } @@ -113,6 +128,14 @@ describe('platform/github', () => { allow_merge_commit: true, }, })); + // getPrList + get.mockImplementationOnce(() => ({ + body: [], + })); + // getFileList + get.mockImplementationOnce(() => ({ + body: [], + })); return github.initRepo(...args); } const config = await squashInitRepo('some/repo', 'token'); @@ -132,6 +155,14 @@ describe('platform/github', () => { allow_merge_commit: true, }, })); + // getPrList + get.mockImplementationOnce(() => ({ + body: [], + })); + // getFileList + get.mockImplementationOnce(() => ({ + body: [], + })); return github.initRepo(...args); } const config = await mergeInitRepo('some/repo', 'token'); @@ -151,6 +182,14 @@ describe('platform/github', () => { allow_merge_commit: true, }, })); + // getPrList + get.mockImplementationOnce(() => ({ + body: [], + })); + // getFileList + get.mockImplementationOnce(() => ({ + body: [], + })); return github.initRepo(...args); } const config = await mergeInitRepo('some/repo', 'token'); @@ -167,6 +206,14 @@ describe('platform/github', () => { default_branch: 'master', }, })); + // getPrList + get.mockImplementationOnce(() => ({ + body: [], + })); + // getFileList + get.mockImplementationOnce(() => ({ + body: [], + })); return github.initRepo(...args); } const config = await mergeInitRepo('some/repo', 'token'); @@ -233,7 +280,6 @@ describe('platform/github', () => { }); describe('getFileList', () => { it('returns empty array if error', async () => { - await initRepo('some/repo', 'token'); get.mockImplementationOnce(() => { throw new Error('some error'); }); @@ -241,7 +287,6 @@ describe('platform/github', () => { expect(files).toEqual([]); }); it('warns if truncated result', async () => { - await initRepo('some/repo', 'token'); get.mockImplementationOnce(() => ({ body: { truncated: true, @@ -252,7 +297,6 @@ describe('platform/github', () => { expect(files.length).toBe(0); }); it('caches the result', async () => { - await initRepo('some/repo', 'token'); get.mockImplementationOnce(() => ({ body: { truncated: true, @@ -265,7 +309,6 @@ describe('platform/github', () => { expect(files.length).toBe(0); }); it('should return the files matching the fileName', async () => { - await initRepo('some/repo', 'token'); get.mockImplementationOnce(() => ({ body: { tree: [ @@ -1044,7 +1087,7 @@ describe('platform/github', () => { expect(await github.mergePr(pr)).toBe(true); expect(get.put.mock.calls).toHaveLength(1); expect(get.delete.mock.calls).toHaveLength(1); - expect(get.mock.calls).toHaveLength(1); + expect(get.mock.calls).toHaveLength(3); }); it('should handle merge error', async () => { await initRepo('some/repo', 'token'); @@ -1060,7 +1103,7 @@ describe('platform/github', () => { expect(await github.mergePr(pr)).toBe(false); expect(get.put.mock.calls).toHaveLength(1); expect(get.delete.mock.calls).toHaveLength(0); - expect(get.mock.calls).toHaveLength(1); + expect(get.mock.calls).toHaveLength(3); }); }); describe('mergePr(prNo) - autodetection', () => { @@ -1075,6 +1118,14 @@ describe('platform/github', () => { default_branch: 'master', }, })); + // getPrList + get.mockImplementationOnce(() => ({ + body: [], + })); + // getFileList + get.mockImplementationOnce(() => ({ + body: [], + })); // getBranchCommit get.mockImplementationOnce(() => ({ body: { @@ -1167,7 +1218,7 @@ describe('platform/github', () => { expect(get.delete.mock.calls).toHaveLength(0); }); }); - describe('getFile(filePatch, branchName)', () => { + describe('getFile()', () => { it('should return the encoded file content', async () => { await initRepo('some/repo', 'token'); get.mockImplementationOnce(() => ({ @@ -1179,6 +1230,11 @@ describe('platform/github', () => { expect(get.mock.calls).toMatchSnapshot(); expect(content).toBe('hello world'); }); + it('should return null if not in file list', async () => { + await initRepo('some/repo', 'token'); + const content = await github.getFile('.npmrc'); + expect(content).toBe(null); + }); it('should return null if GitHub returns a 404', async () => { await initRepo('some/repo', 'token'); get.mockImplementationOnce(() => diff --git a/test/workers/repository/init/apis.spec.js b/test/workers/repository/init/apis.spec.js index 12964958d7775c33beb2ca0d642b1a118005afc7..a67342d6fb46d9bbbddcd9c1ab010fbb2a4efaf4 100644 --- a/test/workers/repository/init/apis.spec.js +++ b/test/workers/repository/init/apis.spec.js @@ -1,8 +1,9 @@ const { initApis } = require('../../../../lib/workers/repository/init/apis'); -const ghGot = require('gh-got'); const glGot = require('gl-got'); +jest.mock('../../../../lib/platform/github'); + describe('workers/repository/init/apis', () => { describe('initApis', () => { let config; @@ -12,10 +13,6 @@ describe('workers/repository/init/apis', () => { config.warnings = []; }); it('runs', async () => { - // initRepo - ghGot.mockReturnValueOnce({ body: { owner: {} } }); - ghGot.mockReturnValueOnce({ body: { object: {} } }); - ghGot.mockReturnValueOnce({ body: {} }); await initApis(config, 'some-token'); }); it('runs gitlab', async () => {