Skip to content

Commit b6dbbd5

Browse files
author
Danny McCormick
authored
Handle semver (#8)
* Handle semver * Clean up
1 parent fa3b0ff commit b6dbbd5

5 files changed

Lines changed: 172 additions & 51 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Basic:
1414
actions:
1515
- uses: actions/setup-java@latest
1616
with:
17-
version: 9.0.4 // The JDK version to make available on the path. Use a whole version, such as 9.0.4, not a semver version
17+
version: 9.0.4 // The JDK version to make available on the path. Takes a whole or semver Jdk version, or 1.x syntax (e.g. 1.8 => Jdk 8.x)
1818
architecture: x64 // (x64 or x86) - defaults to x64
1919
- run: java -cp java HelloWorldApp
2020
```
@@ -36,7 +36,7 @@ jobs:
3636
build:
3737
strategy:
3838
matrix:
39-
java: [ 6.0.119, 9.0.4, 12.0.2 ]
39+
java: [ 1.6, 9.0.x, 12.0.2 ]
4040
name: Java ${{ matrix.java }} sample
4141
actions:
4242
- name: Setup java

__tests__/installer.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,22 @@ describe('installer tests', () => {
7777
expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true);
7878
}, 100000);
7979

80+
it('Downloads java with 1.x syntax', async () => {
81+
await installer.getJava('1.10', 'x64', '');
82+
const JavaDir = path.join(toolDir, 'Java', '10.0.2', 'x64');
83+
84+
expect(fs.existsSync(`${JavaDir}.complete`)).toBe(true);
85+
expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true);
86+
}, 100000);
87+
88+
it('Downloads java with normal semver syntax', async () => {
89+
await installer.getJava('9.0.x', 'x64', '');
90+
const JavaDir = path.join(toolDir, 'Java', '9.0.7', 'x64');
91+
92+
expect(fs.existsSync(`${JavaDir}.complete`)).toBe(true);
93+
expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true);
94+
}, 100000);
95+
8096
it('Throws if invalid directory to jdk', async () => {
8197
let thrown = false;
8298
try {

action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: 'Setup your runner with Java'
33
author: 'GitHub'
44
inputs:
55
version:
6-
description: 'The JDK version to make available on the path. Use a whole version, such as 9.0.4'
6+
description: 'The JDK version to make available on the path. Takes a whole or semver Jdk version, or 1.x syntax (e.g. 1.8 => Jdk 8.x)'
77
required: true
88
architecture:
99
description: 'The architecture (x86, x64) of the JDK.'

lib/installer.js

Lines changed: 70 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const exec = __importStar(require("@actions/exec"));
2222
const tc = __importStar(require("@actions/tool-cache"));
2323
const fs = __importStar(require("fs"));
2424
const path = __importStar(require("path"));
25+
const semver = __importStar(require("semver"));
2526
const httpm = __importStar(require("typed-rest-client/HttpClient"));
2627
const IS_WINDOWS = process.platform === 'win32';
2728
if (!tempDirectory) {
@@ -50,7 +51,12 @@ function getJava(version, arch, jdkFile) {
5051
let compressedFileExtension = '';
5152
if (!jdkFile) {
5253
core.debug('Downloading Jdk from Azul');
53-
jdkFile = yield downloadJava(version);
54+
let http = new httpm.HttpClient('setup-java');
55+
let contents = yield (yield http.get('https://static.azul.com/zulu/bin/')).readBody();
56+
let refs = contents.match(/<a href.*\">/gi) || [];
57+
const downloadInfo = getDownloadInfo(refs, version);
58+
jdkFile = yield tc.downloadTool(downloadInfo.url);
59+
version = downloadInfo.version;
5460
compressedFileExtension = IS_WINDOWS ? '.zip' : '.tar.gz';
5561
}
5662
else {
@@ -60,7 +66,7 @@ function getJava(version, arch, jdkFile) {
6066
let tempDir = path.join(tempDirectory, 'temp_' + Math.floor(Math.random() * 2000000000));
6167
const jdkDir = yield unzipJavaDownload(jdkFile, compressedFileExtension, tempDir);
6268
core.debug(`jdk extracted to ${jdkDir}`);
63-
toolPath = yield tc.cacheDir(jdkDir, 'Java', normalizeVersion(version), arch);
69+
toolPath = yield tc.cacheDir(jdkDir, 'Java', getCacheVersionString(version), arch);
6470
}
6571
let extendedJavaHome = 'JAVA_HOME_' + version + '_' + arch;
6672
core.exportVariable('JAVA_HOME', toolPath);
@@ -69,7 +75,7 @@ function getJava(version, arch, jdkFile) {
6975
});
7076
}
7177
exports.getJava = getJava;
72-
function normalizeVersion(version) {
78+
function getCacheVersionString(version) {
7379
const versionArray = version.split('.');
7480
const major = versionArray[0];
7581
const minor = versionArray.length > 1 ? versionArray[1] : '0';
@@ -156,32 +162,70 @@ function unzipJavaDownload(repoRoot, fileEnding, destinationFolder, extension) {
156162
}
157163
});
158164
}
159-
function downloadJava(version) {
160-
return __awaiter(this, void 0, void 0, function* () {
161-
let filterString = '';
162-
if (IS_WINDOWS) {
163-
filterString = `jdk${version}-win_x64.zip`;
165+
function getDownloadInfo(refs, version) {
166+
version = normalizeVersion(version);
167+
let extension = '';
168+
if (IS_WINDOWS) {
169+
extension = `-win_x64.zip`;
170+
}
171+
else {
172+
if (process.platform === 'darwin') {
173+
extension = `-macosx_x64.tar.gz`;
164174
}
165175
else {
166-
if (process.platform === 'darwin') {
167-
filterString = `jdk${version}-macosx_x64.tar.gz`;
168-
}
169-
else {
170-
filterString = `jdk${version}-linux_x64.tar.gz`;
171-
}
176+
extension = `-linux_x64.tar.gz`;
172177
}
173-
let http = new httpm.HttpClient('setup-java');
174-
let contents = yield (yield http.get('https://static.azul.com/zulu/bin/')).readBody();
175-
let refs = contents.match(/<a href.*\">/gi) || [];
176-
refs = refs.filter(val => {
177-
if (val.indexOf(filterString) > -1) {
178-
return true;
179-
}
180-
});
181-
if (refs.length == 0) {
182-
throw new Error(`No valid download found for version ${version}. Check https://static.azul.com/zulu/bin/ for a list of valid versions or download your own jdk file and add the jdkFile argument`);
178+
}
179+
// Maps version to url
180+
let versionMap = new Map();
181+
// Filter by platform
182+
refs.forEach(ref => {
183+
if (ref.indexOf(extension) < 0) {
184+
return;
185+
}
186+
// If we haven't returned, means we're looking at the correct platform
187+
let versions = ref.match(/jdk.*-/gi) || [];
188+
if (versions.length > 1) {
189+
throw new Error(`Invalid ref received from https://static.azul.com/zulu/bin/: ${ref}`);
190+
}
191+
if (versions.length == 0) {
192+
return;
193+
}
194+
const refVersion = versions[0].slice('jdk'.length, versions[0].length - 1);
195+
if (semver.satisfies(refVersion, version)) {
196+
versionMap.set(refVersion, 'https://static.azul.com/zulu/bin/' +
197+
ref.slice('<a href="'.length, ref.length - '">'.length));
183198
}
184-
const fileName = refs[0].slice('<a href="'.length, refs[0].length - '">'.length);
185-
return yield tc.downloadTool(`https://static.azul.com/zulu/bin/${fileName}`);
186199
});
200+
// Choose the most recent satisfying version
201+
let curVersion = '0.0.0';
202+
let curUrl = '';
203+
for (const entry of versionMap.entries()) {
204+
const entryVersion = entry[0];
205+
const entryUrl = entry[1];
206+
if (semver.gt(entryVersion, curVersion)) {
207+
curUrl = entryUrl;
208+
curVersion = entryVersion;
209+
}
210+
}
211+
if (curUrl == '') {
212+
throw new Error(`No valid download found for version ${version}. Check https://static.azul.com/zulu/bin/ for a list of valid versions or download your own jdk file and add the jdkFile argument`);
213+
}
214+
return { version: curVersion, url: curUrl };
215+
}
216+
function normalizeVersion(version) {
217+
if (version.slice(0, 2) === '1.') {
218+
// Trim leading 1. for versions like 1.8
219+
version = version.slice(2);
220+
if (!version) {
221+
throw new Error('1. is not a valid version');
222+
}
223+
}
224+
// Add trailing .x if it is missing
225+
if (version.split('.').length != 3) {
226+
if (version[version.length - 1] != 'x') {
227+
version = version + '.x';
228+
}
229+
}
230+
return version;
187231
}

