From dc9d954508bf22674565dafbfba903b999c8f359 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Jun 2026 15:33:39 +0000 Subject: [PATCH 1/8] Use Link headers for Adoptium pagination --- .../distributors/adopt-installer.test.ts | 10 +++--- .../distributors/semeru-installer.test.ts | 10 +++--- .../distributors/temurin-installer.test.ts | 10 +++--- __tests__/util.test.ts | 22 +++++++++++++ src/distributions/adopt/installer.ts | 28 +++++++--------- src/distributions/semeru/installer.ts | 31 +++++++----------- src/distributions/temurin/installer.ts | 32 ++++++++----------- src/util.ts | 22 +++++++++++++ 8 files changed, 92 insertions(+), 73 deletions(-) diff --git a/__tests__/distributors/adopt-installer.test.ts b/__tests__/distributors/adopt-installer.test.ts index ff477be0..fa96279d 100644 --- a/__tests__/distributors/adopt-installer.test.ts +++ b/__tests__/distributors/adopt-installer.test.ts @@ -136,22 +136,19 @@ describe('getAvailableVersions', () => { ); it('load available versions', async () => { + const nextPageUrl = + 'https://api.adoptopenjdk.net/v3/assets/version/%5B1.0,100.0%5D?page=1&page_size=20'; spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson'); spyHttpClient .mockReturnValueOnce({ statusCode: 200, - headers: {}, + headers: {link: `<${nextPageUrl}>; rel="next"`}, result: manifestData as any }) .mockReturnValueOnce({ statusCode: 200, headers: {}, result: manifestData as any - }) - .mockReturnValueOnce({ - statusCode: 200, - headers: {}, - result: [] }); const distribution = new AdoptDistribution( @@ -166,6 +163,7 @@ describe('getAvailableVersions', () => { const availableVersions = await distribution['getAvailableVersions'](); expect(availableVersions).not.toBeNull(); expect(availableVersions.length).toBe(manifestData.length * 2); + expect(spyHttpClient).toHaveBeenNthCalledWith(2, nextPageUrl); }); it.each([ diff --git a/__tests__/distributors/semeru-installer.test.ts b/__tests__/distributors/semeru-installer.test.ts index 1c26c79a..d415e747 100644 --- a/__tests__/distributors/semeru-installer.test.ts +++ b/__tests__/distributors/semeru-installer.test.ts @@ -82,22 +82,19 @@ describe('getAvailableVersions', () => { ); it('load available versions', async () => { + const nextPageUrl = + 'https://api.adoptopenjdk.net/v3/assets/version/%5B1.0,100.0%5D?page=1&page_size=20'; spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson'); spyHttpClient .mockReturnValueOnce({ statusCode: 200, - headers: {}, + headers: {link: `<${nextPageUrl}>; rel="next"`}, result: manifestData as any }) .mockReturnValueOnce({ statusCode: 200, headers: {}, result: manifestData as any - }) - .mockReturnValueOnce({ - statusCode: 200, - headers: {}, - result: [] }); const distribution = new SemeruDistribution({ @@ -109,6 +106,7 @@ describe('getAvailableVersions', () => { const availableVersions = await distribution['getAvailableVersions'](); expect(availableVersions).not.toBeNull(); expect(availableVersions.length).toBe(manifestData.length * 2); + expect(spyHttpClient).toHaveBeenNthCalledWith(2, nextPageUrl); }); it.each([ diff --git a/__tests__/distributors/temurin-installer.test.ts b/__tests__/distributors/temurin-installer.test.ts index 0c6ef3f5..93930179 100644 --- a/__tests__/distributors/temurin-installer.test.ts +++ b/__tests__/distributors/temurin-installer.test.ts @@ -93,22 +93,19 @@ describe('getAvailableVersions', () => { ); it('load available versions', async () => { + const nextPageUrl = + 'https://api.adoptium.net/v3/assets/version/%5B1.0,100.0%5D?page=1&page_size=20'; spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson'); spyHttpClient .mockReturnValueOnce({ statusCode: 200, - headers: {}, + headers: {link: `<${nextPageUrl}>; rel="next"`}, result: manifestData as any }) .mockReturnValueOnce({ statusCode: 200, headers: {}, result: manifestData as any - }) - .mockReturnValueOnce({ - statusCode: 200, - headers: {}, - result: [] }); const distribution = new TemurinDistribution( @@ -123,6 +120,7 @@ describe('getAvailableVersions', () => { const availableVersions = await distribution['getAvailableVersions'](); expect(availableVersions).not.toBeNull(); expect(availableVersions.length).toBe(manifestData.length * 2); + expect(spyHttpClient).toHaveBeenNthCalledWith(2, nextPageUrl); }); it.each([ diff --git a/__tests__/util.test.ts b/__tests__/util.test.ts index 85b76069..a0c11de3 100644 --- a/__tests__/util.test.ts +++ b/__tests__/util.test.ts @@ -4,6 +4,7 @@ import * as fs from 'fs'; import * as path from 'path'; import { convertVersionToSemver, + getNextPageUrlFromLinkHeader, getVersionFromFileContent, isVersionSatisfies, isCacheFeatureAvailable, @@ -85,6 +86,27 @@ describe('convertVersionToSemver', () => { }); }); +describe('getNextPageUrlFromLinkHeader', () => { + it.each([ + [ + { + link: '; rel="next"' + }, + 'https://api.adoptium.net/v3/info/release_versions?page=1&page_size=10' + ], + [ + { + Link: '; rel="last", ; rel="next"' + }, + 'https://example.com/next?page=2' + ], + [{link: '; rel="last"'}, null], + [undefined, null] + ])('returns %s -> %s', (headers, expected) => { + expect(getNextPageUrlFromLinkHeader(headers)).toBe(expected); + }); +}); + describe('getVersionFromFileContent', () => { describe('.sdkmanrc', () => { it.each([ diff --git a/src/distributions/adopt/installer.ts b/src/distributions/adopt/installer.ts index 34c1716c..834242c4 100644 --- a/src/distributions/adopt/installer.ts +++ b/src/distributions/adopt/installer.ts @@ -14,6 +14,7 @@ import { } from '../base-models'; import { extractJdkFile, + getNextPageUrlFromLinkHeader, getDownloadArchiveExtension, isVersionSatisfies, renameWinArchive @@ -125,30 +126,23 @@ export class AdoptDistribution extends JavaBase { `jvm_impl=${this.jvmImpl.toLowerCase()}` ].join('&'); - // need to iterate through all pages to retrieve the list of all versions - // Adopt API doesn't provide way to retrieve the count of pages to iterate so infinity loop - let page_index = 0; + const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; + let availableVersionsUrl = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions: IAdoptAvailableVersions[] = []; - while (true) { - const requestArguments = `${baseRequestArguments}&page_size=20&page=${page_index}`; - const availableVersionsUrl = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; - if (core.isDebug() && page_index === 0) { - // url is identical except page_index so print it once for debug - core.debug( - `Gathering available versions from '${availableVersionsUrl}'` - ); - } + if (core.isDebug()) { + core.debug(`Gathering available versions from '${availableVersionsUrl}'`); + } - const paginationPage = ( - await this.http.getJson(availableVersionsUrl) - ).result; + while (availableVersionsUrl) { + const response = + await this.http.getJson(availableVersionsUrl); + const paginationPage = response.result; + availableVersionsUrl = getNextPageUrlFromLinkHeader(response.headers); if (paginationPage === null || paginationPage.length === 0) { - // break infinity loop because we have reached end of pagination break; } availableVersions.push(...paginationPage); - page_index++; } if (core.isDebug()) { diff --git a/src/distributions/semeru/installer.ts b/src/distributions/semeru/installer.ts index edb29480..f59f201d 100644 --- a/src/distributions/semeru/installer.ts +++ b/src/distributions/semeru/installer.ts @@ -7,6 +7,7 @@ import { import semver from 'semver'; import { extractJdkFile, + getNextPageUrlFromLinkHeader, getDownloadArchiveExtension, isVersionSatisfies, renameWinArchive @@ -155,32 +156,24 @@ export class SemeruDistribution extends JavaBase { `jvm_impl=openj9` ].join('&'); - // need to iterate through all pages to retrieve the list of all versions - // Adoptium API doesn't provide way to retrieve the count of pages to iterate so infinity loop - let page_index = 0; + const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; + let availableVersionsUrl = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions: ISemeruAvailableVersions[] = []; - while (true) { - const requestArguments = `${baseRequestArguments}&page_size=20&page=${page_index}`; - const availableVersionsUrl = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; - if (core.isDebug() && page_index === 0) { - // url is identical except page_index so print it once for debug - core.debug( - `Gathering available versions from '${availableVersionsUrl}'` - ); - } + if (core.isDebug()) { + core.debug(`Gathering available versions from '${availableVersionsUrl}'`); + } - const paginationPage = ( - await this.http.getJson( - availableVersionsUrl - ) - ).result; + while (availableVersionsUrl) { + const response = await this.http.getJson( + availableVersionsUrl + ); + const paginationPage = response.result; + availableVersionsUrl = getNextPageUrlFromLinkHeader(response.headers); if (paginationPage === null || paginationPage.length === 0) { - // break infinity loop because we have reached end of pagination break; } availableVersions.push(...paginationPage); - page_index++; } if (core.isDebug()) { diff --git a/src/distributions/temurin/installer.ts b/src/distributions/temurin/installer.ts index 8d03de74..02c3552f 100644 --- a/src/distributions/temurin/installer.ts +++ b/src/distributions/temurin/installer.ts @@ -14,6 +14,7 @@ import { } from '../base-models'; import { extractJdkFile, + getNextPageUrlFromLinkHeader, getDownloadArchiveExtension, isVersionSatisfies, renameWinArchive @@ -123,32 +124,25 @@ export class TemurinDistribution extends JavaBase { `jvm_impl=${this.jvmImpl.toLowerCase()}` ].join('&'); - // need to iterate through all pages to retrieve the list of all versions - // Adoptium API doesn't provide way to retrieve the count of pages to iterate so infinity loop - let page_index = 0; + const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; + let availableVersionsUrl = `https://api.adoptium.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions: ITemurinAvailableVersions[] = []; - while (true) { - const requestArguments = `${baseRequestArguments}&page_size=20&page=${page_index}`; - const availableVersionsUrl = `https://api.adoptium.net/v3/assets/version/${versionRange}?${requestArguments}`; - if (core.isDebug() && page_index === 0) { - // url is identical except page_index so print it once for debug - core.debug( - `Gathering available versions from '${availableVersionsUrl}'` - ); - } + if (core.isDebug()) { + core.debug(`Gathering available versions from '${availableVersionsUrl}'`); + } + + while (availableVersionsUrl) { + const response = await this.http.getJson( + availableVersionsUrl + ); + const paginationPage = response.result; + availableVersionsUrl = getNextPageUrlFromLinkHeader(response.headers); - const paginationPage = ( - await this.http.getJson( - availableVersionsUrl - ) - ).result; if (paginationPage === null || paginationPage.length === 0) { - // break infinity loop because we have reached end of pagination break; } availableVersions.push(...paginationPage); - page_index++; } if (core.isDebug()) { diff --git a/src/util.ts b/src/util.ts index 0325f7f4..43c004ec 100644 --- a/src/util.ts +++ b/src/util.ts @@ -201,6 +201,28 @@ export function getGitHubHttpHeaders(): OutgoingHttpHeaders { return headers; } +export function getNextPageUrlFromLinkHeader( + headers?: Record +): string | null { + if (!headers) { + return null; + } + + const linkHeader = headers.link ?? headers.Link; + if (!linkHeader) { + return null; + } + + const normalizedLinkHeader = Array.isArray(linkHeader) + ? linkHeader.join(',') + : linkHeader; + const nextLinkMatch = normalizedLinkHeader.match( + /<([^>]+)>\s*;\s*rel="?next"?/i + ); + + return nextLinkMatch?.[1] ?? null; +} + // Rename archive to add extension because after downloading // archive does not contain extension type and it leads to some issues // on Windows runners without PowerShell Core. From ff272af8755757591b82c838e13ee86d174d7374 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Jun 2026 15:34:50 +0000 Subject: [PATCH 2/8] Fix nullable pagination URL types and rebuild dist --- dist/cleanup/index.js | 18 +++++- dist/setup/index.js | 84 ++++++++++++++------------ src/distributions/adopt/installer.ts | 2 +- src/distributions/semeru/installer.ts | 2 +- src/distributions/temurin/installer.ts | 2 +- 5 files changed, 64 insertions(+), 44 deletions(-) diff --git a/dist/cleanup/index.js b/dist/cleanup/index.js index df5d6c0e..6804a7be 100644 --- a/dist/cleanup/index.js +++ b/dist/cleanup/index.js @@ -51888,7 +51888,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.renameWinArchive = exports.getGitHubHttpHeaders = exports.convertVersionToSemver = exports.getVersionFromFileContent = exports.isCacheFeatureAvailable = exports.isGhes = exports.isJobStatusSuccess = exports.getToolcachePath = exports.isVersionSatisfies = exports.getDownloadArchiveExtension = exports.extractJdkFile = exports.getVersionFromToolcachePath = exports.getBooleanInput = exports.getTempDir = void 0; +exports.renameWinArchive = exports.getNextPageUrlFromLinkHeader = exports.getGitHubHttpHeaders = exports.convertVersionToSemver = exports.getVersionFromFileContent = exports.isCacheFeatureAvailable = exports.isGhes = exports.isJobStatusSuccess = exports.getToolcachePath = exports.isVersionSatisfies = exports.getDownloadArchiveExtension = exports.extractJdkFile = exports.getVersionFromToolcachePath = exports.getBooleanInput = exports.getTempDir = void 0; const os_1 = __importDefault(__nccwpck_require__(22037)); const path_1 = __importDefault(__nccwpck_require__(71017)); const fs = __importStar(__nccwpck_require__(57147)); @@ -52055,6 +52055,22 @@ function getGitHubHttpHeaders() { return headers; } exports.getGitHubHttpHeaders = getGitHubHttpHeaders; +function getNextPageUrlFromLinkHeader(headers) { + var _a, _b; + if (!headers) { + return null; + } + const linkHeader = (_a = headers.link) !== null && _a !== void 0 ? _a : headers.Link; + if (!linkHeader) { + return null; + } + const normalizedLinkHeader = Array.isArray(linkHeader) + ? linkHeader.join(',') + : linkHeader; + const nextLinkMatch = normalizedLinkHeader.match(/<([^>]+)>\s*;\s*rel="?next"?/i); + return (_b = nextLinkMatch === null || nextLinkMatch === void 0 ? void 0 : nextLinkMatch[1]) !== null && _b !== void 0 ? _b : null; +} +exports.getNextPageUrlFromLinkHeader = getNextPageUrlFromLinkHeader; // Rename archive to add extension because after downloading // archive does not contain extension type and it leads to some issues // on Windows runners without PowerShell Core. diff --git a/dist/setup/index.js b/dist/setup/index.js index fb687e03..dc279330 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -77650,24 +77650,20 @@ class AdoptDistribution extends base_installer_1.JavaBase { `release_type=${releaseType}`, `jvm_impl=${this.jvmImpl.toLowerCase()}` ].join('&'); - // need to iterate through all pages to retrieve the list of all versions - // Adopt API doesn't provide way to retrieve the count of pages to iterate so infinity loop - let page_index = 0; + const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; + let availableVersionsUrl = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions = []; - while (true) { - const requestArguments = `${baseRequestArguments}&page_size=20&page=${page_index}`; - const availableVersionsUrl = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; - if (core.isDebug() && page_index === 0) { - // url is identical except page_index so print it once for debug - core.debug(`Gathering available versions from '${availableVersionsUrl}'`); - } - const paginationPage = (yield this.http.getJson(availableVersionsUrl)).result; + if (core.isDebug()) { + core.debug(`Gathering available versions from '${availableVersionsUrl}'`); + } + while (availableVersionsUrl) { + const response = yield this.http.getJson(availableVersionsUrl); + const paginationPage = response.result; + availableVersionsUrl = (0, util_1.getNextPageUrlFromLinkHeader)(response.headers); if (paginationPage === null || paginationPage.length === 0) { - // break infinity loop because we have reached end of pagination break; } availableVersions.push(...paginationPage); - page_index++; } if (core.isDebug()) { core.startGroup('Print information about available versions'); @@ -79825,24 +79821,20 @@ class SemeruDistribution extends base_installer_1.JavaBase { `release_type=${releaseType}`, `jvm_impl=openj9` ].join('&'); - // need to iterate through all pages to retrieve the list of all versions - // Adoptium API doesn't provide way to retrieve the count of pages to iterate so infinity loop - let page_index = 0; + const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; + let availableVersionsUrl = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions = []; - while (true) { - const requestArguments = `${baseRequestArguments}&page_size=20&page=${page_index}`; - const availableVersionsUrl = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; - if (core.isDebug() && page_index === 0) { - // url is identical except page_index so print it once for debug - core.debug(`Gathering available versions from '${availableVersionsUrl}'`); - } - const paginationPage = (yield this.http.getJson(availableVersionsUrl)).result; + if (core.isDebug()) { + core.debug(`Gathering available versions from '${availableVersionsUrl}'`); + } + while (availableVersionsUrl) { + const response = yield this.http.getJson(availableVersionsUrl); + const paginationPage = response.result; + availableVersionsUrl = (0, util_1.getNextPageUrlFromLinkHeader)(response.headers); if (paginationPage === null || paginationPage.length === 0) { - // break infinity loop because we have reached end of pagination break; } availableVersions.push(...paginationPage); - page_index++; } if (core.isDebug()) { core.startGroup('Print information about available versions'); @@ -79999,24 +79991,20 @@ class TemurinDistribution extends base_installer_1.JavaBase { `release_type=${releaseType}`, `jvm_impl=${this.jvmImpl.toLowerCase()}` ].join('&'); - // need to iterate through all pages to retrieve the list of all versions - // Adoptium API doesn't provide way to retrieve the count of pages to iterate so infinity loop - let page_index = 0; + const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; + let availableVersionsUrl = `https://api.adoptium.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions = []; - while (true) { - const requestArguments = `${baseRequestArguments}&page_size=20&page=${page_index}`; - const availableVersionsUrl = `https://api.adoptium.net/v3/assets/version/${versionRange}?${requestArguments}`; - if (core.isDebug() && page_index === 0) { - // url is identical except page_index so print it once for debug - core.debug(`Gathering available versions from '${availableVersionsUrl}'`); - } - const paginationPage = (yield this.http.getJson(availableVersionsUrl)).result; + if (core.isDebug()) { + core.debug(`Gathering available versions from '${availableVersionsUrl}'`); + } + while (availableVersionsUrl) { + const response = yield this.http.getJson(availableVersionsUrl); + const paginationPage = response.result; + availableVersionsUrl = (0, util_1.getNextPageUrlFromLinkHeader)(response.headers); if (paginationPage === null || paginationPage.length === 0) { - // break infinity loop because we have reached end of pagination break; } availableVersions.push(...paginationPage); - page_index++; } if (core.isDebug()) { core.startGroup('Print information about available versions'); @@ -80642,7 +80630,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.renameWinArchive = exports.getGitHubHttpHeaders = exports.convertVersionToSemver = exports.getVersionFromFileContent = exports.isCacheFeatureAvailable = exports.isGhes = exports.isJobStatusSuccess = exports.getToolcachePath = exports.isVersionSatisfies = exports.getDownloadArchiveExtension = exports.extractJdkFile = exports.getVersionFromToolcachePath = exports.getBooleanInput = exports.getTempDir = void 0; +exports.renameWinArchive = exports.getNextPageUrlFromLinkHeader = exports.getGitHubHttpHeaders = exports.convertVersionToSemver = exports.getVersionFromFileContent = exports.isCacheFeatureAvailable = exports.isGhes = exports.isJobStatusSuccess = exports.getToolcachePath = exports.isVersionSatisfies = exports.getDownloadArchiveExtension = exports.extractJdkFile = exports.getVersionFromToolcachePath = exports.getBooleanInput = exports.getTempDir = void 0; const os_1 = __importDefault(__nccwpck_require__(22037)); const path_1 = __importDefault(__nccwpck_require__(71017)); const fs = __importStar(__nccwpck_require__(57147)); @@ -80809,6 +80797,22 @@ function getGitHubHttpHeaders() { return headers; } exports.getGitHubHttpHeaders = getGitHubHttpHeaders; +function getNextPageUrlFromLinkHeader(headers) { + var _a, _b; + if (!headers) { + return null; + } + const linkHeader = (_a = headers.link) !== null && _a !== void 0 ? _a : headers.Link; + if (!linkHeader) { + return null; + } + const normalizedLinkHeader = Array.isArray(linkHeader) + ? linkHeader.join(',') + : linkHeader; + const nextLinkMatch = normalizedLinkHeader.match(/<([^>]+)>\s*;\s*rel="?next"?/i); + return (_b = nextLinkMatch === null || nextLinkMatch === void 0 ? void 0 : nextLinkMatch[1]) !== null && _b !== void 0 ? _b : null; +} +exports.getNextPageUrlFromLinkHeader = getNextPageUrlFromLinkHeader; // Rename archive to add extension because after downloading // archive does not contain extension type and it leads to some issues // on Windows runners without PowerShell Core. diff --git a/src/distributions/adopt/installer.ts b/src/distributions/adopt/installer.ts index 834242c4..5624cf5c 100644 --- a/src/distributions/adopt/installer.ts +++ b/src/distributions/adopt/installer.ts @@ -127,7 +127,7 @@ export class AdoptDistribution extends JavaBase { ].join('&'); const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; - let availableVersionsUrl = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; + let availableVersionsUrl: string | null = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions: IAdoptAvailableVersions[] = []; if (core.isDebug()) { core.debug(`Gathering available versions from '${availableVersionsUrl}'`); diff --git a/src/distributions/semeru/installer.ts b/src/distributions/semeru/installer.ts index f59f201d..9b161909 100644 --- a/src/distributions/semeru/installer.ts +++ b/src/distributions/semeru/installer.ts @@ -157,7 +157,7 @@ export class SemeruDistribution extends JavaBase { ].join('&'); const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; - let availableVersionsUrl = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; + let availableVersionsUrl: string | null = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions: ISemeruAvailableVersions[] = []; if (core.isDebug()) { core.debug(`Gathering available versions from '${availableVersionsUrl}'`); diff --git a/src/distributions/temurin/installer.ts b/src/distributions/temurin/installer.ts index 02c3552f..9b5aaa55 100644 --- a/src/distributions/temurin/installer.ts +++ b/src/distributions/temurin/installer.ts @@ -125,7 +125,7 @@ export class TemurinDistribution extends JavaBase { ].join('&'); const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; - let availableVersionsUrl = `https://api.adoptium.net/v3/assets/version/${versionRange}?${requestArguments}`; + let availableVersionsUrl: string | null = `https://api.adoptium.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions: ITemurinAvailableVersions[] = []; if (core.isDebug()) { core.debug(`Gathering available versions from '${availableVersionsUrl}'`); From 7ee69becdcba23655a04b193aa2344c65889d29b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Jun 2026 15:50:15 +0000 Subject: [PATCH 3/8] Add 1000-page safeguard for JetBrains pagination --- .../distributors/jetbrains-installer.test.ts | 31 +++++++++++++++++++ src/distributions/jetbrains/installer.ts | 10 +++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/__tests__/distributors/jetbrains-installer.test.ts b/__tests__/distributors/jetbrains-installer.test.ts index bf1dc15d..afc41c47 100644 --- a/__tests__/distributors/jetbrains-installer.test.ts +++ b/__tests__/distributors/jetbrains-installer.test.ts @@ -9,6 +9,8 @@ import * as core from '@actions/core'; describe('getAvailableVersions', () => { let spyHttpClient: jest.SpyInstance; let spyCoreError: jest.SpyInstance; + let spyCoreWarning: jest.SpyInstance; + let spyHeadRequest: jest.SpyInstance; beforeEach(() => { spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson'); @@ -21,6 +23,14 @@ describe('getAvailableVersions', () => { // Mock core.error to suppress error logs spyCoreError = jest.spyOn(core, 'error'); spyCoreError.mockImplementation(() => {}); + spyCoreWarning = jest.spyOn(core, 'warning'); + spyCoreWarning.mockImplementation(() => {}); + spyHeadRequest = jest.spyOn(HttpClient.prototype, 'head'); + spyHeadRequest.mockResolvedValue({ + message: { + statusCode: 404 + } + } as any); }); afterEach(() => { @@ -50,6 +60,27 @@ describe('getAvailableVersions', () => { os.platform() === 'win32' ? manifestData.length : manifestData.length + 2; expect(availableVersions.length).toBe(length); }, 10_000); + + it('stops pagination after 1000 pages as a safeguard', async () => { + spyHttpClient.mockResolvedValue({ + statusCode: 200, + headers: {}, + result: [{tag_name: 'jbr17-b87.7', name: 'jbr17-b87.7', prerelease: false}] + }); + + const distribution = new JetBrainsDistribution({ + version: '17', + architecture: 'x64', + packageType: 'jdk', + checkLatest: false + }); + await distribution['getAvailableVersions'](); + + expect(spyHttpClient).toHaveBeenCalledTimes(1000); + expect(spyCoreWarning).toHaveBeenCalledWith( + expect.stringContaining('Reached pagination safeguard limit (1000 pages)') + ); + }, 20_000); }); describe('findPackageForDownload', () => { diff --git a/src/distributions/jetbrains/installer.ts b/src/distributions/jetbrains/installer.ts index e3458e1e..15c4cd6f 100644 --- a/src/distributions/jetbrains/installer.ts +++ b/src/distributions/jetbrains/installer.ts @@ -16,6 +16,8 @@ import {extractJdkFile, isVersionSatisfies} from '../../util'; import {OutgoingHttpHeaders} from 'http'; import {HttpCodes} from '@actions/http-client'; +const MAX_PAGINATION_PAGES = 1000; + export class JetBrainsDistribution extends JavaBase { constructor(installerOptions: JavaInstallerOptions) { super('JetBrains', installerOptions); @@ -93,7 +95,7 @@ export class JetBrainsDistribution extends JavaBase { const rawVersions: IJetBrainsRawVersion[] = []; const bearerToken = process.env.GITHUB_TOKEN; - while (true) { + while (page_index <= MAX_PAGINATION_PAGES) { const requestArguments = `per_page=100&page=${page_index}`; const requestHeaders: OutgoingHttpHeaders = {}; @@ -129,6 +131,12 @@ export class JetBrainsDistribution extends JavaBase { page_index++; } + if (page_index > MAX_PAGINATION_PAGES) { + core.warning( + `Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing JetBrains runtime releases.` + ); + } + if (this.stable) { // Add versions not available from the API but are downloadable const hidden = ['11_0_10b1145.115', '11_0_11b1341.60']; From a22487fd8ce1511df26df8e932be34ad4a4e171d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Jun 2026 15:51:14 +0000 Subject: [PATCH 4/8] Adjust plan for pagination safeguard scope --- dist/setup/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index dc279330..622b4c3e 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -78728,6 +78728,7 @@ const semver_1 = __importDefault(__nccwpck_require__(11383)); const base_installer_1 = __nccwpck_require__(59741); const util_1 = __nccwpck_require__(92629); const http_client_1 = __nccwpck_require__(96255); +const MAX_PAGINATION_PAGES = 1000; class JetBrainsDistribution extends base_installer_1.JavaBase { constructor(installerOptions) { super('JetBrains', installerOptions); @@ -78780,7 +78781,7 @@ class JetBrainsDistribution extends base_installer_1.JavaBase { let page_index = 1; const rawVersions = []; const bearerToken = process.env.GITHUB_TOKEN; - while (true) { + while (page_index <= MAX_PAGINATION_PAGES) { const requestArguments = `per_page=100&page=${page_index}`; const requestHeaders = {}; if (bearerToken) { @@ -78804,6 +78805,9 @@ class JetBrainsDistribution extends base_installer_1.JavaBase { rawVersions.push(...paginationPage); page_index++; } + if (page_index > MAX_PAGINATION_PAGES) { + core.warning(`Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing JetBrains runtime releases.`); + } if (this.stable) { // Add versions not available from the API but are downloadable const hidden = ['11_0_10b1145.115', '11_0_11b1341.60']; From 3b472a4e313e4d0d540a6d45b61a71ad187dedd0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Jun 2026 15:52:24 +0000 Subject: [PATCH 5/8] Move pagination safeguard to non-JetBrains installers --- .../distributors/adopt-installer.test.ts | 29 +++++++++++++++++ .../distributors/jetbrains-installer.test.ts | 31 ------------------- .../distributors/semeru-installer.test.ts | 26 ++++++++++++++++ .../distributors/temurin-installer.test.ts | 29 +++++++++++++++++ src/distributions/adopt/installer.ts | 11 +++++++ src/distributions/jetbrains/installer.ts | 10 +----- src/distributions/semeru/installer.ts | 11 +++++++ src/distributions/temurin/installer.ts | 11 +++++++ 8 files changed, 118 insertions(+), 40 deletions(-) diff --git a/__tests__/distributors/adopt-installer.test.ts b/__tests__/distributors/adopt-installer.test.ts index fa96279d..5442d3f6 100644 --- a/__tests__/distributors/adopt-installer.test.ts +++ b/__tests__/distributors/adopt-installer.test.ts @@ -14,6 +14,7 @@ import * as core from '@actions/core'; describe('getAvailableVersions', () => { let spyHttpClient: jest.SpyInstance; let spyCoreError: jest.SpyInstance; + let spyCoreWarning: jest.SpyInstance; beforeEach(() => { spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson'); @@ -26,6 +27,8 @@ describe('getAvailableVersions', () => { // Mock core.error to suppress error logs spyCoreError = jest.spyOn(core, 'error'); spyCoreError.mockImplementation(() => {}); + spyCoreWarning = jest.spyOn(core, 'warning'); + spyCoreWarning.mockImplementation(() => {}); }); afterEach(() => { @@ -166,6 +169,32 @@ describe('getAvailableVersions', () => { expect(spyHttpClient).toHaveBeenNthCalledWith(2, nextPageUrl); }); + it('stops pagination after 1000 pages as a safeguard', async () => { + const nextPageUrl = 'https://example.com/releases?page=2'; + spyHttpClient.mockReturnValue({ + statusCode: 200, + headers: {link: `<${nextPageUrl}>; rel="next"`}, + result: [{version_data: {semver: '17.0.1'}, binaries: []}] as any + }); + + const distribution = new AdoptDistribution( + { + version: '11', + architecture: 'x64', + packageType: 'jdk', + checkLatest: false + }, + AdoptImplementation.Hotspot + ); + + await distribution['getAvailableVersions'](); + + expect(spyHttpClient).toHaveBeenCalledTimes(1000); + expect(spyCoreWarning).toHaveBeenCalledWith( + expect.stringContaining('Reached pagination safeguard limit (1000 pages)') + ); + }); + it.each([ [AdoptImplementation.Hotspot, 'jdk', 'Java_Adopt_jdk'], [AdoptImplementation.Hotspot, 'jre', 'Java_Adopt_jre'], diff --git a/__tests__/distributors/jetbrains-installer.test.ts b/__tests__/distributors/jetbrains-installer.test.ts index afc41c47..bf1dc15d 100644 --- a/__tests__/distributors/jetbrains-installer.test.ts +++ b/__tests__/distributors/jetbrains-installer.test.ts @@ -9,8 +9,6 @@ import * as core from '@actions/core'; describe('getAvailableVersions', () => { let spyHttpClient: jest.SpyInstance; let spyCoreError: jest.SpyInstance; - let spyCoreWarning: jest.SpyInstance; - let spyHeadRequest: jest.SpyInstance; beforeEach(() => { spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson'); @@ -23,14 +21,6 @@ describe('getAvailableVersions', () => { // Mock core.error to suppress error logs spyCoreError = jest.spyOn(core, 'error'); spyCoreError.mockImplementation(() => {}); - spyCoreWarning = jest.spyOn(core, 'warning'); - spyCoreWarning.mockImplementation(() => {}); - spyHeadRequest = jest.spyOn(HttpClient.prototype, 'head'); - spyHeadRequest.mockResolvedValue({ - message: { - statusCode: 404 - } - } as any); }); afterEach(() => { @@ -60,27 +50,6 @@ describe('getAvailableVersions', () => { os.platform() === 'win32' ? manifestData.length : manifestData.length + 2; expect(availableVersions.length).toBe(length); }, 10_000); - - it('stops pagination after 1000 pages as a safeguard', async () => { - spyHttpClient.mockResolvedValue({ - statusCode: 200, - headers: {}, - result: [{tag_name: 'jbr17-b87.7', name: 'jbr17-b87.7', prerelease: false}] - }); - - const distribution = new JetBrainsDistribution({ - version: '17', - architecture: 'x64', - packageType: 'jdk', - checkLatest: false - }); - await distribution['getAvailableVersions'](); - - expect(spyHttpClient).toHaveBeenCalledTimes(1000); - expect(spyCoreWarning).toHaveBeenCalledWith( - expect.stringContaining('Reached pagination safeguard limit (1000 pages)') - ); - }, 20_000); }); describe('findPackageForDownload', () => { diff --git a/__tests__/distributors/semeru-installer.test.ts b/__tests__/distributors/semeru-installer.test.ts index d415e747..ffef9530 100644 --- a/__tests__/distributors/semeru-installer.test.ts +++ b/__tests__/distributors/semeru-installer.test.ts @@ -9,6 +9,7 @@ import * as core from '@actions/core'; describe('getAvailableVersions', () => { let spyHttpClient: jest.SpyInstance; let spyCoreError: jest.SpyInstance; + let spyCoreWarning: jest.SpyInstance; beforeEach(() => { spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson'); @@ -20,6 +21,8 @@ describe('getAvailableVersions', () => { // Mock core.error to suppress error logs spyCoreError = jest.spyOn(core, 'error'); spyCoreError.mockImplementation(() => {}); + spyCoreWarning = jest.spyOn(core, 'warning'); + spyCoreWarning.mockImplementation(() => {}); }); afterEach(() => { @@ -109,6 +112,29 @@ describe('getAvailableVersions', () => { expect(spyHttpClient).toHaveBeenNthCalledWith(2, nextPageUrl); }); + it('stops pagination after 1000 pages as a safeguard', async () => { + const nextPageUrl = 'https://example.com/releases?page=2'; + spyHttpClient.mockReturnValue({ + statusCode: 200, + headers: {link: `<${nextPageUrl}>; rel="next"`}, + result: [{version_data: {semver: '17.0.1'}, binaries: []}] as any + }); + + const distribution = new SemeruDistribution({ + version: '8', + architecture: 'x64', + packageType: 'jdk', + checkLatest: false + }); + + await distribution['getAvailableVersions'](); + + expect(spyHttpClient).toHaveBeenCalledTimes(1000); + expect(spyCoreWarning).toHaveBeenCalledWith( + expect.stringContaining('Reached pagination safeguard limit (1000 pages)') + ); + }); + it.each([ ['jdk', 'Java_IBM_Semeru_jdk'], ['jre', 'Java_IBM_Semeru_jre'] diff --git a/__tests__/distributors/temurin-installer.test.ts b/__tests__/distributors/temurin-installer.test.ts index 93930179..49a52a7d 100644 --- a/__tests__/distributors/temurin-installer.test.ts +++ b/__tests__/distributors/temurin-installer.test.ts @@ -12,6 +12,7 @@ import * as core from '@actions/core'; describe('getAvailableVersions', () => { let spyHttpClient: jest.SpyInstance; let spyCoreError: jest.SpyInstance; + let spyCoreWarning: jest.SpyInstance; beforeEach(() => { spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson'); @@ -23,6 +24,8 @@ describe('getAvailableVersions', () => { // Mock core.error to suppress error logs spyCoreError = jest.spyOn(core, 'error'); spyCoreError.mockImplementation(() => {}); + spyCoreWarning = jest.spyOn(core, 'warning'); + spyCoreWarning.mockImplementation(() => {}); }); afterEach(() => { @@ -123,6 +126,32 @@ describe('getAvailableVersions', () => { expect(spyHttpClient).toHaveBeenNthCalledWith(2, nextPageUrl); }); + it('stops pagination after 1000 pages as a safeguard', async () => { + const nextPageUrl = 'https://example.com/releases?page=2'; + spyHttpClient.mockReturnValue({ + statusCode: 200, + headers: {link: `<${nextPageUrl}>; rel="next"`}, + result: [{version_data: {semver: '17.0.1'}, binaries: []}] as any + }); + + const distribution = new TemurinDistribution( + { + version: '8', + architecture: 'x64', + packageType: 'jdk', + checkLatest: false + }, + TemurinImplementation.Hotspot + ); + + await distribution['getAvailableVersions'](); + + expect(spyHttpClient).toHaveBeenCalledTimes(1000); + expect(spyCoreWarning).toHaveBeenCalledWith( + expect.stringContaining('Reached pagination safeguard limit (1000 pages)') + ); + }); + it.each([ [TemurinImplementation.Hotspot, 'jdk', 'Java_Temurin-Hotspot_jdk'], [TemurinImplementation.Hotspot, 'jre', 'Java_Temurin-Hotspot_jre'] diff --git a/src/distributions/adopt/installer.ts b/src/distributions/adopt/installer.ts index 5624cf5c..3827a0c8 100644 --- a/src/distributions/adopt/installer.ts +++ b/src/distributions/adopt/installer.ts @@ -20,6 +20,8 @@ import { renameWinArchive } from '../../util'; +const MAX_PAGINATION_PAGES = 1000; + export enum AdoptImplementation { Hotspot = 'Hotspot', OpenJ9 = 'OpenJ9' @@ -129,11 +131,13 @@ export class AdoptDistribution extends JavaBase { const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; let availableVersionsUrl: string | null = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions: IAdoptAvailableVersions[] = []; + let pageCount = 0; if (core.isDebug()) { core.debug(`Gathering available versions from '${availableVersionsUrl}'`); } while (availableVersionsUrl) { + pageCount++; const response = await this.http.getJson(availableVersionsUrl); const paginationPage = response.result; @@ -143,6 +147,13 @@ export class AdoptDistribution extends JavaBase { } availableVersions.push(...paginationPage); + + if (pageCount >= MAX_PAGINATION_PAGES && availableVersionsUrl) { + core.warning( + `Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing Adopt releases.` + ); + break; + } } if (core.isDebug()) { diff --git a/src/distributions/jetbrains/installer.ts b/src/distributions/jetbrains/installer.ts index 15c4cd6f..e3458e1e 100644 --- a/src/distributions/jetbrains/installer.ts +++ b/src/distributions/jetbrains/installer.ts @@ -16,8 +16,6 @@ import {extractJdkFile, isVersionSatisfies} from '../../util'; import {OutgoingHttpHeaders} from 'http'; import {HttpCodes} from '@actions/http-client'; -const MAX_PAGINATION_PAGES = 1000; - export class JetBrainsDistribution extends JavaBase { constructor(installerOptions: JavaInstallerOptions) { super('JetBrains', installerOptions); @@ -95,7 +93,7 @@ export class JetBrainsDistribution extends JavaBase { const rawVersions: IJetBrainsRawVersion[] = []; const bearerToken = process.env.GITHUB_TOKEN; - while (page_index <= MAX_PAGINATION_PAGES) { + while (true) { const requestArguments = `per_page=100&page=${page_index}`; const requestHeaders: OutgoingHttpHeaders = {}; @@ -131,12 +129,6 @@ export class JetBrainsDistribution extends JavaBase { page_index++; } - if (page_index > MAX_PAGINATION_PAGES) { - core.warning( - `Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing JetBrains runtime releases.` - ); - } - if (this.stable) { // Add versions not available from the API but are downloadable const hidden = ['11_0_10b1145.115', '11_0_11b1341.60']; diff --git a/src/distributions/semeru/installer.ts b/src/distributions/semeru/installer.ts index 9b161909..4b1317fa 100644 --- a/src/distributions/semeru/installer.ts +++ b/src/distributions/semeru/installer.ts @@ -18,6 +18,8 @@ import fs from 'fs'; import path from 'path'; import {ISemeruAvailableVersions} from './models'; +const MAX_PAGINATION_PAGES = 1000; + const supportedArchitectures = [ 'x64', 'x86', @@ -159,11 +161,13 @@ export class SemeruDistribution extends JavaBase { const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; let availableVersionsUrl: string | null = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions: ISemeruAvailableVersions[] = []; + let pageCount = 0; if (core.isDebug()) { core.debug(`Gathering available versions from '${availableVersionsUrl}'`); } while (availableVersionsUrl) { + pageCount++; const response = await this.http.getJson( availableVersionsUrl ); @@ -174,6 +178,13 @@ export class SemeruDistribution extends JavaBase { } availableVersions.push(...paginationPage); + + if (pageCount >= MAX_PAGINATION_PAGES && availableVersionsUrl) { + core.warning( + `Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing Semeru releases.` + ); + break; + } } if (core.isDebug()) { diff --git a/src/distributions/temurin/installer.ts b/src/distributions/temurin/installer.ts index 9b5aaa55..0f566139 100644 --- a/src/distributions/temurin/installer.ts +++ b/src/distributions/temurin/installer.ts @@ -20,6 +20,8 @@ import { renameWinArchive } from '../../util'; +const MAX_PAGINATION_PAGES = 1000; + export enum TemurinImplementation { Hotspot = 'Hotspot' } @@ -127,11 +129,13 @@ export class TemurinDistribution extends JavaBase { const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; let availableVersionsUrl: string | null = `https://api.adoptium.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions: ITemurinAvailableVersions[] = []; + let pageCount = 0; if (core.isDebug()) { core.debug(`Gathering available versions from '${availableVersionsUrl}'`); } while (availableVersionsUrl) { + pageCount++; const response = await this.http.getJson( availableVersionsUrl ); @@ -143,6 +147,13 @@ export class TemurinDistribution extends JavaBase { } availableVersions.push(...paginationPage); + + if (pageCount >= MAX_PAGINATION_PAGES && availableVersionsUrl) { + core.warning( + `Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing Temurin releases.` + ); + break; + } } if (core.isDebug()) { From 870106f6947a7c1e0525860bccbefee2c957e73c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Jun 2026 15:56:57 +0000 Subject: [PATCH 6/8] Add 1000-page safeguard to Adopt Temurin and Semeru pagination --- dist/setup/index.js | 27 +++++++++++++++++++++----- src/distributions/adopt/installer.ts | 2 +- src/distributions/semeru/installer.ts | 2 +- src/distributions/temurin/installer.ts | 2 +- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index 622b4c3e..5dc4a958 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -77569,6 +77569,7 @@ const path_1 = __importDefault(__nccwpck_require__(71017)); const semver_1 = __importDefault(__nccwpck_require__(11383)); const base_installer_1 = __nccwpck_require__(59741); const util_1 = __nccwpck_require__(92629); +const MAX_PAGINATION_PAGES = 1000; var AdoptImplementation; (function (AdoptImplementation) { AdoptImplementation["Hotspot"] = "Hotspot"; @@ -77653,10 +77654,12 @@ class AdoptDistribution extends base_installer_1.JavaBase { const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; let availableVersionsUrl = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions = []; + let pageCount = 0; if (core.isDebug()) { core.debug(`Gathering available versions from '${availableVersionsUrl}'`); } while (availableVersionsUrl) { + pageCount++; const response = yield this.http.getJson(availableVersionsUrl); const paginationPage = response.result; availableVersionsUrl = (0, util_1.getNextPageUrlFromLinkHeader)(response.headers); @@ -77664,6 +77667,10 @@ class AdoptDistribution extends base_installer_1.JavaBase { break; } availableVersions.push(...paginationPage); + if (pageCount >= MAX_PAGINATION_PAGES) { + core.warning(`Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing Adopt releases.`); + break; + } } if (core.isDebug()) { core.startGroup('Print information about available versions'); @@ -78728,7 +78735,6 @@ const semver_1 = __importDefault(__nccwpck_require__(11383)); const base_installer_1 = __nccwpck_require__(59741); const util_1 = __nccwpck_require__(92629); const http_client_1 = __nccwpck_require__(96255); -const MAX_PAGINATION_PAGES = 1000; class JetBrainsDistribution extends base_installer_1.JavaBase { constructor(installerOptions) { super('JetBrains', installerOptions); @@ -78781,7 +78787,7 @@ class JetBrainsDistribution extends base_installer_1.JavaBase { let page_index = 1; const rawVersions = []; const bearerToken = process.env.GITHUB_TOKEN; - while (page_index <= MAX_PAGINATION_PAGES) { + while (true) { const requestArguments = `per_page=100&page=${page_index}`; const requestHeaders = {}; if (bearerToken) { @@ -78805,9 +78811,6 @@ class JetBrainsDistribution extends base_installer_1.JavaBase { rawVersions.push(...paginationPage); page_index++; } - if (page_index > MAX_PAGINATION_PAGES) { - core.warning(`Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing JetBrains runtime releases.`); - } if (this.stable) { // Add versions not available from the API but are downloadable const hidden = ['11_0_10b1145.115', '11_0_11b1341.60']; @@ -79730,6 +79733,7 @@ const core = __importStar(__nccwpck_require__(42186)); const tc = __importStar(__nccwpck_require__(27784)); const fs_1 = __importDefault(__nccwpck_require__(57147)); const path_1 = __importDefault(__nccwpck_require__(71017)); +const MAX_PAGINATION_PAGES = 1000; const supportedArchitectures = [ 'x64', 'x86', @@ -79828,10 +79832,12 @@ class SemeruDistribution extends base_installer_1.JavaBase { const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; let availableVersionsUrl = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions = []; + let pageCount = 0; if (core.isDebug()) { core.debug(`Gathering available versions from '${availableVersionsUrl}'`); } while (availableVersionsUrl) { + pageCount++; const response = yield this.http.getJson(availableVersionsUrl); const paginationPage = response.result; availableVersionsUrl = (0, util_1.getNextPageUrlFromLinkHeader)(response.headers); @@ -79839,6 +79845,10 @@ class SemeruDistribution extends base_installer_1.JavaBase { break; } availableVersions.push(...paginationPage); + if (pageCount >= MAX_PAGINATION_PAGES) { + core.warning(`Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing Semeru releases.`); + break; + } } if (core.isDebug()) { core.startGroup('Print information about available versions'); @@ -79916,6 +79926,7 @@ const path_1 = __importDefault(__nccwpck_require__(71017)); const semver_1 = __importDefault(__nccwpck_require__(11383)); const base_installer_1 = __nccwpck_require__(59741); const util_1 = __nccwpck_require__(92629); +const MAX_PAGINATION_PAGES = 1000; var TemurinImplementation; (function (TemurinImplementation) { TemurinImplementation["Hotspot"] = "Hotspot"; @@ -79998,10 +80009,12 @@ class TemurinDistribution extends base_installer_1.JavaBase { const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; let availableVersionsUrl = `https://api.adoptium.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions = []; + let pageCount = 0; if (core.isDebug()) { core.debug(`Gathering available versions from '${availableVersionsUrl}'`); } while (availableVersionsUrl) { + pageCount++; const response = yield this.http.getJson(availableVersionsUrl); const paginationPage = response.result; availableVersionsUrl = (0, util_1.getNextPageUrlFromLinkHeader)(response.headers); @@ -80009,6 +80022,10 @@ class TemurinDistribution extends base_installer_1.JavaBase { break; } availableVersions.push(...paginationPage); + if (pageCount >= MAX_PAGINATION_PAGES) { + core.warning(`Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing Temurin releases.`); + break; + } } if (core.isDebug()) { core.startGroup('Print information about available versions'); diff --git a/src/distributions/adopt/installer.ts b/src/distributions/adopt/installer.ts index 3827a0c8..3320ed3d 100644 --- a/src/distributions/adopt/installer.ts +++ b/src/distributions/adopt/installer.ts @@ -148,7 +148,7 @@ export class AdoptDistribution extends JavaBase { availableVersions.push(...paginationPage); - if (pageCount >= MAX_PAGINATION_PAGES && availableVersionsUrl) { + if (pageCount >= MAX_PAGINATION_PAGES) { core.warning( `Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing Adopt releases.` ); diff --git a/src/distributions/semeru/installer.ts b/src/distributions/semeru/installer.ts index 4b1317fa..6d469f0a 100644 --- a/src/distributions/semeru/installer.ts +++ b/src/distributions/semeru/installer.ts @@ -179,7 +179,7 @@ export class SemeruDistribution extends JavaBase { availableVersions.push(...paginationPage); - if (pageCount >= MAX_PAGINATION_PAGES && availableVersionsUrl) { + if (pageCount >= MAX_PAGINATION_PAGES) { core.warning( `Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing Semeru releases.` ); diff --git a/src/distributions/temurin/installer.ts b/src/distributions/temurin/installer.ts index 0f566139..b5dfb4e5 100644 --- a/src/distributions/temurin/installer.ts +++ b/src/distributions/temurin/installer.ts @@ -148,7 +148,7 @@ export class TemurinDistribution extends JavaBase { availableVersions.push(...paginationPage); - if (pageCount >= MAX_PAGINATION_PAGES && availableVersionsUrl) { + if (pageCount >= MAX_PAGINATION_PAGES) { core.warning( `Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing Temurin releases.` ); From 9663ddbae523ab6e4374821ec15bbdbfe1cb9298 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Jun 2026 16:10:06 +0000 Subject: [PATCH 7/8] Fix Prettier formatting in adopt, semeru, and temurin installer files --- src/distributions/adopt/installer.ts | 7 +++++-- src/distributions/semeru/installer.ts | 10 ++++++---- src/distributions/temurin/installer.ts | 10 ++++++---- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/distributions/adopt/installer.ts b/src/distributions/adopt/installer.ts index 3320ed3d..e1200564 100644 --- a/src/distributions/adopt/installer.ts +++ b/src/distributions/adopt/installer.ts @@ -129,7 +129,8 @@ export class AdoptDistribution extends JavaBase { ].join('&'); const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; - let availableVersionsUrl: string | null = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; + let availableVersionsUrl: string | null = + `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions: IAdoptAvailableVersions[] = []; let pageCount = 0; if (core.isDebug()) { @@ -139,7 +140,9 @@ export class AdoptDistribution extends JavaBase { while (availableVersionsUrl) { pageCount++; const response = - await this.http.getJson(availableVersionsUrl); + await this.http.getJson( + availableVersionsUrl + ); const paginationPage = response.result; availableVersionsUrl = getNextPageUrlFromLinkHeader(response.headers); if (paginationPage === null || paginationPage.length === 0) { diff --git a/src/distributions/semeru/installer.ts b/src/distributions/semeru/installer.ts index 6d469f0a..14adc89f 100644 --- a/src/distributions/semeru/installer.ts +++ b/src/distributions/semeru/installer.ts @@ -159,7 +159,8 @@ export class SemeruDistribution extends JavaBase { ].join('&'); const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; - let availableVersionsUrl: string | null = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; + let availableVersionsUrl: string | null = + `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions: ISemeruAvailableVersions[] = []; let pageCount = 0; if (core.isDebug()) { @@ -168,9 +169,10 @@ export class SemeruDistribution extends JavaBase { while (availableVersionsUrl) { pageCount++; - const response = await this.http.getJson( - availableVersionsUrl - ); + const response = + await this.http.getJson( + availableVersionsUrl + ); const paginationPage = response.result; availableVersionsUrl = getNextPageUrlFromLinkHeader(response.headers); if (paginationPage === null || paginationPage.length === 0) { diff --git a/src/distributions/temurin/installer.ts b/src/distributions/temurin/installer.ts index b5dfb4e5..225ced96 100644 --- a/src/distributions/temurin/installer.ts +++ b/src/distributions/temurin/installer.ts @@ -127,7 +127,8 @@ export class TemurinDistribution extends JavaBase { ].join('&'); const requestArguments = `${baseRequestArguments}&page_size=20&page=0`; - let availableVersionsUrl: string | null = `https://api.adoptium.net/v3/assets/version/${versionRange}?${requestArguments}`; + let availableVersionsUrl: string | null = + `https://api.adoptium.net/v3/assets/version/${versionRange}?${requestArguments}`; const availableVersions: ITemurinAvailableVersions[] = []; let pageCount = 0; if (core.isDebug()) { @@ -136,9 +137,10 @@ export class TemurinDistribution extends JavaBase { while (availableVersionsUrl) { pageCount++; - const response = await this.http.getJson( - availableVersionsUrl - ); + const response = + await this.http.getJson( + availableVersionsUrl + ); const paginationPage = response.result; availableVersionsUrl = getNextPageUrlFromLinkHeader(response.headers); From b5ba67c2b3dd9b55cf118dae1b6ab9f9f1001b6d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Jun 2026 16:19:16 +0000 Subject: [PATCH 8/8] Fix CI audit failure by updating vulnerable transitive deps --- package-lock.json | 62 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 24f6a21f..5b39f749 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1465,6 +1465,18 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@nodable/entities": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.1.tgz", + "integrity": "sha512-Pig3HxDIoMgjdEH8OCf/dkcTmLFjJRjWuq8jSnklu284/TKOPibSRERmOykiwmyXTtv61mP+44f3GMx0tLAyjg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ], + "license": "MIT" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3032,9 +3044,9 @@ "dev": true }, "node_modules/fast-xml-builder": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz", - "integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz", + "integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==", "funding": [ { "type": "github", @@ -3043,13 +3055,14 @@ ], "license": "MIT", "dependencies": { - "path-expression-matcher": "^1.1.3" + "path-expression-matcher": "^1.5.0", + "xml-naming": "^0.1.0" } }, "node_modules/fast-xml-parser": { - "version": "5.5.10", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.10.tgz", - "integrity": "sha512-go2J2xODMc32hT+4Xr/bBGXMaIoiCwrwp2mMtAvKyvEFW6S/v5Gn2pBmE4nvbwNjGhpcAiOwEv7R6/GZ6XRa9w==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.8.0.tgz", + "integrity": "sha512-6bIM7fsJxeo3uXv7OncQYsBAMPJ7V16Slahl/6M98C/i2q+vB1+4a0MtrvYwDFEUrwDSbAmeLDRXsOBwrL7yAg==", "funding": [ { "type": "github", @@ -3058,9 +3071,11 @@ ], "license": "MIT", "dependencies": { - "fast-xml-builder": "^1.1.4", - "path-expression-matcher": "^1.2.1", - "strnum": "^2.2.2" + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.2.0", + "path-expression-matcher": "^1.5.0", + "strnum": "^2.3.0", + "xml-naming": "^0.1.0" }, "bin": { "fxparser": "src/cli/cli.js" @@ -4562,9 +4577,9 @@ } }, "node_modules/path-expression-matcher": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.4.0.tgz", - "integrity": "sha512-s4DQMxIdhj3jLFWd9LxHOplj4p9yQ4ffMGowFf3cpEgrrJjEhN0V5nxw4Ye1EViAGDoL4/1AeO6qHpqYPOzE4Q==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz", + "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==", "funding": [ { "type": "github", @@ -5102,9 +5117,9 @@ } }, "node_modules/strnum": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.3.tgz", - "integrity": "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.3.0.tgz", + "integrity": "sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==", "funding": [ { "type": "github", @@ -5438,6 +5453,21 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/xml-naming": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz", + "integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/xmlbuilder2": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/xmlbuilder2/-/xmlbuilder2-4.0.3.tgz",