mirror of
https://github.com/actions/setup-java.git
synced 2026-08-18 18:52:57 +00:00
416c6d1e8a
* Add Red Hat Build of OpenJDK support Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Fix Red Hat tests on Windows Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Update compiled Red Hat distribution Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
181 lines
5.6 KiB
TypeScript
181 lines
5.6 KiB
TypeScript
import * as core from '@actions/core';
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import semver from 'semver';
|
|
import {
|
|
cacheJdkDir,
|
|
extractJdkFile,
|
|
isVersionSatisfies,
|
|
renameWinArchive
|
|
} from '../../util.js';
|
|
import {JavaBase} from '../base-installer.js';
|
|
import {
|
|
JavaDownloadRelease,
|
|
JavaInstallerOptions,
|
|
JavaInstallerResults
|
|
} from '../base-models.js';
|
|
import {
|
|
IDiscoPackage,
|
|
IDiscoPackageDetailsResponse,
|
|
IDiscoPackageListResponse
|
|
} from './models.js';
|
|
import {isAlpineLinux} from '../platform-types.js';
|
|
|
|
const DISCO_API_URL = 'https://api.foojay.io/disco/v3.0';
|
|
|
|
export class RedHatDistribution extends JavaBase {
|
|
constructor(installerOptions: JavaInstallerOptions) {
|
|
super('RedHat', installerOptions);
|
|
}
|
|
|
|
protected async findPackageForDownload(
|
|
range: string
|
|
): Promise<JavaDownloadRelease> {
|
|
if (!this.stable) {
|
|
throw new Error('Early access versions are not supported');
|
|
}
|
|
|
|
const availablePackages = await this.getAvailablePackages();
|
|
const normalizedPackages = availablePackages
|
|
.map(item => ({
|
|
item,
|
|
version: this.normalizeDiscoVersion(item.java_version)
|
|
}))
|
|
.filter(
|
|
(item): item is {item: IDiscoPackage; version: string} =>
|
|
item.version !== null
|
|
)
|
|
.sort((left, right) => -semver.compareBuild(left.version, right.version));
|
|
|
|
const selectedPackage = normalizedPackages.find(item =>
|
|
isVersionSatisfies(range, item.version)
|
|
);
|
|
if (!selectedPackage) {
|
|
throw this.createVersionNotFoundError(
|
|
range,
|
|
normalizedPackages.map(item => item.version),
|
|
`Operating system: ${this.getOperatingSystem()}`
|
|
);
|
|
}
|
|
|
|
const detailsUrl = `${DISCO_API_URL}/ids/${selectedPackage.item.id}`;
|
|
const response =
|
|
await this.http.getJson<IDiscoPackageDetailsResponse>(detailsUrl);
|
|
const details = response.result?.result?.[0];
|
|
if (!details?.direct_download_uri) {
|
|
throw new Error(
|
|
`Foojay Disco returned no direct Red Hat download URL for package '${selectedPackage.item.id}'.`
|
|
);
|
|
}
|
|
const checksum = details.checksum?.trim();
|
|
if (details.checksum_type?.toLowerCase() !== 'sha256' || !checksum) {
|
|
throw new Error(
|
|
`Foojay Disco returned no SHA-256 checksum for Red Hat package '${selectedPackage.item.id}'.`
|
|
);
|
|
}
|
|
|
|
return {
|
|
version: selectedPackage.version,
|
|
url: details.direct_download_uri,
|
|
checksum: {
|
|
algorithm: 'sha256',
|
|
value: checksum,
|
|
source: detailsUrl
|
|
}
|
|
};
|
|
}
|
|
|
|
protected async downloadTool(
|
|
javaRelease: JavaDownloadRelease
|
|
): Promise<JavaInstallerResults> {
|
|
core.info(
|
|
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
|
|
);
|
|
let javaArchivePath = await this.downloadAndVerify(javaRelease);
|
|
|
|
core.info('Extracting Java archive...');
|
|
const archiveType = this.getArchiveType();
|
|
if (archiveType === 'zip') {
|
|
javaArchivePath = renameWinArchive(javaArchivePath);
|
|
}
|
|
const extractedJavaPath = await extractJdkFile(
|
|
javaArchivePath,
|
|
archiveType
|
|
);
|
|
const archiveName = fs.readdirSync(extractedJavaPath)[0];
|
|
if (!archiveName) {
|
|
throw new Error(
|
|
`The Red Hat archive for Java ${javaRelease.version} was empty.`
|
|
);
|
|
}
|
|
const archivePath = path.join(extractedJavaPath, archiveName);
|
|
const javaPath = await cacheJdkDir(
|
|
archivePath,
|
|
this.toolcacheFolderName,
|
|
this.getToolcacheVersionName(javaRelease.version),
|
|
this.architecture
|
|
);
|
|
|
|
return {version: javaRelease.version, path: javaPath};
|
|
}
|
|
|
|
private async getAvailablePackages(): Promise<IDiscoPackage[]> {
|
|
const operatingSystem = this.getOperatingSystem();
|
|
const archiveType = this.getArchiveType();
|
|
const query = new URLSearchParams({
|
|
distro: 'redhat',
|
|
release_status: 'ga',
|
|
operating_system: operatingSystem,
|
|
architecture: this.distributionArchitecture(),
|
|
package_type: this.packageType,
|
|
archive_type: archiveType,
|
|
directly_downloadable: 'true'
|
|
});
|
|
const url = `${DISCO_API_URL}/packages?${query.toString()}`;
|
|
const response = await this.http.getJson<IDiscoPackageListResponse>(url);
|
|
const packages = response.result?.result;
|
|
if (!Array.isArray(packages)) {
|
|
throw new Error(
|
|
`Could not fetch Red Hat package metadata from Foojay Disco: ${url}`
|
|
);
|
|
}
|
|
|
|
return packages.filter(
|
|
item =>
|
|
item.distribution === 'redhat' &&
|
|
item.release_status === 'ga' &&
|
|
item.operating_system === operatingSystem &&
|
|
item.architecture === this.distributionArchitecture() &&
|
|
item.package_type === this.packageType &&
|
|
item.archive_type === archiveType &&
|
|
item.directly_downloadable
|
|
);
|
|
}
|
|
|
|
private getOperatingSystem(alpine = isAlpineLinux()): string {
|
|
if (alpine) {
|
|
throw new Error(
|
|
"Distribution 'redhat' does not support Alpine Linux because Red Hat portable archives require glibc."
|
|
);
|
|
}
|
|
return process.platform === 'win32' ? 'windows' : 'linux';
|
|
}
|
|
|
|
private getArchiveType(): string {
|
|
return process.platform === 'win32' ? 'zip' : 'tar.xz';
|
|
}
|
|
|
|
private normalizeDiscoVersion(version: string): string | null {
|
|
let normalizedVersion = version.trim();
|
|
if (/^\d+\+\d+$/.test(normalizedVersion)) {
|
|
normalizedVersion = normalizedVersion.replace('+', '.0.0+');
|
|
} else if (/^\d+$/.test(normalizedVersion)) {
|
|
normalizedVersion = `${normalizedVersion}.0.0`;
|
|
} else if (/^\d+\.\d+$/.test(normalizedVersion)) {
|
|
normalizedVersion = `${normalizedVersion}.0`;
|
|
}
|
|
|
|
return semver.valid(normalizedVersion) ? normalizedVersion : null;
|
|
}
|
|
}
|