diff --git a/docs/usage/self-hosted-experimental.md b/docs/usage/self-hosted-experimental.md index 5679da59154e893e7bdaabbf402b40ac741be552..cfed99f956b8c96445784c3a260a7dace7dc09bf 100644 --- a/docs/usage/self-hosted-experimental.md +++ b/docs/usage/self-hosted-experimental.md @@ -35,6 +35,11 @@ If set to "false" (string), Renovate will remove any existing `package-lock.json If set to any string, Renovate will use this as the `user-agent` it sends with HTTP requests. +## `RENOVATE_X_DOCKER_MAX_PAGES` + +If set to an integer, Renovate will use this as max page number for docker tags lookup on docker registries, instead of the default 20 pages. +This is useful for registries which ignores the `n` parameter in the query string and only return 50 tags per page. + ## `RENOVATE_X_HARD_EXIT` If set to any value, Renovate will use a "hard" `process.exit()` once all work is done, even if a sub-process is otherwise delaying Node.js from exiting. diff --git a/lib/modules/datasource/docker/index.spec.ts b/lib/modules/datasource/docker/index.spec.ts index 15ed77dbad2c78a5dce4ed1a5188611228d8f3d5..5b4fa32cd7af8bdc6e2c248b48d9f72c999b9cb0 100644 --- a/lib/modules/datasource/docker/index.spec.ts +++ b/lib/modules/datasource/docker/index.spec.ts @@ -40,6 +40,7 @@ describe('modules/datasource/docker/index', () => { password: 'some-password', }); hostRules.hosts.mockReturnValue([]); + delete process.env.RENOVATE_X_DOCKER_MAX_PAGES; }); describe('getDigest', () => { @@ -1039,6 +1040,41 @@ describe('modules/datasource/docker/index', () => { expect(res?.releases).toHaveLength(1); }); + it('uses custom max pages', async () => { + process.env.RENOVATE_X_DOCKER_MAX_PAGES = '2'; + httpMock + .scope(baseUrl) + .get('/library/node/tags/list?n=10000') + .reply(200, '', {}) + .get('/library/node/tags/list?n=10000') + .reply( + 200, + { tags: ['1.0.0'] }, + { + link: `<${baseUrl}/library/node/tags/list?n=1&page=1>; rel="next", `, + } + ) + .get('/library/node/tags/list?n=1&page=1') + .reply( + 200, + { tags: ['1.0.1'] }, + { + link: `<${baseUrl}/library/node/tags/list?n=1&page=2>; rel="next", `, + } + ) + .get('/') + .reply(200) + .get('/library/node/manifests/1.0.1') + .reply(200); + + const config = { + datasource: DockerDatasource.id, + packageName: 'node', + }; + const res = await getPkgReleases(config); + expect(res?.releases).toHaveLength(2); + }); + it('uses custom registry in packageName', async () => { const tags = ['1.0.0']; httpMock diff --git a/lib/modules/datasource/docker/index.ts b/lib/modules/datasource/docker/index.ts index 6fd32709ed633e51a6f363572cf3735305530d10..a349ce3ac66604ca710b0f328df651ba7a21efff 100644 --- a/lib/modules/datasource/docker/index.ts +++ b/lib/modules/datasource/docker/index.ts @@ -560,6 +560,9 @@ export class DockerDatasource extends Datasource { return null; } let page = 0; + const pages = process.env.RENOVATE_X_DOCKER_MAX_PAGES + ? parseInt(process.env.RENOVATE_X_DOCKER_MAX_PAGES, 10) + : 20; let foundMaxResultsError = false; do { let res: HttpResponse<{ tags: string[] }>; @@ -594,7 +597,7 @@ export class DockerDatasource extends Datasource { url = linkHeader?.next ? new URL(linkHeader.next.url, url).href : null; } page += 1; - } while (url && page < 20); + } while (url && page < pages); return tags; }