Skip to content

Commit c02f2a2

Browse files
committed
Add support for EA builds of Oracle GraalVM
1 parent adc0a82 commit c02f2a2

File tree

5 files changed

+180
-16
lines changed

5 files changed

+180
-16
lines changed

.github/workflows/e2e-versions.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ jobs:
5757
- distribution: graalvm
5858
os: ubuntu-latest
5959
version: 21
60+
- distribution: graalvm
61+
os: ubuntu-latest
62+
version: '24-ea'
6063
steps:
6164
- name: Checkout
6265
uses: actions/checkout@v4

__tests__/distributors/graalvm-installer.test.ts

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,37 @@ describe('findPackageForDownload', () => {
6666
expect(result.url).toBe(url);
6767
});
6868

69+
it.each([
70+
[
71+
'24-ea',
72+
/^https:\/\/github\.com\/graalvm\/oracle-graalvm-ea-builds\/releases\/download\/jdk-24\.0\.0-ea\./
73+
]
74+
])('version is %s -> %s', async (version, expectedUrlPrefix) => {
75+
/* Needed only for this particular test because /latest/ urls tend to change */
76+
spyHttpClient = jest.spyOn(HttpClient.prototype, 'head');
77+
spyHttpClient.mockReturnValue(
78+
Promise.resolve({
79+
message: {
80+
statusCode: 200
81+
}
82+
})
83+
);
84+
85+
const eaDistro = new GraalVMDistribution({
86+
version,
87+
architecture: '', // to get default value
88+
packageType: 'jdk',
89+
checkLatest: false
90+
});
91+
92+
const versionWithoutEA = version.split('-')[0];
93+
const result = await eaDistro['findPackageForDownload'](versionWithoutEA);
94+
95+
jest.restoreAllMocks();
96+
97+
expect(result.url).toEqual(expect.stringMatching(expectedUrlPrefix));
98+
});
99+
69100
it.each([
70101
['amd64', 'x64'],
71102
['arm64', 'aarch64']
@@ -75,7 +106,7 @@ describe('findPackageForDownload', () => {
75106
jest.spyOn(os, 'arch').mockReturnValue(osArch);
76107
jest.spyOn(os, 'platform').mockReturnValue('linux');
77108

78-
const version = '17';
109+
const version = '21';
79110
const distro = new GraalVMDistribution({
80111
version,
81112
architecture: '', // to get default value
@@ -89,21 +120,33 @@ describe('findPackageForDownload', () => {
89120
}
90121
const archiveType = getDownloadArchiveExtension();
91122
const result = await distro['findPackageForDownload'](version);
92-
const expectedUrl = `https://download.oracle.com/graalvm/17/latest/graalvm-jdk-17_${osType}-${distroArch}_bin.${archiveType}`;
123+
const expectedUrl = `https://download.oracle.com/graalvm/21/latest/graalvm-jdk-21_${osType}-${distroArch}_bin.${archiveType}`;
93124

94125
expect(result.url).toBe(expectedUrl);
95126
}
96127
);
97128

98129
it('should throw an error', async () => {
99130
await expect(distribution['findPackageForDownload']('8')).rejects.toThrow(
100-
/GraalVM JDK is only supported for JDK 17 and later/
131+
/GraalVM is only supported for JDK 17 and later/
101132
);
102133
await expect(distribution['findPackageForDownload']('11')).rejects.toThrow(
103-
/GraalVM JDK is only supported for JDK 17 and later/
134+
/GraalVM is only supported for JDK 17 and later/
104135
);
105136
await expect(distribution['findPackageForDownload']('18')).rejects.toThrow(
106-
/Could not find GraalVM JDK for SemVer */
137+
/Could not find GraalVM for SemVer */
138+
);
139+
140+
const unavailableEADistro = new GraalVMDistribution({
141+
version: '17-ea',
142+
architecture: '', // to get default value
143+
packageType: 'jdk',
144+
checkLatest: false
145+
});
146+
await expect(
147+
unavailableEADistro['findPackageForDownload']('17')
148+
).rejects.toThrow(
149+
/No GraalVM EA build found\. Are you sure java-version: '17-ea' is correct\?/
107150
);
108151
});
109152
});

dist/setup/index.js

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124362,6 +124362,8 @@ const base_installer_1 = __nccwpck_require__(59741);
124362124362
const util_1 = __nccwpck_require__(92629);
124363124363
const http_client_1 = __nccwpck_require__(96255);
124364124364
const GRAALVM_DL_BASE = 'https://download.oracle.com/graalvm';
124365+
const IS_WINDOWS = process.platform === 'win32';
124366+
const GRAALVM_PLATFORM = IS_WINDOWS ? 'windows' : process.platform;
124365124367
class GraalVMDistribution extends base_installer_1.JavaBase {
124366124368
constructor(installerOptions) {
124367124369
super('GraalVM', installerOptions);
@@ -124387,10 +124389,10 @@ class GraalVMDistribution extends base_installer_1.JavaBase {
124387124389
throw new Error(`Unsupported architecture: ${this.architecture}`);
124388124390
}
124389124391
if (!this.stable) {
124390-
throw new Error('Early access versions are not supported');
124392+
return this.findEABuildDownloadUrl(`${range}-ea`);
124391124393
}
124392124394
if (this.packageType !== 'jdk') {
124393-
throw new Error('GraalVM JDK provides only the `jdk` package type');
124395+
throw new Error('GraalVM provides only the `jdk` package type');
124394124396
}
124395124397
const platform = this.getPlatform();
124396124398
const extension = (0, util_1.getDownloadArchiveExtension)();
@@ -124405,18 +124407,58 @@ class GraalVMDistribution extends base_installer_1.JavaBase {
124405124407
fileUrl = `${GRAALVM_DL_BASE}/${range}/latest/graalvm-jdk-${range}_${platform}-${arch}_bin.${extension}`;
124406124408
}
124407124409
if (parseInt(major) < 17) {
124408-
throw new Error('GraalVM JDK is only supported for JDK 17 and later');
124410+
throw new Error('GraalVM is only supported for JDK 17 and later');
124409124411
}
124410124412
const response = yield this.http.head(fileUrl);
124411124413
if (response.message.statusCode === http_client_1.HttpCodes.NotFound) {
124412-
throw new Error(`Could not find GraalVM JDK for SemVer ${range}`);
124414+
throw new Error(`Could not find GraalVM for SemVer ${range}`);
124413124415
}
124414124416
if (response.message.statusCode !== http_client_1.HttpCodes.OK) {
124415-
throw new Error(`Http request for GraalVM JDK failed with status code: ${response.message.statusCode}`);
124417+
throw new Error(`Http request for GraalVM failed with status code: ${response.message.statusCode}`);
124416124418
}
124417124419
return { url: fileUrl, version: range };
124418124420
});
124419124421
}
124422+
findEABuildDownloadUrl(javaEaVersion) {
124423+
return __awaiter(this, void 0, void 0, function* () {
124424+
const versions = yield this.fetchEAJson(javaEaVersion);
124425+
const latestVersion = versions.find(v => v.latest);
124426+
if (!latestVersion) {
124427+
throw new Error(`Unable to find latest version for '${javaEaVersion}'`);
124428+
}
124429+
const arch = this.distributionArchitecture();
124430+
const file = latestVersion.files.find(f => f.arch === arch && f.platform === GRAALVM_PLATFORM);
124431+
if (!file || !file.filename.startsWith('graalvm-jdk-')) {
124432+
throw new Error(`Unable to find file metadata for '${javaEaVersion}'`);
124433+
}
124434+
return {
124435+
url: `${latestVersion.download_base_url}${file.filename}`,
124436+
version: latestVersion.version
124437+
};
124438+
});
124439+
}
124440+
fetchEAJson(javaEaVersion) {
124441+
return __awaiter(this, void 0, void 0, function* () {
124442+
const owner = 'graalvm';
124443+
const repository = 'oracle-graalvm-ea-builds';
124444+
const branch = 'main';
124445+
const filePath = `versions/${javaEaVersion}.json`;
124446+
const url = `https://api.github.com/repos/${owner}/${repository}/contents/${filePath}?ref=${branch}`;
124447+
const headers = (0, util_1.getGitHubHttpHeaders)();
124448+
core.debug(`Trying to fetch available version info for GraalVM EA builds from '${url}'`);
124449+
let fetchedJson;
124450+
try {
124451+
fetchedJson = (yield this.http.getJson(url, headers)).result;
124452+
}
124453+
catch (err) {
124454+
throw Error(`Fetching version info for GraalVM EA builds from '${url}' failed with the error: ${err.message}`);
124455+
}
124456+
if (fetchedJson === null) {
124457+
throw Error(`No GraalVM EA build found. Are you sure java-version: '${javaEaVersion}' is correct?`);
124458+
}
124459+
return fetchedJson;
124460+
});
124461+
}
124420124462
getPlatform(platform = process.platform) {
124421124463
switch (platform) {
124422124464
case 'darwin':

src/distributions/graalvm/installer.ts

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,17 @@ import {
1010
JavaInstallerOptions,
1111
JavaInstallerResults
1212
} from '../base-models';
13-
import {extractJdkFile, getDownloadArchiveExtension} from '../../util';
13+
import {
14+
extractJdkFile,
15+
getDownloadArchiveExtension,
16+
getGitHubHttpHeaders
17+
} from '../../util';
1418
import {HttpCodes} from '@actions/http-client';
19+
import {OracleGraalVMEAVersion} from './models';
1520

1621
const GRAALVM_DL_BASE = 'https://download.oracle.com/graalvm';
22+
const IS_WINDOWS = process.platform === 'win32';
23+
const GRAALVM_PLATFORM = IS_WINDOWS ? 'windows' : process.platform;
1724

1825
export class GraalVMDistribution extends JavaBase {
1926
constructor(installerOptions: JavaInstallerOptions) {
@@ -56,11 +63,11 @@ export class GraalVMDistribution extends JavaBase {
5663
}
5764

5865
if (!this.stable) {
59-
throw new Error('Early access versions are not supported');
66+
return this.findEABuildDownloadUrl(`${range}-ea`);
6067
}
6168

6269
if (this.packageType !== 'jdk') {
63-
throw new Error('GraalVM JDK provides only the `jdk` package type');
70+
throw new Error('GraalVM provides only the `jdk` package type');
6471
}
6572

6673
const platform = this.getPlatform();
@@ -76,24 +83,80 @@ export class GraalVMDistribution extends JavaBase {
7683
}
7784

7885
if (parseInt(major) < 17) {
79-
throw new Error('GraalVM JDK is only supported for JDK 17 and later');
86+
throw new Error('GraalVM is only supported for JDK 17 and later');
8087
}
8188

8289
const response = await this.http.head(fileUrl);
8390

8491
if (response.message.statusCode === HttpCodes.NotFound) {
85-
throw new Error(`Could not find GraalVM JDK for SemVer ${range}`);
92+
throw new Error(`Could not find GraalVM for SemVer ${range}`);
8693
}
8794

8895
if (response.message.statusCode !== HttpCodes.OK) {
8996
throw new Error(
90-
`Http request for GraalVM JDK failed with status code: ${response.message.statusCode}`
97+
`Http request for GraalVM failed with status code: ${response.message.statusCode}`
9198
);
9299
}
93100

94101
return {url: fileUrl, version: range};
95102
}
96103

104+
private async findEABuildDownloadUrl(
105+
javaEaVersion: string
106+
): Promise<JavaDownloadRelease> {
107+
const versions = await this.fetchEAJson(javaEaVersion);
108+
const latestVersion = versions.find(v => v.latest);
109+
if (!latestVersion) {
110+
throw new Error(`Unable to find latest version for '${javaEaVersion}'`);
111+
}
112+
const arch = this.distributionArchitecture();
113+
const file = latestVersion.files.find(
114+
f => f.arch === arch && f.platform === GRAALVM_PLATFORM
115+
);
116+
if (!file || !file.filename.startsWith('graalvm-jdk-')) {
117+
throw new Error(`Unable to find file metadata for '${javaEaVersion}'`);
118+
}
119+
return {
120+
url: `${latestVersion.download_base_url}${file.filename}`,
121+
version: latestVersion.version
122+
};
123+
}
124+
125+
private async fetchEAJson(
126+
javaEaVersion: string
127+
): Promise<OracleGraalVMEAVersion[]> {
128+
const owner = 'graalvm';
129+
const repository = 'oracle-graalvm-ea-builds';
130+
const branch = 'main';
131+
const filePath = `versions/${javaEaVersion}.json`;
132+
133+
const url = `https://api.github.com/repos/${owner}/${repository}/contents/${filePath}?ref=${branch}`;
134+
135+
const headers = getGitHubHttpHeaders();
136+
137+
core.debug(
138+
`Trying to fetch available version info for GraalVM EA builds from '${url}'`
139+
);
140+
let fetchedJson;
141+
try {
142+
fetchedJson = (
143+
await this.http.getJson<OracleGraalVMEAVersion[]>(url, headers)
144+
).result;
145+
} catch (err) {
146+
throw Error(
147+
`Fetching version info for GraalVM EA builds from '${url}' failed with the error: ${
148+
(err as Error).message
149+
}`
150+
);
151+
}
152+
if (fetchedJson === null) {
153+
throw Error(
154+
`No GraalVM EA build found. Are you sure java-version: '${javaEaVersion}' is correct?`
155+
);
156+
}
157+
return fetchedJson;
158+
}
159+
97160
public getPlatform(platform: NodeJS.Platform = process.platform): OsVersions {
98161
switch (platform) {
99162
case 'darwin':
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,14 @@
11
export type OsVersions = 'linux' | 'macos' | 'windows';
2+
3+
export interface OracleGraalVMEAFile {
4+
filename: string;
5+
arch: 'aarch64' | 'x64';
6+
platform: 'darwin' | 'linux' | 'windows';
7+
}
8+
9+
export interface OracleGraalVMEAVersion {
10+
version: string;
11+
latest?: boolean;
12+
download_base_url: string;
13+
files: OracleGraalVMEAFile[];
14+
}

0 commit comments

Comments
 (0)