From 2c4a2dda70f301abffea10f395f1172ffcfe5e3c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Jul 2026 02:28:21 +0000 Subject: [PATCH] Support archived OpenJDK release formats --- .../distributors/openjdk-installer.test.ts | 41 ++++++++++++++++++- dist/setup/index.js | 31 ++++++++------ src/distributions/openjdk/installer.ts | 37 ++++++++++------- 3 files changed, 80 insertions(+), 29 deletions(-) diff --git a/__tests__/distributors/openjdk-installer.test.ts b/__tests__/distributors/openjdk-installer.test.ts index f6714fd7..5c47f218 100644 --- a/__tests__/distributors/openjdk-installer.test.ts +++ b/__tests__/distributors/openjdk-installer.test.ts @@ -46,6 +46,7 @@ const earlyAccessPage = ` const archivePage = ` tar.gz tar.gz + tar.gz `; function createDistribution( @@ -88,7 +89,7 @@ describe('OpenJdkDistribution', () => { const result = await createDistribution()['findPackageForDownload']('26'); expect(result).toEqual({ - version: '26.0.2', + version: '26.0.2+10', url: 'https://download.java.net/java/GA/jdk26.0.2/hash/10/GPL/openjdk-26.0.2_linux-x64_bin.tar.gz' }); }); @@ -97,10 +98,29 @@ describe('OpenJdkDistribution', () => { const result = await createDistribution('26.0.1')['findPackageForDownload']('26.0.1'); - expect(result.version).toBe('26.0.1'); + expect(result.version).toBe('26.0.1+8'); expect(result.url).toContain('/openjdk-26.0.1_linux-x64_bin.tar.gz'); }); + it('resolves an exact GA build', async () => { + const result = + await createDistribution('26.0.2+10')['findPackageForDownload']( + '26.0.2+10' + ); + + expect(result.version).toBe('26.0.2+10'); + }); + + it('resolves a four-field Java version', async () => { + const result = + await createDistribution('18.0.1.1')['findPackageForDownload']( + '18.0.1+1' + ); + + expect(result.version).toBe('18.0.1+1'); + expect(result.url).toContain('/openjdk-18.0.1.1_linux-x64_bin.tar.gz'); + }); + it('resolves an early-access release without requesting the archive', async () => { const result = await createDistribution('27-ea')['findPackageForDownload']('27'); @@ -148,6 +168,23 @@ describe('OpenJdkDistribution', () => { ); }); + it('parses legacy platform names and archive formats', () => { + const distribution = createDistribution(); + const macRelease = distribution['parseReleases']( + 'tar.gz', + 'macos', + 'x64' + ); + const windowsRelease = distribution['parseReleases']( + 'tar.gz', + 'windows', + 'x64' + ); + + expect(macRelease[0].version).toBe('16.0.0+7'); + expect(windowsRelease[0].url.endsWith('.tar.gz')).toBe(true); + }); + it('is registered in the distribution factory', () => { const distribution = getJavaDistribution('openjdk', { version: '26', diff --git a/dist/setup/index.js b/dist/setup/index.js index 58dbe7b6..55831b10 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -131909,8 +131909,8 @@ class OpenJdkDistribution extends JavaBase { info(`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`); let javaArchivePath = await downloadTool(javaRelease.url); info(`Extracting Java archive...`); - const extension = getDownloadArchiveExtension(); - if (process.platform === 'win32') { + const extension = javaRelease.url.endsWith('.zip') ? 'zip' : 'tar.gz'; + if (extension === 'zip') { javaArchivePath = renameWinArchive(javaArchivePath); } const extractedJavaPath = await extractJdkFile(javaArchivePath, extension); @@ -131934,18 +131934,23 @@ class OpenJdkDistribution extends JavaBase { return response.readBody(); } parseReleases(html, platform, arch) { - const extension = platform === 'windows' ? 'zip' : 'tar.gz'; - const pattern = new RegExp(`href="(https://download\\.java\\.net/[^"]+/openjdk-([^"_]+)_${platform}-${arch}_bin\\.${extension.replaceAll('.', '\\.')})"`, 'g'); - return Array.from(html.matchAll(pattern), match => ({ - version: this.toSemver(match[2]), - url: match[1] - })); + const platformPattern = platform === 'macos' ? '(?:macos|osx)' : platform; + const extensionPattern = platform === 'windows' ? '(?:zip|tar\\.gz)' : 'tar\\.gz'; + const pattern = new RegExp(`href="(https://download\\.java\\.net/[^"]+/openjdk-([^"_]+)_${platformPattern}-${arch}_bin\\.${extensionPattern})"`, 'g'); + return Array.from(html.matchAll(pattern), match => { + const url = match[1]; + const build = url.match(/\/(\d+)\/GPL\/openjdk-/)?.[1]; + return { + version: this.toSemver(match[2], build), + url + }; + }); } - toSemver(version) { - const [javaVersion, build] = version.replace('-ea', '').split('+'); - const normalizedVersion = javaVersion.includes('.') - ? javaVersion - : `${javaVersion}.0.0`; + toSemver(version, urlBuild) { + const [javaVersion, filenameBuild] = version.replace('-ea', '').split('+'); + const versionParts = javaVersion.split('.'); + const normalizedVersion = convertVersionToSemver(versionParts.length === 1 ? `${javaVersion}.0.0` : javaVersion); + const build = filenameBuild ?? (versionParts.length <= 3 ? urlBuild : undefined); return build ? `${normalizedVersion}+${build}` : normalizedVersion; } getPlatform(platform = process.platform) { diff --git a/src/distributions/openjdk/installer.ts b/src/distributions/openjdk/installer.ts index 7c225172..21b4f7f7 100644 --- a/src/distributions/openjdk/installer.ts +++ b/src/distributions/openjdk/installer.ts @@ -11,8 +11,8 @@ import { JavaInstallerResults } from '../base-models.js'; import { + convertVersionToSemver, extractJdkFile, - getDownloadArchiveExtension, isVersionSatisfies, renameWinArchive } from '../../util.js'; @@ -62,8 +62,8 @@ export class OpenJdkDistribution extends JavaBase { let javaArchivePath = await tc.downloadTool(javaRelease.url); core.info(`Extracting Java archive...`); - const extension = getDownloadArchiveExtension(); - if (process.platform === 'win32') { + const extension = javaRelease.url.endsWith('.zip') ? 'zip' : 'tar.gz'; + if (extension === 'zip') { javaArchivePath = renameWinArchive(javaArchivePath); } const extractedJavaPath = await extractJdkFile(javaArchivePath, extension); @@ -116,23 +116,32 @@ export class OpenJdkDistribution extends JavaBase { platform: string, arch: string ): JavaDownloadRelease[] { - const extension = platform === 'windows' ? 'zip' : 'tar.gz'; + const platformPattern = platform === 'macos' ? '(?:macos|osx)' : platform; + const extensionPattern = + platform === 'windows' ? '(?:zip|tar\\.gz)' : 'tar\\.gz'; const pattern = new RegExp( - `href="(https://download\\.java\\.net/[^"]+/openjdk-([^"_]+)_${platform}-${arch}_bin\\.${extension.replaceAll('.', '\\.')})"`, + `href="(https://download\\.java\\.net/[^"]+/openjdk-([^"_]+)_${platformPattern}-${arch}_bin\\.${extensionPattern})"`, 'g' ); - return Array.from(html.matchAll(pattern), match => ({ - version: this.toSemver(match[2]), - url: match[1] - })); + return Array.from(html.matchAll(pattern), match => { + const url = match[1]; + const build = url.match(/\/(\d+)\/GPL\/openjdk-/)?.[1]; + return { + version: this.toSemver(match[2], build), + url + }; + }); } - private toSemver(version: string): string { - const [javaVersion, build] = version.replace('-ea', '').split('+'); - const normalizedVersion = javaVersion.includes('.') - ? javaVersion - : `${javaVersion}.0.0`; + private toSemver(version: string, urlBuild?: string): string { + const [javaVersion, filenameBuild] = version.replace('-ea', '').split('+'); + const versionParts = javaVersion.split('.'); + const normalizedVersion = convertVersionToSemver( + versionParts.length === 1 ? `${javaVersion}.0.0` : javaVersion + ); + const build = + filenameBuild ?? (versionParts.length <= 3 ? urlBuild : undefined); return build ? `${normalizedVersion}+${build}` : normalizedVersion; }