From 651865a8a827a8cb6d8edd87d3b47eb2ca23a5e8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Jun 2026 22:08:46 +0000 Subject: [PATCH] refactor: simplify GraalVM Community release resolution --- dist/setup/index.js | 76 +++++++-------- src/distributions/graalvm/installer.ts | 125 +++++++++++-------------- 2 files changed, 94 insertions(+), 107 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index a16d4117..989958be 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -79086,6 +79086,7 @@ const GRAALVM_DOWNLOAD_URL = 'https://www.graalvm.org/downloads/'; const GRAALVM_COMMUNITY_RELEASES_URL = 'https://api.github.com/repos/graalvm/graalvm-ce-builds/releases?per_page=100'; const GRAALVM_COMMUNITY_RELEASES_PAGE_ORIGIN = 'https://api.github.com'; const GRAALVM_COMMUNITY_DOWNLOAD_URL = 'https://github.com/graalvm/graalvm-ce-builds/releases'; +const GRAALVM_COMMUNITY_ASSET_PREFIX = 'graalvm-community-jdk-'; const IS_WINDOWS = process.platform === 'win32'; const GRAALVM_PLATFORM = IS_WINDOWS ? 'windows' : process.platform; const GRAALVM_MIN_VERSION = 17; @@ -79275,7 +79276,10 @@ class GraalVMCommunityDistribution extends GraalVMDistribution { } const arch = this.getSupportedArchitecture(); const { platform, extension } = this.validateStableBuildRequest(range); - const availableVersions = yield this.getAvailableVersionsForPlatform(platform, arch, extension); + // GraalVM Community asset names embed the platform, architecture and + // archive type, e.g. `graalvm-community-jdk-21.0.2_linux-x64_bin.tar.gz`. + const assetSuffix = `_${platform}-${arch}_bin.${extension}`; + const availableVersions = yield this.getAvailableVersions(assetSuffix); const satisfiedVersion = availableVersions .filter(item => (0, util_1.isVersionSatisfies)(range, item.version)) .sort((a, b) => -semver_1.default.compareBuild(a.version, b.version))[0]; @@ -79287,60 +79291,58 @@ class GraalVMCommunityDistribution extends GraalVMDistribution { return satisfiedVersion; }); } - getAvailableVersionsForPlatform(platform, arch, extension) { - var _a; + getAvailableVersions(assetSuffix) { + var _a, _b; return __awaiter(this, void 0, void 0, function* () { const headers = (0, util_1.getGitHubHttpHeaders)(); - const availableVersions = new Map(); + const versions = new Map(); let releasesUrl = GRAALVM_COMMUNITY_RELEASES_URL; - let pageCount = 0; - while (releasesUrl) { - pageCount++; + for (let page = 0; releasesUrl && page < util_1.MAX_PAGINATION_PAGES; page++) { const response = yield this.http.getJson(releasesUrl, headers); - const releases = Array.isArray(response.result) ? response.result : []; + const releases = (_a = response.result) !== null && _a !== void 0 ? _a : []; + if (releases.length === 0) { + break; + } for (const release of releases) { if (release.draft || release.prerelease) { continue; } - for (const asset of (_a = release.assets) !== null && _a !== void 0 ? _a : []) { - const releaseForPlatform = this.toCommunityReleaseForPlatform(asset, platform, arch, extension); - if (releaseForPlatform) { - availableVersions.set(releaseForPlatform.version, releaseForPlatform); + for (const asset of (_b = release.assets) !== null && _b !== void 0 ? _b : []) { + const version = this.extractAssetVersion(asset.name, assetSuffix); + if (version) { + versions.set(version, { + version, + url: asset.browser_download_url + }); } } } - const nextUrl = (0, util_1.getNextPageUrlFromLinkHeader)(response.headers); - if (nextUrl && - !(0, util_1.validatePaginationUrl)(nextUrl, GRAALVM_COMMUNITY_RELEASES_PAGE_ORIGIN)) { - core.warning(`Ignoring pagination link with unexpected origin: ${nextUrl}`); - break; - } - releasesUrl = nextUrl; - if (releases.length === 0) { - break; - } - if (pageCount >= util_1.MAX_PAGINATION_PAGES) { - core.warning(`Reached pagination safeguard limit (${util_1.MAX_PAGINATION_PAGES} pages) while listing GraalVM Community releases.`); - break; - } + releasesUrl = this.getNextReleasesUrl(response.headers); } - return [...availableVersions.values()]; + return [...versions.values()]; }); } - toCommunityReleaseForPlatform(asset, platform, arch, extension) { - const match = asset.name.match(/^graalvm-community-jdk-(?\d+(?:\.\d+)+)_(?linux|macos|windows)-(?x64|aarch64)_bin\.(?tar\.gz|zip)$/); - if (!(match === null || match === void 0 ? void 0 : match.groups)) { + // Returns the GraalVM JDK version encoded in a release asset name when it + // matches the requested platform/architecture/archive suffix, otherwise null. + extractAssetVersion(assetName, assetSuffix) { + if (!assetName.startsWith(GRAALVM_COMMUNITY_ASSET_PREFIX) || + !assetName.endsWith(assetSuffix)) { return null; } - if (match.groups.platform !== platform || - match.groups.arch !== arch || - match.groups.extension !== extension) { + const rawVersion = assetName.slice(GRAALVM_COMMUNITY_ASSET_PREFIX.length, -assetSuffix.length); + if (!/^\d+(?:\.\d+)*$/.test(rawVersion)) { return null; } - return { - version: (0, util_1.convertVersionToSemver)(match.groups.version), - url: asset.browser_download_url - }; + return (0, util_1.convertVersionToSemver)(rawVersion); + } + getNextReleasesUrl(headers) { + const nextUrl = (0, util_1.getNextPageUrlFromLinkHeader)(headers); + if (nextUrl && + !(0, util_1.validatePaginationUrl)(nextUrl, GRAALVM_COMMUNITY_RELEASES_PAGE_ORIGIN)) { + core.warning(`Ignoring pagination link with unexpected origin: ${nextUrl}`); + return null; + } + return nextUrl; } } exports.GraalVMCommunityDistribution = GraalVMCommunityDistribution; diff --git a/src/distributions/graalvm/installer.ts b/src/distributions/graalvm/installer.ts index 608d1ed7..377d1b6e 100644 --- a/src/distributions/graalvm/installer.ts +++ b/src/distributions/graalvm/installer.ts @@ -30,6 +30,7 @@ const GRAALVM_COMMUNITY_RELEASES_URL = const GRAALVM_COMMUNITY_RELEASES_PAGE_ORIGIN = 'https://api.github.com'; const GRAALVM_COMMUNITY_DOWNLOAD_URL = 'https://github.com/graalvm/graalvm-ce-builds/releases'; +const GRAALVM_COMMUNITY_ASSET_PREFIX = 'graalvm-community-jdk-'; const IS_WINDOWS = process.platform === 'win32'; const GRAALVM_PLATFORM = IS_WINDOWS ? 'windows' : process.platform; const GRAALVM_MIN_VERSION = 17; @@ -350,11 +351,10 @@ export class GraalVMCommunityDistribution extends GraalVMDistribution { const arch = this.getSupportedArchitecture(); const {platform, extension} = this.validateStableBuildRequest(range); - const availableVersions = await this.getAvailableVersionsForPlatform( - platform, - arch, - extension - ); + // GraalVM Community asset names embed the platform, architecture and + // archive type, e.g. `graalvm-community-jdk-21.0.2_linux-x64_bin.tar.gz`. + const assetSuffix = `_${platform}-${arch}_bin.${extension}`; + const availableVersions = await this.getAvailableVersions(assetSuffix); const satisfiedVersion = availableVersions .filter(item => isVersionSatisfies(range, item.version)) @@ -373,24 +373,23 @@ export class GraalVMCommunityDistribution extends GraalVMDistribution { return satisfiedVersion; } - private async getAvailableVersionsForPlatform( - platform: OsVersions, - arch: SupportedArchitecture, - extension: string + private async getAvailableVersions( + assetSuffix: string ): Promise { const headers = getGitHubHttpHeaders(); - const availableVersions = new Map(); + const versions = new Map(); let releasesUrl: string | null = GRAALVM_COMMUNITY_RELEASES_URL; - let pageCount = 0; - while (releasesUrl) { - pageCount++; + for (let page = 0; releasesUrl && page < MAX_PAGINATION_PAGES; page++) { const response = await this.http.getJson( releasesUrl, headers ); - const releases = Array.isArray(response.result) ? response.result : []; + const releases = response.result ?? []; + if (releases.length === 0) { + break; + } for (const release of releases) { if (release.draft || release.prerelease) { @@ -398,74 +397,60 @@ export class GraalVMCommunityDistribution extends GraalVMDistribution { } for (const asset of release.assets ?? []) { - const releaseForPlatform = this.toCommunityReleaseForPlatform( - asset, - platform, - arch, - extension - ); - if (releaseForPlatform) { - availableVersions.set( - releaseForPlatform.version, - releaseForPlatform - ); + const version = this.extractAssetVersion(asset.name, assetSuffix); + if (version) { + versions.set(version, { + version, + url: asset.browser_download_url + }); } } } - const nextUrl = getNextPageUrlFromLinkHeader(response.headers); - if ( - nextUrl && - !validatePaginationUrl(nextUrl, GRAALVM_COMMUNITY_RELEASES_PAGE_ORIGIN) - ) { - core.warning( - `Ignoring pagination link with unexpected origin: ${nextUrl}` - ); - break; - } - - releasesUrl = nextUrl; - - if (releases.length === 0) { - break; - } - - if (pageCount >= MAX_PAGINATION_PAGES) { - core.warning( - `Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing GraalVM Community releases.` - ); - break; - } + releasesUrl = this.getNextReleasesUrl(response.headers); } - return [...availableVersions.values()]; + return [...versions.values()]; } - private toCommunityReleaseForPlatform( - asset: GraalVMCommunityAsset, - platform: OsVersions, - arch: SupportedArchitecture, - extension: string - ): JavaDownloadRelease | null { - const match = asset.name.match( - /^graalvm-community-jdk-(?\d+(?:\.\d+)+)_(?linux|macos|windows)-(?x64|aarch64)_bin\.(?tar\.gz|zip)$/ - ); - - if (!match?.groups) { - return null; - } - + // Returns the GraalVM JDK version encoded in a release asset name when it + // matches the requested platform/architecture/archive suffix, otherwise null. + private extractAssetVersion( + assetName: string, + assetSuffix: string + ): string | null { if ( - match.groups.platform !== platform || - match.groups.arch !== arch || - match.groups.extension !== extension + !assetName.startsWith(GRAALVM_COMMUNITY_ASSET_PREFIX) || + !assetName.endsWith(assetSuffix) ) { return null; } - return { - version: convertVersionToSemver(match.groups.version), - url: asset.browser_download_url - }; + const rawVersion = assetName.slice( + GRAALVM_COMMUNITY_ASSET_PREFIX.length, + -assetSuffix.length + ); + + if (!/^\d+(?:\.\d+)*$/.test(rawVersion)) { + return null; + } + + return convertVersionToSemver(rawVersion); + } + + private getNextReleasesUrl( + headers: Record + ): string | null { + const nextUrl = getNextPageUrlFromLinkHeader(headers); + if ( + nextUrl && + !validatePaginationUrl(nextUrl, GRAALVM_COMMUNITY_RELEASES_PAGE_ORIGIN) + ) { + core.warning( + `Ignoring pagination link with unexpected origin: ${nextUrl}` + ); + return null; + } + return nextUrl; } }