Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 60 additions & 62 deletions __tests__/distributors/graalvm-installer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import {GraalVMDistribution} from '../../src/distributions/graalvm/installer';
import os from 'os';
import * as core from '@actions/core';
import {getDownloadArchiveExtension} from '../../src/util';
import {HttpClient} from '@actions/http-client';
import {HttpClient, HttpClientResponse} from '@actions/http-client';

describe('findPackageForDownload', () => {
describe('GraalVMDistribution', () => {
let distribution: GraalVMDistribution;
let spyDebug: jest.SpyInstance;
let spyHttpClient: jest.SpyInstance;
Expand All @@ -17,11 +17,21 @@ describe('findPackageForDownload', () => {
checkLatest: false
});

spyDebug = jest.spyOn(core, 'debug');
spyDebug.mockImplementation(() => {});
spyDebug = jest.spyOn(core, 'debug').mockImplementation(() => {});
});

it.each([
afterEach(() => {
jest.restoreAllMocks();
});

const setupHttpClientSpy = () => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'head').mockResolvedValue({
message: {statusCode: 200} as any, // Minimal mock for IncomingMessage
readBody: jest.fn().mockResolvedValue('')
} as HttpClientResponse);
};

const testCases = [
[
'21',
'21',
Expand All @@ -42,82 +52,71 @@ describe('findPackageForDownload', () => {
'17.0.12',
'https://download.oracle.com/graalvm/17/archive/graalvm-jdk-17.0.12_{{OS_TYPE}}-x64_bin.{{ARCHIVE_TYPE}}'
]
])('version is %s -> %s', async (input, expectedVersion, expectedUrl) => {
/* Needed only for this particular test because /latest/ urls tend to change */
spyHttpClient = jest.spyOn(HttpClient.prototype, 'head');
spyHttpClient.mockReturnValue(
Promise.resolve({
message: {
statusCode: 200
}
})
);
];

const result = await distribution['findPackageForDownload'](input);
it.each(testCases)(
'should find package for version %s',
async (input, expectedVersion, expectedUrl) => {
setupHttpClientSpy();

jest.restoreAllMocks();
const result = await distribution['findPackageForDownload'](input);
const osType = distribution.getPlatform();
const archiveType = getDownloadArchiveExtension();
const expectedFormattedUrl = expectedUrl
.replace('{{OS_TYPE}}', osType)
.replace('{{ARCHIVE_TYPE}}', archiveType);

expect(result.version).toBe(expectedVersion);
const osType = distribution.getPlatform();
const archiveType = getDownloadArchiveExtension();
const url = expectedUrl
.replace('{{OS_TYPE}}', osType)
.replace('{{ARCHIVE_TYPE}}', archiveType);
expect(result.url).toBe(url);
});
expect(result.version).toBe(expectedVersion);
expect(result.url).toBe(expectedFormattedUrl);
}
);

it.each([
[
'24-ea',
/^https:\/\/github\.com\/graalvm\/oracle-graalvm-ea-builds\/releases\/download\/jdk-24\.0\.0-ea\./
]
])('version is %s -> %s', async (version, expectedUrlPrefix) => {
/* Needed only for this particular test because /latest/ urls tend to change */
spyHttpClient = jest.spyOn(HttpClient.prototype, 'head');
spyHttpClient.mockReturnValue(
Promise.resolve({
message: {
statusCode: 200
}
})
);

const eaDistro = new GraalVMDistribution({
version,
architecture: '', // to get default value
packageType: 'jdk',
checkLatest: false
});
])(
'should find EA package for version %s',
async (version, expectedUrlPrefix) => {
setupHttpClientSpy();

const versionWithoutEA = version.split('-')[0];
const result = await eaDistro['findPackageForDownload'](versionWithoutEA);
const eaDistro = new GraalVMDistribution({
version,
architecture: '',
packageType: 'jdk',
checkLatest: false
});

jest.restoreAllMocks();
const versionWithoutEA = version.split('-')[0];
const result = await eaDistro['findPackageForDownload'](versionWithoutEA);

expect(result.url).toEqual(expect.stringMatching(expectedUrlPrefix));
});
expect(result.url).toEqual(expect.stringMatching(expectedUrlPrefix));
}
);

