diff --git a/__tests__/distributors/adopt-installer.test.ts b/__tests__/distributors/adopt-installer.test.ts index 5564925..05be8d5 100644 --- a/__tests__/distributors/adopt-installer.test.ts +++ b/__tests__/distributors/adopt-installer.test.ts @@ -4,6 +4,7 @@ import { AdoptDistribution, AdoptImplementation } from '../../src/distributions/adopt/installer'; +import {TemurinDistribution} from '../../src/distributions/temurin/installer'; import {JavaInstallerOptions} from '../../src/distributions/base-models'; import os from 'os'; @@ -256,6 +257,38 @@ describe('getAvailableVersions', () => { }); describe('findPackageForDownload', () => { + it('returns Temurin result and does not query Adopt API when Temurin succeeds', async () => { + const temurinRelease = { + version: '11.0.31+11', + url: 'https://example.test/temurin-11.tar.gz' + }; + const temurinFindPackageForDownload = jest + .fn() + .mockResolvedValue(temurinRelease); + const temurinDistribution = { + findPackageForDownload: temurinFindPackageForDownload + } as unknown as TemurinDistribution; + + const distribution = new AdoptDistribution( + { + version: '11', + architecture: 'x64', + packageType: 'jdk', + checkLatest: false + }, + AdoptImplementation.Hotspot, + temurinDistribution + ); + const adoptLookupSpy = jest.fn(); + distribution['getAvailableVersions'] = adoptLookupSpy; + + const resolvedVersion = await distribution['findPackageForDownload']('11'); + + expect(resolvedVersion).toEqual(temurinRelease); + expect(temurinFindPackageForDownload).toHaveBeenCalledWith('11'); + expect(adoptLookupSpy).not.toHaveBeenCalled(); + }); + it.each([ ['9', '9.0.7+10'], ['15', '15.0.2+7'], @@ -278,6 +311,11 @@ describe('findPackageForDownload', () => { }, AdoptImplementation.Hotspot ); + // Mock Temurin to fail so fallback to AdoptOpenJDK is tested + distribution['temurinDistribution']!['findPackageForDownload'] = + async () => { + throw new Error('No matching version found for SemVer'); + }; distribution['getAvailableVersions'] = async () => manifestData as any; const resolvedVersion = await distribution['findPackageForDownload'](input); expect(resolvedVersion.version).toBe(expected); @@ -293,6 +331,11 @@ describe('findPackageForDownload', () => { }, AdoptImplementation.Hotspot ); + // Mock Temurin to fail so fallback to AdoptOpenJDK is tested + distribution['temurinDistribution']!['findPackageForDownload'] = + async () => { + throw new Error('No matching version found for SemVer'); + }; distribution['getAvailableVersions'] = async () => manifestData as any; await expect( distribution['findPackageForDownload']('9.0.8') @@ -309,6 +352,11 @@ describe('findPackageForDownload', () => { }, AdoptImplementation.Hotspot ); + // Mock Temurin to fail so fallback to AdoptOpenJDK is tested + distribution['temurinDistribution']!['findPackageForDownload'] = + async () => { + throw new Error('No matching version found for SemVer'); + }; distribution['getAvailableVersions'] = async () => manifestData as any; await expect(distribution['findPackageForDownload']('7.x')).rejects.toThrow( /No matching version found for SemVer */ @@ -325,6 +373,11 @@ describe('findPackageForDownload', () => { }, AdoptImplementation.Hotspot ); + // Mock Temurin to fail so fallback to AdoptOpenJDK is tested + distribution['temurinDistribution']!['findPackageForDownload'] = + async () => { + throw new Error('No matching version found for SemVer'); + }; distribution['getAvailableVersions'] = async () => []; await expect(distribution['findPackageForDownload']('11')).rejects.toThrow( /No matching version found for SemVer */ diff --git a/dist/setup/index.js b/dist/setup/index.js index 16fca2a..a2efc14 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -77815,17 +77815,54 @@ 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 installer_1 = __nccwpck_require__(18579); var AdoptImplementation; (function (AdoptImplementation) { AdoptImplementation["Hotspot"] = "Hotspot"; AdoptImplementation["OpenJ9"] = "OpenJ9"; })(AdoptImplementation || (exports.AdoptImplementation = AdoptImplementation = {})); class AdoptDistribution extends base_installer_1.JavaBase { - constructor(installerOptions, jvmImpl) { + constructor(installerOptions, jvmImpl, temurinDistribution = null) { super(`Adopt-${jvmImpl}`, installerOptions); this.jvmImpl = jvmImpl; + if (temurinDistribution !== null && + jvmImpl !== AdoptImplementation.Hotspot) { + throw new Error('Only Hotspot JVM is supported by Temurin.'); + } + // Only use the temurin repo for Hotspot JVMs + this.temurinDistribution = + temurinDistribution !== null && temurinDistribution !== void 0 ? temurinDistribution : (jvmImpl === AdoptImplementation.Hotspot + ? new installer_1.TemurinDistribution(installerOptions, installer_1.TemurinImplementation.Hotspot) + : null); } findPackageForDownload(version) { + return __awaiter(this, void 0, void 0, function* () { + if (this.jvmImpl === AdoptImplementation.Hotspot) { + core.notice("AdoptOpenJDK has moved to Eclipse Temurin https://github.com/actions/setup-java#supported-distributions please consider changing to the 'temurin' distribution type in your setup-java configuration."); + } + if (this.jvmImpl === AdoptImplementation.Hotspot && + this.temurinDistribution !== null) { + try { + return yield this.temurinDistribution.findPackageForDownload(version); + } + catch (error) { + // Log the failure but always fall back to legacy AdoptOpenJDK for resilience + const errorMessage = error instanceof Error ? error.message : String(error); + if (error instanceof Error && error.name === 'VersionNotFoundError') { + core.notice('The JVM you are looking for could not be found in the Temurin repository, this likely indicates ' + + 'that you are using an out of date version of Java, consider updating and moving to using the Temurin distribution type in setup-java.'); + } + else { + // Log other errors for debugging but gracefully fall back + core.debug(`Temurin lookup failed: ${errorMessage}. Falling back to AdoptOpenJDK API.`); + } + } + } + // failed to find a Temurin version, so fall back to AdoptOpenJDK + return this.findPackageForDownloadOldAdoptOpenJdk(version); + }); + } + findPackageForDownloadOldAdoptOpenJdk(version) { return __awaiter(this, void 0, void 0, function* () { const availableVersionsRaw = yield this.getAvailableVersions(); const availableVersionsWithBinaries = availableVersionsRaw @@ -78223,7 +78260,9 @@ class JavaBase { parts.push(`(showing first ${maxVersionsToShow} of ${availableVersions.length} versions, enable debug mode to see all)`); } } - return new Error(parts.join('\n')); + const error = new Error(parts.join('\n')); + error.name = 'VersionNotFoundError'; + return error; } setJavaDefault(version, toolPath) { const majorVersion = version.split('.')[0]; @@ -80195,6 +80234,9 @@ class TemurinDistribution extends base_installer_1.JavaBase { super(`Temurin-${jvmImpl}`, installerOptions); this.jvmImpl = jvmImpl; } + /** + * @internal For cross-distribution reuse only. Not intended as a public API. + */ findPackageForDownload(version) { return __awaiter(this, void 0, void 0, function* () { const availableVersionsRaw = yield this.getAvailableVersions(); diff --git a/package-lock.json b/package-lock.json index b910a8f..208a2e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6470,21 +6470,6 @@ "node": ">=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", diff --git a/src/distributions/adopt/installer.ts b/src/distributions/adopt/installer.ts index b6393f7..78798bf 100644 --- a/src/distributions/adopt/installer.ts +++ b/src/distributions/adopt/installer.ts @@ -21,6 +21,7 @@ import { MAX_PAGINATION_PAGES, validatePaginationUrl } from '../../util'; +import {TemurinDistribution, TemurinImplementation} from '../temurin/installer'; export enum AdoptImplementation { Hotspot = 'Hotspot', @@ -28,15 +29,72 @@ export enum AdoptImplementation { } export class AdoptDistribution extends JavaBase { + private readonly temurinDistribution: TemurinDistribution | null; + constructor( installerOptions: JavaInstallerOptions, - private readonly jvmImpl: AdoptImplementation + private readonly jvmImpl: AdoptImplementation, + temurinDistribution: TemurinDistribution | null = null ) { super(`Adopt-${jvmImpl}`, installerOptions); + + if ( + temurinDistribution !== null && + jvmImpl !== AdoptImplementation.Hotspot + ) { + throw new Error('Only Hotspot JVM is supported by Temurin.'); + } + + // Only use the temurin repo for Hotspot JVMs + this.temurinDistribution = + temurinDistribution ?? + (jvmImpl === AdoptImplementation.Hotspot + ? new TemurinDistribution( + installerOptions, + TemurinImplementation.Hotspot + ) + : null); } protected async findPackageForDownload( version: string + ): Promise { + if (this.jvmImpl === AdoptImplementation.Hotspot) { + core.notice( + "AdoptOpenJDK has moved to Eclipse Temurin https://github.com/actions/setup-java#supported-distributions please consider changing to the 'temurin' distribution type in your setup-java configuration." + ); + } + + if ( + this.jvmImpl === AdoptImplementation.Hotspot && + this.temurinDistribution !== null + ) { + try { + return await this.temurinDistribution.findPackageForDownload(version); + } catch (error) { + // Log the failure but always fall back to legacy AdoptOpenJDK for resilience + const errorMessage = + error instanceof Error ? error.message : String(error); + if (error instanceof Error && error.name === 'VersionNotFoundError') { + core.notice( + 'The JVM you are looking for could not be found in the Temurin repository, this likely indicates ' + + 'that you are using an out of date version of Java, consider updating and moving to using the Temurin distribution type in setup-java.' + ); + } else { + // Log other errors for debugging but gracefully fall back + core.debug( + `Temurin lookup failed: ${errorMessage}. Falling back to AdoptOpenJDK API.` + ); + } + } + } + + // failed to find a Temurin version, so fall back to AdoptOpenJDK + return this.findPackageForDownloadOldAdoptOpenJdk(version); + } + + private async findPackageForDownloadOldAdoptOpenJdk( + version: string ): Promise { const availableVersionsRaw = await this.getAvailableVersions(); const availableVersionsWithBinaries = availableVersionsRaw diff --git a/src/distributions/base-installer.ts b/src/distributions/base-installer.ts index 10e37d9..5d9f3c8 100644 --- a/src/distributions/base-installer.ts +++ b/src/distributions/base-installer.ts @@ -292,7 +292,9 @@ export abstract class JavaBase { } } - return new Error(parts.join('\n')); + const error = new Error(parts.join('\n')); + error.name = 'VersionNotFoundError'; + return error; } protected setJavaDefault(version: string, toolPath: string) { diff --git a/src/distributions/temurin/installer.ts b/src/distributions/temurin/installer.ts index 7e5617c..109c2d4 100644 --- a/src/distributions/temurin/installer.ts +++ b/src/distributions/temurin/installer.ts @@ -34,7 +34,10 @@ export class TemurinDistribution extends JavaBase { super(`Temurin-${jvmImpl}`, installerOptions); } - protected async findPackageForDownload( + /** + * @internal For cross-distribution reuse only. Not intended as a public API. + */ + public async findPackageForDownload( version: string ): Promise { const availableVersionsRaw = await this.getAvailableVersions();