mirror of
https://github.com/actions/setup-java.git
synced 2026-08-19 04:02:51 +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:
co-authored by
Copilot App
Copilot Autofix powered by AI
parent
5f75b27283
commit
416c6d1e8a
@@ -211,6 +211,7 @@ Deprecated aliases `jdkFile`, `server-username`, `server-password`, and `gpg-pas
|
|||||||
| `microsoft` | [Microsoft Build of OpenJDK](https://www.microsoft.com/openjdk) | [License](https://docs.microsoft.com/java/openjdk/faq) |
|
| `microsoft` | [Microsoft Build of OpenJDK](https://www.microsoft.com/openjdk) | [License](https://docs.microsoft.com/java/openjdk/faq) |
|
||||||
| `oracle` | [Oracle JDK](https://www.oracle.com/java/technologies/downloads/) | [License](https://java.com/freeuselicense) |
|
| `oracle` | [Oracle JDK](https://www.oracle.com/java/technologies/downloads/) | [License](https://java.com/freeuselicense) |
|
||||||
| `oracle-openjdk` | [Oracle OpenJDK](https://jdk.java.net/) | [License](https://openjdk.org/legal/gplv2+ce.html) |
|
| `oracle-openjdk` | [Oracle OpenJDK](https://jdk.java.net/) | [License](https://openjdk.org/legal/gplv2+ce.html) |
|
||||||
|
| `redhat` | [Red Hat Build of OpenJDK](https://developers.redhat.com/products/openjdk/overview) | [License](https://openjdk.org/legal/gplv2+ce.html) |
|
||||||
| `sapmachine` | [SAP SapMachine JDK/JRE](https://sapmachine.io/) | [License](https://github.com/SAP/SapMachine/blob/sapmachine/LICENSE) |
|
| `sapmachine` | [SAP SapMachine JDK/JRE](https://sapmachine.io/) | [License](https://github.com/SAP/SapMachine/blob/sapmachine/LICENSE) |
|
||||||
| `semeru` | [IBM Semeru Runtime Open Edition](https://developer.ibm.com/languages/java/semeru-runtimes/downloads/) | [License](https://openjdk.java.net/legal/gplv2+ce.html) |
|
| `semeru` | [IBM Semeru Runtime Open Edition](https://developer.ibm.com/languages/java/semeru-runtimes/downloads/) | [License](https://openjdk.java.net/legal/gplv2+ce.html) |
|
||||||
| `temurin` | [Eclipse Temurin](https://adoptium.net/) | [License](https://adoptium.net/about.html) |
|
| `temurin` | [Eclipse Temurin](https://adoptium.net/) | [License](https://adoptium.net/about.html) |
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"result": [
|
||||||
|
{
|
||||||
|
"filename": "java-21-openjdk-21.0.8.0.9-1.portable.jdk.x86_64.tar.xz",
|
||||||
|
"direct_download_uri": "https://developers.redhat.com/content-gateway/file/pub/openjdk/java-21-openjdk-21.0.8.0.9-1.portable.jdk.x86_64.tar.xz",
|
||||||
|
"checksum": "91a6f3284cbded9de17f65985a4fca48dd4fd0aa295162178631c23ade335aad",
|
||||||
|
"checksum_type": "sha256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"message": ""
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
{
|
||||||
|
"result": [
|
||||||
|
{
|
||||||
|
"id": "redhat-21.0.8-jdk-linux-x64",
|
||||||
|
"archive_type": "tar.xz",
|
||||||
|
"distribution": "redhat",
|
||||||
|
"java_version": "21.0.8+9",
|
||||||
|
"release_status": "ga",
|
||||||
|
"operating_system": "linux",
|
||||||
|
"architecture": "x64",
|
||||||
|
"package_type": "jdk",
|
||||||
|
"directly_downloadable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "redhat-21.0.7-jdk-linux-x64",
|
||||||
|
"archive_type": "tar.xz",
|
||||||
|
"distribution": "redhat",
|
||||||
|
"java_version": "21.0.7+6",
|
||||||
|
"release_status": "ga",
|
||||||
|
"operating_system": "linux",
|
||||||
|
"architecture": "x64",
|
||||||
|
"package_type": "jdk",
|
||||||
|
"directly_downloadable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "redhat-17.0.16-jdk-linux-x64",
|
||||||
|
"archive_type": "tar.xz",
|
||||||
|
"distribution": "redhat",
|
||||||
|
"java_version": "17.0.16+8",
|
||||||
|
"release_status": "ga",
|
||||||
|
"operating_system": "linux",
|
||||||
|
"architecture": "x64",
|
||||||
|
"package_type": "jdk",
|
||||||
|
"directly_downloadable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "redhat-9-jdk-linux-x64",
|
||||||
|
"archive_type": "tar.xz",
|
||||||
|
"distribution": "redhat",
|
||||||
|
"java_version": "9+181",
|
||||||
|
"release_status": "ga",
|
||||||
|
"operating_system": "linux",
|
||||||
|
"architecture": "x64",
|
||||||
|
"package_type": "jdk",
|
||||||
|
"directly_downloadable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "redhat-21.0.8-jre-linux-x64",
|
||||||
|
"archive_type": "tar.xz",
|
||||||
|
"distribution": "redhat",
|
||||||
|
"java_version": "21.0.8+9",
|
||||||
|
"release_status": "ga",
|
||||||
|
"operating_system": "linux",
|
||||||
|
"architecture": "x64",
|
||||||
|
"package_type": "jre",
|
||||||
|
"directly_downloadable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "redhat-17.0.16-jdk-windows-x64",
|
||||||
|
"archive_type": "zip",
|
||||||
|
"distribution": "redhat",
|
||||||
|
"java_version": "17.0.16+8",
|
||||||
|
"release_status": "ga",
|
||||||
|
"operating_system": "windows",
|
||||||
|
"architecture": "x64",
|
||||||
|
"package_type": "jdk",
|
||||||
|
"directly_downloadable": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"message": "6 package(s) found"
|
||||||
|
}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
import {beforeEach, describe, expect, it, jest} from '@jest/globals';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
const mockReaddirSync = jest.fn();
|
||||||
|
const realFs = await import('fs');
|
||||||
|
jest.unstable_mockModule('fs', () => ({
|
||||||
|
...realFs,
|
||||||
|
default: {...realFs.default, readdirSync: mockReaddirSync},
|
||||||
|
readdirSync: mockReaddirSync
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.unstable_mockModule('@actions/core', () => ({
|
||||||
|
info: jest.fn(),
|
||||||
|
debug: jest.fn(),
|
||||||
|
isDebug: jest.fn(() => false),
|
||||||
|
startGroup: jest.fn(),
|
||||||
|
endGroup: jest.fn()
|
||||||
|
}));
|
||||||
|
|
||||||
|
const realUtil = await import('../../src/util.js');
|
||||||
|
const mockCacheJdkDir = jest.fn();
|
||||||
|
const mockExtractJdkFile = jest.fn();
|
||||||
|
const mockRenameWinArchive = jest.fn();
|
||||||
|
jest.unstable_mockModule('../../src/util.js', () => ({
|
||||||
|
...realUtil,
|
||||||
|
cacheJdkDir: mockCacheJdkDir,
|
||||||
|
extractJdkFile: mockExtractJdkFile,
|
||||||
|
renameWinArchive: mockRenameWinArchive
|
||||||
|
}));
|
||||||
|
|
||||||
|
const {RedHatDistribution} =
|
||||||
|
await import('../../src/distributions/redhat/installer.js');
|
||||||
|
|
||||||
|
const release = {
|
||||||
|
version: '21.0.8+9',
|
||||||
|
url: 'https://developers.redhat.com/openjdk-21.tar.xz',
|
||||||
|
checksum: {
|
||||||
|
algorithm: 'sha256' as const,
|
||||||
|
value: 'a'.repeat(64)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const createDistribution = () =>
|
||||||
|
new RedHatDistribution({
|
||||||
|
version: '21',
|
||||||
|
architecture: 'x64',
|
||||||
|
packageType: 'jdk',
|
||||||
|
checkLatest: false
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
mockReaddirSync.mockReturnValue(['jdk-21']);
|
||||||
|
mockExtractJdkFile.mockResolvedValue('/tmp/extracted');
|
||||||
|
mockCacheJdkDir.mockResolvedValue('/toolcache/Java_RedHat_jdk/21.0.8-9/x64');
|
||||||
|
mockRenameWinArchive.mockReturnValue('/tmp/download.zip');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Red Hat package installation', () => {
|
||||||
|
it('extracts and caches Linux tar.xz archives', async () => {
|
||||||
|
const distribution = createDistribution();
|
||||||
|
distribution['downloadAndVerify'] = jest
|
||||||
|
.fn()
|
||||||
|
.mockResolvedValue('/tmp/download');
|
||||||
|
distribution['getArchiveType'] = () => 'tar.xz';
|
||||||
|
|
||||||
|
const result = await distribution['downloadTool'](release);
|
||||||
|
|
||||||
|
expect(mockExtractJdkFile).toHaveBeenCalledWith('/tmp/download', 'tar.xz');
|
||||||
|
expect(mockRenameWinArchive).not.toHaveBeenCalled();
|
||||||
|
expect(mockCacheJdkDir).toHaveBeenCalledWith(
|
||||||
|
path.join('/tmp/extracted', 'jdk-21'),
|
||||||
|
'Java_RedHat_jdk',
|
||||||
|
'21.0.8-9',
|
||||||
|
'x64'
|
||||||
|
);
|
||||||
|
expect(result).toEqual({
|
||||||
|
version: '21.0.8+9',
|
||||||
|
path: '/toolcache/Java_RedHat_jdk/21.0.8-9/x64'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renames downloaded Windows ZIP archives before extraction', async () => {
|
||||||
|
const distribution = createDistribution();
|
||||||
|
distribution['downloadAndVerify'] = jest
|
||||||
|
.fn()
|
||||||
|
.mockResolvedValue('/tmp/download');
|
||||||
|
distribution['getArchiveType'] = () => 'zip';
|
||||||
|
|
||||||
|
await distribution['downloadTool'](release);
|
||||||
|
|
||||||
|
expect(mockRenameWinArchive).toHaveBeenCalledWith('/tmp/download');
|
||||||
|
expect(mockExtractJdkFile).toHaveBeenCalledWith('/tmp/download.zip', 'zip');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails when the extracted archive is empty', async () => {
|
||||||
|
mockReaddirSync.mockReturnValue([]);
|
||||||
|
const distribution = createDistribution();
|
||||||
|
distribution['downloadAndVerify'] = jest
|
||||||
|
.fn()
|
||||||
|
.mockResolvedValue('/tmp/download');
|
||||||
|
distribution['getArchiveType'] = () => 'tar.xz';
|
||||||
|
|
||||||
|
await expect(distribution['downloadTool'](release)).rejects.toThrow(
|
||||||
|
'The Red Hat archive for Java 21.0.8+9 was empty.'
|
||||||
|
);
|
||||||
|
expect(mockCacheJdkDir).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,181 @@
|
|||||||
|
import {afterEach, describe, expect, it, jest} from '@jest/globals';
|
||||||
|
import {HttpClient} from '@actions/http-client';
|
||||||
|
import packageDetails from '../data/redhat-package-details.json' with {type: 'json'};
|
||||||
|
import packages from '../data/redhat-packages.json' with {type: 'json'};
|
||||||
|
import {RedHatDistribution} from '../../src/distributions/redhat/installer.js';
|
||||||
|
|
||||||
|
const createDistribution = (
|
||||||
|
version: string,
|
||||||
|
packageType = 'jdk'
|
||||||
|
): RedHatDistribution => {
|
||||||
|
const distribution = new RedHatDistribution({
|
||||||
|
version,
|
||||||
|
architecture: 'x64',
|
||||||
|
packageType,
|
||||||
|
checkLatest: false
|
||||||
|
});
|
||||||
|
distribution['getOperatingSystem'] = () => 'linux';
|
||||||
|
distribution['getArchiveType'] = () => 'tar.xz';
|
||||||
|
return distribution;
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockDisco = (
|
||||||
|
packageResponse: unknown = packages,
|
||||||
|
detailsResponse: unknown = packageDetails
|
||||||
|
) =>
|
||||||
|
jest.spyOn(HttpClient.prototype, 'getJson').mockImplementation(async url => ({
|
||||||
|
result: url.includes('/packages?') ? packageResponse : detailsResponse,
|
||||||
|
statusCode: 200,
|
||||||
|
headers: {}
|
||||||
|
}));
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.restoreAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Red Hat package resolution', () => {
|
||||||
|
it('resolves the newest matching release and authoritative checksum', async () => {
|
||||||
|
const getJson = mockDisco();
|
||||||
|
const distribution = createDistribution('21');
|
||||||
|
|
||||||
|
const release = await distribution['findPackageForDownload']('21');
|
||||||
|
|
||||||
|
expect(release).toEqual({
|
||||||
|
version: '21.0.8+9',
|
||||||
|
url: packageDetails.result[0].direct_download_uri,
|
||||||
|
checksum: {
|
||||||
|
algorithm: 'sha256',
|
||||||
|
value: packageDetails.result[0].checksum,
|
||||||
|
source:
|
||||||
|
'https://api.foojay.io/disco/v3.0/ids/redhat-21.0.8-jdk-linux-x64'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(getJson).toHaveBeenNthCalledWith(
|
||||||
|
1,
|
||||||
|
expect.stringContaining(
|
||||||
|
'distro=redhat&release_status=ga&operating_system=linux&architecture=x64&package_type=jdk&archive_type=tar.xz&directly_downloadable=true'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
expect(getJson).toHaveBeenNthCalledWith(
|
||||||
|
2,
|
||||||
|
'https://api.foojay.io/disco/v3.0/ids/redhat-21.0.8-jdk-linux-x64'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('normalizes feature-only Disco versions before matching', async () => {
|
||||||
|
mockDisco(undefined, {
|
||||||
|
result: [
|
||||||
|
{
|
||||||
|
...packageDetails.result[0],
|
||||||
|
direct_download_uri: 'https://developers.redhat.com/openjdk-9.tar.xz'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
message: ''
|
||||||
|
});
|
||||||
|
const distribution = createDistribution('9');
|
||||||
|
|
||||||
|
const release = await distribution['findPackageForDownload']('9');
|
||||||
|
|
||||||
|
expect(release.version).toBe('9.0.0+181');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('selects the requested package type', async () => {
|
||||||
|
const getJson = mockDisco();
|
||||||
|
const distribution = createDistribution('21', 'jre');
|
||||||
|
|
||||||
|
await distribution['findPackageForDownload']('21');
|
||||||
|
|
||||||
|
expect(getJson).toHaveBeenNthCalledWith(
|
||||||
|
1,
|
||||||
|
expect.stringContaining('package_type=jre')
|
||||||
|
);
|
||||||
|
expect(getJson).toHaveBeenNthCalledWith(
|
||||||
|
2,
|
||||||
|
'https://api.foojay.io/disco/v3.0/ids/redhat-21.0.8-jre-linux-x64'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('maps Windows to ZIP packages', async () => {
|
||||||
|
const getJson = mockDisco();
|
||||||
|
const distribution = createDistribution('17');
|
||||||
|
distribution['getOperatingSystem'] = () => 'windows';
|
||||||
|
distribution['getArchiveType'] = () => 'zip';
|
||||||
|
|
||||||
|
await distribution['findPackageForDownload']('17');
|
||||||
|
|
||||||
|
expect(getJson).toHaveBeenNthCalledWith(
|
||||||
|
1,
|
||||||
|
expect.stringContaining(
|
||||||
|
'operating_system=windows&architecture=x64&package_type=jdk&archive_type=zip'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
expect(getJson).toHaveBeenNthCalledWith(
|
||||||
|
2,
|
||||||
|
'https://api.foojay.io/disco/v3.0/ids/redhat-17.0.16-jdk-windows-x64'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects Alpine before requesting glibc package metadata', async () => {
|
||||||
|
const getJson = mockDisco();
|
||||||
|
const distribution = new RedHatDistribution({
|
||||||
|
version: '21',
|
||||||
|
architecture: 'x64',
|
||||||
|
packageType: 'jdk',
|
||||||
|
checkLatest: false
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(() => distribution['getOperatingSystem'](true)).toThrow(
|
||||||
|
"Distribution 'redhat' does not support Alpine Linux because Red Hat portable archives require glibc."
|
||||||
|
);
|
||||||
|
expect(getJson).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects early-access versions before requesting metadata', async () => {
|
||||||
|
const getJson = mockDisco();
|
||||||
|
const distribution = createDistribution('21-ea');
|
||||||
|
|
||||||
|
await expect(distribution['findPackageForDownload']('21')).rejects.toThrow(
|
||||||
|
'Early access versions are not supported'
|
||||||
|
);
|
||||||
|
expect(getJson).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('reports available versions when no release matches', async () => {
|
||||||
|
mockDisco();
|
||||||
|
const distribution = createDistribution('25');
|
||||||
|
|
||||||
|
await expect(distribution['findPackageForDownload']('25')).rejects.toThrow(
|
||||||
|
"No matching version found for SemVer '25'.\nDistribution: RedHat"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails when the package detail has no direct Red Hat URL', async () => {
|
||||||
|
mockDisco(packages, {result: [], message: ''});
|
||||||
|
const distribution = createDistribution('21');
|
||||||
|
|
||||||
|
await expect(distribution['findPackageForDownload']('21')).rejects.toThrow(
|
||||||
|
'returned no direct Red Hat download URL'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails when the package detail has no SHA-256 checksum', async () => {
|
||||||
|
mockDisco(packages, {
|
||||||
|
result: [{...packageDetails.result[0], checksum: ''}],
|
||||||
|
message: ''
|
||||||
|
});
|
||||||
|
const distribution = createDistribution('21');
|
||||||
|
|
||||||
|
await expect(distribution['findPackageForDownload']('21')).rejects.toThrow(
|
||||||
|
'returned no SHA-256 checksum'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails with a targeted error when package metadata is missing', async () => {
|
||||||
|
mockDisco(null);
|
||||||
|
const distribution = createDistribution('21');
|
||||||
|
|
||||||
|
await expect(distribution['findPackageForDownload']('21')).rejects.toThrow(
|
||||||
|
'Could not fetch Red Hat package metadata from Foojay Disco'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -405,6 +405,18 @@ describe('extractJdkFile', () => {
|
|||||||
expect(io.which).not.toHaveBeenCalled();
|
expect(io.which).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('extracts xz-compressed tarballs with xz tar flags', async () => {
|
||||||
|
(tc.extractTar as jest.Mock).mockResolvedValue('/extracted' as never);
|
||||||
|
|
||||||
|
await expect(extractJdkFile('/tmp/jdk.tar.xz')).resolves.toBe('/extracted');
|
||||||
|
expect(tc.extractTar).toHaveBeenCalledWith(
|
||||||
|
'/tmp/jdk.tar.xz',
|
||||||
|
undefined,
|
||||||
|
'xJ'
|
||||||
|
);
|
||||||
|
expect(io.which).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
it('uses the bundled tar.exe for zip archives on Windows', async () => {
|
it('uses the bundled tar.exe for zip archives on Windows', async () => {
|
||||||
setPlatform('win32');
|
setPlatform('win32');
|
||||||
const systemRoot = path.join(workDir, 'Windows');
|
const systemRoot = path.join(workDir, 'Windows');
|
||||||
|
|||||||
Vendored
+5
-1
@@ -30905,7 +30905,9 @@ async function extractJdkFile(toolPath, extension) {
|
|||||||
if (!extension) {
|
if (!extension) {
|
||||||
extension = toolPath.endsWith('.tar.gz')
|
extension = toolPath.endsWith('.tar.gz')
|
||||||
? 'tar.gz'
|
? 'tar.gz'
|
||||||
: path.extname(toolPath);
|
: toolPath.endsWith('.tar.xz')
|
||||||
|
? 'tar.xz'
|
||||||
|
: path.extname(toolPath);
|
||||||
if (extension.startsWith('.')) {
|
if (extension.startsWith('.')) {
|
||||||
extension = extension.substring(1);
|
extension = extension.substring(1);
|
||||||
}
|
}
|
||||||
@@ -30913,6 +30915,8 @@ async function extractJdkFile(toolPath, extension) {
|
|||||||
switch (extension) {
|
switch (extension) {
|
||||||
case 'tar.gz':
|
case 'tar.gz':
|
||||||
return await extractTarGz(toolPath);
|
return await extractTarGz(toolPath);
|
||||||
|
case 'tar.xz':
|
||||||
|
return await tc.extractTar(toolPath, undefined, 'xJ');
|
||||||
case 'tar':
|
case 'tar':
|
||||||
return await tc.extractTar(toolPath);
|
return await tc.extractTar(toolPath);
|
||||||
case 'zip':
|
case 'zip':
|
||||||
|
|||||||
Vendored
+139
@@ -0,0 +1,139 @@
|
|||||||
|
export const id = 228;
|
||||||
|
export const ids = [228];
|
||||||
|
export const modules = {
|
||||||
|
|
||||||
|
/***/ 8228:
|
||||||
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||||
|
|
||||||
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||||
|
/* harmony export */ RedHatDistribution: () => (/* binding */ RedHatDistribution)
|
||||||
|
/* harmony export */ });
|
||||||
|
/* harmony import */ var _actions_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3838);
|
||||||
|
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9896);
|
||||||
|
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__);
|
||||||
|
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6928);
|
||||||
|
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__);
|
||||||
|
/* harmony import */ var semver__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2088);
|
||||||
|
/* harmony import */ var semver__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(semver__WEBPACK_IMPORTED_MODULE_3__);
|
||||||
|
/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4527);
|
||||||
|
/* harmony import */ var _base_installer_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(6242);
|
||||||
|
/* harmony import */ var _platform_types_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7444);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const DISCO_API_URL = 'https://api.foojay.io/disco/v3.0';
|
||||||
|
class RedHatDistribution extends _base_installer_js__WEBPACK_IMPORTED_MODULE_5__/* .JavaBase */ .O {
|
||||||
|
constructor(installerOptions) {
|
||||||
|
super('RedHat', installerOptions);
|
||||||
|
}
|
||||||
|
async findPackageForDownload(range) {
|
||||||
|
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.version !== null)
|
||||||
|
.sort((left, right) => -semver__WEBPACK_IMPORTED_MODULE_3___default().compareBuild(left.version, right.version));
|
||||||
|
const selectedPackage = normalizedPackages.find(item => (0,_util_js__WEBPACK_IMPORTED_MODULE_4__/* .isVersionSatisfies */ .y)(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(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
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async downloadTool(javaRelease) {
|
||||||
|
_actions_core__WEBPACK_IMPORTED_MODULE_0__/* .info */ .pq(`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`);
|
||||||
|
let javaArchivePath = await this.downloadAndVerify(javaRelease);
|
||||||
|
_actions_core__WEBPACK_IMPORTED_MODULE_0__/* .info */ .pq('Extracting Java archive...');
|
||||||
|
const archiveType = this.getArchiveType();
|
||||||
|
if (archiveType === 'zip') {
|
||||||
|
javaArchivePath = (0,_util_js__WEBPACK_IMPORTED_MODULE_4__/* .renameWinArchive */ .n2)(javaArchivePath);
|
||||||
|
}
|
||||||
|
const extractedJavaPath = await (0,_util_js__WEBPACK_IMPORTED_MODULE_4__/* .extractJdkFile */ .PE)(javaArchivePath, archiveType);
|
||||||
|
const archiveName = fs__WEBPACK_IMPORTED_MODULE_1___default().readdirSync(extractedJavaPath)[0];
|
||||||
|
if (!archiveName) {
|
||||||
|
throw new Error(`The Red Hat archive for Java ${javaRelease.version} was empty.`);
|
||||||
|
}
|
||||||
|
const archivePath = path__WEBPACK_IMPORTED_MODULE_2___default().join(extractedJavaPath, archiveName);
|
||||||
|
const javaPath = await (0,_util_js__WEBPACK_IMPORTED_MODULE_4__/* .cacheJdkDir */ .Vj)(archivePath, this.toolcacheFolderName, this.getToolcacheVersionName(javaRelease.version), this.architecture);
|
||||||
|
return { version: javaRelease.version, path: javaPath };
|
||||||
|
}
|
||||||
|
async getAvailablePackages() {
|
||||||
|
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(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);
|
||||||
|
}
|
||||||
|
getOperatingSystem(alpine = (0,_platform_types_js__WEBPACK_IMPORTED_MODULE_6__/* .isAlpineLinux */ .G6)()) {
|
||||||
|
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';
|
||||||
|
}
|
||||||
|
getArchiveType() {
|
||||||
|
return process.platform === 'win32' ? 'zip' : 'tar.xz';
|
||||||
|
}
|
||||||
|
normalizeDiscoVersion(version) {
|
||||||
|
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__WEBPACK_IMPORTED_MODULE_3___default().valid(normalizedVersion) ? normalizedVersion : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***/ })
|
||||||
|
|
||||||
|
};
|
||||||
Vendored
+25
-2
@@ -30915,6 +30915,7 @@ var JavaDistribution;
|
|||||||
JavaDistribution["JetBrains"] = "jetbrains";
|
JavaDistribution["JetBrains"] = "jetbrains";
|
||||||
JavaDistribution["Kona"] = "kona";
|
JavaDistribution["Kona"] = "kona";
|
||||||
JavaDistribution["OracleOpenJdk"] = "oracle-openjdk";
|
JavaDistribution["OracleOpenJdk"] = "oracle-openjdk";
|
||||||
|
JavaDistribution["RedHat"] = "redhat";
|
||||||
})(JavaDistribution || (JavaDistribution = {}));
|
})(JavaDistribution || (JavaDistribution = {}));
|
||||||
const JAVA_PACKAGE_CAPABILITIES = {
|
const JAVA_PACKAGE_CAPABILITIES = {
|
||||||
[JavaDistribution.Temurin]: ['jdk', 'jre', 'jdk+jmods'],
|
[JavaDistribution.Temurin]: ['jdk', 'jre', 'jdk+jmods'],
|
||||||
@@ -30946,7 +30947,8 @@ const JAVA_PACKAGE_CAPABILITIES = {
|
|||||||
'jre+ft'
|
'jre+ft'
|
||||||
],
|
],
|
||||||
[JavaDistribution.Kona]: ['jdk'],
|
[JavaDistribution.Kona]: ['jdk'],
|
||||||
[JavaDistribution.OracleOpenJdk]: ['jdk']
|
[JavaDistribution.OracleOpenJdk]: ['jdk'],
|
||||||
|
[JavaDistribution.RedHat]: ['jdk', 'jre']
|
||||||
};
|
};
|
||||||
function validateJavaPackage(distributionName, packageType, version) {
|
function validateJavaPackage(distributionName, packageType, version) {
|
||||||
if (!isJavaDistribution(distributionName)) {
|
if (!isJavaDistribution(distributionName)) {
|
||||||
@@ -31131,6 +31133,19 @@ const JAVA_PLATFORM_CAPABILITIES = {
|
|||||||
macos: X64_ARM64,
|
macos: X64_ARM64,
|
||||||
windows: ['x64']
|
windows: ['x64']
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
[_package_types_js__WEBPACK_IMPORTED_MODULE_2__/* .JavaDistribution */ .zS.RedHat]: {
|
||||||
|
platforms: {
|
||||||
|
linux: [
|
||||||
|
'x64',
|
||||||
|
{ architecture: 'aarch64', versionRange: '<12' },
|
||||||
|
{ architecture: 'ppc64le', versionRange: '<12' }
|
||||||
|
],
|
||||||
|
windows: [
|
||||||
|
{ architecture: 'x64', versionRange: '<22' },
|
||||||
|
{ architecture: 'x86', versionRange: '<11' }
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const ARCHITECTURE_ALIASES = {
|
const ARCHITECTURE_ALIASES = {
|
||||||
@@ -31346,7 +31361,9 @@ async function extractJdkFile(toolPath, extension) {
|
|||||||
if (!extension) {
|
if (!extension) {
|
||||||
extension = toolPath.endsWith('.tar.gz')
|
extension = toolPath.endsWith('.tar.gz')
|
||||||
? 'tar.gz'
|
? 'tar.gz'
|
||||||
: path__WEBPACK_IMPORTED_MODULE_1___default().extname(toolPath);
|
: toolPath.endsWith('.tar.xz')
|
||||||
|
? 'tar.xz'
|
||||||
|
: path__WEBPACK_IMPORTED_MODULE_1___default().extname(toolPath);
|
||||||
if (extension.startsWith('.')) {
|
if (extension.startsWith('.')) {
|
||||||
extension = extension.substring(1);
|
extension = extension.substring(1);
|
||||||
}
|
}
|
||||||
@@ -31354,6 +31371,8 @@ async function extractJdkFile(toolPath, extension) {
|
|||||||
switch (extension) {
|
switch (extension) {
|
||||||
case 'tar.gz':
|
case 'tar.gz':
|
||||||
return await extractTarGz(toolPath);
|
return await extractTarGz(toolPath);
|
||||||
|
case 'tar.xz':
|
||||||
|
return await _actions_tool_cache__WEBPACK_IMPORTED_MODULE_5__/* .extractTar */ .nN(toolPath, undefined, 'xJ');
|
||||||
case 'tar':
|
case 'tar':
|
||||||
return await _actions_tool_cache__WEBPACK_IMPORTED_MODULE_5__/* .extractTar */ .nN(toolPath);
|
return await _actions_tool_cache__WEBPACK_IMPORTED_MODULE_5__/* .extractTar */ .nN(toolPath);
|
||||||
case 'zip':
|
case 'zip':
|
||||||
@@ -36309,6 +36328,10 @@ async function getJavaDistribution(distributionName, installerOptions, jdkFile)
|
|||||||
const { OpenJdkDistribution } = await Promise.all(/* import() */[__nccwpck_require__.e(242), __nccwpck_require__.e(735)]).then(__nccwpck_require__.bind(__nccwpck_require__, 3735));
|
const { OpenJdkDistribution } = await Promise.all(/* import() */[__nccwpck_require__.e(242), __nccwpck_require__.e(735)]).then(__nccwpck_require__.bind(__nccwpck_require__, 3735));
|
||||||
return new OpenJdkDistribution(normalizedInstallerOptions);
|
return new OpenJdkDistribution(normalizedInstallerOptions);
|
||||||
}
|
}
|
||||||
|
case package_types/* JavaDistribution */.zS.RedHat: {
|
||||||
|
const { RedHatDistribution } = await Promise.all(/* import() */[__nccwpck_require__.e(242), __nccwpck_require__.e(228)]).then(__nccwpck_require__.bind(__nccwpck_require__, 8228));
|
||||||
|
return new RedHatDistribution(normalizedInstallerOptions);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,19 @@ steps:
|
|||||||
- run: java --version
|
- run: java --version
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Red Hat Build of OpenJDK
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v7
|
||||||
|
- uses: actions/setup-java@v6
|
||||||
|
with:
|
||||||
|
distribution: 'redhat'
|
||||||
|
java-version: '21'
|
||||||
|
java-package: jdk # optional (jdk or jre) - defaults to jdk
|
||||||
|
- run: java --version
|
||||||
|
```
|
||||||
|
|
||||||
### Liberica
|
### Liberica
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@@ -329,6 +342,7 @@ The package types have these meanings:
|
|||||||
| `corretto` | `jdk`, `jre` | Accepts major versions only. JDK availability follows Amazon's platform catalog. For the operating systems directly selected by `setup-java`, JRE downloads are limited to Java 8 on Windows; Linux and macOS use `jdk`. |
|
| `corretto` | `jdk`, `jre` | Accepts major versions only. JDK availability follows Amazon's platform catalog. For the operating systems directly selected by `setup-java`, JRE downloads are limited to Java 8 on Windows; Linux and macOS use `jdk`. |
|
||||||
| `oracle` | `jdk` | Stable Oracle JDK 17 and later only. |
|
| `oracle` | `jdk` | Stable Oracle JDK 17 and later only. |
|
||||||
| `oracle-openjdk` | `jdk` | Installs the GA or early-access JDK builds currently listed or archived on `jdk.java.net`; use a `-ea` version such as `27-ea` for early access. |
|
| `oracle-openjdk` | `jdk` | Installs the GA or early-access JDK builds currently listed or archived on `jdk.java.net`; use a `-ea` version such as `27-ea` for early access. |
|
||||||
|
| `redhat` | `jdk`, `jre` | Stable builds only. Version availability follows the Foojay Disco catalog for Red Hat Build of OpenJDK and can lag Red Hat's downloads page. |
|
||||||
| `dragonwell` | `jdk` | Stable builds only. The current vendor catalog provides Java 8, 11, 17, 21, and 25. |
|
| `dragonwell` | `jdk` | Stable builds only. The current vendor catalog provides Java 8, 11, 17, 21, and 25. |
|
||||||
| `sapmachine` | `jdk`, `jre` | Follows the SapMachine catalog. Both editions are represented from Java 10 onward, but individual versions and platforms can differ. |
|
| `sapmachine` | `jdk`, `jre` | Follows the SapMachine catalog. Both editions are represented from Java 10 onward, but individual versions and platforms can differ. |
|
||||||
| `graalvm` | `jdk` | Stable Oracle GraalVM for JDK 17 and later only. |
|
| `graalvm` | `jdk` | Stable Oracle GraalVM for JDK 17 and later only. |
|
||||||
@@ -644,6 +658,7 @@ absent from a vendor catalog.
|
|||||||
| `corretto` | `x64`, `x86`, `armv7`, `aarch64` | `x64`, `aarch64` | `x64`, `x86` | `x86` is limited to Java 11 or earlier; Linux `armv7` is available for Java 11. |
|
| `corretto` | `x64`, `x86`, `armv7`, `aarch64` | `x64`, `aarch64` | `x64`, `x86` | `x86` is limited to Java 11 or earlier; Linux `armv7` is available for Java 11. |
|
||||||
| `oracle` | `x64`, `aarch64` | `x64`, `aarch64` | `x64` | |
|
| `oracle` | `x64`, `aarch64` | `x64`, `aarch64` | `x64` | |
|
||||||
| `oracle-openjdk` | `x64`, `aarch64` | `x64`, `aarch64` | `x64` | |
|
| `oracle-openjdk` | `x64`, `aarch64` | `x64`, `aarch64` | `x64` | |
|
||||||
|
| `redhat` | `x64`, `aarch64`, `ppc64le` | — | `x64`, `x86` | Linux requires glibc; Alpine is unsupported. Linux `aarch64` and `ppc64le` are limited to Java 11 or earlier. Windows `x64` is limited to Java 21 or earlier and `x86` to Java 10 or earlier. |
|
||||||
| `dragonwell` | `x64`, `aarch64` | — | `x64` | |
|
| `dragonwell` | `x64`, `aarch64` | — | `x64` | |
|
||||||
| `sapmachine` | `x64`, `aarch64`, `ppc64le` | `x64`, `aarch64` | `x64`, `aarch64` | |
|
| `sapmachine` | `x64`, `aarch64`, `ppc64le` | `x64`, `aarch64` | `x64`, `aarch64` | |
|
||||||
| `graalvm`, `graalvm-community` | `x64`, `aarch64` | `x64`, `aarch64` | `x64` | |
|
| `graalvm`, `graalvm-community` | `x64`, `aarch64` | `x64`, `aarch64` | `x64` | |
|
||||||
|
|||||||
@@ -98,6 +98,10 @@ export async function getJavaDistribution(
|
|||||||
const {OpenJdkDistribution} = await import('./openjdk/installer.js');
|
const {OpenJdkDistribution} = await import('./openjdk/installer.js');
|
||||||
return new OpenJdkDistribution(normalizedInstallerOptions);
|
return new OpenJdkDistribution(normalizedInstallerOptions);
|
||||||
}
|
}
|
||||||
|
case JavaDistribution.RedHat: {
|
||||||
|
const {RedHatDistribution} = await import('./redhat/installer.js');
|
||||||
|
return new RedHatDistribution(normalizedInstallerOptions);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ export enum JavaDistribution {
|
|||||||
GraalVMCommunity = 'graalvm-community',
|
GraalVMCommunity = 'graalvm-community',
|
||||||
JetBrains = 'jetbrains',
|
JetBrains = 'jetbrains',
|
||||||
Kona = 'kona',
|
Kona = 'kona',
|
||||||
OracleOpenJdk = 'oracle-openjdk'
|
OracleOpenJdk = 'oracle-openjdk',
|
||||||
|
RedHat = 'redhat'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const JAVA_PACKAGE_CAPABILITIES = {
|
export const JAVA_PACKAGE_CAPABILITIES = {
|
||||||
@@ -50,7 +51,8 @@ export const JAVA_PACKAGE_CAPABILITIES = {
|
|||||||
'jre+ft'
|
'jre+ft'
|
||||||
],
|
],
|
||||||
[JavaDistribution.Kona]: ['jdk'],
|
[JavaDistribution.Kona]: ['jdk'],
|
||||||
[JavaDistribution.OracleOpenJdk]: ['jdk']
|
[JavaDistribution.OracleOpenJdk]: ['jdk'],
|
||||||
|
[JavaDistribution.RedHat]: ['jdk', 'jre']
|
||||||
} as const satisfies Record<JavaDistribution, readonly string[]>;
|
} as const satisfies Record<JavaDistribution, readonly string[]>;
|
||||||
|
|
||||||
export function validateJavaPackage(
|
export function validateJavaPackage(
|
||||||
|
|||||||
@@ -145,6 +145,19 @@ export const JAVA_PLATFORM_CAPABILITIES: Record<
|
|||||||
macos: X64_ARM64,
|
macos: X64_ARM64,
|
||||||
windows: ['x64']
|
windows: ['x64']
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
[JavaDistribution.RedHat]: {
|
||||||
|
platforms: {
|
||||||
|
linux: [
|
||||||
|
'x64',
|
||||||
|
{architecture: 'aarch64', versionRange: '<12'},
|
||||||
|
{architecture: 'ppc64le', versionRange: '<12'}
|
||||||
|
],
|
||||||
|
windows: [
|
||||||
|
{architecture: 'x64', versionRange: '<22'},
|
||||||
|
{architecture: 'x86', versionRange: '<11'}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
export interface IDiscoPackage {
|
||||||
|
id: string;
|
||||||
|
archive_type: string;
|
||||||
|
distribution: string;
|
||||||
|
java_version: string;
|
||||||
|
release_status: string;
|
||||||
|
operating_system: string;
|
||||||
|
architecture: string;
|
||||||
|
package_type: string;
|
||||||
|
directly_downloadable: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IDiscoPackageListResponse {
|
||||||
|
result: IDiscoPackage[];
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IDiscoPackageDetails {
|
||||||
|
filename: string;
|
||||||
|
direct_download_uri: string;
|
||||||
|
checksum: string;
|
||||||
|
checksum_type: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IDiscoPackageDetailsResponse {
|
||||||
|
result: IDiscoPackageDetails[];
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
+5
-1
@@ -59,7 +59,9 @@ export async function extractJdkFile(toolPath: string, extension?: string) {
|
|||||||
if (!extension) {
|
if (!extension) {
|
||||||
extension = toolPath.endsWith('.tar.gz')
|
extension = toolPath.endsWith('.tar.gz')
|
||||||
? 'tar.gz'
|
? 'tar.gz'
|
||||||
: path.extname(toolPath);
|
: toolPath.endsWith('.tar.xz')
|
||||||
|
? 'tar.xz'
|
||||||
|
: path.extname(toolPath);
|
||||||
if (extension.startsWith('.')) {
|
if (extension.startsWith('.')) {
|
||||||
extension = extension.substring(1);
|
extension = extension.substring(1);
|
||||||
}
|
}
|
||||||
@@ -68,6 +70,8 @@ export async function extractJdkFile(toolPath: string, extension?: string) {
|
|||||||
switch (extension) {
|
switch (extension) {
|
||||||
case 'tar.gz':
|
case 'tar.gz':
|
||||||
return await extractTarGz(toolPath);
|
return await extractTarGz(toolPath);
|
||||||
|
case 'tar.xz':
|
||||||
|
return await tc.extractTar(toolPath, undefined, 'xJ');
|
||||||
case 'tar':
|
case 'tar':
|
||||||
return await tc.extractTar(toolPath);
|
return await tc.extractTar(toolPath);
|
||||||
case 'zip':
|
case 'zip':
|
||||||
|
|||||||
Reference in New Issue
Block a user