Skip to content

Commit db2f350

Browse files
brendandburnsbrendanburnsbrcrista
authored
Add microsoft distribution of the JDK. (#252)
* Add microsoft distribution of the JDK. * Fix formatting to match prettier. * Rebuild js. * Fix archive suffix for Windows. * Update src/distributions/microsoft/installer.ts Co-authored-by: Brian Cristante <[email protected]> * Update src/distributions/microsoft/installer.ts Co-authored-by: Brian Cristante <[email protected]> * Add support for the microsoft distribution. * revert lockfile changes * npm run format * fix e2e-versions.yml * eliminate duplication in version numbers * Fix test Co-authored-by: Brendan Burns <[email protected]> Co-authored-by: Brian Cristante <[email protected]>
1 parent 5f00602 commit db2f350

File tree

7 files changed

+367
-8
lines changed

7 files changed

+367
-8
lines changed

.github/workflows/e2e-versions.yml

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@ jobs:
2020
fail-fast: false
2121
matrix:
2222
os: [macos-latest, windows-latest, ubuntu-latest]
23-
distribution: ['temurin', 'adopt', 'adopt-openj9', 'zulu', 'liberica'] # internally 'adopt-hotspot' is the same as 'adopt'
23+
distribution: ['temurin', 'adopt', 'adopt-openj9', 'zulu', 'liberica', 'microsoft' ] # internally 'adopt-hotspot' is the same as 'adopt'
2424
version: ['8', '11', '16']
25+
exclude:
26+
- distribution: microsoft
27+
version: 8
2528
steps:
2629
- name: Checkout
2730
uses: actions/checkout@v2
@@ -174,16 +177,17 @@ jobs:
174177
run: bash __tests__/verify-java.sh "${{ matrix.version }}" "${{ steps.setup-java.outputs.path }}"
175178
shell: bash
176179

177-
setup-java-custom-architecture:
178-
name: ${{ matrix.distribution }} ${{ matrix.version }} (jdk-x86) - ${{ matrix.os }}
180+
# Only Liberica and Zulu provide x86
181+
setup-java-x86:
182+
name: ${{ matrix.distribution }} ${{ matrix.version }} (jdk-${{ matrix.architecture }}) - ${{ matrix.os }}
179183
needs: setup-java-major-minor-versions
180184
runs-on: ${{ matrix.os }}
181185
strategy:
182186
fail-fast: false
183187
matrix:
184-
# Only Zulu and Liberica provides x86 arch for now and only for windows / ubuntu
188+
# x86 is not supported on macOS
185189
os: [windows-latest, ubuntu-latest]
186-
distribution: ['zulu', 'liberica']
190+
distribution: ['liberica', 'zulu']
187191
version: ['11']
188192
steps:
189193
- name: Checkout
@@ -194,7 +198,9 @@ jobs:
194198
with:
195199
distribution: ${{ matrix.distribution }}
196200
java-version: ${{ matrix.version }}
197-
architecture: x86
201+
architecture: 'x86'
198202
- name: Verify Java
199203
run: bash __tests__/verify-java.sh "${{ matrix.version }}" "${{ steps.setup-java.outputs.path }}"
200204
shell: bash
205+
206+
# Only Microsoft provides AArch64. However, GitHub-hosted runners do not support this architecture.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ Currently, the following distributions are supported:
5959
| `adopt` or `adopt-hotspot` | Adopt OpenJDK Hotspot | [Link](https://adoptopenjdk.net/) | [Link](https://adoptopenjdk.net/about.html) |
6060
| `adopt-openj9` | Adopt OpenJDK OpenJ9 | [Link](https://adoptopenjdk.net/) | [Link](https://adoptopenjdk.net/about.html) |
6161
| `liberica` | Liberica JDK | [Link](https://bell-sw.com/) | [Link](https://bell-sw.com/liberica_eula/) |
62+
| `microsoft` | Microsoft Build of OpenJDK | [Link](https://www.microsoft.com/openjdk) | [Link](https://docs.microsoft.com/java/openjdk/faq)
6263

6364
**NOTE:** The different distributors can provide discrepant list of available versions / supported configurations. Please refer to the official documentation to see the list of supported versions.
6465

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { MicrosoftDistributions } from '../../src/distributions/microsoft/installer';
2+
3+
describe('findPackageForDownload', () => {
4+
let distribution: MicrosoftDistributions;
5+
6+
beforeEach(() => {
7+
distribution = new MicrosoftDistributions({
8+
version: '',
9+
architecture: 'x64',
10+
packageType: 'jdk',
11+
checkLatest: false
12+
});
13+
});
14+
15+
it.each([
16+
[
17+
'17.x',
18+
'17.0.1',
19+
'https://aka.ms/download-jdk/microsoft-jdk-17.0.1.12.1-{{OS_TYPE}}-x64.{{ARCHIVE_TYPE}}'
20+
],
21+
[
22+
'16.0.x',
23+
'16.0.2',
24+
'https://aka.ms/download-jdk/microsoft-jdk-16.0.2.7.1-{{OS_TYPE}}-x64.{{ARCHIVE_TYPE}}'
25+
],
26+
[
27+
'11.0.13',
28+
'11.0.13',
29+
'https://aka.ms/download-jdk/microsoft-jdk-11.0.13.8.1-{{OS_TYPE}}-x64.{{ARCHIVE_TYPE}}'
30+
]
31+
])('version is %s -> %s', async (input, expectedVersion, expectedUrl) => {
32+
const result = await distribution['findPackageForDownload'](input);
33+
expect(result.version).toBe(expectedVersion);
34+
let os: string;
35+
let archive: string;
36+
switch (process.platform) {
37+
case 'darwin':
38+
os = 'macos';
39+
archive = 'tar.gz';
40+
break;
41+
case 'win32':
42+
os = 'windows';
43+
archive = 'zip';
44+
break;
45+
default:
46+
os = process.platform.toString();
47+
archive = 'tar.gz';
48+
break;
49+
}
50+
const url = expectedUrl.replace('{{OS_TYPE}}', os).replace('{{ARCHIVE_TYPE}}', archive);
51+
expect(result.url).toBe(url);
52+
});
53+
54+
it('should throw an error', async () => {
55+
await expect(distribution['findPackageForDownload']('8')).rejects.toThrow(
56+
/Could not find satisfied version for SemVer */
57+
);
58+
});
59+
});
60+
61+
describe('getPlatformOption', () => {
62+
const distributions = new MicrosoftDistributions({
63+
architecture: 'x64',
64+
version: '11',
65+
packageType: 'jdk',
66+
checkLatest: false
67+
});
68+
69+
it.each([
70+
['linux', 'tar.gz', 'linux'],
71+
['darwin', 'tar.gz', 'macos'],
72+
['win32', 'zip', 'windows']
73+
])('os version %s -> %s', (input, expectedArchive, expectedOs) => {
74+
const actual = distributions['getPlatformOption'](input as NodeJS.Platform);
75+
76+
expect(actual.archive).toEqual(expectedArchive);
77+
expect(actual.os).toEqual(expectedOs);
78+
});
79+
80+
it.each(['aix', 'android', 'freebsd', 'openbsd', 'netbsd', 'solaris', 'cygwin'])(
81+
'not support os version %s',
82+
input => {
83+
expect(() => distributions['getPlatformOption'](input as NodeJS.Platform)).toThrow(
84+
/Platform '\w+' is not supported\. Supported platforms: .+/
85+
);
86+
}
87+
);
88+
});

dist/setup/index.js

Lines changed: 134 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13819,7 +13819,136 @@ exports.XMLCBWriter = XMLCBWriter;
1381913819
/* 193 */,
1382013820
/* 194 */,
1382113821
/* 195 */,
13822-
/* 196 */,
13822+
/* 196 */
13823+
/***/ (function(__unusedmodule, exports, __webpack_require__) {
13824+
13825+
"use strict";
13826+
13827+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13828+
if (k2 === undefined) k2 = k;
13829+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
13830+
}) : (function(o, m, k, k2) {
13831+
if (k2 === undefined) k2 = k;
13832+
o[k2] = m[k];
13833+
}));
13834+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
13835+
Object.defineProperty(o, "default", { enumerable: true, value: v });
13836+
}) : function(o, v) {
13837+
o["default"] = v;
13838+
});
13839+
var __importStar = (this && this.__importStar) || function (mod) {
13840+
if (mod && mod.__esModule) return mod;
13841+
var result = {};
13842+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
13843+
__setModuleDefault(result, mod);
13844+
return result;
13845+
};
13846+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13847+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13848+
return new (P || (P = Promise))(function (resolve, reject) {
13849+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
13850+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
13851+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
13852+
step((generator = generator.apply(thisArg, _arguments || [])).next());
13853+
});
13854+
};
13855+
var __importDefault = (this && this.__importDefault) || function (mod) {
13856+
return (mod && mod.__esModule) ? mod : { "default": mod };
13857+
};
13858+
Object.defineProperty(exports, "__esModule", { value: true });
13859+
exports.MicrosoftDistributions = void 0;
13860+
const base_installer_1 = __webpack_require__(83);
13861+
const semver_1 = __importDefault(__webpack_require__(876));
13862+
const util_1 = __webpack_require__(322);
13863+
const core = __importStar(__webpack_require__(470));
13864+
const tc = __importStar(__webpack_require__(139));
13865+
const fs_1 = __importDefault(__webpack_require__(747));
13866+
const path_1 = __importDefault(__webpack_require__(622));
13867+
class MicrosoftDistributions extends base_installer_1.JavaBase {
13868+
constructor(installerOptions) {
13869+
super('Microsoft', installerOptions);
13870+
}
13871+
downloadTool(javaRelease) {
13872+
return __awaiter(this, void 0, void 0, function* () {
13873+
core.info(`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`);
13874+
const javaArchivePath = yield tc.downloadTool(javaRelease.url);
13875+
core.info(`Extracting Java archive...`);
13876+
const extension = util_1.getDownloadArchiveExtension();
13877+
const extractedJavaPath = yield util_1.extractJdkFile(javaArchivePath, extension);
13878+
const archiveName = fs_1.default.readdirSync(extractedJavaPath)[0];
13879+
const archivePath = path_1.default.join(extractedJavaPath, archiveName);
13880+
const javaPath = yield tc.cacheDir(archivePath, this.toolcacheFolderName, this.getToolcacheVersionName(javaRelease.version), this.architecture);
13881+
return { version: javaRelease.version, path: javaPath };
13882+
});
13883+
}
13884+
findPackageForDownload(range) {
13885+
return __awaiter(this, void 0, void 0, function* () {
13886+
if (this.architecture !== 'x64' && this.architecture !== 'aarch64') {
13887+
throw new Error(`Unsupported architecture: ${this.architecture}`);
13888+
}
13889+
const availableVersionsRaw = yield this.getAvailableVersions();
13890+
const opts = this.getPlatformOption();
13891+
const availableVersions = availableVersionsRaw.map(item => ({
13892+
url: `https://aka.ms/download-jdk/microsoft-jdk-${item.version.join('.')}-${opts.os}-${this.architecture}.${opts.archive}`,
13893+
version: this.convertVersionToSemver(item)
13894+
}));
13895+
const satisfiedVersion = availableVersions
13896+
.filter(item => util_1.isVersionSatisfies(range, item.version))
13897+
.sort((a, b) => -semver_1.default.compareBuild(a.version, b.version))[0];
13898+
if (!satisfiedVersion) {
13899+
const availableOptions = availableVersions.map(item => item.version).join(', ');
13900+
const availableOptionsMessage = availableOptions
13901+
? `\nAvailable versions: ${availableOptions}`
13902+
: '';
13903+
throw new Error(`Could not find satisfied version for SemVer ${range}. ${availableOptionsMessage}`);
13904+
}
13905+
return satisfiedVersion;
13906+
});
13907+
}
13908+
getAvailableVersions() {
13909+
return __awaiter(this, void 0, void 0, function* () {
13910+
// TODO get these dynamically!
13911+
// We will need Microsoft to add an endpoint where we can query for versions.
13912+
const jdkVersions = [
13913+
{
13914+
version: [17, 0, 1, 12, 1]
13915+
},
13916+
{
13917+
version: [16, 0, 2, 7, 1]
13918+
}
13919+
];
13920+
// M1 is only supported for Java 16 & 17
13921+
if (process.platform !== 'darwin' || this.architecture !== 'aarch64') {
13922+
jdkVersions.push({
13923+
version: [11, 0, 13, 8, 1]
13924+
});
13925+
}
13926+
return jdkVersions;
13927+
});
13928+
}
13929+
getPlatformOption(platform = process.platform /* for testing */) {
13930+
switch (platform) {
13931+
case 'darwin':
13932+
return { archive: 'tar.gz', os: 'macos' };
13933+
case 'win32':
13934+
return { archive: 'zip', os: 'windows' };
13935+
case 'linux':
13936+
return { archive: 'tar.gz', os: 'linux' };
13937+
default:
13938+
throw new Error(`Platform '${platform}' is not supported. Supported platforms: 'darwin', 'linux', 'win32'`);
13939+
}
13940+
}
13941+
convertVersionToSemver(version) {
13942+
const major = version.version[0];
13943+
const minor = version.version[1];
13944+
const patch = version.version[2];
13945+
return `${major}.${minor}.${patch}`;
13946+
}
13947+
}
13948+
exports.MicrosoftDistributions = MicrosoftDistributions;
13949+
13950+
13951+
/***/ }),
1382313952
/* 197 */
1382413953
/***/ (function(__unusedmodule, exports, __webpack_require__) {
1382513954

@@ -56004,6 +56133,7 @@ const installer_2 = __webpack_require__(834);
5600456133
const installer_3 = __webpack_require__(584);
5600556134
const installer_4 = __webpack_require__(439);
5600656135
const installer_5 = __webpack_require__(507);
56136+
const installer_6 = __webpack_require__(196);
5600756137
var JavaDistribution;
5600856138
(function (JavaDistribution) {
5600956139
JavaDistribution["Adopt"] = "adopt";
@@ -56013,6 +56143,7 @@ var JavaDistribution;
5601356143
JavaDistribution["Zulu"] = "zulu";
5601456144
JavaDistribution["Liberica"] = "liberica";
5601556145
JavaDistribution["JdkFile"] = "jdkfile";
56146+
JavaDistribution["Microsoft"] = "microsoft";
5601656147
})(JavaDistribution || (JavaDistribution = {}));
5601756148
function getJavaDistribution(distributionName, installerOptions, jdkFile) {
5601856149
switch (distributionName) {
@@ -56029,6 +56160,8 @@ function getJavaDistribution(distributionName, installerOptions, jdkFile) {
5602956160
return new installer_2.ZuluDistribution(installerOptions);
5603056161
case JavaDistribution.Liberica:
5603156162
return new installer_5.LibericaDistributions(installerOptions);
56163+
case JavaDistribution.Microsoft:
56164+
return new installer_6.MicrosoftDistributions(installerOptions);
5603256165
default:
5603356166
return null;
5603456167
}

src/distributions/distribution-factory.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ZuluDistribution } from './zulu/installer';
55
import { AdoptDistribution, AdoptImplementation } from './adopt/installer';
66
import { TemurinDistribution, TemurinImplementation } from './temurin/installer';
77
import { LibericaDistributions } from './liberica/installer';
8+
import { MicrosoftDistributions } from './microsoft/installer';
89

910
enum JavaDistribution {
1011
Adopt = 'adopt',
@@ -13,7 +14,8 @@ enum JavaDistribution {
1314
Temurin = 'temurin',
1415
Zulu = 'zulu',
1516
Liberica = 'liberica',
16-
JdkFile = 'jdkfile'
17+
JdkFile = 'jdkfile',
18+
Microsoft = 'microsoft'
1719
}
1820

1921
export function getJavaDistribution(
@@ -35,6 +37,8 @@ export function getJavaDistribution(
3537
return new ZuluDistribution(installerOptions);
3638
case JavaDistribution.Liberica:
3739
return new LibericaDistributions(installerOptions);
40+
case JavaDistribution.Microsoft:
41+
return new MicrosoftDistributions(installerOptions);
3842
default:
3943
return null;
4044
}

0 commit comments

Comments
 (0)