This commit is contained in:
Chiranjib Swain 2026-03-19 04:45:55 +00:00 committed by GitHub
commit 8b1cb90567
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
34 changed files with 386 additions and 164 deletions

View File

@ -17,6 +17,7 @@ describe('dependency cache', () => {
let spyWarning: jest.SpyInstance<void, Parameters<typeof core.warning>>;
let spyDebug: jest.SpyInstance<void, Parameters<typeof core.debug>>;
let spySaveState: jest.SpyInstance<void, Parameters<typeof core.saveState>>;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
workspace = mkdtempSync(join(tmpdir(), 'setup-java-cache-'));
@ -51,6 +52,10 @@ describe('dependency cache', () => {
spySaveState = jest.spyOn(core, 'saveState');
spySaveState.mockImplementation(() => null);
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
afterEach(() => {
@ -58,6 +63,10 @@ describe('dependency cache', () => {
process.env['GITHUB_WORKSPACE'] = ORIGINAL_GITHUB_WORKSPACE;
process.env['RUNNER_OS'] = ORIGINAL_RUNNER_OS;
resetState();
jest.resetAllMocks();
jest.clearAllMocks();
jest.restoreAllMocks();
});
describe('restore', () => {

View File

@ -11,19 +11,32 @@ describe('cleanup', () => {
Parameters<typeof cache.saveCache>
>;
let spyJobStatusSuccess: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
spyWarning = jest.spyOn(core, 'warning');
spyWarning.mockImplementation(() => null);
spyInfo = jest.spyOn(core, 'info');
spyInfo.mockImplementation(() => null);
spyCacheSave = jest.spyOn(cache, 'saveCache');
spyJobStatusSuccess = jest.spyOn(util, 'isJobStatusSuccess');
spyJobStatusSuccess.mockReturnValue(true);
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
createStateForSuccessfulRestore();
});
afterEach(() => {
resetState();
jest.resetAllMocks();
jest.clearAllMocks();
jest.restoreAllMocks();
});
it('does not fail nor warn even when the save process throws a ReserveCacheError', async () => {

View File

@ -9,9 +9,11 @@ import {JavaInstallerOptions} from '../../src/distributions/base-models';
import os from 'os';
import manifestData from '../data/adopt.json';
import * as core from '@actions/core';
describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
@ -20,6 +22,10 @@ describe('getAvailableVersions', () => {
headers: {},
result: []
});
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
afterEach(() => {

View File

@ -38,7 +38,7 @@ class EmptyJavaBase extends JavaBase {
): Promise<JavaDownloadRelease> {
const availableVersion = '11.0.9';
if (!semver.satisfies(availableVersion, range)) {
throw new Error('Available version not found');
throw this.createVersionNotFoundError(range, [availableVersion]);
}
return {
@ -248,6 +248,7 @@ describe('setupJava', () => {
let spyCoreExportVariable: jest.SpyInstance;
let spyCoreAddPath: jest.SpyInstance;
let spyCoreSetOutput: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
spyGetToolcachePath = jest.spyOn(util, 'getToolcachePath');
@ -287,6 +288,10 @@ describe('setupJava', () => {
spyCoreSetOutput = jest.spyOn(core, 'setOutput');
spyCoreSetOutput.mockImplementation(() => undefined);
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => undefined);
jest.spyOn(os, 'arch').mockReturnValue('x86' as ReturnType<typeof os.arch>);
});
@ -530,19 +535,16 @@ describe('setupJava', () => {
checkLatest: false
}
]
])(
'should throw an error for Available version not found for %s',
async input => {
mockJavaBase = new EmptyJavaBase(input);
await expect(mockJavaBase.setupJava()).rejects.toThrow(
'Available version not found'
);
expect(spyTcFindAllVersions).toHaveBeenCalled();
expect(spyCoreAddPath).not.toHaveBeenCalled();
expect(spyCoreExportVariable).not.toHaveBeenCalled();
expect(spyCoreSetOutput).not.toHaveBeenCalled();
}
);
])('should throw an error for version not found for %s', async input => {
mockJavaBase = new EmptyJavaBase(input);
await expect(mockJavaBase.setupJava()).rejects.toThrow(
`Could not find satisfied version for SemVer '${input.version}'`
);
expect(spyTcFindAllVersions).toHaveBeenCalled();
expect(spyCoreAddPath).not.toHaveBeenCalled();
expect(spyCoreExportVariable).not.toHaveBeenCalled();
expect(spyCoreSetOutput).not.toHaveBeenCalled();
});
});
describe('normalizeVersion', () => {
@ -570,6 +572,97 @@ describe('normalizeVersion', () => {
});
});
describe('createVersionNotFoundError', () => {
it('should include all required fields in error message without available versions', () => {
const mockJavaBase = new EmptyJavaBase({
version: '17.0.5',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
const error = (mockJavaBase as any).createVersionNotFoundError('17.0.5');
expect(error.message).toContain(
"Could not find satisfied version for SemVer '17.0.5'"
);
expect(error.message).toContain('Distribution: Empty');
expect(error.message).toContain('Package type: jdk');
expect(error.message).toContain('Architecture: x64');
});
it('should include available versions when provided', () => {
const mockJavaBase = new EmptyJavaBase({
version: '17.0.5',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
const availableVersions = ['11.0.1', '11.0.2', '17.0.1', '17.0.2'];
const error = (mockJavaBase as any).createVersionNotFoundError(
'17.0.5',
availableVersions
);
expect(error.message).toContain(
"Could not find satisfied version for SemVer '17.0.5'"
);
expect(error.message).toContain('Distribution: Empty');
expect(error.message).toContain('Package type: jdk');
expect(error.message).toContain('Architecture: x64');
expect(error.message).toContain(
'Available versions: 11.0.1, 11.0.2, 17.0.1, 17.0.2'
);
});
it('should truncate available versions when there are many', () => {
const mockJavaBase = new EmptyJavaBase({
version: '17.0.5',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
// Create 60 versions to test truncation
const availableVersions = Array.from({length: 60}, (_, i) => `11.0.${i}`);
const error = (mockJavaBase as any).createVersionNotFoundError(
'17.0.5',
availableVersions
);
expect(error.message).toContain('Available versions:');
expect(error.message).toContain('...');
expect(error.message).toContain('(showing first 50 of 60 versions');
});
it('should include additional context when provided', () => {
const mockJavaBase = new EmptyJavaBase({
version: '17.0.5',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
const availableVersions = ['11.0.1', '11.0.2'];
const additionalContext = 'Platform: linux';
const error = (mockJavaBase as any).createVersionNotFoundError(
'17.0.5',
availableVersions,
additionalContext
);
expect(error.message).toContain(
"Could not find satisfied version for SemVer '17.0.5'"
);
expect(error.message).toContain('Distribution: Empty');
expect(error.message).toContain('Package type: jdk');
expect(error.message).toContain('Architecture: x64');
expect(error.message).toContain('Platform: linux');
expect(error.message).toContain('Available versions: 11.0.1, 11.0.2');
});
});
describe('getToolcacheVersionName', () => {
const DummyJavaBase = JavaBase as any;

View File

@ -4,13 +4,14 @@ import {JavaInstallerOptions} from '../../src/distributions/base-models';
import {CorrettoDistribution} from '../../src/distributions/corretto/installer';
import * as util from '../../src/util';
import os from 'os';
import {isGeneratorFunction} from 'util/types';
import * as core from '@actions/core';
import manifestData from '../data/corretto.json';
describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance;
let spyGetDownloadArchiveExtension: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
@ -23,6 +24,10 @@ describe('getAvailableVersions', () => {
util,
'getDownloadArchiveExtension'
);
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
afterEach(() => {

View File

@ -1,12 +1,14 @@
import {HttpClient} from '@actions/http-client';
import {DragonwellDistribution} from '../../src/distributions/dragonwell/installer';
import * as utils from '../../src/util';
import * as core from '@actions/core';
import manifestData from '../data/dragonwell.json';
describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance;
let spyUtilGetDownloadArchiveExtension: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
@ -21,6 +23,10 @@ describe('getAvailableVersions', () => {
'getDownloadArchiveExtension'
);
spyUtilGetDownloadArchiveExtension.mockReturnValue('tar.gz');
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
afterEach(() => {
@ -232,7 +238,7 @@ describe('getAvailableVersions', () => {
await expect(
distribution['findPackageForDownload'](jdkVersion)
).rejects.toThrow(
`Couldn't find any satisfied version for the specified java-version: "${jdkVersion}" and architecture: "${arch}".`
`Could not find satisfied version for SemVer '${jdkVersion}'`
);
}
);

View File

@ -42,6 +42,7 @@ beforeAll(() => {
describe('GraalVMDistribution', () => {
let distribution: GraalVMDistribution;
let mockHttpClient: jest.Mocked<http.HttpClient>;
let spyCoreError: jest.SpyInstance;
const defaultOptions: JavaInstallerOptions = {
version: '17',
@ -59,6 +60,10 @@ describe('GraalVMDistribution', () => {
(distribution as any).http = mockHttpClient;
(util.getDownloadArchiveExtension as jest.Mock).mockReturnValue('tar.gz');
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
afterAll(() => {
@ -348,11 +353,17 @@ describe('GraalVMDistribution', () => {
} as http.HttpClientResponse;
mockHttpClient.head.mockResolvedValue(mockResponse);
// Verify the error is thrown with the expected message
await expect(
(distribution as any).findPackageForDownload('17.0.99')
).rejects.toThrow(
'Could not find GraalVM for SemVer 17.0.99. Please check if this version is available at https://download.oracle.com/graalvm'
"Could not find satisfied version for SemVer '17.0.99'"
);
// Verify the hint about checking the base URL is included
await expect(
(distribution as any).findPackageForDownload('17.0.99')
).rejects.toThrow('https://download.oracle.com/graalvm');
});
it('should throw error for unauthorized access (401)', async () => {
@ -496,12 +507,11 @@ describe('GraalVMDistribution', () => {
await expect(
(distribution as any).findPackageForDownload('23')
).rejects.toThrow("Unable to find latest version for '23-ea'");
// Verify error logging
expect(core.error).toHaveBeenCalledWith(
'Available versions: 23-ea-20240716'
).rejects.toThrow(
"No EA build is marked as 'latest' for version range '23-ea'. Available EA versions: 23-ea-20240716."
);
// Verify error logging - removed as we now use the helper method which doesn't call core.error
});
it('should throw error when no matching file for architecture in EA build', async () => {
@ -708,11 +718,11 @@ describe('GraalVMDistribution', () => {
await expect(
(distribution as any).findEABuildDownloadUrl('23-ea')
).rejects.toThrow("Unable to find latest version for '23-ea'");
expect(core.error).toHaveBeenCalledWith(
'Available versions: 23-ea-20240716, 23-ea-20240709'
).rejects.toThrow(
"No EA build is marked as 'latest' for version range '23-ea'. Available EA versions: 23-ea-20240716, 23-ea-20240709."
);
// Verify error logging - removed as we now use the helper method which doesn't call core.error
});
it('should throw error when no matching file for architecture', async () => {

View File

@ -4,9 +4,11 @@ import {JetBrainsDistribution} from '../../src/distributions/jetbrains/installer
import manifestData from '../data/jetbrains.json';
import os from 'os';
import * as core from '@actions/core';
describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
@ -15,6 +17,10 @@ describe('getAvailableVersions', () => {
headers: {},
result: []
});
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
afterEach(() => {

View File

@ -5,11 +5,13 @@ import {
} from '../../src/distributions/liberica/models';
import {HttpClient} from '@actions/http-client';
import os from 'os';
import * as core from '@actions/core';
import manifestData from '../data/liberica.json';
describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
@ -18,6 +20,10 @@ describe('getAvailableVersions', () => {
headers: {},
result: manifestData as LibericaVersion[]
});
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
afterEach(() => {
@ -209,7 +215,7 @@ describe('findPackageForDownload', () => {
it('should throw an error', async () => {
await expect(distribution['findPackageForDownload']('17')).rejects.toThrow(
/Could not find satisfied version for semver */
/Could not find satisfied version for SemVer/
);
});
});

View File

@ -5,11 +5,13 @@ import {
} from '../../src/distributions/liberica/models';
import {HttpClient} from '@actions/http-client';
import os from 'os';
import * as core from '@actions/core';
import manifestData from '../data/liberica-linux.json';
describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
@ -18,6 +20,10 @@ describe('getAvailableVersions', () => {
headers: {},
result: manifestData as LibericaVersion[]
});
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
afterEach(() => {
@ -209,7 +215,7 @@ describe('findPackageForDownload', () => {
it('should throw an error', async () => {
await expect(distribution['findPackageForDownload']('18')).rejects.toThrow(
/Could not find satisfied version for semver */
/Could not find satisfied version for SemVer/
);
});
});

View File

@ -5,11 +5,13 @@ import {
} from '../../src/distributions/liberica/models';
import {HttpClient} from '@actions/http-client';
import os from 'os';
import * as core from '@actions/core';
import manifestData from '../data/liberica-windows.json';
describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
@ -18,6 +20,9 @@ describe('getAvailableVersions', () => {
headers: {},
result: manifestData as LibericaVersion[]
});
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
afterEach(() => {
@ -209,7 +214,7 @@ describe('findPackageForDownload', () => {
it('should throw an error', async () => {
await expect(distribution['findPackageForDownload']('18')).rejects.toThrow(
/Could not find satisfied version for semver */
/Could not find satisfied version for SemVer/
);
});
});

View File

@ -27,6 +27,7 @@ describe('setupJava', () => {
let spyFsReadDir: jest.SpyInstance;
let spyUtilsExtractJdkFile: jest.SpyInstance;
let spyPathResolve: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
const expectedJdkFile = 'JavaLocalJdkFile';
beforeEach(() => {
@ -93,6 +94,10 @@ describe('setupJava', () => {
// Spy on path methods
spyPathResolve = jest.spyOn(path, 'resolve');
spyPathResolve.mockImplementation((path: string) => path);
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
afterEach(() => {

View File

@ -8,6 +8,7 @@ describe('findPackageForDownload', () => {
let distribution: MicrosoftDistributions;
let spyGetManifestFromRepo: jest.SpyInstance;
let spyDebug: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
distribution = new MicrosoftDistributions({
@ -26,6 +27,10 @@ describe('findPackageForDownload', () => {
spyDebug = jest.spyOn(core, 'debug');
spyDebug.mockImplementation(() => {});
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
it.each([

View File

@ -8,6 +8,7 @@ describe('findPackageForDownload', () => {
let distribution: OracleDistribution;
let spyDebug: jest.SpyInstance;
let spyHttpClient: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
distribution = new OracleDistribution({
@ -19,6 +20,10 @@ describe('findPackageForDownload', () => {
spyDebug = jest.spyOn(core, 'debug');
spyDebug.mockImplementation(() => {});
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
it.each([

View File

@ -1,12 +1,14 @@
import {HttpClient} from '@actions/http-client';
import {SapMachineDistribution} from '../../src/distributions/sapmachine/installer';
import * as utils from '../../src/util';
import * as core from '@actions/core';
import manifestData from '../data/sapmachine.json';
describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance;
let spyUtilGetDownloadArchiveExtension: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
@ -21,6 +23,10 @@ describe('getAvailableVersions', () => {
'getDownloadArchiveExtension'
);
spyUtilGetDownloadArchiveExtension.mockReturnValue('tar.gz');
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
afterEach(() => {
@ -266,7 +272,7 @@ describe('getAvailableVersions', () => {
await expect(
distribution['findPackageForDownload'](normalizedVersion)
).rejects.toThrow(
`Couldn't find any satisfied version for the specified java-version: "${normalizedVersion}" and architecture: "${arch}".`
`Could not find satisfied version for SemVer '${normalizedVersion}'`
);
}
);

View File

@ -4,9 +4,11 @@ import {JavaInstallerOptions} from '../../src/distributions/base-models';
import {SemeruDistribution} from '../../src/distributions/semeru/installer';
import manifestData from '../data/semeru.json';
import * as core from '@actions/core';
describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
@ -15,6 +17,9 @@ describe('getAvailableVersions', () => {
headers: {},
result: []
});
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
afterEach(() => {

View File

@ -7,9 +7,11 @@ import {
import {JavaInstallerOptions} from '../../src/distributions/base-models';
import manifestData from '../data/temurin.json';
import * as core from '@actions/core';
describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
@ -18,6 +20,9 @@ describe('getAvailableVersions', () => {
headers: {},
result: []
});
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
afterEach(() => {

View File

@ -3,12 +3,14 @@ import {ZuluDistribution} from '../../src/distributions/zulu/installer';
import {IZuluVersions} from '../../src/distributions/zulu/models';
import * as utils from '../../src/util';
import os from 'os';
import * as core from '@actions/core';
import manifestData from '../data/zulu-releases-default.json';
describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance;
let spyUtilGetDownloadArchiveExtension: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
@ -23,6 +25,10 @@ describe('getAvailableVersions', () => {
'getDownloadArchiveExtension'
);
spyUtilGetDownloadArchiveExtension.mockReturnValue('tar.gz');
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
afterEach(() => {
@ -225,6 +231,6 @@ describe('findPackageForDownload', () => {
distribution['getAvailableVersions'] = async () => manifestData;
await expect(
distribution['findPackageForDownload'](distribution['version'])
).rejects.toThrow(/Could not find satisfied version for semver */);
).rejects.toThrow(/Could not find satisfied version for SemVer/);
});
});

View File

@ -4,12 +4,14 @@ import {ZuluDistribution} from '../../src/distributions/zulu/installer';
import {IZuluVersions} from '../../src/distributions/zulu/models';
import * as utils from '../../src/util';
import os from 'os';
import * as core from '@actions/core';
import manifestData from '../data/zulu-linux.json';
describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance;
let spyUtilGetDownloadArchiveExtension: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
@ -24,6 +26,10 @@ describe('getAvailableVersions', () => {
'getDownloadArchiveExtension'
);
spyUtilGetDownloadArchiveExtension.mockReturnValue('zip');
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
afterEach(() => {
@ -228,6 +234,6 @@ describe('findPackageForDownload', () => {
distribution['getAvailableVersions'] = async () => manifestData;
await expect(
distribution['findPackageForDownload'](distribution['version'])
).rejects.toThrow(/Could not find satisfied version for semver */);
).rejects.toThrow(/Could not find satisfied version for SemVer/);
});
});

View File

@ -4,12 +4,14 @@ import {ZuluDistribution} from '../../src/distributions/zulu/installer';
import {IZuluVersions} from '../../src/distributions/zulu/models';
import * as utils from '../../src/util';
import os from 'os';
import * as core from '@actions/core';
import manifestData from '../data/zulu-windows.json';
describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance;
let spyUtilGetDownloadArchiveExtension: jest.SpyInstance;
let spyCoreError: jest.SpyInstance;
beforeEach(() => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
@ -24,6 +26,10 @@ describe('getAvailableVersions', () => {
'getDownloadArchiveExtension'
);
spyUtilGetDownloadArchiveExtension.mockReturnValue('zip');
// Mock core.error to suppress error logs
spyCoreError = jest.spyOn(core, 'error');
spyCoreError.mockImplementation(() => {});
});
afterEach(() => {
@ -226,6 +232,6 @@ describe('findPackageForDownload', () => {
distribution['getAvailableVersions'] = async () => manifestData;
await expect(
distribution['findPackageForDownload'](distribution['version'])
).rejects.toThrow(/Could not find satisfied version for semver */);
).rejects.toThrow(/Could not find satisfied version for SemVer/);
});
});

114
dist/setup/index.js vendored
View File

@ -112219,13 +112219,8 @@ class AdoptDistribution extends base_installer_1.JavaBase {
});
const resolvedFullVersion = satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
if (!resolvedFullVersion) {
const availableOptions = availableVersionsWithBinaries
.map(item => item.version)
.join(', ');
const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}`
: '';
throw new Error(`Could not find satisfied version for SemVer '${version}'. ${availableOptionsMessage}`);
const availableVersionStrings = availableVersionsWithBinaries.map(item => item.version);
throw this.createVersionNotFoundError(version, availableVersionStrings);
}
return resolvedFullVersion;
});
@ -112574,6 +112569,28 @@ class JavaBase {
stable
};
}
createVersionNotFoundError(versionOrRange, availableVersions, additionalContext) {
const parts = [
`Could not find satisfied version for SemVer '${versionOrRange}'.`,
`Distribution: ${this.distribution}`,
`Package type: ${this.packageType}`,
`Architecture: ${this.architecture}`
];
// Add additional context if provided (e.g., platform/OS info)
if (additionalContext) {
parts.push(additionalContext);
}
if (availableVersions && availableVersions.length > 0) {
const maxVersionsToShow = core.isDebug() ? availableVersions.length : 50;
const versionsToShow = availableVersions.slice(0, maxVersionsToShow);
const truncated = availableVersions.length > maxVersionsToShow;
parts.push(`Available versions: ${versionsToShow.join(', ')}${truncated ? ', ...' : ''}`);
if (truncated) {
parts.push(`(showing first ${maxVersionsToShow} of ${availableVersions.length} versions, enable debug mode to see all)`);
}
}
return new Error(parts.join('\n'));
}
setJavaDefault(version, toolPath) {
const majorVersion = version.split('.')[0];
core.exportVariable('JAVA_HOME', toolPath);
@ -112695,13 +112712,8 @@ class CorrettoDistribution extends base_installer_1.JavaBase {
});
const resolvedVersion = matchingVersions.length > 0 ? matchingVersions[0] : null;
if (!resolvedVersion) {
const availableOptions = availableVersions
.map(item => item.version)
.join(', ');
const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}`
: '';
throw new Error(`Could not find satisfied version for SemVer '${version}'. ${availableOptionsMessage}`);
const availableVersionStrings = availableVersions.map(item => item.version);
throw this.createVersionNotFoundError(version, availableVersionStrings);
}
return resolvedVersion;
});
@ -112935,7 +112947,8 @@ class DragonwellDistribution extends base_installer_1.JavaBase {
};
});
if (!matchedVersions.length) {
throw new Error(`Couldn't find any satisfied version for the specified java-version: "${version}" and architecture: "${this.architecture}".`);
const availableVersionStrings = availableVersions.map(item => item.jdk_version);
throw this.createVersionNotFoundError(version, availableVersionStrings);
}
const resolvedVersion = matchedVersions[0];
return resolvedVersion;
@ -113204,7 +113217,10 @@ class GraalVMDistribution extends base_installer_1.JavaBase {
handleHttpResponse(response, range) {
const statusCode = response.message.statusCode;
if (statusCode === http_client_1.HttpCodes.NotFound) {
throw new Error(`Could not find GraalVM for SemVer ${range}. Please check if this version is available at ${GRAALVM_DL_BASE}`);
// Create the standard error with additional hint about checking the download URL
const error = this.createVersionNotFoundError(range);
error.message += `\nPlease check if this version is available at ${GRAALVM_DL_BASE}`;
throw error;
}
if (statusCode === http_client_1.HttpCodes.Unauthorized ||
statusCode === http_client_1.HttpCodes.Forbidden) {
@ -113221,8 +113237,12 @@ class GraalVMDistribution extends base_installer_1.JavaBase {
core.debug(`Found ${versions.length} EA versions`);
const latestVersion = versions.find(v => v.latest);
if (!latestVersion) {
core.error(`Available versions: ${versions.map(v => v.version).join(', ')}`);
throw new Error(`Unable to find latest version for '${javaEaVersion}'`);
const availableVersions = versions.map(v => v.version);
let message = `No EA build is marked as 'latest' for version range '${javaEaVersion}'.`;
if (availableVersions.length > 0) {
message += ` Available EA versions: ${availableVersions.join(', ')}.`;
}
throw new Error(message);
}
core.debug(`Latest version found: ${latestVersion.version}`);
const arch = this.distributionArchitecture();
@ -113358,13 +113378,8 @@ class JetBrainsDistribution extends base_installer_1.JavaBase {
});
const resolvedFullVersion = satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
if (!resolvedFullVersion) {
const availableOptions = versionsRaw
.map(item => `${item.tag_name} (${item.semver}+${item.build})`)
.join(', ');
const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}`
: '';
throw new Error(`Could not find satisfied version for SemVer '${range}'. ${availableOptionsMessage}`);
const availableVersionStrings = versionsRaw.map(item => `${item.tag_name} (${item.semver}+${item.build})`);
throw this.createVersionNotFoundError(range, availableVersionStrings);
}
return resolvedFullVersion;
});
@ -113601,13 +113616,8 @@ class LibericaDistributions extends base_installer_1.JavaBase {
.filter(item => (0, util_1.isVersionSatisfies)(range, item.version))
.sort((a, b) => -semver_1.default.compareBuild(a.version, b.version))[0];
if (!satisfiedVersion) {
const availableOptions = availableVersions
.map(item => item.version)
.join(', ');
const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}`
: '';
throw new Error(`Could not find satisfied version for semver ${range}. ${availableOptionsMessage}`);
const availableVersionStrings = availableVersions.map(item => item.version);
throw this.createVersionNotFoundError(range, availableVersionStrings);
}
return satisfiedVersion;
});
@ -113893,9 +113903,8 @@ class MicrosoftDistributions extends base_installer_1.JavaBase {
}
const foundRelease = yield tc.findFromManifest(range, true, manifest, arch);
if (!foundRelease) {
throw new Error(`Could not find satisfied version for SemVer ${range}.\nAvailable versions: ${manifest
.map(item => item.version)
.join(', ')}`);
const availableVersionStrings = manifest.map(item => item.version);
throw this.createVersionNotFoundError(range, availableVersionStrings);
}
return {
url: foundRelease.files[0].download_url,
@ -114058,7 +114067,7 @@ class OracleDistribution extends base_installer_1.JavaBase {
throw new Error(`Http request for Oracle JDK failed with status code: ${response.message.statusCode}`);
}
}
throw new Error(`Could not find Oracle JDK for SemVer ${range}`);
throw this.createVersionNotFoundError(range);
});
}
getPlatform(platform = process.platform) {
@ -114150,7 +114159,8 @@ class SapMachineDistribution extends base_installer_1.JavaBase {
};
});
if (!matchedVersions.length) {
throw new Error(`Couldn't find any satisfied version for the specified java-version: "${version}" and architecture: "${this.architecture}".`);
const availableVersionStrings = availableVersions.map(item => item.version);
throw this.createVersionNotFoundError(version, availableVersionStrings);
}
const resolvedVersion = matchedVersions[0];
return resolvedVersion;
@ -114389,13 +114399,11 @@ class SemeruDistribution extends base_installer_1.JavaBase {
});
const resolvedFullVersion = satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
if (!resolvedFullVersion) {
const availableOptions = availableVersionsWithBinaries
.map(item => item.version)
.join(', ');
const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}`
: '';
throw new Error(`Could not find satisfied version for SemVer version '${version}' for your current OS version for ${this.architecture} architecture ${availableOptionsMessage}`);
const availableVersionStrings = availableVersionsWithBinaries.map(item => item.version);
// Include platform context to help users understand OS-specific version availability
// IBM Semeru builds are OS-specific, so platform info aids in troubleshooting
const platformContext = `Platform: ${process.platform}`;
throw this.createVersionNotFoundError(version, availableVersionStrings, platformContext);
}
return resolvedFullVersion;
});
@ -114568,13 +114576,8 @@ class TemurinDistribution extends base_installer_1.JavaBase {
});
const resolvedFullVersion = satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
if (!resolvedFullVersion) {
const availableOptions = availableVersionsWithBinaries
.map(item => item.version)
.join(', ');
const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}`
: '';
throw new Error(`Could not find satisfied version for SemVer '${version}'. ${availableOptionsMessage}`);
const availableVersionStrings = availableVersionsWithBinaries.map(item => item.version);
throw this.createVersionNotFoundError(version, availableVersionStrings);
}
return resolvedFullVersion;
});
@ -114746,13 +114749,8 @@ class ZuluDistribution extends base_installer_1.JavaBase {
});
const resolvedFullVersion = satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
if (!resolvedFullVersion) {
const availableOptions = availableVersions
.map(item => item.version)
.join(', ');
const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}`
: '';
throw new Error(`Could not find satisfied version for semver ${version}. ${availableOptionsMessage}`);
const availableVersionStrings = availableVersions.map(item => item.version);
throw this.createVersionNotFoundError(version, availableVersionStrings);
}
return resolvedFullVersion;
});

View File

@ -54,15 +54,10 @@ export class AdoptDistribution extends JavaBase {
const resolvedFullVersion =
satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
if (!resolvedFullVersion) {
const availableOptions = availableVersionsWithBinaries
.map(item => item.version)
.join(', ');
const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}`
: '';
throw new Error(
`Could not find satisfied version for SemVer '${version}'. ${availableOptionsMessage}`
const availableVersionStrings = availableVersionsWithBinaries.map(
item => item.version
);
throw this.createVersionNotFoundError(version, availableVersionStrings);
}
return resolvedFullVersion;

View File

@ -259,6 +259,42 @@ export abstract class JavaBase {
};
}
protected createVersionNotFoundError(
versionOrRange: string,
availableVersions?: string[],
additionalContext?: string
): Error {
const parts = [
`Could not find satisfied version for SemVer '${versionOrRange}'.`,
`Distribution: ${this.distribution}`,
`Package type: ${this.packageType}`,
`Architecture: ${this.architecture}`
];
// Add additional context if provided (e.g., platform/OS info)
if (additionalContext) {
parts.push(additionalContext);
}
if (availableVersions && availableVersions.length > 0) {
const maxVersionsToShow = core.isDebug() ? availableVersions.length : 50;
const versionsToShow = availableVersions.slice(0, maxVersionsToShow);
const truncated = availableVersions.length > maxVersionsToShow;
parts.push(
`Available versions: ${versionsToShow.join(', ')}${truncated ? ', ...' : ''}`
);
if (truncated) {
parts.push(
`(showing first ${maxVersionsToShow} of ${availableVersions.length} versions, enable debug mode to see all)`
);
}
}
return new Error(parts.join('\n'));
}
protected setJavaDefault(version: string, toolPath: string) {
const majorVersion = version.split('.')[0];
core.exportVariable('JAVA_HOME', toolPath);

View File

@ -75,15 +75,10 @@ export class CorrettoDistribution extends JavaBase {
const resolvedVersion =
matchingVersions.length > 0 ? matchingVersions[0] : null;
if (!resolvedVersion) {
const availableOptions = availableVersions
.map(item => item.version)
.join(', ');
const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}`
: '';
throw new Error(
`Could not find satisfied version for SemVer '${version}'. ${availableOptionsMessage}`
const availableVersionStrings = availableVersions.map(
item => item.version
);
throw this.createVersionNotFoundError(version, availableVersionStrings);
}
return resolvedVersion;
}

View File

@ -51,9 +51,10 @@ export class DragonwellDistribution extends JavaBase {
});
if (!matchedVersions.length) {
throw new Error(
`Couldn't find any satisfied version for the specified java-version: "${version}" and architecture: "${this.architecture}".`
const availableVersionStrings = availableVersions.map(
item => item.jdk_version
);
throw this.createVersionNotFoundError(version, availableVersionStrings);
}
const resolvedVersion = matchedVersions[0];

View File

@ -149,9 +149,10 @@ export class GraalVMDistribution extends JavaBase {
const statusCode = response.message.statusCode;
if (statusCode === HttpCodes.NotFound) {
throw new Error(
`Could not find GraalVM for SemVer ${range}. Please check if this version is available at ${GRAALVM_DL_BASE}`
);
// Create the standard error with additional hint about checking the download URL
const error = this.createVersionNotFoundError(range);
error.message += `\nPlease check if this version is available at ${GRAALVM_DL_BASE}`;
throw error;
}
if (
@ -180,10 +181,12 @@ export class GraalVMDistribution extends JavaBase {
const latestVersion = versions.find(v => v.latest);
if (!latestVersion) {
core.error(
`Available versions: ${versions.map(v => v.version).join(', ')}`
);
throw new Error(`Unable to find latest version for '${javaEaVersion}'`);
const availableVersions = versions.map(v => v.version);
let message = `No EA build is marked as 'latest' for version range '${javaEaVersion}'.`;
if (availableVersions.length > 0) {
message += ` Available EA versions: ${availableVersions.join(', ')}.`;
}
throw new Error(message);
}
core.debug(`Latest version found: ${latestVersion.version}`);

View File

@ -44,15 +44,10 @@ export class JetBrainsDistribution extends JavaBase {
const resolvedFullVersion =
satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
if (!resolvedFullVersion) {
const availableOptions = versionsRaw
.map(item => `${item.tag_name} (${item.semver}+${item.build})`)
.join(', ');
const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}`
: '';
throw new Error(
`Could not find satisfied version for SemVer '${range}'. ${availableOptionsMessage}`
const availableVersionStrings = versionsRaw.map(
item => `${item.tag_name} (${item.semver}+${item.build})`
);
throw this.createVersionNotFoundError(range, availableVersionStrings);
}
return resolvedFullVersion;

View File

@ -69,15 +69,10 @@ export class LibericaDistributions extends JavaBase {
.sort((a, b) => -semver.compareBuild(a.version, b.version))[0];
if (!satisfiedVersion) {
const availableOptions = availableVersions
.map(item => item.version)
.join(', ');
const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}`
: '';
throw new Error(
`Could not find satisfied version for semver ${range}. ${availableOptionsMessage}`
const availableVersionStrings = availableVersions.map(
item => item.version
);
throw this.createVersionNotFoundError(range, availableVersionStrings);
}
return satisfiedVersion;

View File

@ -76,11 +76,8 @@ export class MicrosoftDistributions extends JavaBase {
const foundRelease = await tc.findFromManifest(range, true, manifest, arch);
if (!foundRelease) {
throw new Error(
`Could not find satisfied version for SemVer ${range}.\nAvailable versions: ${manifest
.map(item => item.version)
.join(', ')}`
);
const availableVersionStrings = manifest.map(item => item.version);
throw this.createVersionNotFoundError(range, availableVersionStrings);
}
return {

View File

@ -112,7 +112,7 @@ export class OracleDistribution extends JavaBase {
}
}
throw new Error(`Could not find Oracle JDK for SemVer ${range}`);
throw this.createVersionNotFoundError(range);
}
public getPlatform(platform: NodeJS.Platform = process.platform): OsVersions {

View File

@ -49,9 +49,10 @@ export class SapMachineDistribution extends JavaBase {
});
if (!matchedVersions.length) {
throw new Error(
`Couldn't find any satisfied version for the specified java-version: "${version}" and architecture: "${this.architecture}".`
const availableVersionStrings = availableVersions.map(
item => item.version
);
throw this.createVersionNotFoundError(version, availableVersionStrings);
}
const resolvedVersion = matchedVersions[0];

View File

@ -79,14 +79,16 @@ export class SemeruDistribution extends JavaBase {
const resolvedFullVersion =
satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
if (!resolvedFullVersion) {
const availableOptions = availableVersionsWithBinaries
.map(item => item.version)
.join(', ');
const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}`
: '';
throw new Error(
`Could not find satisfied version for SemVer version '${version}' for your current OS version for ${this.architecture} architecture ${availableOptionsMessage}`
const availableVersionStrings = availableVersionsWithBinaries.map(
item => item.version
);
// Include platform context to help users understand OS-specific version availability
// IBM Semeru builds are OS-specific, so platform info aids in troubleshooting
const platformContext = `Platform: ${process.platform}`;
throw this.createVersionNotFoundError(
version,
availableVersionStrings,
platformContext
);
}

View File

@ -57,15 +57,10 @@ export class TemurinDistribution extends JavaBase {
const resolvedFullVersion =
satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
if (!resolvedFullVersion) {
const availableOptions = availableVersionsWithBinaries
.map(item => item.version)
.join(', ');
const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}`
: '';
throw new Error(
`Could not find satisfied version for SemVer '${version}'. ${availableOptionsMessage}`
const availableVersionStrings = availableVersionsWithBinaries.map(
item => item.version
);
throw this.createVersionNotFoundError(version, availableVersionStrings);
}
return resolvedFullVersion;

View File

@ -57,15 +57,10 @@ export class ZuluDistribution extends JavaBase {
const resolvedFullVersion =
satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
if (!resolvedFullVersion) {
const availableOptions = availableVersions
.map(item => item.version)
.join(', ');
const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}`
: '';
throw new Error(
`Could not find satisfied version for semver ${version}. ${availableOptionsMessage}`
const availableVersionStrings = availableVersions.map(
item => item.version
);
throw this.createVersionNotFoundError(version, availableVersionStrings);
}
return resolvedFullVersion;