diff --git a/lib/api/gh-got-retry.js b/lib/api/gh-got-retry.js index d1656376beb3ea0dae7c984b7c5584affcae1a6e..2f700a2adcbc672cfd5b223abfff519e7145586c 100644 --- a/lib/api/gh-got-retry.js +++ b/lib/api/gh-got-retry.js @@ -26,6 +26,22 @@ async function get(path, opts, retries = 5) { } } const res = await ghGot(path, opts); + // Check if result is paginated + const linkHeader = + res && res.headers && res.headers.link ? res.headers.link : ''; + const matches = linkHeader.match( + /<https:\/\/api.github\.com\/(.*?)>; rel="next".*/ + ); + if (matches) { + if (Array.isArray(res.body)) { + res.body = res.body.concat((await get(matches[1], opts, retries)).body); + } else { + logger.warn( + { path }, + 'Found next in link header but res.body is not an array' + ); + } + } return res; } catch (err) { if (err.statusCode >= 500 && err.statusCode < 600 && retries > 0) { diff --git a/test/api/gh-got-retry.spec.js b/test/api/gh-got-retry.spec.js index 7b11e0854a5aa818e23da093dc73c7d7afce0cae..b457ff4609a542aa3d83e6a4733ba2142409b7ac 100644 --- a/test/api/gh-got-retry.spec.js +++ b/test/api/gh-got-retry.spec.js @@ -16,6 +16,30 @@ describe('api/gh-got-retry', () => { 'application/vnd.github.machine-man-preview+json, some-accept' ); }); + it('paginates', async () => { + ghGot.mockReturnValueOnce({ + headers: { + link: '<https://api.github.com/something>; rel="next">', + }, + body: ['a'], + }); + ghGot.mockReturnValueOnce({ + headers: {}, + body: ['b'], + }); + const res = await get('some-url'); + expect(res.body).toHaveLength(2); + }); + it('warns if body cannot be paginated', async () => { + ghGot.mockReturnValueOnce({ + headers: { + link: '<https://api.github.com/something>; rel="next">', + }, + body: {}, + }); + const res = await get('some-url'); + expect(res.body).toEqual({}); + }); it('should retry 502s', async () => { ghGot.mockImplementationOnce(() => Promise.reject({