import { JavaBase } from '../base-installer'; import { JavaDownloadRelease, JavaInstallerOptions, JavaInstallerResults } from '../base-models'; import { extractJdkFile, getDownloadArchiveExtension } from '../../util'; import * as core from '@actions/core'; import { MicrosoftVersion, PlatformOptions } from './models'; import * as tc from '@actions/tool-cache'; import fs from 'fs'; import path from 'path'; export interface IToolRelease { version: string; stable: boolean; files: tc.IToolReleaseFile[]; } export class MicrosoftDistributions extends JavaBase { constructor(installerOptions: JavaInstallerOptions) { super('Microsoft', installerOptions); } protected async downloadTool(javaRelease: JavaDownloadRelease): Promise { core.info( `Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...` ); const javaArchivePath = await tc.downloadTool(javaRelease.url); core.info(`Extracting Java archive...`); const extension = getDownloadArchiveExtension(); const extractedJavaPath = await extractJdkFile(javaArchivePath, extension); const archiveName = fs.readdirSync(extractedJavaPath)[0]; const archivePath = path.join(extractedJavaPath, archiveName); const javaPath = await tc.cacheDir( archivePath, this.toolcacheFolderName, this.getToolcacheVersionName(javaRelease.version), this.architecture ); return { version: javaRelease.version, path: javaPath }; } protected async findPackageForDownload(range: string): Promise { if (this.architecture !== 'x64' && this.architecture !== 'aarch64') { throw new Error(`Unsupported architecture: ${this.architecture}`); } if (!this.stable) { throw new Error('Early access versions are not supported'); } if (this.packageType !== 'jdk') { throw new Error('Microsoft Build of OpenJDK provides only the `jdk` package type'); } const availableVersionsRaw = await this.getAvailableVersions(); if (!availableVersionsRaw) { throw new Error('Could not load manifest for Microsoft Build of OpenJDK'); } const foundRelease = await tc.findFromManifest( range, true, availableVersionsRaw, this.architecture ); // const opts = this.getPlatformOption(); // const availableVersions = availableVersionsRaw.map(item => ({ // url: `https://aka.ms/download-jdk/microsoft-jdk-${item.version.join('.')}-${opts.os}-${ // this.architecture // https://aka.ms/download-jdk/microsoft-jdk-17.0.3-linux-aarch64.tar.gz // }.${opts.archive}`, // version: this.convertVersionToSemver(item) // })); // const satisfiedVersion = availableVersions // .filter(item => isVersionSatisfies(range, item.version)) // .sort((a, b) => -semver.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}` // ); // } if (!foundRelease) { throw new Error( `Could not find satisfied version for SemVer ${range}. ${availableVersionsRaw .map(item => item.version) .join(', ')}` ); } return { url: foundRelease.files[0].download_url, version: foundRelease.version }; } private async getAvailableVersions(): Promise { // TODO get these dynamically! // We will need Microsoft to add an endpoint where we can query for versions. const token = core.getInput('token'); const manifest = await tc.getManifestFromRepo( 'dmitry-shibanov', 'setup-java', token, 'add-json-for-microsoft-versions' ); return manifest; } private getPlatformOption( platform: NodeJS.Platform = process.platform /* for testing */ ): PlatformOptions { 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: 'darwin', 'linux', 'win32'` ); } } private convertVersionToSemver(version: MicrosoftVersion): string { const major = version.version[0]; const minor = version.version[1]; const patch = version.version[2]; return `${major}.${minor}.${patch}`; } }