mirror of
https://github.com/actions/setup-java.git
synced 2026-08-20 19:02:58 +00:00
Add Red Hat Build of OpenJDK support (#1241)
* 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>
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user