fix: set GitHub App headers for every request ()

pull/959/head v9.80.1
Rhys Arkins 2017-10-17 08:04:58 +02:00 committed by GitHub
parent e6e8b541cf
commit c188a71081
4 changed files with 335 additions and 468 deletions

View File

@ -10,16 +10,20 @@ function sleep(ms) {
async function get(path, opts, retries = 5) {
try {
if (appMode) {
// eslint-disable-next-line no-param-reassign
opts = opts || {};
// eslint-disable-next-line no-param-reassign
/* eslint-disable no-param-reassign */
opts = Object.assign({}, opts);
const appAccept = 'application/vnd.github.machine-man-preview+json';
opts.headers = Object.assign(
{},
{
accept: 'application/vnd.github.machine-man-preview+json',
accept: appAccept,
'user-agent': 'https://github.com/singapore/renovate',
},
opts.headers
);
if (opts.headers.accept !== appAccept) {
opts.headers.accept = `${appAccept}, ${opts.headers.accept}`;
}
}
const res = await ghGot(path, opts);
return res;
@ -77,17 +81,8 @@ async function get(path, opts, retries = 5) {
const helpers = ['get', 'post', 'put', 'patch', 'head', 'delete'];
for (const x of helpers) {
get[x] = async (path, opts, retries = 3) => {
try {
const res = await ghGot[x](path, opts);
return res;
} catch (err) {
if (err.statusCode === 502 && retries > 0) {
return get[x](path, opts, retries - 1);
}
throw err;
}
};
get[x] = (url, opts) =>
get(url, Object.assign({}, opts, { method: x.toUpperCase() }));
}
let appMode = false;

View File

@ -61,7 +61,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -73,7 +72,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/thebranchname",
undefined,
],
]
`;
@ -90,7 +88,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -102,7 +99,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/thebranchname",
undefined,
],
]
`;
@ -119,7 +115,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -131,7 +126,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/thebranchname",
undefined,
],
]
`;
@ -148,7 +142,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -160,7 +153,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/thebranchname",
undefined,
],
]
`;
@ -177,7 +169,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -189,7 +180,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/thebranchname",
undefined,
],
]
`;
@ -206,7 +196,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -218,7 +207,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/thebranchname",
undefined,
],
]
`;
@ -235,7 +223,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -247,15 +234,12 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/git/commits/1111",
undefined,
],
Array [
"repos/some/repo/git/refs/heads/package.json",
undefined,
],
]
`;
@ -325,7 +309,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -337,15 +320,12 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/git/commits/1111",
undefined,
],
Array [
"repos/some/repo/git/refs/heads/package.json",
undefined,
],
]
`;
@ -472,7 +452,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -484,7 +463,6 @@ Array [
],
Array [
"repos/some/repo/pulls?head=theowner:master&state=all",
undefined,
],
]
`;
@ -510,7 +488,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -522,7 +499,6 @@ Array [
],
Array [
"repos/some/repo/pulls?head=theowner:master&state=all",
undefined,
],
]
`;
@ -539,7 +515,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -551,7 +526,6 @@ Array [
],
Array [
"repos/some/repo/pulls?head=theowner:master&state=all",
undefined,
],
]
`;
@ -604,7 +578,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -616,7 +589,6 @@ Array [
],
Array [
"repos/some/repo/pulls?state=open&base=master&head=theowner:somebranch",
undefined,
],
]
`;
@ -633,7 +605,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -645,11 +616,9 @@ Array [
],
Array [
"repos/some/repo/pulls?state=open&base=master&head=theowner:somebranch",
undefined,
],
Array [
"repos/some/repo/pulls/91",
undefined,
],
]
`;
@ -687,7 +656,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -699,7 +667,6 @@ Array [
],
Array [
"repos/some/repo/contents/package.json?ref=master",
undefined,
],
]
`;
@ -716,7 +683,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -728,7 +694,6 @@ Array [
],
Array [
"repos/some/repo/contents/package.json?ref=master",
undefined,
],
]
`;
@ -745,7 +710,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -757,7 +721,6 @@ Array [
],
Array [
"repos/some/repo/contents/package.json?ref=master",
undefined,
],
]
`;
@ -774,7 +737,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -786,7 +748,6 @@ Array [
],
Array [
"repos/some/repo/contents/package.json?ref=master",
undefined,
],
]
`;
@ -803,7 +764,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -815,7 +775,6 @@ Array [
],
Array [
"repos/some/repo/contents/package.json?ref=master",
undefined,
],
]
`;
@ -832,7 +791,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -844,7 +802,6 @@ Array [
],
Array [
"repos/some/repo/contents/package.json?ref=master",
undefined,
],
]
`;
@ -879,83 +836,10 @@ Object {
}
`;
exports[`api/github getInstallationToken should retry posts 1`] = `Array []`;
exports[`api/github getInstallationToken should retry posts 2`] = `"aUserToken"`;
exports[`api/github getInstallationToken should return an installation token 1`] = `Array []`;
exports[`api/github getInstallationToken should return an installation token 2`] = `"aUserToken"`;
exports[`api/github getInstallations should retry 502s once 1`] = `
Array [
Array [
"app/installations",
Object {
"headers": Object {
"accept": "application/vnd.github.machine-man-preview+json",
"authorization": "Bearer sometoken",
},
},
],
Array [
"app/installations",
Object {
"headers": Object {
"accept": "application/vnd.github.machine-man-preview+json",
"authorization": "Bearer sometoken",
},
},
],
]
`;
exports[`api/github getInstallations should retry 502s once 2`] = `
Array [
"a",
"b",
]
`;
exports[`api/github getInstallations should retry 502s until success 1`] = `
Array [
Array [
"app/installations",
Object {
"headers": Object {
"accept": "application/vnd.github.machine-man-preview+json",
"authorization": "Bearer sometoken",
},
},
],
Array [
"app/installations",
Object {
"headers": Object {
"accept": "application/vnd.github.machine-man-preview+json",
"authorization": "Bearer sometoken",
},
},
],
Array [
"app/installations",
Object {
"headers": Object {
"accept": "application/vnd.github.machine-man-preview+json",
"authorization": "Bearer sometoken",
},
},
],
]
`;
exports[`api/github getInstallations should retry 502s until success 2`] = `
Array [
"a",
"b",
]
`;
exports[`api/github getInstallations should return an array of installations 1`] = `
Array [
Array [
@ -964,7 +848,6 @@ Array [
"headers": Object {
"accept": "application/vnd.github.machine-man-preview+json",
"authorization": "Bearer sometoken",
"user-agent": "https://github.com/singapore/renovate",
},
},
],
@ -1052,7 +935,6 @@ exports[`api/github getRepos should return an array of repos 1`] = `
Array [
Array [
"user/repos",
undefined,
],
]
`;
@ -1068,7 +950,6 @@ exports[`api/github getRepos should support a custom endpoint 1`] = `
Array [
Array [
"user/repos",
undefined,
],
]
`;
@ -1092,7 +973,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -1104,7 +984,6 @@ Array [
],
Array [
"repos/some/repo/contents/some-path",
undefined,
],
]
`;
@ -1151,7 +1030,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -1184,7 +1062,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -1217,7 +1094,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -1282,7 +1158,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -1294,7 +1169,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
]
`;
@ -1321,7 +1195,6 @@ exports[`api/github mergeBranch(branchName, mergeType) should perform a branch-m
Array [
Array [
"repos/some/repo/git/refs/heads/thebranchname",
undefined,
],
]
`;
@ -1338,7 +1211,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -1350,11 +1222,9 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/thebranchname",
undefined,
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
]
`;
@ -1380,7 +1250,6 @@ exports[`api/github mergeBranch(branchName, mergeType) should perform a branch-p
Array [
Array [
"repos/some/repo/git/refs/heads/thebranchname",
undefined,
],
]
`;
@ -1399,7 +1268,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -1446,7 +1314,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -1458,7 +1325,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/thebranchname",
undefined,
],
]
`;
@ -1496,7 +1362,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -1529,7 +1394,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/master",
undefined,
],
Array [
"repos/some/repo/branches/master/protection/required_status_checks",
@ -1541,7 +1405,6 @@ Array [
],
Array [
"repos/some/repo/git/refs/heads/some-branch",
undefined,
],
]
`;