it.each([
['amd64', 'x64'],
['arm64', 'aarch64']
])(
'defaults to os.arch(): %s mapped to distro arch: %s',
'should map OS architecture %s to distribution architecture %s',
async (osArch: string, distroArch: string) => {
jest.spyOn(os, 'arch').mockReturnValue(osArch);
jest.spyOn(os, 'platform').mockReturnValue('linux');

const version = '21';
const distro = new GraalVMDistribution({
version,
architecture: '', // to get default value
architecture: '',
packageType: 'jdk',
checkLatest: false
});

const osType = distribution.getPlatform();
if (osType === 'windows' && distroArch == 'aarch64') {
if (osType === 'windows' && distroArch === 'aarch64') {
return; // skip, aarch64 is not available for Windows
Copy link

Copilot AI Jun 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Instead of returning early inside the test body to skip the unsupported Windows aarch64 case, consider using a conditional test skip (e.g. test.skip for that iteration) to make the intent clearer.

Suggested change
return; // skip, aarch64 is not available for Windows
test.skip('Skipping test: aarch64 is not available for Windows');

Copilot uses AI. Check for mistakes.
}

const archiveType = getDownloadArchiveExtension();
const result = await distro['findPackageForDownload'](version);
const expectedUrl = `https://download.oracle.com/graalvm/21/latest/graalvm-jdk-21_${osType}-${distroArch}_bin.${archiveType}`;
Expand All @@ -126,27 +125,26 @@ describe('findPackageForDownload', () => {
}
);

it('should throw an error', async () => {
await expect(distribution['findPackageForDownload']('8')).rejects.toThrow(
/GraalVM is only supported for JDK 17 and later/
);
await expect(distribution['findPackageForDownload']('11')).rejects.toThrow(
/GraalVM is only supported for JDK 17 and later/
);
await expect(distribution['findPackageForDownload']('18')).rejects.toThrow(
/Could not find GraalVM for SemVer */
);
it('should throw an error for unsupported versions', async () => {
setupHttpClientSpy();

const unsupportedVersions = ['8', '11'];
for (const version of unsupportedVersions) {
await expect(
distribution['findPackageForDownload'](version)
).rejects.toThrow(/GraalVM is only supported for JDK 17 and later/);
}

const unavailableEADistro = new GraalVMDistribution({
version: '17-ea',
architecture: '', // to get default value
architecture: '',
packageType: 'jdk',
checkLatest: false
});
await expect(
unavailableEADistro['findPackageForDownload']('17')
).rejects.toThrow(
/No GraalVM EA build found\. Are you sure java-version: '17-ea' is correct\?/
`No GraalVM EA build found for version '17-ea'. Please check if the version is correct.`
);
});
});
6 changes: 3 additions & 3 deletions dist/cleanup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -93676,9 +93676,9 @@ function convertVersionToSemver(version) {
return mainVersion;
}
exports.convertVersionToSemver = convertVersionToSemver;
function getGitHubHttpHeaders() {
const token = core.getInput('token');
const auth = !token ? undefined : `token ${token}`;
function getGitHubHttpHeaders(token) {
const resolvedToken = token || core.getInput('token');
const auth = !resolvedToken ? undefined : `token ${resolvedToken}`;
const headers = {
accept: 'application/vnd.github.VERSION.raw'
};
Expand Down
86 changes: 38 additions & 48 deletions dist/setup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -129432,8 +129432,8 @@ const tc = __importStar(__nccwpck_require__(27784));
const fs_1 = __importDefault(__nccwpck_require__(57147));
const path_1 = __importDefault(__nccwpck_require__(71017));
const base_installer_1 = __nccwpck_require__(59741);
const util_1 = __nccwpck_require__(92629);
const http_client_1 = __nccwpck_require__(96255);
const util_1 = __nccwpck_require__(92629);
const GRAALVM_DL_BASE = 'https://download.oracle.com/graalvm';
const IS_WINDOWS = process.platform === 'win32';
const GRAALVM_PLATFORM = IS_WINDOWS ? 'windows' : process.platform;
Expand All @@ -129447,12 +129447,11 @@ class GraalVMDistribution extends base_installer_1.JavaBase {
let javaArchivePath = yield tc.downloadTool(javaRelease.url);
core.info(`Extracting Java archive...`);
const extension = (0, util_1.getDownloadArchiveExtension)();
if (process.platform === 'win32') {
if (IS_WINDOWS) {
javaArchivePath = (0, util_1.renameWinArchive)(javaArchivePath);
}
const extractedJavaPath = yield (0, util_1.extractJdkFile)(javaArchivePath, extension);
const archiveName = fs_1.default.readdirSync(extractedJavaPath)[0];
const archivePath = path_1.default.join(extractedJavaPath, archiveName);
const archivePath = path_1.default.join(extractedJavaPath, fs_1.default.readdirSync(extractedJavaPath)[0]);
const version = this.getToolcacheVersionName(javaRelease.version);
const javaPath = yield tc.cacheDir(archivePath, this.toolcacheFolderName, version, this.architecture);
return { version: javaRelease.version, path: javaPath };
Expand All @@ -129461,7 +129460,7 @@ class GraalVMDistribution extends base_installer_1.JavaBase {
findPackageForDownload(range) {
return __awaiter(this, void 0, void 0, function* () {
const arch = this.distributionArchitecture();
if (arch !== 'x64' && arch !== 'aarch64') {
if (!['x64', 'aarch64'].includes(arch)) {
throw new Error(`Unsupported architecture: ${this.architecture}`);
}
if (!this.stable) {
Expand All @@ -129472,29 +129471,29 @@ class GraalVMDistribution extends base_installer_1.JavaBase {
}
const platform = this.getPlatform();
const extension = (0, util_1.getDownloadArchiveExtension)();
let major;
let fileUrl;
if (range.includes('.')) {
major = range.split('.')[0];
fileUrl = `${GRAALVM_DL_BASE}/${major}/archive/graalvm-jdk-${range}_${platform}-${arch}_bin.${extension}`;
}
else {
major = range;
fileUrl = `${GRAALVM_DL_BASE}/${range}/latest/graalvm-jdk-${range}_${platform}-${arch}_bin.${extension}`;
}
const major = range.includes('.') ? range.split('.')[0] : range;
const fileUrl = this.constructFileUrl(range, major, platform, arch, extension);
if (parseInt(major) < 17) {
throw new Error('GraalVM is only supported for JDK 17 and later');
}
const response = yield this.http.head(fileUrl);
if (response.message.statusCode === http_client_1.HttpCodes.NotFound) {
throw new Error(`Could not find GraalVM for SemVer ${range}`);
}
if (response.message.statusCode !== http_client_1.HttpCodes.OK) {
throw new Error(`Http request for GraalVM failed with status code: ${response.message.statusCode}`);
}
this.handleHttpResponse(response, range);
return { url: fileUrl, version: range };
});
}
constructFileUrl(range, major, platform, arch, extension) {
return range.includes('.')
? `${GRAALVM_DL_BASE}/${major}/archive/graalvm-jdk-${range}_${platform}-${arch}_bin.${extension}`
: `${GRAALVM_DL_BASE}/${range}/latest/graalvm-jdk-${range}_${platform}-${arch}_bin.${extension}`;
}
handleHttpResponse(response, range) {
if (response.message.statusCode === http_client_1.HttpCodes.NotFound) {
throw new Error(`Could not find GraalVM for SemVer ${range}`);
}
if (response.message.statusCode !== http_client_1.HttpCodes.OK) {
throw new Error(`Http request for GraalVM failed with status code: ${response.message.statusCode}`);
}
}
findEABuildDownloadUrl(javaEaVersion) {
return __awaiter(this, void 0, void 0, function* () {
const versions = yield this.fetchEAJson(javaEaVersion);
Expand All @@ -129515,38 +129514,29 @@ class GraalVMDistribution extends base_installer_1.JavaBase {
}
fetchEAJson(javaEaVersion) {
return __awaiter(this, void 0, void 0, function* () {
const owner = 'graalvm';
const repository = 'oracle-graalvm-ea-builds';
const branch = 'main';
const filePath = `versions/${javaEaVersion}.json`;
const url = `https://api.github.com/repos/${owner}/${repository}/contents/${filePath}?ref=${branch}`;
const url = `https://api.github.com/repos/graalvm/oracle-graalvm-ea-builds/contents/versions/${javaEaVersion}.json?ref=main`;
const headers = (0, util_1.getGitHubHttpHeaders)();
core.debug(`Trying to fetch available version info for GraalVM EA builds from '${url}'`);
let fetchedJson;
try {
fetchedJson = (yield this.http.getJson(url, headers))
.result;
}
catch (err) {
throw Error(`Fetching version info for GraalVM EA builds from '${url}' failed with the error: ${err.message}`);
}
if (fetchedJson === null) {
throw Error(`No GraalVM EA build found. Are you sure java-version: '${javaEaVersion}' is correct?`);
const fetchedJson = yield this.http
.getJson(url, headers)
.then(res => res.result);
if (!fetchedJson) {
throw new Error(`No GraalVM EA build found for version '${javaEaVersion}'. Please check if the version is correct.`);
}
return fetchedJson;
});
}
getPlatform(platform = process.platform) {
switch (platform) {
case 'darwin':
return 'macos';
case 'win32':
return 'windows';
case 'linux':
return 'linux';
default:
throw new Error(`Platform '${platform}' is not supported. Supported platforms: 'linux', 'macos', 'windows'`);
const platformMap = {
darwin: 'macos',
win32: 'windows',
linux: 'linux'
};
const result = platformMap[platform];
if (!result) {
throw new Error(`Platform '${platform}' is not supported. Supported platforms: 'linux', 'macos', 'windows'`);
}
return result;
}
}
exports.GraalVMDistribution = GraalVMDistribution;
Expand Down Expand Up @@ -131681,9 +131671,9 @@ function convertVersionToSemver(version) {
return mainVersion;
}
exports.convertVersionToSemver = convertVersionToSemver;
function getGitHubHttpHeaders() {
const token = core.getInput('token');
const auth = !token ? undefined : `token ${token}`;
function getGitHubHttpHeaders(token) {
const resolvedToken = token || core.getInput('token');
const auth = !resolvedToken ? undefined : `token ${resolvedToken}`;
const headers = {
accept: 'application/vnd.github.VERSION.raw'
};
Expand Down
Loading
Loading