src/installer.ts

Lines changed: 83 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as exec from '@actions/exec';
66
import * as tc from '@actions/tool-cache';
77
import * as fs from 'fs';
88
import * as path from 'path';
9+
import * as semver from 'semver';
910
import * as httpm from 'typed-rest-client/HttpClient';
1011

1112
const IS_WINDOWS = process.platform === 'win32';
@@ -38,7 +39,16 @@ export async function getJava(
3839
let compressedFileExtension = '';
3940
if (!jdkFile) {
4041
core.debug('Downloading Jdk from Azul');
41-
jdkFile = await downloadJava(version);
42+
let http: httpm.HttpClient = new httpm.HttpClient('setup-java');
43+
let contents = await (await http.get(
44+
'https://static.azul.com/zulu/bin/'
45+
)).readBody();
46+
let refs = contents.match(/<a href.*\">/gi) || [];
47+
48+
const downloadInfo = getDownloadInfo(refs, version);
49+
50+
jdkFile = await tc.downloadTool(downloadInfo.url);
51+
version = downloadInfo.version;
4252
compressedFileExtension = IS_WINDOWS ? '.zip' : '.tar.gz';
4353
} else {
4454
core.debug('Retrieving Jdk from local path');
@@ -57,7 +67,7 @@ export async function getJava(
5767
toolPath = await tc.cacheDir(
5868
jdkDir,
5969
'Java',
60-
normalizeVersion(version),
70+
getCacheVersionString(version),
6171
arch
6272
);
6373
}
@@ -68,7 +78,7 @@ export async function getJava(
6878
core.addPath(path.join(toolPath, 'bin'));
6979
}
7080

71-
function normalizeVersion(version: string) {
81+
function getCacheVersionString(version: string) {
7282
const versionArray = version.split('.');
7383
const major = versionArray[0];
7484
const minor = versionArray.length > 1 ? versionArray[1] : '0';
@@ -161,37 +171,88 @@ async function unzipJavaDownload(
161171
}
162172
}
163173

164-
async function downloadJava(version: string): Promise<string> {
165-
let filterString = '';
174+
function getDownloadInfo(
175+
refs: string[],
176+
version: string
177+
): {version: string; url: string} {
178+
version = normalizeVersion(version);
179+
let extension = '';
166180
if (IS_WINDOWS) {
167-
filterString = `jdk${version}-win_x64.zip`;
181+
extension = `-win_x64.zip`;
168182
} else {
169183
if (process.platform === 'darwin') {
170-
filterString = `jdk${version}-macosx_x64.tar.gz`;
184+
extension = `-macosx_x64.tar.gz`;
171185
} else {
172-
filterString = `jdk${version}-linux_x64.tar.gz`;
186+
extension = `-linux_x64.tar.gz`;
173187
}
174188
}
175-
let http: httpm.HttpClient = new httpm.HttpClient('setup-java');
176-
let contents = await (await http.get(
177-
'https://static.azul.com/zulu/bin/'
178-
)).readBody();
179-
let refs = contents.match(/<a href.*\">/gi) || [];
180-
refs = refs.filter(val => {
181-
if (val.indexOf(filterString) > -1) {
182-
return true;
189+
190+
// Maps version to url
191+
let versionMap = new Map();
192+
193+
// Filter by platform
194+
refs.forEach(ref => {
195+
if (ref.indexOf(extension) < 0) {
196+
return;
197+
}
198+
199+
// If we haven't returned, means we're looking at the correct platform
200+
let versions = ref.match(/jdk.*-/gi) || [];
201+
if (versions.length > 1) {
202+
throw new Error(
203+
`Invalid ref received from https://static.azul.com/zulu/bin/: ${ref}`
204+
);
205+
}
206+
if (versions.length == 0) {
207+
return;
208+
}
209+
const refVersion = versions[0].slice('jdk'.length, versions[0].length - 1);
210+
211+
if (semver.satisfies(refVersion, version)) {
212+
versionMap.set(
213+
refVersion,
214+
'https://static.azul.com/zulu/bin/' +
215+
ref.slice('<a href="'.length, ref.length - '">'.length)
216+
);
183217
}
184218
});
185219

186-
if (refs.length == 0) {
220+
// Choose the most recent satisfying version
221+
let curVersion = '0.0.0';
222+
let curUrl = '';
223+
for (const entry of versionMap.entries()) {
224+
const entryVersion = entry[0];
225+
const entryUrl = entry[1];
226+
if (semver.gt(entryVersion, curVersion)) {
227+
curUrl = entryUrl;
228+
curVersion = entryVersion;
229+
}
230+
}
231+
232+
if (curUrl == '') {
187233
throw new Error(
188234
`No valid download found for version ${version}. Check https://static.azul.com/zulu/bin/ for a list of valid versions or download your own jdk file and add the jdkFile argument`
189235
);
190236
}
191237

192-
const fileName = refs[0].slice(
193-
'<a href="'.length,
194-
refs[0].length - '">'.length
195-
);
196-
return await tc.downloadTool(`https://static.azul.com/zulu/bin/${fileName}`);
238+
return {version: curVersion, url: curUrl};
239+
}
240+
241+
function normalizeVersion(version: string): string {
242+
if (version.slice(0, 2) === '1.') {
243+
// Trim leading 1. for versions like 1.8
244+
version = version.slice(2);
245+
if (!version) {
246+
throw new Error('1. is not a valid version');
247+
}
248+
}
249+
250+
// Add trailing .x if it is missing
251+
if (version.split('.').length != 3) {
252+
if (version[version.length - 1] != 'x') {
253+
version = version + '.x';
254+
}
255+
}
256+
257+
return version;
197258
}

0 commit comments

Comments
 (0)