Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add microsoft distribution of the JDK. #252

Merged
merged 12 commits into from Dec 8, 2021
18 changes: 15 additions & 3 deletions .github/workflows/e2e-versions.yml
Expand Up @@ -20,8 +20,11 @@ jobs:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
distribution: ['temurin', 'adopt', 'adopt-openj9', 'zulu', 'liberica'] # internally 'adopt-hotspot' is the same as 'adopt'
distribution: ['temurin', 'adopt', 'adopt-openj9', 'zulu', 'liberica', 'microsoft' ] # internally 'adopt-hotspot' is the same as 'adopt'
version: ['8', '11', '16']

Choose a reason for hiding this comment

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

Can we replace 16 with 17 here, since 17 is the latest LTS now?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Probably worth doing in a different PR since it is unrelated to adding MSFT.

Choose a reason for hiding this comment

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

Ah, yes. That'd be better indeed.

exclude:

Choose a reason for hiding this comment

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

I think we should also exclude Microsoft's version 16, as it is not an LTS release and we will no longer provide updates.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think for now, since Microsoft hosts it, we should keep it in the spirit of meeting users where they are. Many users haven't updated their CI/CD for JDK 17.

Choose a reason for hiding this comment

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

Yeah, that makes sense. We are not exposing support timelines for any of the distros through the GH Action anyways, so, it is up to the end-user to check the documentation of each distro.

- distribution: microsoft
version: 8
steps:
- name: Checkout
uses: actions/checkout@v2
Expand Down Expand Up @@ -175,16 +178,25 @@ jobs:
shell: bash

setup-java-custom-architecture:
name: ${{ matrix.distribution }} ${{ matrix.version }} (jdk-x86) - ${{ matrix.os }}
# Only Zulu provides x86 arch for now and only for windows / ubuntu
# Only Microsoft provides arm64 for windows / ubuntu / os x
if: ${{ (matrix.distribution == 'zulu' && matrix.architecture == 'x86' && matrix.os != 'macos-latest' ) || (matrix.distribution == 'microsoft' && matrix.architecture == 'arm64') }}
brcrista marked this conversation as resolved.
Show resolved Hide resolved
name: ${{ matrix.distribution }} ${{ matrix.version }} (jdk-${{ matrix.architecture }}) - ${{ matrix.os }}
needs: setup-java-major-minor-versions
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
<<<<<<< HEAD
# Only Zulu and Liberica provides x86 arch for now and only for windows / ubuntu
os: [windows-latest, ubuntu-latest]
distribution: ['zulu', 'liberica']
=======
os: [macos-latest, windows-latest, ubuntu-latest]
distribution: ['zulu', 'microsoft']
>>>>>>> Add microsoft distribution of the JDK.
brcrista marked this conversation as resolved.
Show resolved Hide resolved
version: ['11']

Choose a reason for hiding this comment

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

Should we move up to 17?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As above.

Choose a reason for hiding this comment

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

Noted.