View File

@ -0,0 +1,133 @@
const get = require('../../lib/api/gh-got-retry');
const ghGot = require('gh-got');
jest.mock('gh-got');
describe('api/gh-got-retry', () => {
const body = ['a', 'b'];
beforeEach(() => {
jest.resetAllMocks();
get.setAppMode(false);
});
it('supports app mode', async () => {
get.setAppMode(true);
await get('some-url', { headers: { accept: 'some-accept' } });
expect(ghGot.mock.calls[0][1].headers.accept).toBe(
'application/vnd.github.machine-man-preview+json, some-accept'
);
});
it('should retry 502s', async () => {
ghGot.mockImplementationOnce(() =>
Promise.reject({
statusCode: 502,
})
);
ghGot.mockImplementationOnce(() => ({
body,
}));
const res = await get('some-url');
expect(res.body).toEqual(body);
});
it('should retry 502s until success', async () => {
ghGot.mockImplementationOnce(() =>
Promise.reject({
statusCode: 502,
})
);
ghGot.mockImplementationOnce(() =>
Promise.reject({
statusCode: 502,
})
);
ghGot.mockImplementationOnce(() => ({
body,
}));
const res = await get('some-url');
expect(ghGot.mock.calls).toHaveLength(3);
expect(res.body).toEqual(body);
});
it('should retry until failure', async () => {
ghGot.mockImplementationOnce(() =>
Promise.reject({
statusCode: 502,
})
);
ghGot.mockImplementationOnce(() =>
Promise.reject({
statusCode: 403,
message: 'API rate limit exceeded for x.',
})
);
ghGot.mockImplementationOnce(() =>
Promise.reject({
statusCode: 403,
message:
'You have triggered an abuse detection mechanism. Please wait a few minutes before you try again.',
})
);
ghGot.mockImplementationOnce(() =>
Promise.reject({
statusCode: 404,
})
);
let err;
try {
await get('some-url');
} catch (e) {
err = e;
}
expect(err.statusCode).toBe(404);
});
it('should give up after 5 retries', async () => {
ghGot.mockImplementationOnce(() =>
Promise.reject({
statusCode: 502,
})
);
ghGot.mockImplementationOnce(() =>
Promise.reject({
statusCode: 502,
})
);
ghGot.mockImplementationOnce(() =>
Promise.reject({
statusCode: 500,
})
);
ghGot.mockImplementationOnce(() =>
Promise.reject({
statusCode: 500,
})
);
ghGot.mockImplementationOnce(() =>
Promise.reject({
statusCode: 502,
})
);
ghGot.mockImplementationOnce(() =>
Promise.reject({
statusCode: 403,
message: 'API rate limit exceeded for x.',
})
);
let err;
try {
await get('some-url');
} catch (e) {
err = e;
}
expect(err.statusCode).toBe(403);
});
it('should retry posts', async () => {
ghGot.mockImplementationOnce(() =>
Promise.reject({
statusCode: 502,
})
);
ghGot.mockImplementationOnce(() => ({
body,
}));
const res = await get.post('some-url');
expect(res.body).toEqual(body);
});
});

File diff suppressed because it is too large Load Diff