mirror of
https://github.com/actions/setup-java.git
synced 2026-07-08 14:21:50 +00:00
229 lines
7.0 KiB
TypeScript
229 lines
7.0 KiB
TypeScript
import {JavaBase} from '../base-installer';
|
|
import {
|
|
JavaDownloadRelease,
|
|
JavaInstallerOptions,
|
|
JavaInstallerResults
|
|
} from '../base-models';
|
|
import {
|
|
extractJdkFile,
|
|
getDownloadArchiveExtension,
|
|
getGitHubHttpHeaders,
|
|
isVersionSatisfies,
|
|
renameWinArchive
|
|
} from '../../util';
|
|
import * as gpg from '../../gpg';
|
|
import {MICROSOFT_PUBLIC_KEY} from './microsoft-key';
|
|
import * as core from '@actions/core';
|
|
import * as tc from '@actions/tool-cache';
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import semver from 'semver';
|
|
import {TypedResponse} from '@actions/http-client/lib/interfaces';
|
|
|
|
export {MICROSOFT_PUBLIC_KEY} from './microsoft-key';
|
|
|
|
export class MicrosoftDistributions extends JavaBase {
|
|
constructor(installerOptions: JavaInstallerOptions) {
|
|
super('Microsoft', installerOptions);
|
|
}
|
|
|
|
protected async downloadTool(
|
|
javaRelease: JavaDownloadRelease
|
|
): Promise<JavaInstallerResults> {
|
|
core.info(
|
|
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
|
|
);
|
|
let javaArchivePath = await tc.downloadTool(javaRelease.url);
|
|
|
|
if (this.verifySignature) {
|
|
if (!javaRelease.signatureUrl) {
|
|
throw new Error(
|
|
`Input 'verify-signature' is enabled, but no signature URL was found for Microsoft Build of OpenJDK version ${javaRelease.version}.`
|
|
);
|
|
}
|
|
core.info(`Verifying Java package signature...`);
|
|
try {
|
|
await gpg.verifyPackageSignature(
|
|
javaArchivePath,
|
|
javaRelease.signatureUrl,
|
|
this.verifySignaturePublicKey ?? MICROSOFT_PUBLIC_KEY
|
|
);
|
|
} catch (error) {
|
|
throw new Error(
|
|
`Failed to verify signature for Microsoft Build of OpenJDK version ${javaRelease.version}. Signature URL: ${javaRelease.signatureUrl}. Error: ${(error as Error).message}`
|
|
);
|
|
}
|
|
}
|
|
|
|
core.info(`Extracting Java archive...`);
|
|
const extension = getDownloadArchiveExtension();
|
|
if (process.platform === 'win32') {
|
|
javaArchivePath = renameWinArchive(javaArchivePath);
|
|
}
|
|
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<JavaDownloadRelease> {
|
|
const arch = this.distributionArchitecture();
|
|
if (arch !== 'x64' && arch !== '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 manifest = await this.getAvailableVersions();
|
|
|
|
if (!manifest) {
|
|
throw new Error('Could not load manifest for Microsoft Build of OpenJDK');
|
|
}
|
|
|
|
let foundRelease: tc.IToolRelease | undefined;
|
|
|
|
if (this.isRunningOnAlpine() && this.isAlpineSupportedVersion(range)) {
|
|
foundRelease = this.findFromManifestForPlatform(
|
|
range,
|
|
manifest,
|
|
arch,
|
|
'alpine'
|
|
);
|
|
if (foundRelease) {
|
|
core.debug(`Resolved Alpine package for Microsoft OpenJDK ${range}`);
|
|
}
|
|
} else if (this.isRunningOnAlpine()) {
|
|
core.debug(
|
|
`No Alpine package found for Microsoft OpenJDK ${range}, defaulting to standard linux package`
|
|
);
|
|
}
|
|
|
|
// Runs if user is not running on alpine, or if no Alpine package was found
|
|
if (!foundRelease) {
|
|
foundRelease = await tc.findFromManifest(range, true, manifest, arch);
|
|
}
|
|
|
|
// Runs if failed to find any matching package
|
|
if (!foundRelease) {
|
|
const availableVersionStrings = manifest.map(item => item.version);
|
|
throw this.createVersionNotFoundError(range, availableVersionStrings);
|
|
}
|
|
|
|
const file = foundRelease.files[0] as {
|
|
download_url: string;
|
|
signature_url?: string;
|
|
};
|
|
const signatureUrl = file.signature_url ?? `${file.download_url}.sig`;
|
|
|
|
return {
|
|
url: file.download_url,
|
|
signatureUrl,
|
|
version: foundRelease.version
|
|
};
|
|
}
|
|
|
|
private findFromManifestForPlatform(
|
|
range: string,
|
|
manifest: tc.IToolRelease[],
|
|
arch: string,
|
|
platform: string
|
|
): tc.IToolRelease | undefined {
|
|
const matched = manifest
|
|
.filter(release => release.stable)
|
|
.filter(release => isVersionSatisfies(range, release.version))
|
|
.map(release => {
|
|
const matchedFile = release.files.find(
|
|
(file: tc.IToolReleaseFile) =>
|
|
file.arch === arch && file.platform === platform
|
|
);
|
|
if (!matchedFile) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
...release,
|
|
files: [matchedFile]
|
|
};
|
|
})
|
|
.filter((release): release is tc.IToolRelease => release !== null)
|
|
.sort((a, b) => -semver.compareBuild(a.version, b.version));
|
|
|
|
return matched[0];
|
|
}
|
|
|
|
private isAlpineSupportedVersion(range: string): boolean {
|
|
const minVersion = semver.minVersion(range);
|
|
return !!minVersion && (minVersion.major === 11 || minVersion.major === 17);
|
|
}
|
|
|
|
private isRunningOnAlpine(): boolean {
|
|
return process.platform === 'linux' && fs.existsSync('/etc/alpine-release');
|
|
}
|
|
|
|
protected supportsSignatureVerification(): boolean {
|
|
return true;
|
|
}
|
|
|
|
private async getAvailableVersions(): Promise<tc.IToolRelease[] | null> {
|
|
const owner = 'microsoft';
|
|
const repository = 'openjdk-adoptium-marketplace-data';
|
|
const branch = 'main';
|
|
const filePath = 'general_info/microsoft-openjdk-versions.json';
|
|
let releases: tc.IToolRelease[] | null = null;
|
|
const fileUrl = `https://api.github.com/repos/${owner}/${repository}/contents/${filePath}?ref=${branch}`;
|
|
|
|
const headers = getGitHubHttpHeaders();
|
|
|
|
let response: TypedResponse<tc.IToolRelease[]> | null = null;
|
|
|
|
if (core.isDebug()) {
|
|
console.time('Retrieving available versions for Microsoft took'); // eslint-disable-line no-console
|
|
}
|
|
|
|
try {
|
|
response = await this.http.getJson<tc.IToolRelease[]>(fileUrl, headers);
|
|
if (!response.result) {
|
|
return null;
|
|
}
|
|
} catch (err) {
|
|
core.debug(
|
|
`Http request for microsoft-openjdk-versions.json failed with status code: ${response?.statusCode}. Error: ${err}`
|
|
);
|
|
return null;
|
|
}
|
|
|
|
if (response.result) {
|
|
releases = response.result;
|
|
}
|
|
|
|
if (core.isDebug() && releases) {
|
|
core.startGroup('Print information about available versions');
|
|
console.timeEnd('Retrieving available versions for Microsoft took'); // eslint-disable-line no-console
|
|
core.debug(`Available versions: [${releases.length}]`);
|
|
core.debug(releases.map(item => item.version).join(', '));
|
|
core.endGroup();
|
|
}
|
|
|
|
return releases;
|
|
}
|
|
}
|