architecture: [ 'x86', 'arm64' ]
steps:
- name: Checkout
uses: actions/checkout@v2
Expand All @@ -194,7 +206,7 @@ jobs:
with:
distribution: ${{ matrix.distribution }}
java-version: ${{ matrix.version }}
architecture: x86
architecture: ${{ matrix.architecture }}
- name: Verify Java
run: bash __tests__/verify-java.sh "${{ matrix.version }}" "${{ steps.setup-java.outputs.path }}"
shell: bash
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -59,6 +59,7 @@ Currently, the following distributions are supported:
| `adopt` or `adopt-hotspot` | Adopt OpenJDK Hotspot | [Link](https://adoptopenjdk.net/) | [Link](https://adoptopenjdk.net/about.html) |
| `adopt-openj9` | Adopt OpenJDK OpenJ9 | [Link](https://adoptopenjdk.net/) | [Link](https://adoptopenjdk.net/about.html) |
| `liberica` | Liberica JDK | [Link](https://bell-sw.com/) | [Link](https://bell-sw.com/liberica_eula/) |
| `microsoft` | Microsoft Build of OpenJDK | [Link](https://www.microsoft.com/openjdk) | [Link](https://docs.microsoft.com/java/openjdk/faq)

**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.

Expand Down
88 changes: 88 additions & 0 deletions __tests__/distributors/microsoft-installer.test.ts
@@ -0,0 +1,88 @@
import { MicrosoftDistributions } from '../../src/distributions/microsoft/installer';

describe('findPackageForDownload', () => {
let distribution: MicrosoftDistributions;

beforeEach(() => {
distribution = new MicrosoftDistributions({
version: '',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
});

it.each([
[
'17.x',
'17.0.1',
'https://aka.ms/download-jdk/microsoft-jdk-17.0.1.12.1-{{OS_TYPE}}-x64.{{ARCHIVE_TYPE}}'
],
[
'16.0.x',

Choose a reason for hiding this comment

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

Given 16 is not an LTS release of MS Build of OpenJDK, I think we should not list it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

as above, but if you feel strongly I will remove it.

Choose a reason for hiding this comment

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

No, it's fine. See previous comment.

'16.0.2',
'https://aka.ms/download-jdk/microsoft-jdk-16.0.2.7.1-{{OS_TYPE}}-x64.{{ARCHIVE_TYPE}}'
],
[
'11.0.13',
'11.0.13',
'https://aka.ms/download-jdk/microsoft-jdk-11.0.13.8.1-{{OS_TYPE}}-x64.{{ARCHIVE_TYPE}}'
]
])('version is %s -> %s', async (input, expectedVersion, expectedUrl) => {
const result = await distribution['findPackageForDownload'](input);
expect(result.version).toBe(expectedVersion);
let os: string;
let archive: string;
switch (process.platform) {
case 'darwin':
os = 'macos';
archive = 'tar.gz';
break;
case 'win32':
os = 'windows';
archive = 'zip';
break;
default:
os = process.platform.toString();
archive = 'tar.gz';
break;
}
const url = expectedUrl.replace('{{OS_TYPE}}', os).replace('{{ARCHIVE_TYPE}}', archive);
expect(result.url).toBe(url);
});

it('should throw an error', async () => {
await expect(distribution['findPackageForDownload']('8')).rejects.toThrow(
/Could not find satisfied version for SemVer */
);
});
});

describe('getPlatformOption', () => {
const distributions = new MicrosoftDistributions({
architecture: 'x64',
version: '11',
packageType: 'jdk',
checkLatest: false
});

it.each([
['linux', 'tar.gz', 'linux'],
['darwin', 'tar.gz', 'macos'],
['win32', 'zip', 'windows']
])('os version %s -> %s', (input, expectedArchive, expectedOs) => {
const actual = distributions['getPlatformOption'](input as NodeJS.Platform);

expect(actual.archive).toEqual(expectedArchive);
expect(actual.os).toEqual(expectedOs);
});

it.each(['aix', 'android', 'freebsd', 'openbsd', 'netbsd', 'solaris', 'cygwin'])(
'not support os version %s',
input => {
expect(() => distributions['getPlatformOption'](input as NodeJS.Platform)).toThrow(
/Platform '\w+' is not supported\. Supported platforms: .+/
);
}
);
});
141 changes: 140 additions & 1 deletion dist/setup/index.js
Expand Up @@ -13819,7 +13819,142 @@ exports.XMLCBWriter = XMLCBWriter;
/* 193 */,
/* 194 */,
/* 195 */,
/* 196 */,
/* 196 */
/***/ (function(__unusedmodule, exports, __webpack_require__) {

"use strict";

var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MicrosoftDistributions = void 0;
const base_installer_1 = __webpack_require__(83);
const semver_1 = __importDefault(__webpack_require__(876));
const util_1 = __webpack_require__(322);
const core = __importStar(__webpack_require__(470));
const tc = __importStar(__webpack_require__(139));
const fs_1 = __importDefault(__webpack_require__(747));
const path_1 = __importDefault(__webpack_require__(622));
const supportedPlatform = `'linux', 'macos', 'windows'`;
class MicrosoftDistributions extends base_installer_1.JavaBase {
constructor(installerOptions) {
super('Microsoft', installerOptions);
}
downloadTool(javaRelease) {
return __awaiter(this, void 0, void 0, function* () {
core.info(`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`);
const javaArchivePath = yield tc.downloadTool(javaRelease.url);
core.info(`Extracting Java archive...`);
const extension = util_1.getDownloadArchiveExtension();
const extractedJavaPath = yield util_1.extractJdkFile(javaArchivePath, extension);
const archiveName = fs_1.default.readdirSync(extractedJavaPath)[0];
const archivePath = path_1.default.join(extractedJavaPath, archiveName);
const javaPath = yield tc.cacheDir(archivePath, this.toolcacheFolderName, this.getToolcacheVersionName(javaRelease.version), this.architecture);
return { version: javaRelease.version, path: javaPath };
});
}
findPackageForDownload(range) {
return __awaiter(this, void 0, void 0, function* () {
if (this.architecture !== 'x64' && this.architecture != 'aarch64') {
throw new Error(`Unsupported architecture: ${this.architecture}`);
}
const availableVersionsRaw = yield this.getAvailableVersions();
const opts = this.getPlatformOption();
const availableVersions = availableVersionsRaw.map(item => ({
url: `https://aka.ms/download-jdk/microsoft-jdk-${item.fullVersion.join('.')}-${opts.os}-${this.architecture}.${opts.archive}`,
version: this.convertVersionToSemver(item)
}));
const satisfiedVersion = availableVersions
.filter(item => 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}`);
}
return satisfiedVersion;
});
}
getAvailableVersions() {
return __awaiter(this, void 0, void 0, function* () {
// TODO get these dynamically!
const jdkVersions = [
{
majorVersion: 17,
minorVersion: 0,
patchVersion: 1,
fullVersion: [17, 0, 1, 12, 1],
},
{
majorVersion: 16,
minorVersion: 0,
patchVersion: 2,
fullVersion: [16, 0, 2.7, 1],
},
];
// M1 is only supported for Java 16 & 17
if (process.platform !== 'darwin' || this.architecture !== 'aarch64') {
jdkVersions.push({
majorVersion: 11,
minorVersion: 0,
patchVersion: 13,
fullVersion: [11, 0, 13, 8, 1],
});
}
return jdkVersions;
});
}
getPlatformOption(platform = process.platform) {
switch (platform) {
case 'darwin':
return { archive: 'tar.gz', os: 'macos' };
case 'win32':
return { archive: 'zip', os: 'windows' };
case 'linux':
return { archive: 'tar.gz', os: 'linux' };
default:
throw new Error(`Platform '${platform}' is not supported. Supported platforms: ${supportedPlatform}`);
}
}
convertVersionToSemver(version) {
return `${version.majorVersion}.${version.minorVersion}.${version.patchVersion}`;
}
}
exports.MicrosoftDistributions = MicrosoftDistributions;


/***/ }),
/* 197 */
/***/ (function(__unusedmodule, exports, __webpack_require__) {

Expand Down Expand Up @@ -56004,6 +56139,7 @@ const installer_2 = __webpack_require__(834);
const installer_3 = __webpack_require__(584);
const installer_4 = __webpack_require__(439);
const installer_5 = __webpack_require__(507);
const installer_6 = __webpack_require__(196);
var JavaDistribution;
(function (JavaDistribution) {
JavaDistribution["Adopt"] = "adopt";
Expand All @@ -56013,6 +56149,7 @@ var JavaDistribution;
JavaDistribution["Zulu"] = "zulu";
JavaDistribution["Liberica"] = "liberica";
JavaDistribution["JdkFile"] = "jdkfile";
JavaDistribution["Microsoft"] = "microsoft";
})(JavaDistribution || (JavaDistribution = {}));
function getJavaDistribution(distributionName, installerOptions, jdkFile) {
switch (distributionName) {
Expand All @@ -56029,6 +56166,8 @@ function getJavaDistribution(distributionName, installerOptions, jdkFile) {
return new installer_2.ZuluDistribution(installerOptions);
case JavaDistribution.Liberica:
return new installer_5.LibericaDistributions(installerOptions);
case JavaDistribution.Microsoft:
return new installer_6.MicrosoftDistributions(installerOptions);
default:
return null;
}
Expand Down