feat: retrieve and cache PR list for better performance

This commit is contained in:
Rhys Arkins 2017-10-17 11:01:21 +02:00
parent e310887f36
commit 78cff771af
3 changed files with 73 additions and 139 deletions

View file

@ -30,6 +30,7 @@ module.exports = {
addReviewers,
addLabels,
// PR
getPrList,
findPr,
createPr,
getPr,
@ -147,6 +148,7 @@ async function initRepo(repoName, token, endpoint, repoLogger) {
}
config.repoName = repoName;
config.fileList = null;
config.prList = null;
const platformConfig = {};
try {
const res = await get(`repos/${repoName}`, {
@ -464,22 +466,32 @@ async function addLabels(issueNo, labels) {
// Pull Request
async function getPrList() {
if (!config.prList) {
const res = await get(
`repos/${config.repoName}/pulls?per_page=100&state=all`
);
config.prList = res.body.map(pr => ({
number: pr.number,
branchName: pr.head.ref,
title: pr.title,
state: pr.state,
closed_at: pr.closed_at,
}));
}
return config.prList;
}
async function findPr(branchName, prTitle, state = 'all') {
logger.debug(`findPr(${branchName}, ${state})`);
const urlString = `repos/${config.repoName}/pulls?head=${config.owner}:${branchName}&state=${state}`;
logger.debug(`findPr urlString: ${urlString}`);
const res = await get(urlString);
let pr = null;
res.body.forEach(result => {
if (!prTitle || result.title === prTitle) {
pr = result;
if (pr.state === 'closed') {
pr.isClosed = true;
}
pr.displayNumber = `Pull Request #${pr.number}`;
}
});
return pr;
logger.debug(`findPr(${branchName}, ${prTitle}, ${state})`);
const prList = await module.exports.getPrList();
const pr = prList.filter(
p =>
p.branchName === branchName &&
(!prTitle || p.title === prTitle) &&
(state === 'all' || p.state === state)
)[0];
return pr ? { ...pr, isClosed: pr.state === 'closed' } : undefined;
}
// Creates PR and returns PR number

View file

@ -440,106 +440,6 @@ Array [
]
`;
exports[`api/github findPr(branchName, prTitle, state) should return a PR object 1`] = `
Array [
Array [
"repos/some/repo",
Object {
"headers": Object {
"accept": "application/vnd.github.loki-preview+json",
},
},
],
Array [
"repos/some/repo/git/refs/heads/master",
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
Object {
"headers": Object {
"accept": "application/vnd.github.loki-preview+json",
},
},
],
Array [
"repos/some/repo/pulls?head=theowner:master&state=all",
],
]
`;
exports[`api/github findPr(branchName, prTitle, state) should return a PR object 2`] = `
Object {
"displayNumber": "Pull Request #42",
"number": 42,
"state": "open",
"title": "PR Title",
}
`;
exports[`api/github findPr(branchName, prTitle, state) should return null if no PR's are found 1`] = `
Array [
Array [
"repos/some/repo",
Object {
"headers": Object {
"accept": "application/vnd.github.loki-preview+json",
},
},
],
Array [
"repos/some/repo/git/refs/heads/master",
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
Object {
"headers": Object {
"accept": "application/vnd.github.loki-preview+json",
},
},
],
Array [
"repos/some/repo/pulls?head=theowner:master&state=all",
],
]
`;
exports[`api/github findPr(branchName, prTitle, state) should set the isClosed attribute of the PR to true if the PR is closed 1`] = `
Array [
Array [
"repos/some/repo",
Object {
"headers": Object {
"accept": "application/vnd.github.loki-preview+json",
},
},
],
Array [
"repos/some/repo/git/refs/heads/master",
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
Object {
"headers": Object {
"accept": "application/vnd.github.loki-preview+json",
},
},
],
Array [
"repos/some/repo/pulls?head=theowner:master&state=all",
],
]
`;
exports[`api/github findPr(branchName, prTitle, state) should set the isClosed attribute of the PR to true if the PR is closed 2`] = `
Object {
"displayNumber": "Pull Request #42",
"isClosed": true,
"number": 42,
"state": "closed",
"title": "PR Title",
}
`;
exports[`api/github getAllPrs() maps results to simple array 1`] = `
Array [
Object {

View file

@ -959,32 +959,54 @@ describe('api/github', () => {
});
});
describe('findPr(branchName, prTitle, state)', () => {
it('should return a PR object', async () => {
await initRepo('some/repo', 'token');
get.mockImplementationOnce(() => ({
body: [{ title: 'PR Title', state: 'open', number: 42 }],
}));
const pr = await github.findPr('master', 'PR Title');
expect(get.mock.calls).toMatchSnapshot();
expect(pr).toMatchSnapshot();
it('returns true if no title and all state', async () => {
get.mockReturnValueOnce({
body: [
{
number: 1,
head: { ref: 'branch-a' },
title: 'branch a pr',
state: 'open',
},
],
});
const res = await github.findPr('branch-a', null);
expect(res).toBeDefined();
});
it("should return null if no PR's are found", async () => {
await initRepo('some/repo', 'token');
get.mockImplementationOnce(() => ({
body: [],
}));
const pr = await github.findPr('master', 'PR Title');
expect(get.mock.calls).toMatchSnapshot();
expect(pr).toBe(null);
it('returns isClosed if closed', async () => {
get.mockReturnValueOnce({
body: [
{
number: 1,
head: { ref: 'branch-a' },
title: 'branch a pr',
state: 'closed',
closed_at: '2017-01-01',
},
],
});
const res = await github.findPr('branch-a', null);
expect(res.isClosed).toBe(true);
});
it('should set the isClosed attribute of the PR to true if the PR is closed', async () => {
await initRepo('some/repo', 'token');
get.mockImplementationOnce(() => ({
body: [{ title: 'PR Title', state: 'closed', number: 42 }],
}));
const pr = await github.findPr('master');
expect(get.mock.calls).toMatchSnapshot();
expect(pr).toMatchSnapshot();
it('caches pr list', async () => {
get.mockReturnValueOnce({
body: [
{
number: 1,
head: { ref: 'branch-a' },
title: 'branch a pr',
state: 'open',
},
],
});
let res = await github.findPr('branch-a', null);
expect(res).toBeDefined();
res = await github.findPr('branch-a', 'branch a pr');
expect(res).toBeDefined();
res = await github.findPr('branch-a', 'branch a pr', 'open');
expect(res).toBeDefined();
res = await github.findPr('branch-b');
expect(res).not.toBeDefined();
});
});
describe('createPr(branchName, title, body)', () => {