2022-01-03 08:52:11 +01:00
import * as c from './constants'
2023-11-03 13:01:11 +01:00
import * as semver from 'semver'
2022-03-01 10:50:00 +01:00
import {
downloadAndExtractJDK ,
downloadExtractAndCacheJDK ,
2024-02-13 13:37:00 +01:00
getLatestPrerelease ,
2023-06-13 19:17:04 +02:00
getLatestRelease ,
2023-06-16 09:19:49 +02:00
getMatchingTags ,
2024-02-13 15:44:22 +01:00
getTaggedRelease ,
toSemVer
2022-03-01 10:50:00 +01:00
} from './utils'
2023-06-16 09:19:49 +02:00
import { downloadGraalVMEELegacy } from './gds'
2022-03-03 17:24:24 +01:00
import { downloadTool } from '@actions/tool-cache'
2023-06-16 09:19:49 +02:00
import { basename } from 'path'
2022-01-03 08:52:11 +01:00
2023-06-16 09:19:49 +02:00
const GRAALVM_DL_BASE = 'https://download.oracle.com/graalvm'
2023-01-24 10:35:51 +01:00
const GRAALVM_CE_DL_BASE = ` https://github.com/graalvm/ ${ c . GRAALVM_RELEASES_REPO } /releases/download `
2024-02-13 13:37:00 +01:00
const ORACLE_GRAALVM_REPO_EA_BUILDS = 'oracle-graalvm-dev-builds'
2022-01-03 13:11:04 +01:00
const GRAALVM_REPO_DEV_BUILDS = 'graalvm-ce-dev-builds'
2023-06-16 09:19:49 +02:00
const GRAALVM_JDK_TAG_PREFIX = 'jdk-'
2022-01-03 08:52:11 +01:00
const GRAALVM_TAG_PREFIX = 'vm-'
2023-06-16 09:19:49 +02:00
// Support for GraalVM for JDK 17 and later
export async function setUpGraalVMJDK (
javaVersionOrDev : string
2022-03-03 17:24:24 +01:00
) : Promise < string > {
2023-06-16 09:19:49 +02:00
if ( javaVersionOrDev === c . VERSION_DEV ) {
return setUpGraalVMJDKDevBuild ( )
2022-03-03 17:24:24 +01:00
}
2023-06-16 09:19:49 +02:00
const javaVersion = javaVersionOrDev
2024-02-13 17:16:15 +01:00
const toolName = determineToolName ( javaVersion , false )
let downloadName = toolName
2023-06-16 09:19:49 +02:00
let downloadUrl : string
if ( javaVersion . includes ( '.' ) ) {
2023-11-03 13:01:11 +01:00
if ( semver . valid ( javaVersion ) ) {
const majorJavaVersion = semver . major ( javaVersion )
const minorJavaVersion = semver . minor ( javaVersion )
const patchJavaVersion = semver . patch ( javaVersion )
const isGARelease = minorJavaVersion === 0 && patchJavaVersion === 0
if ( isGARelease ) {
// For GA versions of JDKs, /archive/ does not use minor and patch version (see https://www.oracle.com/java/technologies/jdk-script-friendly-urls/)
downloadName = determineToolName ( majorJavaVersion . toString ( ) , false )
}
downloadUrl = ` ${ GRAALVM_DL_BASE } / ${ majorJavaVersion } /archive/ ${ downloadName } ${ c . GRAALVM_FILE_EXTENSION } `
} else {
throw new Error (
` java-version set to ' ${ javaVersion } '. Please make sure the java-version is set correctly. ${ c . ERROR_HINT } `
)
}
2024-02-13 13:37:00 +01:00
} else if ( javaVersion === '22-ea' ) {
downloadUrl = await findLatestEABuildDownloadUrl ( javaVersion )
2023-06-16 09:19:49 +02:00
} else {
2024-02-13 17:16:15 +01:00
downloadUrl = ` ${ GRAALVM_DL_BASE } / ${ javaVersion } /latest/ ${ downloadName } ${ c . GRAALVM_FILE_EXTENSION } `
2023-06-16 09:19:49 +02:00
}
const downloader = async ( ) = > downloadGraalVMJDK ( downloadUrl , javaVersion )
return downloadExtractAndCacheJDK ( downloader , toolName , javaVersion )
2022-11-02 14:00:51 +01:00
}
2024-02-13 13:37:00 +01:00
async function findLatestEABuildDownloadUrl (
javaEaVersion : string
) : Promise < string > {
const latestPrerelease = await getLatestPrerelease (
ORACLE_GRAALVM_REPO_EA_BUILDS
)
const expectedFileNamePrefix = 'graalvm-jdk-'
const expectedFileNameSuffix = ` _ ${ c . JDK_PLATFORM } - ${ c . JDK_ARCH } _bin ${ c . GRAALVM_FILE_EXTENSION } `
for ( const asset of latestPrerelease . assets ) {
if (
asset . name . startsWith ( expectedFileNamePrefix ) &&
asset . name . endsWith ( expectedFileNameSuffix )
) {
return asset . browser_download_url
}
}
throw new Error (
` Could not find Oracle GraalVM build for ${ javaEaVersion } . ${ c . ERROR_HINT } `
)
}
2023-06-16 09:19:49 +02:00
export async function setUpGraalVMJDKCE (
javaVersionOrDev : string
) : Promise < string > {
if ( javaVersionOrDev === c . VERSION_DEV ) {
return setUpGraalVMJDKDevBuild ( )
2022-01-03 08:52:11 +01:00
}
2023-06-16 09:19:49 +02:00
let javaVersion = javaVersionOrDev
if ( ! javaVersion . includes ( '.' ) ) {
javaVersion = await findLatestGraalVMJDKCEJavaVersion ( javaVersion )
}
if ( javaVersion . split ( '.' ) . length != 3 ) {
throw new Error (
` java-version set to ' ${ javaVersionOrDev } ', which was resolved to ' ${ javaVersion } '. Please make sure the java-version is set correctly. ${ c . ERROR_HINT } `
)
}
const toolName = determineToolName ( javaVersion , true )
const downloadUrl = ` ${ GRAALVM_CE_DL_BASE } /jdk- ${ javaVersion } / ${ toolName } ${ c . GRAALVM_FILE_EXTENSION } `
const downloader = async ( ) = > downloadGraalVMJDK ( downloadUrl , javaVersion )
return downloadExtractAndCacheJDK ( downloader , toolName , javaVersion )
2022-01-03 08:52:11 +01:00
}
2023-06-16 09:19:49 +02:00
export async function findLatestGraalVMJDKCEJavaVersion (
majorJavaVersion : string
2022-01-03 08:52:11 +01:00
) : Promise < string > {
2023-06-16 09:19:49 +02:00
const matchingRefs = await getMatchingTags (
` ${ GRAALVM_JDK_TAG_PREFIX } ${ majorJavaVersion } `
)
const lowestNonExistingVersion = '0.0.1'
let highestVersion = lowestNonExistingVersion
const versionNumberStartIndex = ` refs/tags/ ${ GRAALVM_JDK_TAG_PREFIX } ` . length
for ( const matchingRef of matchingRefs ) {
const currentVersion = matchingRef . ref . substring ( versionNumberStartIndex )
2023-06-16 10:31:54 +02:00
if (
2023-11-03 13:01:11 +01:00
semver . valid ( currentVersion ) &&
semver . gt ( currentVersion , highestVersion )
2023-06-16 10:31:54 +02:00
) {
2023-06-16 09:19:49 +02:00
highestVersion = currentVersion
}
2022-03-03 17:24:24 +01:00
}
2023-06-16 09:19:49 +02:00
if ( highestVersion === lowestNonExistingVersion ) {
throw new Error (
` Unable to find the latest Java version for ' ${ majorJavaVersion } '. Please make sure the java-version is set correctly. ${ c . ERROR_HINT } `
)
2022-01-03 08:52:11 +01:00
}
2023-06-16 09:19:49 +02:00
return highestVersion
2022-01-03 08:52:11 +01:00
}
2023-06-16 09:19:49 +02:00
function determineToolName ( javaVersion : string , isCommunity : boolean ) {
2024-02-13 17:16:15 +01:00
return ` graalvm ${ isCommunity ? '-community' : '' } -jdk- ${ javaVersion } _ ${
2023-06-16 09:19:49 +02:00
c . JDK_PLATFORM
} - $ { c . JDK_ARCH } _bin `
}
async function downloadGraalVMJDK (
downloadUrl : string ,
2022-01-03 08:52:11 +01:00
javaVersion : string
) : Promise < string > {
2023-06-16 09:19:49 +02:00
try {
return await downloadTool ( downloadUrl )
} catch ( error ) {
if ( error instanceof Error && error . message . includes ( '404' ) ) {
// Not Found
throw new Error (
` Failed to download ${ basename (
downloadUrl
) } . Are you sure java - version : '${javaVersion}' is correct ? `
)
}
throw new Error (
` Failed to download ${ basename ( downloadUrl ) } (error: ${ error } ). `
)
2022-03-03 17:24:24 +01:00
}
2023-06-16 09:19:49 +02:00
}
// Support for GraalVM dev builds
export async function setUpGraalVMJDKDevBuild ( ) : Promise < string > {
const latestDevBuild = await getLatestRelease ( GRAALVM_REPO_DEV_BUILDS )
const resolvedJavaVersion = findHighestJavaVersion (
latestDevBuild ,
c . VERSION_DEV
)
const downloadUrl = findDownloadUrl ( latestDevBuild , resolvedJavaVersion )
return downloadAndExtractJDK ( downloadUrl )
2022-01-03 08:52:11 +01:00
}
2023-01-24 10:35:51 +01:00
export function findHighestJavaVersion (
release : c.LatestReleaseResponse [ 'data' ] ,
version : string
) : string {
2023-06-16 09:19:49 +02:00
const graalVMIdentifierPattern = determineGraalVMLegacyIdentifier (
2023-01-24 10:35:51 +01:00
false ,
version ,
'(\\d+)'
)
const expectedFileNameRegExp = new RegExp (
` ^ ${ graalVMIdentifierPattern } ${ c . GRAALVM_FILE_EXTENSION . replace (
/\./g ,
'\\.'
) } $ `
)
let highestJavaVersion = 0
for ( const asset of release . assets ) {
const matches = asset . name . match ( expectedFileNameRegExp )
if ( matches ) {
const javaVersion = + matches [ 1 ]
if ( javaVersion > highestJavaVersion ) {
highestJavaVersion = javaVersion
}
}
}
if ( highestJavaVersion > 0 ) {
return String ( highestJavaVersion )
} else {
throw new Error (
'Could not find highest Java version. Please file an issue at: https://github.com/graalvm/setup-graalvm/issues.'
)
}
}
2023-06-16 09:19:49 +02:00
// Support for GraalVM 22.X releases and earlier
2023-06-20 13:02:17 +02:00
export async function setUpGraalVMLatest_22_X (
2023-06-16 09:19:49 +02:00
gdsToken : string ,
javaVersion : string
) : Promise < string > {
2023-09-06 09:13:37 +02:00
const lockedVersion = javaVersion === '19' ? '22.3.1' : '22.3.3'
2023-06-16 09:19:49 +02:00
if ( gdsToken . length > 0 ) {
return setUpGraalVMRelease ( gdsToken , lockedVersion , javaVersion )
}
const latestRelease = await getTaggedRelease (
c . GRAALVM_RELEASES_REPO ,
GRAALVM_TAG_PREFIX + lockedVersion
)
const version = findGraalVMVersion ( latestRelease )
return setUpGraalVMRelease ( gdsToken , version , javaVersion )
}
export function findGraalVMVersion ( release : c.LatestReleaseResponse [ 'data' ] ) {
const tag_name = release . tag_name
if ( ! tag_name . startsWith ( GRAALVM_TAG_PREFIX ) ) {
throw new Error ( ` Could not find latest GraalVM release: ${ tag_name } ` )
}
return tag_name . substring ( GRAALVM_TAG_PREFIX . length , tag_name . length )
}
export async function setUpGraalVMRelease (
gdsToken : string ,
version : string ,
javaVersion : string
) : Promise < string > {
const isEE = gdsToken . length > 0
const toolName = determineLegacyToolName ( isEE , version , javaVersion )
let downloader : ( ) = > Promise < string >
if ( isEE ) {
downloader = async ( ) = >
downloadGraalVMEELegacy ( gdsToken , version , javaVersion )
} else {
downloader = async ( ) = > downloadGraalVMCELegacy ( version , javaVersion )
}
return downloadExtractAndCacheJDK ( downloader , toolName , version )
}
2023-01-24 10:35:51 +01:00
function findDownloadUrl (
release : c.LatestReleaseResponse [ 'data' ] ,
javaVersion : string
) : string {
2023-06-16 09:19:49 +02:00
const graalVMIdentifier = determineGraalVMLegacyIdentifier (
2023-01-24 10:35:51 +01:00
false ,
c . VERSION_DEV ,
javaVersion
)
const expectedFileName = ` ${ graalVMIdentifier } ${ c . GRAALVM_FILE_EXTENSION } `
for ( const asset of release . assets ) {
if ( asset . name === expectedFileName ) {
return asset . browser_download_url
}
}
throw new Error (
2023-06-16 09:19:49 +02:00
` Could not find GraalVM dev build for Java ${ javaVersion } . It may no longer be available, so please consider upgrading the Java version. ${ c . ERROR_HINT } `
2023-01-24 10:35:51 +01:00
)
}
2023-06-16 09:19:49 +02:00
function determineGraalVMLegacyIdentifier (
2022-03-03 17:24:24 +01:00
isEE : boolean ,
2022-01-03 08:52:11 +01:00
version : string ,
javaVersion : string
) : string {
2023-06-16 09:19:49 +02:00
return ` ${ determineLegacyToolName ( isEE , version , javaVersion ) } - ${
2023-04-10 12:48:07 +02:00
c . GRAALVM_ARCH
} - $ { version } `
2022-01-03 08:52:11 +01:00
}
2022-03-01 10:50:00 +01:00
2023-06-16 09:19:49 +02:00
function determineLegacyToolName (
2023-04-10 12:48:07 +02:00
isEE : boolean ,
version : string ,
javaVersion : string
) : string {
const infix = isEE ? 'ee' : version === c . VERSION_DEV ? 'community' : 'ce'
return ` graalvm- ${ infix } -java ${ javaVersion } - ${ c . GRAALVM_PLATFORM } `
2022-03-01 10:50:00 +01:00
}
2022-12-16 18:43:51 +01:00
2023-06-16 09:19:49 +02:00
async function downloadGraalVMCELegacy (
2022-12-16 18:43:51 +01:00
version : string ,
javaVersion : string
) : Promise < string > {
2023-06-16 09:19:49 +02:00
const graalVMIdentifier = determineGraalVMLegacyIdentifier (
2022-12-16 18:43:51 +01:00
false ,
version ,
javaVersion
)
const downloadUrl = ` ${ GRAALVM_CE_DL_BASE } / ${ GRAALVM_TAG_PREFIX } ${ version } / ${ graalVMIdentifier } ${ c . GRAALVM_FILE_EXTENSION } `
try {
return await downloadTool ( downloadUrl )
} catch ( error ) {
if ( error instanceof Error && error . message . includes ( '404' ) ) {
// Not Found
throw new Error (
2023-01-24 10:35:51 +01:00
` Failed to download ${ graalVMIdentifier } . Are you sure version: ' ${ version } ' and java-version: ' ${ javaVersion } ' are correct? `
2022-12-16 18:43:51 +01:00
)
}
throw new Error (
` Failed to download ${ graalVMIdentifier } (error: ${ error } ). `
)
}
}