Added Liberica distribution

This commit is contained in:
peterz 2024-02-20 17:14:10 +03:00 committed by Fabio Niephaus
parent 3d7ab58c1d
commit df4b80eebe
No known key found for this signature in database
GPG Key ID: F21CF5275F31DFD6
10 changed files with 302 additions and 5 deletions

View File

@ -243,6 +243,48 @@ jobs:
java --version
native-image --version
if: runner.os == 'Windows'
test-liberica:
needs: test
name: ${{ matrix.version }} + JDK${{ matrix.java-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
java-version: ['17', '21.0.2']
version: ['core', 'full', 'std', '']
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- name: Run setup-graalvm action
uses: ./
with:
distribution: liberica
java-version: ${{ matrix.java-version }}
version: ${{ matrix.version }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Check environment
run: |
echo "GRAALVM_HOME: $GRAALVM_HOME"
[[ "$GRAALVM_HOME" == *"$RUNNER_TOOL_CACHE"* ]] || exit 12
echo "JAVA_HOME: $JAVA_HOME"
java --version
java --version | fgrep -qw ${{ matrix.java-version }} || exit 23
native-image --version
native-image --version | fgrep -qw ${{ matrix.java-version }} || exit 24
if: runner.os != 'Windows'
- name: Check Windows environment
shell: pwsh
run: |
echo "GRAALVM_HOME: $env:GRAALVM_HOME"
echo "JAVA_HOME: $env:JAVA_HOME"
java --version
if (!(java --version | findstr \<${{ matrix.java-version }}\>)) {
exit 23
}
native-image --version
if (!(native-image --version | findstr \<${{ matrix.java-version }}\>)) {
exit 24
}
if: runner.os == 'Windows'
test-native-image-windows:
name: native-image on windows-latest
runs-on: windows-latest

View File

@ -7,7 +7,7 @@ import {
findHighestJavaVersion,
findLatestEABuildDownloadUrl
} from '../src/graalvm'
import {GRAALVM_RELEASES_REPO} from '../src/constants'
import {GRAALVM_GH_USER, GRAALVM_RELEASES_REPO} from '../src/constants'
process.env['RUNNER_TOOL_CACHE'] = path.join(__dirname, 'TOOL_CACHE')
process.env['RUNNER_TEMP'] = path.join(__dirname, 'TEMP')
@ -53,6 +53,7 @@ test('find version/javaVersion', async () => {
expect(error.message).toContain('Unable to find the latest Java version for')
const latestRelease = await getTaggedRelease(
GRAALVM_GH_USER,
GRAALVM_RELEASES_REPO,
'vm-22.3.1'
)

138
__tests__/liberica.test.ts Normal file
View File

@ -0,0 +1,138 @@
import * as liberica from '../src/liberica'
import * as path from 'path'
import * as semver from 'semver'
import {expect, test} from '@jest/globals'
process.env['RUNNER_TOOL_CACHE'] = path.join(__dirname, 'TOOL_CACHE')
process.env['RUNNER_TEMP'] = path.join(__dirname, 'TEMP')
test('find latest JDK version', async () => {
// Make sure the action can find the latest Java version for known major versions
await expectLatestToBe('11', atLeast('11.0.22+12'))
await expectLatestToBe('11.0.22', upToBuild('11.0.22+12'))
await expectLatestToBe('11.0.22+12', exactly('11.0.22+12'))
await expectLatestToBe('17', atLeast('17.0.10+13'))
await expectLatestToBe('17.0.10', upToBuild('17.0.10+13'))
await expectLatestToBe('17.0.10+13', exactly('17.0.10+13'))
await expectLatestToBe('21', atLeast('21.0.2+14'))
await expectLatestToBe('21.0.2', upToBuild('21.0.2+14'))
await expectLatestToBe('21.0.2+14', exactly('21.0.2+14'))
// Outdated major version
await expectLatestToFail('20')
// Outdated CPU versions
await expectLatestToFail('11.0.2') // should not resolve to 11.0.22
await expectLatestToFail('17.0.1') // should not resolve to 17.0.10
await expectLatestToFail('17.0.7+11')
await expectLatestToFail('21.0.0+8')
await expectLatestToFail('21.0.1')
// Incorrect build number
await expectLatestToFail('17.0.10+10')
}, 30000)
test('find asset URL', async () => {
await expectURL(
'17.0.10+13',
'core',
'bellsoft-liberica-vm-core-openjdk17.0.10'
)
await expectURL('17.0.10+13', 'std', 'bellsoft-liberica-vm-openjdk17.0.10')
await expectURL(
'21.0.2+14',
'full',
'bellsoft-liberica-vm-full-openjdk21.0.2'
)
await expectURL('21.0.2+14', '', 'bellsoft-liberica-vm-openjdk21.0.2')
}, 10000)
type verifier = (
version: string,
major: number,
minor: number,
patch: number
) => void
function atLeast(expectedMinVersion: string): verifier {
const expectedMajor = semver.major(expectedMinVersion)
return function (
version: string,
major: number,
minor: number,
patch: number
) {
expect(major).toBe(expectedMajor)
if (semver.compareBuild(version, expectedMinVersion) < 0) {
throw new Error(`Version ${version} is older than ${expectedMinVersion}`)
}
}
}
function upToBuild(expectedMinVersion: string): verifier {
const expectedMinor = semver.minor(expectedMinVersion)
const expectedPatch = semver.patch(expectedMinVersion)
const atLeastVerifier = atLeast(expectedMinVersion)
return function (
version: string,
major: number,
minor: number,
patch: number
) {
atLeastVerifier(version, major, minor, patch)
expect(minor).toBe(expectedMinor)
expect(patch).toBe(expectedPatch)
}
}
function exactly(expectedVersion: string): verifier {
return function (
version: string,
major: number,
minor: number,
patch: number
) {
if (semver.compareBuild(version, expectedVersion) != 0) {
throw new Error(`Expected version ${expectedVersion} but got ${version}`)
}
}
}
async function expectLatestToBe(pattern: string, verify: verifier) {
const result = await liberica.findLatestLibericaJavaVersion(pattern)
expect(semver.valid(result)).toBeDefined()
const major = semver.major(result)
const minor = semver.minor(result)
const patch = semver.patch(result)
verify(result, major, minor, patch)
}
async function expectLatestToFail(pattern: string) {
try {
const result = await liberica.findLatestLibericaJavaVersion(pattern)
throw new Error(
`findLatest(${pattern}) should have failed but returned ${result}`
)
} catch (err) {
if (!(err instanceof Error)) {
throw new Error(`Unexpected non-Error: ${err}`)
}
expect(err.message).toContain(
`Unable to find the latest version for JDK${pattern}`
)
}
}
async function expectURL(
javaVersion: string,
version: string,
expectedPrefix: string
) {
const url = await liberica.findLibericaURL(javaVersion, version)
expect(url).toBeDefined()
const parts = url.split('/')
const file = parts[parts.length - 1]
expect(file.startsWith(expectedPrefix)).toBe(true)
}

BIN
dist/cleanup/index.js generated vendored

Binary file not shown.

BIN
dist/main/index.js generated vendored

Binary file not shown.

View File

@ -20,6 +20,7 @@ export const EXECUTABLE_SUFFIX = IS_WINDOWS ? '.exe' : ''
export const DISTRIBUTION_GRAALVM = 'graalvm'
export const DISTRIBUTION_GRAALVM_COMMUNITY = 'graalvm-community'
export const DISTRIBUTION_MANDREL = 'mandrel'
export const DISTRIBUTION_LIBERICA = 'liberica'
export const VERSION_DEV = 'dev'
export const VERSION_LATEST = 'latest'

View File

@ -138,6 +138,8 @@ export async function findLatestGraalVMJDKCEJavaVersion(
majorJavaVersion: string
): Promise<string> {
const matchingRefs = await getMatchingTags(
c.GRAALVM_GH_USER,
c.GRAALVM_RELEASES_REPO,
`${GRAALVM_JDK_TAG_PREFIX}${majorJavaVersion}`
)
const lowestNonExistingVersion = '0.0.1'
@ -244,6 +246,7 @@ export async function setUpGraalVMLatest_22_X(
return setUpGraalVMRelease(gdsToken, lockedVersion, javaVersion)
}
const latestRelease = await getTaggedRelease(
c.GRAALVM_GH_USER,
c.GRAALVM_RELEASES_REPO,
GRAALVM_TAG_PREFIX + lockedVersion
)

105
src/liberica.ts Normal file
View File

@ -0,0 +1,105 @@
import * as c from './constants'
import * as semver from 'semver'
import {
downloadExtractAndCacheJDK,
getTaggedRelease,
getMatchingTags
} from './utils'
import {downloadTool} from '@actions/tool-cache'
const LIBERICA_GH_USER = 'bell-sw'
const LIBERICA_RELEASES_REPO = 'LibericaNIK'
const LIBERICA_JDK_TAG_PREFIX = 'jdk-'
const LIBERICA_VM_PREFIX = 'bellsoft-liberica-vm-'
export async function setUpLiberica(
javaVersion: string,
version: string
): Promise<string> {
const resolvedJavaVersion = await findLatestLibericaJavaVersion(javaVersion)
const downloadUrl = await findLibericaURL(resolvedJavaVersion, version)
const toolName = determineToolName(javaVersion, version)
return downloadExtractAndCacheJDK(
async () => downloadTool(downloadUrl),
toolName,
javaVersion
)
}
export async function findLatestLibericaJavaVersion(
javaVersion: string
): Promise<string> {
const matchingRefs = await getMatchingTags(
LIBERICA_GH_USER,
LIBERICA_RELEASES_REPO,
`${LIBERICA_JDK_TAG_PREFIX}${javaVersion}`
)
const noMatch = '0.0.1'
let bestMatch = noMatch
const prefixLength = `refs/tags/${LIBERICA_JDK_TAG_PREFIX}`.length
const patternLength = javaVersion.length
for (const matchingRef of matchingRefs) {
const version = matchingRef.ref.substring(prefixLength)
if (
semver.valid(version) &&
// pattern '17.0.1' should match '17.0.1+12' but not '17.0.10'
(version.length <= patternLength ||
!isDigit(version.charAt(patternLength))) &&
semver.compareBuild(version, bestMatch) == 1
) {
bestMatch = version
}
}
if (bestMatch === noMatch) {
throw new Error(
`Unable to find the latest version for JDK${javaVersion}. Please make sure the java-version is set correctly. ${c.ERROR_HINT}`
)
}
return bestMatch
}
export async function findLibericaURL(
javaVersion: string,
version: string
): Promise<string> {
const release = await getTaggedRelease(
LIBERICA_GH_USER,
LIBERICA_RELEASES_REPO,
LIBERICA_JDK_TAG_PREFIX + javaVersion
)
const platform = determinePlatformPart()
const assetPrefix = `${LIBERICA_VM_PREFIX}${determineToolVersionPart(
version
)}openjdk${javaVersion}`
const assetSuffix = `-${platform}${c.GRAALVM_FILE_EXTENSION}`
for (const asset of release.assets) {
if (
asset.name.startsWith(assetPrefix) &&
asset.name.endsWith(assetSuffix)
) {
return asset.browser_download_url
}
}
throw new Error(
`Unable to find asset for java-version: ${javaVersion}, version: ${version}, platform: ${platform}`
)
}
function determineToolVersionPart(version: string) {
return version === 'std' || version === '' ? '' : `${version}-`
}
function determineToolName(javaVersion: string, version: string) {
return `${LIBERICA_VM_PREFIX}${determineToolVersionPart(
version
)}openjdk${javaVersion}-${determinePlatformPart()}`
}
function determinePlatformPart() {
// for linux-musl, return `linux-${c.JDK_ARCH}-musl`
return `${c.JDK_PLATFORM}-${c.GRAALVM_ARCH}`
}
function isDigit(c: string) {
return c.charAt(0) >= '0' && c.charAt(0) <= '9'
}

View File

@ -8,6 +8,7 @@ import {restore} from './features/cache'
import {setUpDependencies} from './dependencies'
import {setUpGUComponents} from './gu'
import {setUpMandrel} from './mandrel'
import {setUpLiberica} from './liberica'
import {checkForUpdates} from './features/check-for-updates'
import {setUpNativeImageMusl} from './features/musl'
import {setUpWindowsEnvironment} from './msvc'
@ -65,6 +66,9 @@ async function run(): Promise<void> {
case c.DISTRIBUTION_MANDREL:
graalVMHome = await setUpMandrel(graalVMVersion, javaVersion)
break
case c.DISTRIBUTION_LIBERICA:
graalVMHome = await setUpLiberica(javaVersion, graalVMVersion)
break
case '':
if (javaVersion === c.VERSION_DEV) {
core.info(

View File

@ -65,6 +65,7 @@ export async function getContents(
}
export async function getTaggedRelease(
owner: string,
repo: string,
tag: string
): Promise<c.LatestReleaseResponse['data']> {
@ -73,7 +74,7 @@ export async function getTaggedRelease(
const octokit = new GitHubDotCom(options)
return (
await octokit.request('GET /repos/{owner}/{repo}/releases/tags/{tag}', {
owner: c.GRAALVM_GH_USER,
owner,
repo,
tag
})
@ -81,6 +82,8 @@ export async function getTaggedRelease(
}
export async function getMatchingTags(
owner: string,
repo: string,
tagPrefix: string
): Promise<c.MatchingRefsResponse['data']> {
const githubToken = getGitHubToken()
@ -90,8 +93,8 @@ export async function getMatchingTags(
await octokit.request(
'GET /repos/{owner}/{repo}/git/matching-refs/tags/{tagPrefix}',
{
owner: c.GRAALVM_GH_USER,
repo: c.GRAALVM_RELEASES_REPO,
owner,
repo,
tagPrefix
}
)