mirror of
https://github.com/actions/setup-java.git
synced 2026-07-05 12:00:58 +00:00
Compare commits
11 Commits
a2db51233a
...
d3e3b95d7c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3e3b95d7c | ||
|
|
40b9536ce5 | ||
|
|
0a40ce6f61 | ||
|
|
bcfbca5b71 | ||
|
|
78eae7945c | ||
|
|
2dfa2011c5 | ||
|
|
7467385c61 | ||
|
|
8bb7cab8d1 | ||
|
|
d299400510 | ||
|
|
a368241022 | ||
|
|
19a6381cef |
58
.github/workflows/e2e-versions.yml
vendored
58
.github/workflows/e2e-versions.yml
vendored
@ -30,7 +30,8 @@ jobs:
|
||||
'microsoft',
|
||||
'semeru',
|
||||
'corretto',
|
||||
'dragonwell'
|
||||
'dragonwell',
|
||||
'sapmachine'
|
||||
] # internally 'adopt-hotspot' is the same as 'adopt'
|
||||
version: ['21', '11', '17']
|
||||
exclude:
|
||||
@ -44,11 +45,22 @@ jobs:
|
||||
version: 17
|
||||
- distribution: oracle
|
||||
os: windows-latest
|
||||
version: 20
|
||||
version: 21
|
||||
- distribution: oracle
|
||||
os: ubuntu-latest
|
||||
version: 20
|
||||
|
||||
version: 21
|
||||
- distribution: graalvm
|
||||
os: macos-latest
|
||||
version: 17
|
||||
- distribution: graalvm
|
||||
os: windows-latest
|
||||
version: 21
|
||||
- distribution: graalvm
|
||||
os: ubuntu-latest
|
||||
version: 21
|
||||
- distribution: graalvm
|
||||
os: ubuntu-latest
|
||||
version: '24-ea'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
@ -78,13 +90,19 @@ jobs:
|
||||
include:
|
||||
- distribution: oracle
|
||||
os: ubuntu-latest
|
||||
version: '20.0.1'
|
||||
version: '21.0.4'
|
||||
- distribution: graalvm
|
||||
os: ubuntu-latest
|
||||
version: '21.0.4'
|
||||
- distribution: dragonwell
|
||||
os: ubuntu-latest
|
||||
version: '11.0'
|
||||
- distribution: dragonwell
|
||||
os: ubuntu-latest
|
||||
version: '11.0.13+9'
|
||||
- distribution: sapmachine
|
||||
os: ubuntu-latest
|
||||
version: '17.0.7'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
@ -106,7 +124,8 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
distribution: ['temurin', 'zulu', 'liberica', 'dragonwell']
|
||||
distribution:
|
||||
['temurin', 'zulu', 'liberica', 'dragonwell', 'sapmachine']
|
||||
exclude:
|
||||
- distribution: dragonwell
|
||||
os: macos-latest
|
||||
@ -132,7 +151,8 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
distribution: ['temurin', 'zulu', 'liberica', 'dragonwell']
|
||||
distribution:
|
||||
['temurin', 'zulu', 'liberica', 'dragonwell', 'sapmachine']
|
||||
exclude:
|
||||
- distribution: dragonwell
|
||||
os: macos-latest
|
||||
@ -208,6 +228,28 @@ jobs:
|
||||
run: bash __tests__/verify-java.sh "${{ matrix.version }}" "${{ steps.setup-java.outputs.path }}"
|
||||
shell: bash
|
||||
|
||||
setup-java-ea-versions-sapmachine:
|
||||
name: sapmachine ${{ matrix.version }} (jdk-x64) - ${{ matrix.os }}
|
||||
needs: setup-java-major-minor-versions
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
version: ['17-ea', '21-ea']
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: setup-java
|
||||
uses: ./
|
||||
id: setup-java
|
||||
with:
|
||||
java-version: ${{ matrix.version }}
|
||||
distribution: sapmachine
|
||||
- name: Verify Java
|
||||
run: bash __tests__/verify-java.sh "${{ matrix.version }}" "${{ steps.setup-java.outputs.path }}"
|
||||
shell: bash
|
||||
|
||||
setup-java-custom-package-type:
|
||||
name: ${{ matrix.distribution }} ${{ matrix.version }} (${{ matrix.java-package }}-x64) - ${{ matrix.os }}
|
||||
needs: setup-java-major-minor-versions
|
||||
@ -216,7 +258,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-13, windows-latest, ubuntu-latest]
|
||||
distribution: ['temurin', 'zulu', 'liberica', 'semeru']
|
||||
distribution: ['temurin', 'zulu', 'liberica', 'semeru', 'sapmachine']
|
||||
java-package: ['jre']
|
||||
version: ['17.0']
|
||||
include:
|
||||
|
||||
22
.github/workflows/publish-immutable-actions.yml
vendored
Normal file
22
.github/workflows/publish-immutable-actions.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
name: 'Publish Immutable Action Version'
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checking out
|
||||
uses: actions/checkout@v4
|
||||
- name: Publish
|
||||
id: publish
|
||||
uses: actions/publish-immutable-action@0.0.1
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
16
README.md
16
README.md
@ -46,7 +46,13 @@ This action allows you to work with Java and Scala projects.
|
||||
#### Maven options
|
||||
The action has a bunch of inputs to generate maven's [settings.xml](https://maven.apache.org/settings.html) on the fly and pass the values to Apache Maven GPG Plugin as well as Apache Maven Toolchains. See [advanced usage](docs/advanced-usage.md) for more.
|
||||
|
||||
- `overwrite-settings`: By default action overwrites the settings.xml. In order to skip generation of file if it exists, set this to `false`.
|
||||
- `overwrite-settings`: By default action overwrites the settings.xml and adds a toolchain entry to toolchains.xml. In order to skip generation of settings.xml and skip adding a toolchain entry to toolchains.xml if the according file exists, set this to `false`.
|
||||
|
||||
- `update-env-javahome`: By default action updates `env.JAVA_HOME` with the path of java installed. In order to skip update of JAVA_HOME, set this to `false`. The creation of the env variable JAVA_HOME_{{ MAJOR_VERSION }}_{{ ARCHITECTURE }} is NOT affected by this item. That will be created for any setup.
|
||||
|
||||
- `update-env-path`: By default action adds `<java_install_dir>/bin` to `env.PATH`. In order to skip this, set this to `false`.
|
||||
|
||||
- `update-toolchains-only`: If set to true, then `overwrite-settings`, `update-env-javahome` and `update-env-path` are propagated to `false` if the specific one is not explicitly configured to `true`. Only a toolchain entry will be added to toolchains.xml. Default is `false`.
|
||||
|
||||
- `server-id`: ID of the distributionManagement repository in the pom.xml file. Default is `github`.
|
||||
|
||||
@ -108,6 +114,8 @@ Currently, the following distributions are supported:
|
||||
| `semeru` | IBM Semeru Runtime Open Edition | [Link](https://developer.ibm.com/languages/java/semeru-runtimes/downloads/) | [Link](https://openjdk.java.net/legal/gplv2+ce.html) |
|
||||
| `oracle` | Oracle JDK | [Link](https://www.oracle.com/java/technologies/downloads/) | [Link](https://java.com/freeuselicense)
|
||||
| `dragonwell` | Alibaba Dragonwell JDK | [Link](https://dragonwell-jdk.io/) | [Link](https://www.aliyun.com/product/dragonwell/)
|
||||
| `sapmachine` | SAP SapMachine JDK/JRE | [Link](https://sapmachine.io/) | [Link](https://github.com/SAP/SapMachine/blob/sapmachine/LICENSE)
|
||||
| `graalvm` | Oracle GraalVM | [Link](https://www.graalvm.org/) | [Link](https://www.oracle.com/downloads/licenses/graal-free-license.html)
|
||||
|
||||
**NOTE:** The different distributors can provide discrepant list of available versions / supported configurations. Please refer to the official documentation to see the list of supported versions.
|
||||
|
||||
@ -230,7 +238,7 @@ jobs:
|
||||
|
||||
### Install multiple JDKs
|
||||
|
||||
All versions are added to the PATH. The last version will be used and available globally. Other Java versions can be accessed through env variables with such specification as 'JAVA_HOME_{{ MAJOR_VERSION }}_{{ ARCHITECTURE }}'.
|
||||
By default all versions are added to the PATH. The last version will be used and available globally. Other Java versions can be accessed through env variables with such specification as 'JAVA_HOME_{{ MAJOR_VERSION }}_{{ ARCHITECTURE }}'.
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
@ -243,6 +251,8 @@ All versions are added to the PATH. The last version will be used and available
|
||||
15
|
||||
```
|
||||
|
||||
**NOTE:** An alternative option is to use multiple setup-java steps. In this case the behavior can be controlled more granular by making use of the input items `overwrite-settings`, `update-env-javahome`, `update-env-path` and `update-toolchains-only`.
|
||||
|
||||
### Using Maven Toolchains
|
||||
In the example above multiple JDKs are installed for the same job. The result after the last JDK is installed is a Maven Toolchains declaration containing references to all three JDKs. The values for `id`, `version`, and `vendor` of the individual Toolchain entries are the given input values for `distribution` and `java-version` (`vendor` being the combination of `${distribution}_${java-version}`) by default.
|
||||
|
||||
@ -257,6 +267,8 @@ In the example above multiple JDKs are installed for the same job. The result af
|
||||
- [Amazon Corretto](docs/advanced-usage.md#Amazon-Corretto)
|
||||
- [Oracle](docs/advanced-usage.md#Oracle)
|
||||
- [Alibaba Dragonwell](docs/advanced-usage.md#Alibaba-Dragonwell)
|
||||
- [SapMachine](docs/advanced-usage.md#SapMachine)
|
||||
- [GraalVM](docs/advanced-usage.md#GraalVM)
|
||||
- [Installing custom Java package type](docs/advanced-usage.md#Installing-custom-Java-package-type)
|
||||
- [Installing custom Java architecture](docs/advanced-usage.md#Installing-custom-Java-architecture)
|
||||
- [Installing custom Java distribution from local file](docs/advanced-usage.md#Installing-Java-from-local-file)
|
||||
|
||||
87242
__tests__/data/sapmachine.json
Normal file
87242
__tests__/data/sapmachine.json
Normal file
File diff suppressed because it is too large
Load Diff
152
__tests__/distributors/graalvm-installer.test.ts
Normal file
152
__tests__/distributors/graalvm-installer.test.ts
Normal file
@ -0,0 +1,152 @@
|
||||
import {GraalVMDistribution} from '../../src/distributions/graalvm/installer';
|
||||
import os from 'os';
|
||||
import * as core from '@actions/core';
|
||||
import {getDownloadArchiveExtension} from '../../src/util';
|
||||
import {HttpClient} from '@actions/http-client';
|
||||
|
||||
describe('findPackageForDownload', () => {
|
||||
let distribution: GraalVMDistribution;
|
||||
let spyDebug: jest.SpyInstance;
|
||||
let spyHttpClient: jest.SpyInstance;
|
||||
|
||||
beforeEach(() => {
|
||||
distribution = new GraalVMDistribution({
|
||||
version: '',
|
||||
architecture: 'x64',
|
||||
packageType: 'jdk',
|
||||
checkLatest: false
|
||||
});
|
||||
|
||||
spyDebug = jest.spyOn(core, 'debug');
|
||||
spyDebug.mockImplementation(() => {});
|
||||
});
|
||||
|
||||
it.each([
|
||||
[
|
||||
'21',
|
||||
'21',
|
||||
'https://download.oracle.com/graalvm/21/latest/graalvm-jdk-21_{{OS_TYPE}}-x64_bin.{{ARCHIVE_TYPE}}'
|
||||
],
|
||||
[
|
||||
'21.0.4',
|
||||
'21.0.4',
|
||||
'https://download.oracle.com/graalvm/21/archive/graalvm-jdk-21.0.4_{{OS_TYPE}}-x64_bin.{{ARCHIVE_TYPE}}'
|
||||
],
|
||||
[
|
||||
'17',
|
||||
'17',
|
||||
'https://download.oracle.com/graalvm/17/latest/graalvm-jdk-17_{{OS_TYPE}}-x64_bin.{{ARCHIVE_TYPE}}'
|
||||
],
|
||||
[
|
||||
'17.0.12',
|
||||
'17.0.12',
|
||||
'https://download.oracle.com/graalvm/17/archive/graalvm-jdk-17.0.12_{{OS_TYPE}}-x64_bin.{{ARCHIVE_TYPE}}'
|
||||
]
|
||||
])('version is %s -> %s', async (input, expectedVersion, expectedUrl) => {
|
||||
/* Needed only for this particular test because /latest/ urls tend to change */
|
||||
spyHttpClient = jest.spyOn(HttpClient.prototype, 'head');
|
||||
spyHttpClient.mockReturnValue(
|
||||
Promise.resolve({
|
||||
message: {
|
||||
statusCode: 200
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
const result = await distribution['findPackageForDownload'](input);
|
||||
|
||||
jest.restoreAllMocks();
|
||||
|
||||
expect(result.version).toBe(expectedVersion);
|
||||
const osType = distribution.getPlatform();
|
||||
const archiveType = getDownloadArchiveExtension();
|
||||
const url = expectedUrl
|
||||
.replace('{{OS_TYPE}}', osType)
|
||||
.replace('{{ARCHIVE_TYPE}}', archiveType);
|
||||
expect(result.url).toBe(url);
|
||||
});
|
||||
|
||||
it.each([
|
||||
[
|
||||
'24-ea',
|
||||
/^https:\/\/github\.com\/graalvm\/oracle-graalvm-ea-builds\/releases\/download\/jdk-24\.0\.0-ea\./
|
||||
]
|
||||
])('version is %s -> %s', async (version, expectedUrlPrefix) => {
|
||||
/* Needed only for this particular test because /latest/ urls tend to change */
|
||||
spyHttpClient = jest.spyOn(HttpClient.prototype, 'head');
|
||||
spyHttpClient.mockReturnValue(
|
||||
Promise.resolve({
|
||||
message: {
|
||||
statusCode: 200
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
const eaDistro = new GraalVMDistribution({
|
||||
version,
|
||||
architecture: '', // to get default value
|
||||
packageType: 'jdk',
|
||||
checkLatest: false
|
||||
});
|
||||
|
||||
const versionWithoutEA = version.split('-')[0];
|
||||
const result = await eaDistro['findPackageForDownload'](versionWithoutEA);
|
||||
|
||||
jest.restoreAllMocks();
|
||||
|
||||
expect(result.url).toEqual(expect.stringMatching(expectedUrlPrefix));
|
||||
});
|
||||
|
||||
it.each([
|
||||
['amd64', 'x64'],
|
||||
['arm64', 'aarch64']
|
||||
])(
|
||||
'defaults to os.arch(): %s mapped to distro arch: %s',
|
||||
async (osArch: string, distroArch: string) => {
|
||||
jest.spyOn(os, 'arch').mockReturnValue(osArch);
|
||||
jest.spyOn(os, 'platform').mockReturnValue('linux');
|
||||
|
||||
const version = '21';
|
||||
const distro = new GraalVMDistribution({
|
||||
version,
|
||||
architecture: '', // to get default value
|
||||
packageType: 'jdk',
|
||||
checkLatest: false
|
||||
});
|
||||
|
||||
const osType = distribution.getPlatform();
|
||||
if (osType === 'windows' && distroArch == 'aarch64') {
|
||||
return; // skip, aarch64 is not available for Windows
|
||||
}
|
||||
const archiveType = getDownloadArchiveExtension();
|
||||
const result = await distro['findPackageForDownload'](version);
|
||||
const expectedUrl = `https://download.oracle.com/graalvm/21/latest/graalvm-jdk-21_${osType}-${distroArch}_bin.${archiveType}`;
|
||||
|
||||
expect(result.url).toBe(expectedUrl);
|
||||
}
|
||||
);
|
||||
|
||||
it('should throw an error', async () => {
|
||||
await expect(distribution['findPackageForDownload']('8')).rejects.toThrow(
|
||||
/GraalVM is only supported for JDK 17 and later/
|
||||
);
|
||||
await expect(distribution['findPackageForDownload']('11')).rejects.toThrow(
|
||||
/GraalVM is only supported for JDK 17 and later/
|
||||
);
|
||||
await expect(distribution['findPackageForDownload']('18')).rejects.toThrow(
|
||||
/Could not find GraalVM for SemVer */
|
||||
);
|
||||
|
||||
const unavailableEADistro = new GraalVMDistribution({
|
||||
version: '17-ea',
|
||||
architecture: '', // to get default value
|
||||
packageType: 'jdk',
|
||||
checkLatest: false
|
||||
});
|
||||
await expect(
|
||||
unavailableEADistro['findPackageForDownload']('17')
|
||||
).rejects.toThrow(
|
||||
/No GraalVM EA build found\. Are you sure java-version: '17-ea' is correct\?/
|
||||
);
|
||||
});
|
||||
});
|
||||
294
__tests__/distributors/sapmachine-installer.test.ts
Normal file
294
__tests__/distributors/sapmachine-installer.test.ts
Normal file
@ -0,0 +1,294 @@
|
||||
import {HttpClient} from '@actions/http-client';
|
||||
import {SapMachineDistribution} from '../../src/distributions/sapmachine/installer';
|
||||
import * as utils from '../../src/util';
|
||||
|
||||
import manifestData from '../data/sapmachine.json';
|
||||
|
||||
describe('getAvailableVersions', () => {
|
||||
let spyHttpClient: jest.SpyInstance;
|
||||
let spyUtilGetDownloadArchiveExtension: jest.SpyInstance;
|
||||
|
||||
beforeEach(() => {
|
||||
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
|
||||
spyHttpClient.mockReturnValue({
|
||||
statusCode: 200,
|
||||
headers: {},
|
||||
result: manifestData
|
||||
});
|
||||
|
||||
spyUtilGetDownloadArchiveExtension = jest.spyOn(
|
||||
utils,
|
||||
'getDownloadArchiveExtension'
|
||||
);
|
||||
spyUtilGetDownloadArchiveExtension.mockReturnValue('tar.gz');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
jest.clearAllMocks();
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
const mockPlatform = (
|
||||
distribution: SapMachineDistribution,
|
||||
platform: string
|
||||
) => {
|
||||
distribution['getPlatformOption'] = () => platform;
|
||||
const mockedExtension = platform == 'windows' ? 'zip' : 'tar.gz';
|
||||
spyUtilGetDownloadArchiveExtension.mockReturnValue(mockedExtension);
|
||||
};
|
||||
|
||||
describe('shouldFallbackToBackupUrl', () => {
|
||||
it('should return correct release when the primary URL is not available', async () => {
|
||||
spyHttpClient.mockReturnValueOnce({
|
||||
statusCode: 404,
|
||||
headers: {},
|
||||
result: ''
|
||||
});
|
||||
spyHttpClient.mockReturnValueOnce({
|
||||
statusCode: 200,
|
||||
headers: {},
|
||||
result: manifestData
|
||||
});
|
||||
|
||||
const version = '17';
|
||||
const distribution = new SapMachineDistribution({
|
||||
version: version,
|
||||
architecture: 'x64',
|
||||
packageType: 'jdk',
|
||||
checkLatest: false
|
||||
});
|
||||
|
||||
mockPlatform(distribution, 'linux');
|
||||
|
||||
const availableVersion = await distribution['findPackageForDownload'](
|
||||
version
|
||||
);
|
||||
expect(availableVersion).not.toBeNull();
|
||||
expect(availableVersion.url).toBe(
|
||||
'https://github.com/SAP/SapMachine/releases/download/sapmachine-17.0.10/sapmachine-jdk-17.0.10_linux-x64_bin.tar.gz'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAvailableVersions', () => {
|
||||
it.each([
|
||||
['11', 'x64', 'linux', 71],
|
||||
['11', 'aarch64', 'linux', 54],
|
||||
['17', 'riscv', 'linux', 0],
|
||||
['16.0.1', 'x64', 'linux', 71],
|
||||
['23-ea', 'x64', 'linux', 798],
|
||||
['23-ea', 'aarch64', 'windows', 0],
|
||||
['23-ea', 'x64', 'windows', 750]
|
||||
])(
|
||||
'should get right number of available versions from JSON',
|
||||
async (
|
||||
jdkVersion: string,
|
||||
arch: string,
|
||||
platform: string,
|
||||
len: number
|
||||
) => {
|
||||
const distribution = new SapMachineDistribution({
|
||||
version: jdkVersion,
|
||||
architecture: arch,
|
||||
packageType: 'jdk',
|
||||
checkLatest: false
|
||||
});
|
||||
mockPlatform(distribution, platform);
|
||||
|
||||
const availableVersions = await distribution['getAvailableVersions']();
|
||||
expect(availableVersions).not.toBeNull();
|
||||
expect(availableVersions.length).toBe(len);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
describe('findPackageForDownload', () => {
|
||||
it.each([
|
||||
[
|
||||
'11',
|
||||
'linux',
|
||||
'x64',
|
||||
'jdk',
|
||||
'https://github.com/SAP/SapMachine/releases/download/sapmachine-11.0.22/sapmachine-jdk-11.0.22_linux-x64_bin.tar.gz'
|
||||
],
|
||||
[
|
||||
'11',
|
||||
'linux',
|
||||
'aarch64',
|
||||
'jdk',
|
||||
'https://github.com/SAP/SapMachine/releases/download/sapmachine-11.0.22/sapmachine-jdk-11.0.22_linux-aarch64_bin.tar.gz'
|
||||
],
|
||||
[
|
||||
'11',
|
||||
'windows',
|
||||
'x64',
|
||||
'jdk',
|
||||
'https://github.com/SAP/SapMachine/releases/download/sapmachine-11.0.22/sapmachine-jdk-11.0.22_windows-x64_bin.zip'
|
||||
],
|
||||
[
|
||||
'11.0.17',
|
||||
'linux',
|
||||
'x64',
|
||||
'jdk',
|
||||
'https://github.com/SAP/SapMachine/releases/download/sapmachine-11.0.17/sapmachine-jdk-11.0.17_linux-x64_bin.tar.gz'
|
||||
],
|
||||
[
|
||||
'17',
|
||||
'linux',
|
||||
'x64',
|
||||
'jdk',
|
||||
'https://github.com/SAP/SapMachine/releases/download/sapmachine-17.0.10/sapmachine-jdk-17.0.10_linux-x64_bin.tar.gz'
|
||||
],
|
||||
[
|
||||
'17',
|
||||
'linux',
|
||||
'aarch64',
|
||||
'jdk',
|
||||
'https://github.com/SAP/SapMachine/releases/download/sapmachine-17.0.10/sapmachine-jdk-17.0.10_linux-aarch64_bin.tar.gz'
|
||||
],
|
||||
[
|
||||
'17',
|
||||
'windows',
|
||||
'x64',
|
||||
'jdk',
|
||||
'https://github.com/SAP/SapMachine/releases/download/sapmachine-17.0.10/sapmachine-jdk-17.0.10_windows-x64_bin.zip'
|
||||
],
|
||||
[
|
||||
'17.0.4',
|
||||
'linux',
|
||||
'x64',
|
||||
'jdk',
|
||||
'https://github.com/SAP/SapMachine/releases/download/sapmachine-17.0.4.1/sapmachine-jdk-17.0.4.1_linux-x64_bin.tar.gz'
|
||||
],
|
||||
[
|
||||
'17',
|
||||
'linux',
|
||||
'x64',
|
||||
'jre',
|
||||
'https://github.com/SAP/SapMachine/releases/download/sapmachine-17.0.10/sapmachine-jre-17.0.10_linux-x64_bin.tar.gz'
|
||||
],
|
||||
[
|
||||
'17',
|
||||
'linux',
|
||||
'aarch64',
|
||||
'jre',
|
||||
'https://github.com/SAP/SapMachine/releases/download/sapmachine-17.0.10/sapmachine-jre-17.0.10_linux-aarch64_bin.tar.gz'
|
||||
],
|
||||
[
|
||||
'17',
|
||||
'windows',
|
||||
'x64',
|
||||
'jre',
|
||||
'https://github.com/SAP/SapMachine/releases/download/sapmachine-17.0.10/sapmachine-jre-17.0.10_windows-x64_bin.zip'
|
||||
],
|
||||
[
|
||||
'17.0.4',
|
||||
'linux',
|
||||
'x64',
|
||||
'jre',
|
||||
'https://github.com/SAP/SapMachine/releases/download/sapmachine-17.0.4.1/sapmachine-jre-17.0.4.1_linux-x64_bin.tar.gz'
|
||||
],
|
||||
[
|
||||
'23-ea',
|
||||
'linux',
|
||||
'x64',
|
||||
'jdk',
|
||||
'https://github.com/SAP/SapMachine/releases/download/sapmachine-23%2B15/sapmachine-jdk-23-ea.15_linux-x64_bin.tar.gz',
|
||||
'23'
|
||||
],
|
||||
[
|
||||
'21.0.2+2-ea',
|
||||
'linux',
|
||||
'x64',
|
||||
'jdk',
|
||||
'https://github.com/SAP/SapMachine/releases/download/sapmachine-21.0.2%2B2/sapmachine-jdk-21.0.2-ea.2_linux-x64_bin.tar.gz',
|
||||
'21.0.2+2'
|
||||
],
|
||||
[
|
||||
'17',
|
||||
'linux-musl',
|
||||
'x64',
|
||||
'jdk',
|
||||
'https://github.com/SAP/SapMachine/releases/download/sapmachine-17.0.10/sapmachine-jdk-17.0.10_linux-x64-musl_bin.tar.gz'
|
||||
]
|
||||
])(
|
||||
'should return proper link according to the specified java-version, platform and arch',
|
||||
async (
|
||||
version: string,
|
||||
platform: string,
|
||||
arch: string,
|
||||
packageType: string,
|
||||
expectedLink: string,
|
||||
normalizedVersion: string = version
|
||||
) => {
|
||||
const distribution = new SapMachineDistribution({
|
||||
version: version,
|
||||
architecture: arch,
|
||||
packageType: packageType,
|
||||
checkLatest: false
|
||||
});
|
||||
mockPlatform(distribution, platform);
|
||||
|
||||
const availableVersion = await distribution['findPackageForDownload'](
|
||||
normalizedVersion
|
||||
);
|
||||
expect(availableVersion).not.toBeNull();
|
||||
expect(availableVersion.url).toBe(expectedLink);
|
||||
}
|
||||
);
|
||||
|
||||
it.each([
|
||||
['8', 'linux', 'x64'],
|
||||
['8', 'macos', 'aarch64'],
|
||||
['23', 'macos', 'aarch64'],
|
||||
['17', 'linux', 'riscv'],
|
||||
['23', 'linux', 'x64'],
|
||||
['25-ea', 'linux', 'x64', '25'],
|
||||
['8-ea', 'linux', 'x64', '8'],
|
||||
['21.0.3+7', 'linux', 'x64', '21.0.3+7'],
|
||||
['21.0.3+8-ea', 'linux', 'x64', '21.0.3+8'],
|
||||
['17', 'linux-muse', 'aarch64']
|
||||
])(
|
||||
'should throw when required version of JDK can not be found in the JSON',
|
||||
async (
|
||||
version: string,
|
||||
platform: string,
|
||||
arch: string,
|
||||
normalizedVersion: string = version
|
||||
) => {
|
||||
const distribution = new SapMachineDistribution({
|
||||
version: version,
|
||||
architecture: arch,
|
||||
packageType: 'jdk',
|
||||
checkLatest: false
|
||||
});
|
||||
mockPlatform(distribution, platform);
|
||||
|
||||
await expect(
|
||||
distribution['findPackageForDownload'](normalizedVersion)
|
||||
).rejects.toThrow(
|
||||
`Couldn't find any satisfied version for the specified java-version: "${normalizedVersion}" and architecture: "${arch}".`
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
it('should throw when required package type is not supported', async () => {
|
||||
const jdkVersion = '17';
|
||||
const arch = 'x64';
|
||||
const platform = 'linux';
|
||||
const distribution = new SapMachineDistribution({
|
||||
version: jdkVersion,
|
||||
architecture: arch,
|
||||
packageType: 'jdk+fx',
|
||||
checkLatest: false
|
||||
});
|
||||
mockPlatform(distribution, platform);
|
||||
await expect(
|
||||
distribution['findPackageForDownload'](jdkVersion)
|
||||
).rejects.toThrow(
|
||||
'SapMachine provides only the `jdk` and `jre` package type'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
16
action.yml
16
action.yml
@ -43,9 +43,21 @@ inputs:
|
||||
description: 'Path to where the settings.xml file will be written. Default is ~/.m2.'
|
||||
required: false
|
||||
overwrite-settings:
|
||||
description: 'Overwrite the settings.xml file if it exists. Default is "true".'
|
||||
description: 'Overwrite the settings.xml file if it exists. Default is "!update-toolchains-only". If explcitly set "true", it will update settings.xml regardless of "update-toolchains-only"'
|
||||
required: false
|
||||
default: true
|
||||
# DO NOT set a default here! The default will be propagated from input 'update-toolchains-only'!
|
||||
update-toolchains-only:
|
||||
description: 'Update toolchains.xml only. Default is "false". No update of settings.xml, no update of JAVA_HOME, no adding to PATH by default - unless "overwrite-settings", "update-env-javahome" or "add-to-env-path" are not explicitly set "true"'
|
||||
required: false
|
||||
default: false
|
||||
update-env-javahome:
|
||||
description: 'Update the JAVA_HOME environment variable. Default is "!update-toolchains-only"'
|
||||
required: false
|
||||
# DO NOT set a default here! The default will be propagated from input 'update-toolchains-only'!
|
||||
add-to-env-path:
|
||||
description: 'Add "<JDK home>/bin" to the PATH environment variable. Default is "!update-toolchains-only"'
|
||||
required: false
|
||||
# DO NOT set a default here! The default will be propagated from input 'update-toolchains-only'!
|
||||
gpg-private-key:
|
||||
description: 'GPG private key to import. Default is empty string.'
|
||||
required: false
|
||||
|
||||
7
dist/cleanup/index.js
vendored
7
dist/cleanup/index.js
vendored
@ -88116,7 +88116,7 @@ function computeCacheKey(packageManager, cacheDependencyPath) {
|
||||
if (!fileHash) {
|
||||
throw new Error(`No file in ${process.cwd()} matched to [${pattern}], make sure you have checked out the target repository`);
|
||||
}
|
||||
return `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${packageManager.id}-${fileHash}`;
|
||||
return `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${process.arch}-${packageManager.id}-${fileHash}`;
|
||||
});
|
||||
}
|
||||
/**
|
||||
@ -88311,7 +88311,7 @@ else {
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.DISTRIBUTIONS_ONLY_MAJOR_VERSION = exports.INPUT_MVN_TOOLCHAIN_VENDOR = exports.INPUT_MVN_TOOLCHAIN_ID = exports.MVN_TOOLCHAINS_FILE = exports.MVN_SETTINGS_FILE = exports.M2_DIR = exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = exports.INPUT_JOB_STATUS = exports.INPUT_CACHE_DEPENDENCY_PATH = exports.INPUT_CACHE = exports.INPUT_DEFAULT_GPG_PASSPHRASE = exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = exports.INPUT_GPG_PASSPHRASE = exports.INPUT_GPG_PRIVATE_KEY = exports.INPUT_OVERWRITE_SETTINGS = exports.INPUT_SETTINGS_PATH = exports.INPUT_SERVER_PASSWORD = exports.INPUT_SERVER_USERNAME = exports.INPUT_SERVER_ID = exports.INPUT_CHECK_LATEST = exports.INPUT_JDK_FILE = exports.INPUT_DISTRIBUTION = exports.INPUT_JAVA_PACKAGE = exports.INPUT_ARCHITECTURE = exports.INPUT_JAVA_VERSION_FILE = exports.INPUT_JAVA_VERSION = exports.MACOS_JAVA_CONTENT_POSTFIX = void 0;
|
||||
exports.DISTRIBUTIONS_ONLY_MAJOR_VERSION = exports.INPUT_MVN_TOOLCHAIN_VENDOR = exports.INPUT_MVN_TOOLCHAIN_ID = exports.MVN_TOOLCHAINS_FILE = exports.MVN_SETTINGS_FILE = exports.M2_DIR = exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = exports.INPUT_JOB_STATUS = exports.INPUT_CACHE_DEPENDENCY_PATH = exports.INPUT_CACHE = exports.INPUT_DEFAULT_GPG_PASSPHRASE = exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = exports.INPUT_GPG_PASSPHRASE = exports.INPUT_GPG_PRIVATE_KEY = exports.INPUT_ADD_TO_PATH = exports.INPUT_UPDATE_JAVA_HOME = exports.INPUT_UPDATE_TOOLCHAINS_ONLY = exports.INPUT_OVERWRITE_SETTINGS = exports.INPUT_SETTINGS_PATH = exports.INPUT_SERVER_PASSWORD = exports.INPUT_SERVER_USERNAME = exports.INPUT_SERVER_ID = exports.INPUT_CHECK_LATEST = exports.INPUT_JDK_FILE = exports.INPUT_DISTRIBUTION = exports.INPUT_JAVA_PACKAGE = exports.INPUT_ARCHITECTURE = exports.INPUT_JAVA_VERSION_FILE = exports.INPUT_JAVA_VERSION = exports.MACOS_JAVA_CONTENT_POSTFIX = void 0;
|
||||
exports.MACOS_JAVA_CONTENT_POSTFIX = 'Contents/Home';
|
||||
exports.INPUT_JAVA_VERSION = 'java-version';
|
||||
exports.INPUT_JAVA_VERSION_FILE = 'java-version-file';
|
||||
@ -88325,6 +88325,9 @@ exports.INPUT_SERVER_USERNAME = 'server-username';
|
||||
exports.INPUT_SERVER_PASSWORD = 'server-password';
|
||||
exports.INPUT_SETTINGS_PATH = 'settings-path';
|
||||
exports.INPUT_OVERWRITE_SETTINGS = 'overwrite-settings';
|
||||
exports.INPUT_UPDATE_TOOLCHAINS_ONLY = 'update-toolchains-only';
|
||||
exports.INPUT_UPDATE_JAVA_HOME = 'update-env-javahome';
|
||||
exports.INPUT_ADD_TO_PATH = 'add-to-env-path';
|
||||
exports.INPUT_GPG_PRIVATE_KEY = 'gpg-private-key';
|
||||
exports.INPUT_GPG_PASSPHRASE = 'gpg-passphrase';
|
||||
exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = undefined;
|
||||
|
||||
9048
dist/setup/index.js
vendored
9048
dist/setup/index.js
vendored
File diff suppressed because it is too large
Load Diff
@ -8,6 +8,8 @@
|
||||
- [Amazon Corretto](#Amazon-Corretto)
|
||||
- [Oracle](#Oracle)
|
||||
- [Alibaba Dragonwell](#Alibaba-Dragonwell)
|
||||
- [SapMachine](#SapMachine)
|
||||
- [GraalVM](#GraalVM)
|
||||
- [Installing custom Java package type](#Installing-custom-Java-package-type)
|
||||
- [Installing custom Java architecture](#Installing-custom-Java-architecture)
|
||||
- [Installing custom Java distribution from local file](#Installing-Java-from-local-file)
|
||||
@ -142,6 +144,33 @@ steps:
|
||||
- run: java -cp java HelloWorldApp
|
||||
```
|
||||
|
||||
### SapMachine
|
||||
**NOTE:** An OpenJDK release maintained and supported by SAP
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'sapmachine'
|
||||
java-version: '21'
|
||||
- run: java -cp java HelloWorldApp
|
||||
```
|
||||
|
||||
### GraalVM
|
||||
**NOTE:** Oracle GraalVM is only available for JDK 17 and later.
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'graalvm'
|
||||
java-version: '21'
|
||||
- run: |
|
||||
java -cp java HelloWorldApp
|
||||
native-image -cp java HelloWorldApp
|
||||
```
|
||||
|
||||
## Installing custom Java package type
|
||||
```yaml
|
||||
steps:
|
||||
|
||||
@ -10,17 +10,13 @@ import * as constants from './constants';
|
||||
import * as gpg from './gpg';
|
||||
import {getBooleanInput} from './util';
|
||||
|
||||
export async function configureAuthentication() {
|
||||
export async function configureAuthentication(overwriteSettings: boolean) {
|
||||
const id = core.getInput(constants.INPUT_SERVER_ID);
|
||||
const username = core.getInput(constants.INPUT_SERVER_USERNAME);
|
||||
const password = core.getInput(constants.INPUT_SERVER_PASSWORD);
|
||||
const settingsDirectory =
|
||||
core.getInput(constants.INPUT_SETTINGS_PATH) ||
|
||||
path.join(os.homedir(), constants.M2_DIR);
|
||||
const overwriteSettings = getBooleanInput(
|
||||
constants.INPUT_OVERWRITE_SETTINGS,
|
||||
true
|
||||
);
|
||||
const gpgPrivateKey =
|
||||
core.getInput(constants.INPUT_GPG_PRIVATE_KEY) ||
|
||||
constants.INPUT_DEFAULT_GPG_PRIVATE_KEY;
|
||||
|
||||
@ -98,7 +98,7 @@ async function computeCacheKey(
|
||||
`No file in ${process.cwd()} matched to [${pattern}], make sure you have checked out the target repository`
|
||||
);
|
||||
}
|
||||
return `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${packageManager.id}-${fileHash}`;
|
||||
return `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${process.arch}-${packageManager.id}-${fileHash}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -11,6 +11,9 @@ export const INPUT_SERVER_USERNAME = 'server-username';
|
||||
export const INPUT_SERVER_PASSWORD = 'server-password';
|
||||
export const INPUT_SETTINGS_PATH = 'settings-path';
|
||||
export const INPUT_OVERWRITE_SETTINGS = 'overwrite-settings';
|
||||
export const INPUT_UPDATE_TOOLCHAINS_ONLY = 'update-toolchains-only';
|
||||
export const INPUT_UPDATE_JAVA_HOME = 'update-env-javahome';
|
||||
export const INPUT_ADD_TO_PATH = 'add-to-env-path';
|
||||
export const INPUT_GPG_PRIVATE_KEY = 'gpg-private-key';
|
||||
export const INPUT_GPG_PASSPHRASE = 'gpg-passphrase';
|
||||
|
||||
|
||||
@ -10,7 +10,11 @@ import {
|
||||
JavaInstallerOptions,
|
||||
JavaInstallerResults
|
||||
} from './base-models';
|
||||
import {MACOS_JAVA_CONTENT_POSTFIX} from '../constants';
|
||||
import {
|
||||
MACOS_JAVA_CONTENT_POSTFIX,
|
||||
INPUT_UPDATE_JAVA_HOME,
|
||||
INPUT_ADD_TO_PATH
|
||||
} from '../constants';
|
||||
import os from 'os';
|
||||
|
||||
export abstract class JavaBase {
|
||||
@ -20,6 +24,8 @@ export abstract class JavaBase {
|
||||
protected packageType: string;
|
||||
protected stable: boolean;
|
||||
protected checkLatest: boolean;
|
||||
protected updateEnvJavaHome: boolean;
|
||||
protected addToEnvPath: boolean;
|
||||
|
||||
constructor(
|
||||
protected distribution: string,
|
||||
@ -36,6 +42,8 @@ export abstract class JavaBase {
|
||||
this.architecture = installerOptions.architecture || os.arch();
|
||||
this.packageType = installerOptions.packageType;
|
||||
this.checkLatest = installerOptions.checkLatest;
|
||||
this.updateEnvJavaHome = installerOptions.updateEnvJavaHome;
|
||||
this.addToEnvPath = installerOptions.addToEnvPath;
|
||||
}
|
||||
|
||||
protected abstract downloadTool(
|
||||
@ -163,8 +171,18 @@ export abstract class JavaBase {
|
||||
|
||||
protected setJavaDefault(version: string, toolPath: string) {
|
||||
const majorVersion = version.split('.')[0];
|
||||
if (this.updateEnvJavaHome) {
|
||||
core.exportVariable('JAVA_HOME', toolPath);
|
||||
} else {
|
||||
core.info(
|
||||
`Skip updating env.JAVA_HOME according to ${INPUT_UPDATE_JAVA_HOME}`
|
||||
);
|
||||
}
|
||||
if (this.addToEnvPath) {
|
||||
core.addPath(path.join(toolPath, 'bin'));
|
||||
} else {
|
||||
core.info(`Skip adding to env.PATH according to ${INPUT_ADD_TO_PATH}`);
|
||||
}
|
||||
core.setOutput('distribution', this.distribution);
|
||||
core.setOutput('path', toolPath);
|
||||
core.setOutput('version', version);
|
||||
|
||||
@ -3,6 +3,8 @@ export interface JavaInstallerOptions {
|
||||
architecture: string;
|
||||
packageType: string;
|
||||
checkLatest: boolean;
|
||||
updateEnvJavaHome: boolean;
|
||||
addToEnvPath: boolean;
|
||||
}
|
||||
|
||||
export interface JavaInstallerResults {
|
||||
|
||||
@ -10,6 +10,8 @@ import {SemeruDistribution} from './semeru/installer';
|
||||
import {CorrettoDistribution} from './corretto/installer';
|
||||
import {OracleDistribution} from './oracle/installer';
|
||||
import {DragonwellDistribution} from './dragonwell/installer';
|
||||
import {SapMachineDistribution} from './sapmachine/installer';
|
||||
import {GraalVMDistribution} from './graalvm/installer';
|
||||
|
||||
enum JavaDistribution {
|
||||
Adopt = 'adopt',
|
||||
@ -23,7 +25,9 @@ enum JavaDistribution {
|
||||
Semeru = 'semeru',
|
||||
Corretto = 'corretto',
|
||||
Oracle = 'oracle',
|
||||
Dragonwell = 'dragonwell'
|
||||
Dragonwell = 'dragonwell',
|
||||
SapMachine = 'sapmachine',
|
||||
GraalVM = 'graalvm'
|
||||
}
|
||||
|
||||
export function getJavaDistribution(
|
||||
@ -64,6 +68,10 @@ export function getJavaDistribution(
|
||||
return new OracleDistribution(installerOptions);
|
||||
case JavaDistribution.Dragonwell:
|
||||
return new DragonwellDistribution(installerOptions);
|
||||
case JavaDistribution.SapMachine:
|
||||
return new SapMachineDistribution(installerOptions);
|
||||
case JavaDistribution.GraalVM:
|
||||
return new GraalVMDistribution(installerOptions);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
173
src/distributions/graalvm/installer.ts
Normal file
173
src/distributions/graalvm/installer.ts
Normal file
@ -0,0 +1,173 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as tc from '@actions/tool-cache';
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
import {JavaBase} from '../base-installer';
|
||||
import {
|
||||
JavaDownloadRelease,
|
||||
JavaInstallerOptions,
|
||||
JavaInstallerResults
|
||||
} from '../base-models';
|
||||
import {
|
||||
extractJdkFile,
|
||||
getDownloadArchiveExtension,
|
||||
getGitHubHttpHeaders
|
||||
} from '../../util';
|
||||
import {HttpCodes} from '@actions/http-client';
|
||||
import {GraalVMEAVersion} from './models';
|
||||
|
||||
const GRAALVM_DL_BASE = 'https://download.oracle.com/graalvm';
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
const GRAALVM_PLATFORM = IS_WINDOWS ? 'windows' : process.platform;
|
||||
|
||||
export class GraalVMDistribution extends JavaBase {
|
||||
constructor(installerOptions: JavaInstallerOptions) {
|
||||
super('GraalVM', installerOptions);
|
||||
}
|
||||
|
||||
protected async downloadTool(
|
||||
javaRelease: JavaDownloadRelease
|
||||
): Promise<JavaInstallerResults> {
|
||||
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 version = this.getToolcacheVersionName(javaRelease.version);
|
||||
|
||||
const javaPath = await tc.cacheDir(
|
||||
archivePath,
|
||||
this.toolcacheFolderName,
|
||||
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) {
|
||||
return this.findEABuildDownloadUrl(`${range}-ea`);
|
||||
}
|
||||
|
||||
if (this.packageType !== 'jdk') {
|
||||
throw new Error('GraalVM provides only the `jdk` package type');
|
||||
}
|
||||
|
||||
const platform = this.getPlatform();
|
||||
const extension = getDownloadArchiveExtension();
|
||||
let major;
|
||||
let fileUrl;
|
||||
if (range.includes('.')) {
|
||||
major = range.split('.')[0];
|
||||
fileUrl = `${GRAALVM_DL_BASE}/${major}/archive/graalvm-jdk-${range}_${platform}-${arch}_bin.${extension}`;
|
||||
} else {
|
||||
major = range;
|
||||
fileUrl = `${GRAALVM_DL_BASE}/${range}/latest/graalvm-jdk-${range}_${platform}-${arch}_bin.${extension}`;
|
||||
}
|
||||
|
||||
if (parseInt(major) < 17) {
|
||||
throw new Error('GraalVM is only supported for JDK 17 and later');
|
||||
}
|
||||
|
||||
const response = await this.http.head(fileUrl);
|
||||
|
||||
if (response.message.statusCode === HttpCodes.NotFound) {
|
||||
throw new Error(`Could not find GraalVM for SemVer ${range}`);
|
||||
}
|
||||
|
||||
if (response.message.statusCode !== HttpCodes.OK) {
|
||||
throw new Error(
|
||||
`Http request for GraalVM failed with status code: ${response.message.statusCode}`
|
||||
);
|
||||
}
|
||||
|
||||
return {url: fileUrl, version: range};
|
||||
}
|
||||
|
||||
private async findEABuildDownloadUrl(
|
||||
javaEaVersion: string
|
||||
): Promise<JavaDownloadRelease> {
|
||||
const versions = await this.fetchEAJson(javaEaVersion);
|
||||
const latestVersion = versions.find(v => v.latest);
|
||||
if (!latestVersion) {
|
||||
throw new Error(`Unable to find latest version for '${javaEaVersion}'`);
|
||||
}
|
||||
const arch = this.distributionArchitecture();
|
||||
const file = latestVersion.files.find(
|
||||
f => f.arch === arch && f.platform === GRAALVM_PLATFORM
|
||||
);
|
||||
if (!file || !file.filename.startsWith('graalvm-jdk-')) {
|
||||
throw new Error(`Unable to find file metadata for '${javaEaVersion}'`);
|
||||
}
|
||||
return {
|
||||
url: `${latestVersion.download_base_url}${file.filename}`,
|
||||
version: latestVersion.version
|
||||
};
|
||||
}
|
||||
|
||||
private async fetchEAJson(
|
||||
javaEaVersion: string
|
||||
): Promise<GraalVMEAVersion[]> {
|
||||
const owner = 'graalvm';
|
||||
const repository = 'oracle-graalvm-ea-builds';
|
||||
const branch = 'main';
|
||||
const filePath = `versions/${javaEaVersion}.json`;
|
||||
|
||||
const url = `https://api.github.com/repos/${owner}/${repository}/contents/${filePath}?ref=${branch}`;
|
||||
|
||||
const headers = getGitHubHttpHeaders();
|
||||
|
||||
core.debug(
|
||||
`Trying to fetch available version info for GraalVM EA builds from '${url}'`
|
||||
);
|
||||
let fetchedJson;
|
||||
try {
|
||||
fetchedJson = (await this.http.getJson<GraalVMEAVersion[]>(url, headers))
|
||||
.result;
|
||||
} catch (err) {
|
||||
throw Error(
|
||||
`Fetching version info for GraalVM EA builds from '${url}' failed with the error: ${
|
||||
(err as Error).message
|
||||
}`
|
||||
);
|
||||
}
|
||||
if (fetchedJson === null) {
|
||||
throw Error(
|
||||
`No GraalVM EA build found. Are you sure java-version: '${javaEaVersion}' is correct?`
|
||||
);
|
||||
}
|
||||
return fetchedJson;
|
||||
}
|
||||
|
||||
public getPlatform(platform: NodeJS.Platform = process.platform): OsVersions {
|
||||
switch (platform) {
|
||||
case 'darwin':
|
||||
return 'macos';
|
||||
case 'win32':
|
||||
return 'windows';
|
||||
case 'linux':
|
||||
return 'linux';
|
||||
default:
|
||||
throw new Error(
|
||||
`Platform '${platform}' is not supported. Supported platforms: 'linux', 'macos', 'windows'`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/distributions/graalvm/models.ts
Normal file
14
src/distributions/graalvm/models.ts
Normal file
@ -0,0 +1,14 @@
|
||||
export type OsVersions = 'linux' | 'macos' | 'windows';
|
||||
|
||||
export interface GraalVMEAFile {
|
||||
filename: string;
|
||||
arch: 'aarch64' | 'x64';
|
||||
platform: 'darwin' | 'linux' | 'windows';
|
||||
}
|
||||
|
||||
export interface GraalVMEAVersion {
|
||||
version: string;
|
||||
latest?: boolean;
|
||||
download_base_url: string;
|
||||
files: GraalVMEAFile[];
|
||||
}
|
||||
268
src/distributions/sapmachine/installer.ts
Normal file
268
src/distributions/sapmachine/installer.ts
Normal file
@ -0,0 +1,268 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as tc from '@actions/tool-cache';
|
||||
import semver from 'semver';
|
||||
import fs from 'fs';
|
||||
import {OutgoingHttpHeaders} from 'http';
|
||||
import path from 'path';
|
||||
import {
|
||||
convertVersionToSemver,
|
||||
extractJdkFile,
|
||||
getDownloadArchiveExtension,
|
||||
getGitHubHttpHeaders,
|
||||
isVersionSatisfies
|
||||
} from '../../util';
|
||||
import {JavaBase} from '../base-installer';
|
||||
import {
|
||||
JavaDownloadRelease,
|
||||
JavaInstallerOptions,
|
||||
JavaInstallerResults
|
||||
} from '../base-models';
|
||||
import {ISapMachineAllVersions, ISapMachineVersions} from './models';
|
||||
|
||||
export class SapMachineDistribution extends JavaBase {
|
||||
constructor(installerOptions: JavaInstallerOptions) {
|
||||
super('SapMachine', installerOptions);
|
||||
}
|
||||
|
||||
protected async findPackageForDownload(
|
||||
version: string
|
||||
): Promise<JavaDownloadRelease> {
|
||||
core.debug(`Only stable versions: ${this.stable}`);
|
||||
|
||||
if (!['jdk', 'jre'].includes(this.packageType)) {
|
||||
throw new Error(
|
||||
'SapMachine provides only the `jdk` and `jre` package type'
|
||||
);
|
||||
}
|
||||
|
||||
const availableVersions = await this.getAvailableVersions();
|
||||
|
||||
const matchedVersions = availableVersions
|
||||
.filter(item => {
|
||||
return isVersionSatisfies(version, item.version);
|
||||
})
|
||||
.map(item => {
|
||||
return {
|
||||
version: item.version,
|
||||
url: item.downloadLink
|
||||
} as JavaDownloadRelease;
|
||||
});
|
||||
|
||||
if (!matchedVersions.length) {
|
||||
throw new Error(
|
||||
`Couldn't find any satisfied version for the specified java-version: "${version}" and architecture: "${this.architecture}".`
|
||||
);
|
||||
}
|
||||
|
||||
const resolvedVersion = matchedVersions[0];
|
||||
return resolvedVersion;
|
||||
}
|
||||
|
||||
private async getAvailableVersions(): Promise<ISapMachineVersions[]> {
|
||||
const platform = this.getPlatformOption();
|
||||
const arch = this.distributionArchitecture();
|
||||
|
||||
let fetchedReleasesJson = await this.fetchReleasesFromUrl(
|
||||
'https://sap.github.io/SapMachine/assets/data/sapmachine-releases-all.json'
|
||||
);
|
||||
|
||||
if (!fetchedReleasesJson) {
|
||||
fetchedReleasesJson = await this.fetchReleasesFromUrl(
|
||||
'https://api.github.com/repos/SAP/SapMachine/contents/assets/data/sapmachine-releases-all.json?ref=gh-pages',
|
||||
getGitHubHttpHeaders()
|
||||
);
|
||||
}
|
||||
|
||||
if (!fetchedReleasesJson) {
|
||||
throw new Error(
|
||||
`Couldn't fetch SapMachine versions information from both primary and backup urls`
|
||||
);
|
||||
}
|
||||
|
||||
core.debug(
|
||||
'Successfully fetched information about available SapMachine versions'
|
||||
);
|
||||
|
||||
const availableVersions = this.parseVersions(
|
||||
platform,
|
||||
arch,
|
||||
fetchedReleasesJson
|
||||
);
|
||||
|
||||
if (core.isDebug()) {
|
||||
core.startGroup('Print information about available versions');
|
||||
core.debug(availableVersions.map(item => item.version).join(', '));
|
||||
core.endGroup();
|
||||
}
|
||||
|
||||
return availableVersions;
|
||||
}
|
||||
|
||||
protected async downloadTool(
|
||||
javaRelease: JavaDownloadRelease
|
||||
): Promise<JavaInstallerResults> {
|
||||
core.info(
|
||||
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
|
||||
);
|
||||
const javaArchivePath = await tc.downloadTool(javaRelease.url);
|
||||
|
||||
core.info(`Extracting Java archive...`);
|
||||
|
||||
const extractedJavaPath = await extractJdkFile(
|
||||
javaArchivePath,
|
||||
getDownloadArchiveExtension()
|
||||
);
|
||||
|
||||
const archiveName = fs.readdirSync(extractedJavaPath)[0];
|
||||
const archivePath = path.join(extractedJavaPath, archiveName);
|
||||
const version = this.getToolcacheVersionName(javaRelease.version);
|
||||
|
||||
const javaPath = await tc.cacheDir(
|
||||
archivePath,
|
||||
this.toolcacheFolderName,
|
||||
version,
|
||||
this.architecture
|
||||
);
|
||||
|
||||
return {version: javaRelease.version, path: javaPath};
|
||||
}
|
||||
|
||||
private parseVersions(
|
||||
platform: string,
|
||||
arch: string,
|
||||
versions: ISapMachineAllVersions
|
||||
): ISapMachineVersions[] {
|
||||
const eligibleVersions: ISapMachineVersions[] = [];
|
||||
|
||||
for (const [, majorVersionMap] of Object.entries(versions)) {
|
||||
for (const [, jdkVersionMap] of Object.entries(majorVersionMap.updates)) {
|
||||
for (const [buildVersion, buildVersionMap] of Object.entries(
|
||||
jdkVersionMap
|
||||
)) {
|
||||
let buildVersionWithoutPrefix = buildVersion.replace(
|
||||
'sapmachine-',
|
||||
''
|
||||
);
|
||||
if (!buildVersionWithoutPrefix.includes('.')) {
|
||||
// replace major version with major.minor.patch and keep the remaining build identifier after the + as is with regex
|
||||
buildVersionWithoutPrefix = buildVersionWithoutPrefix.replace(
|
||||
/(\d+)(\+.*)?/,
|
||||
'$1.0.0$2'
|
||||
);
|
||||
}
|
||||
// replace + with . to convert to semver format if we have more than 3 version digits
|
||||
if (buildVersionWithoutPrefix.split('.').length > 3) {
|
||||
buildVersionWithoutPrefix = buildVersionWithoutPrefix.replace(
|
||||
'+',
|
||||
'.'
|
||||
);
|
||||
}
|
||||
buildVersionWithoutPrefix = convertVersionToSemver(
|
||||
buildVersionWithoutPrefix
|
||||
);
|
||||
|
||||
// ignore invalid version
|
||||
if (!semver.valid(buildVersionWithoutPrefix)) {
|
||||
core.debug(`Invalid version: ${buildVersionWithoutPrefix}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip earlyAccessVersions if stable version requested
|
||||
if (this.stable && buildVersionMap.ea === 'true') {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const [edition, editionAssets] of Object.entries(
|
||||
buildVersionMap.assets
|
||||
)) {
|
||||
if (this.packageType !== edition) {
|
||||
continue;
|
||||
}
|
||||
for (const [archAndPlatForm, archAssets] of Object.entries(
|
||||
editionAssets
|
||||
)) {
|
||||
let expectedArchAndPlatform = `${platform}-${arch}`;
|
||||
if (platform === 'linux-musl') {
|
||||
expectedArchAndPlatform = `linux-${arch}-musl`;
|
||||
}
|
||||
if (archAndPlatForm !== expectedArchAndPlatform) {
|
||||
continue;
|
||||
}
|
||||
for (const [contentType, contentTypeAssets] of Object.entries(
|
||||
archAssets
|
||||
)) {
|
||||
// skip if not tar.gz and zip files
|
||||
if (contentType !== 'tar.gz' && contentType !== 'zip') {
|
||||
continue;
|
||||
}
|
||||
eligibleVersions.push({
|
||||
os: platform,
|
||||
architecture: arch,
|
||||
version: buildVersionWithoutPrefix,
|
||||
checksum: contentTypeAssets.checksum,
|
||||
downloadLink: contentTypeAssets.url,
|
||||
packageType: edition
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const sortedVersions = this.sortParsedVersions(eligibleVersions);
|
||||
|
||||
return sortedVersions;
|
||||
}
|
||||
|
||||
// Sorts versions in descending order as by default data in JSON isn't sorted
|
||||
private sortParsedVersions(
|
||||
eligibleVersions: ISapMachineVersions[]
|
||||
): ISapMachineVersions[] {
|
||||
const sortedVersions = eligibleVersions.sort((versionObj1, versionObj2) => {
|
||||
const version1 = versionObj1.version;
|
||||
const version2 = versionObj2.version;
|
||||
return semver.compareBuild(version1, version2);
|
||||
});
|
||||
return sortedVersions.reverse();
|
||||
}
|
||||
|
||||
private getPlatformOption(): string {
|
||||
switch (process.platform) {
|
||||
case 'win32':
|
||||
return 'windows';
|
||||
case 'darwin':
|
||||
return 'macos';
|
||||
case 'linux':
|
||||
// figure out if alpine/musl
|
||||
if (fs.existsSync('/etc/alpine-release')) {
|
||||
return 'linux-musl';
|
||||
}
|
||||
return 'linux';
|
||||
default:
|
||||
return process.platform;
|
||||
}
|
||||
}
|
||||
|
||||
private async fetchReleasesFromUrl(
|
||||
url: string,
|
||||
headers: OutgoingHttpHeaders = {}
|
||||
): Promise<ISapMachineAllVersions | null> {
|
||||
try {
|
||||
core.debug(
|
||||
`Trying to fetch available SapMachine versions info from the primary url: ${url}`
|
||||
);
|
||||
const releases = (
|
||||
await this.http.getJson<ISapMachineAllVersions>(url, headers)
|
||||
).result;
|
||||
return releases;
|
||||
} catch (err) {
|
||||
core.debug(
|
||||
`Fetching SapMachine versions info from the link: ${url} ended up with the error: ${
|
||||
(err as Error).message
|
||||
}`
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
33
src/distributions/sapmachine/models.ts
Normal file
33
src/distributions/sapmachine/models.ts
Normal file
@ -0,0 +1,33 @@
|
||||
export interface ISapMachineAllVersions {
|
||||
[major: string]: {
|
||||
lts: string;
|
||||
updates: {
|
||||
[full_version: string]: {
|
||||
[sapmachineBuild: string]: {
|
||||
release_url: string;
|
||||
ea: string;
|
||||
assets: {
|
||||
[packageType: string]: {
|
||||
[arch: string]: {
|
||||
[content_type: string]: {
|
||||
name: string;
|
||||
checksum: string;
|
||||
url: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export interface ISapMachineVersions {
|
||||
os: string;
|
||||
architecture: string;
|
||||
version: string;
|
||||
checksum: string;
|
||||
downloadLink: string;
|
||||
packageType: string;
|
||||
}
|
||||
@ -13,6 +13,19 @@ import * as path from 'path';
|
||||
import {getJavaDistribution} from './distributions/distribution-factory';
|
||||
import {JavaInstallerOptions} from './distributions/base-models';
|
||||
|
||||
interface IInstallerInputsOptions {
|
||||
architecture: string;
|
||||
packageType: string;
|
||||
checkLatest: boolean;
|
||||
distributionName: string;
|
||||
jdkFile: string;
|
||||
toolchainIds: Array<string>;
|
||||
updateToolchainsOnly: boolean;
|
||||
overwriteSettings: boolean;
|
||||
updateEnvJavaHome: boolean;
|
||||
addToEnvPath: boolean;
|
||||
}
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
const versions = core.getMultilineInput(constants.INPUT_JAVA_VERSION);
|
||||
@ -28,6 +41,23 @@ async function run() {
|
||||
constants.INPUT_CACHE_DEPENDENCY_PATH
|
||||
);
|
||||
const checkLatest = getBooleanInput(constants.INPUT_CHECK_LATEST, false);
|
||||
const updateToolchainsOnly = getBooleanInput(
|
||||
constants.INPUT_UPDATE_TOOLCHAINS_ONLY,
|
||||
false
|
||||
);
|
||||
const overwriteSettings = getBooleanInput(
|
||||
constants.INPUT_OVERWRITE_SETTINGS,
|
||||
!updateToolchainsOnly
|
||||
);
|
||||
const updateEnvJavaHome = getBooleanInput(
|
||||
constants.INPUT_UPDATE_JAVA_HOME,
|
||||
!updateToolchainsOnly
|
||||
);
|
||||
const addToEnvPath = getBooleanInput(
|
||||
constants.INPUT_ADD_TO_PATH,
|
||||
!updateToolchainsOnly
|
||||
);
|
||||
|
||||
let toolchainIds = core.getMultilineInput(constants.INPUT_MVN_TOOLCHAIN_ID);
|
||||
|
||||
core.startGroup('Installed distributions');
|
||||
@ -40,13 +70,17 @@ async function run() {
|
||||
throw new Error('java-version or java-version-file input expected');
|
||||
}
|
||||
|
||||
const installerInputsOptions: installerInputsOptions = {
|
||||
const installerInputsOptions: IInstallerInputsOptions = {
|
||||
architecture,
|
||||
packageType,
|
||||
checkLatest,
|
||||
distributionName,
|
||||
jdkFile,
|
||||
toolchainIds
|
||||
toolchainIds,
|
||||
updateToolchainsOnly,
|
||||
overwriteSettings,
|
||||
updateEnvJavaHome,
|
||||
addToEnvPath
|
||||
};
|
||||
|
||||
if (!versions.length) {
|
||||
@ -78,7 +112,7 @@ async function run() {
|
||||
const matchersPath = path.join(__dirname, '..', '..', '.github');
|
||||
core.info(`##[add-matcher]${path.join(matchersPath, 'java.json')}`);
|
||||
|
||||
await auth.configureAuthentication();
|
||||
await auth.configureAuthentication(overwriteSettings);
|
||||
if (cache && isCacheFeatureAvailable()) {
|
||||
await restore(cache, cacheDependencyPath);
|
||||
}
|
||||
@ -91,7 +125,7 @@ run();
|
||||
|
||||
async function installVersion(
|
||||
version: string,
|
||||
options: installerInputsOptions,
|
||||
options: IInstallerInputsOptions,
|
||||
toolchainId = 0
|
||||
) {
|
||||
const {
|
||||
@ -100,14 +134,20 @@ async function installVersion(
|
||||
architecture,
|
||||
packageType,
|
||||
checkLatest,
|
||||
toolchainIds
|
||||
toolchainIds,
|
||||
updateToolchainsOnly,
|
||||
overwriteSettings,
|
||||
updateEnvJavaHome,
|
||||
addToEnvPath
|
||||
} = options;
|
||||
|
||||
const installerOptions: JavaInstallerOptions = {
|
||||
version,
|
||||
architecture,
|
||||
packageType,
|
||||
checkLatest,
|
||||
version
|
||||
updateEnvJavaHome,
|
||||
addToEnvPath
|
||||
};
|
||||
|
||||
const distribution = getJavaDistribution(
|
||||
@ -126,6 +166,7 @@ async function installVersion(
|
||||
version,
|
||||
distributionName,
|
||||
result.path,
|
||||
overwriteSettings || updateToolchainsOnly,
|
||||
toolchainIds[toolchainId]
|
||||
);
|
||||
|
||||
@ -136,12 +177,3 @@ async function installVersion(
|
||||
core.info(` Path: ${result.path}`);
|
||||
core.info('');
|
||||
}
|
||||
|
||||
interface installerInputsOptions {
|
||||
architecture: string;
|
||||
packageType: string;
|
||||
checkLatest: boolean;
|
||||
distributionName: string;
|
||||
jdkFile: string;
|
||||
toolchainIds: Array<string>;
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ export async function configureToolchains(
|
||||
version: string,
|
||||
distributionName: string,
|
||||
jdkHome: string,
|
||||
updateToolchains: boolean,
|
||||
toolchainId?: string
|
||||
) {
|
||||
const vendor =
|
||||
@ -27,10 +28,6 @@ export async function configureToolchains(
|
||||
const settingsDirectory =
|
||||
core.getInput(constants.INPUT_SETTINGS_PATH) ||
|
||||
path.join(os.homedir(), constants.M2_DIR);
|
||||
const overwriteSettings = getBooleanInput(
|
||||
constants.INPUT_OVERWRITE_SETTINGS,
|
||||
true
|
||||
);
|
||||
|
||||
await createToolchainsSettings({
|
||||
jdkInfo: {
|
||||
@ -40,21 +37,21 @@ export async function configureToolchains(
|
||||
jdkHome
|
||||
},
|
||||
settingsDirectory,
|
||||
overwriteSettings
|
||||
updateToolchains
|
||||
});
|
||||
}
|
||||
|
||||
export async function createToolchainsSettings({
|
||||
jdkInfo,
|
||||
settingsDirectory,
|
||||
overwriteSettings
|
||||
updateToolchains
|
||||
}: {
|
||||
jdkInfo: JdkInfo;
|
||||
settingsDirectory: string;
|
||||
overwriteSettings: boolean;
|
||||
updateToolchains: boolean;
|
||||
}) {
|
||||
core.info(
|
||||
`Creating ${constants.MVN_TOOLCHAINS_FILE} for JDK version ${jdkInfo.version} from ${jdkInfo.vendor}`
|
||||
`Adding a toolchain entry in ${constants.MVN_TOOLCHAINS_FILE} for JDK version ${jdkInfo.version} from ${jdkInfo.vendor}`
|
||||
);
|
||||
// when an alternate m2 location is specified use only that location (no .m2 directory)
|
||||
// otherwise use the home/.m2/ path
|
||||
@ -72,7 +69,7 @@ export async function createToolchainsSettings({
|
||||
await writeToolchainsFileToDisk(
|
||||
settingsDirectory,
|
||||
updatedToolchains,
|
||||
overwriteSettings
|
||||
updateToolchains
|
||||
);
|
||||
}
|
||||
|
||||
@ -147,17 +144,17 @@ async function readExistingToolchainsFile(directory: string) {
|
||||
async function writeToolchainsFileToDisk(
|
||||
directory: string,
|
||||
settings: string,
|
||||
overwriteSettings: boolean
|
||||
updateToolchains: boolean
|
||||
) {
|
||||
const location = path.join(directory, constants.MVN_TOOLCHAINS_FILE);
|
||||
const settingsExists = fs.existsSync(location);
|
||||
if (settingsExists && overwriteSettings) {
|
||||
core.info(`Overwriting existing file ${location}`);
|
||||
} else if (!settingsExists) {
|
||||
core.info(`Writing to ${location}`);
|
||||
const toolchainsExists = fs.existsSync(location);
|
||||
if (toolchainsExists && updateToolchains) {
|
||||
core.info(`Updating existing file ${location}`);
|
||||
} else if (!toolchainsExists) {
|
||||
core.info(`Creating file ${location}`);
|
||||
} else {
|
||||
core.info(
|
||||
`Skipping generation of ${location} because file already exists and overwriting is not enabled`
|
||||
`Skipping update of ${location} since file already exists and updating is not enabled`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user