mirror of
https://github.com/graalvm/setup-graalvm.git
synced 2025-02-23 12:20:10 +08:00
Add infrastructure for setting up GraalVM.
This commit is contained in:
parent
db50d45bd5
commit
a686e47055
19
src/constants.ts
Normal file
19
src/constants.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import * as otypes from '@octokit/types'
|
||||
import {homedir} from 'os'
|
||||
import {join} from 'path'
|
||||
|
||||
export const IS_MACOS = process.platform === 'darwin'
|
||||
export const IS_WINDOWS = process.platform === 'win32'
|
||||
|
||||
export const VERSION_LATEST = 'latest'
|
||||
export const VERSION_NIGHTLY = 'nightly'
|
||||
export const VERSION_TRUNK = 'trunk'
|
||||
|
||||
export const GRAALVM_BASE = join(homedir(), '.graalvm')
|
||||
export const GRAALVM_FILE_EXTENSION = IS_WINDOWS ? '.zip' : '.tar.gz'
|
||||
export const GRAALVM_GH_USER = 'graalvm'
|
||||
export const GRAALVM_PLATFORM = IS_WINDOWS ? 'windows' : process.platform
|
||||
export const JDK_HOME_SUFFIX = IS_MACOS ? '/Contents/Home' : ''
|
||||
|
||||
export type LatestReleaseResponse =
|
||||
otypes.Endpoints['GET /repos/{owner}/{repo}/releases/latest']['response']
|
103
src/graalvm-trunk.ts
Normal file
103
src/graalvm-trunk.ts
Normal file
@ -0,0 +1,103 @@
|
||||
import * as c from './constants'
|
||||
import * as core from '@actions/core'
|
||||
import * as tc from '@actions/tool-cache'
|
||||
import {SpawnSyncOptionsWithStringEncoding, spawnSync} from 'child_process'
|
||||
import {mkdirP, mv} from '@actions/io'
|
||||
import {findJavaHomeInSubfolder} from './utils'
|
||||
import {join} from 'path'
|
||||
|
||||
const GRAALVM_TRUNK_DL =
|
||||
'https://github.com/oracle/graal/archive/refs/heads/master.zip'
|
||||
const GRAALVM_MX_DL =
|
||||
'https://github.com/graalvm/mx/archive/refs/heads/master.zip'
|
||||
const DEFAULT_SUITES = '/compiler,/regex,/sdk,/tools,/truffle'
|
||||
const GRAAL_REPO_DIR = join(c.GRAALVM_BASE, 'graal')
|
||||
const VM_DIR = join(GRAAL_REPO_DIR, 'vm')
|
||||
const MX_DIR = join(c.GRAALVM_BASE, 'mx')
|
||||
const MX_EXEC = c.IS_WINDOWS ? 'mx.cmd' : 'mx'
|
||||
const SPAWN_OPTIONS: SpawnSyncOptionsWithStringEncoding = {
|
||||
cwd: VM_DIR,
|
||||
encoding: 'utf8',
|
||||
stdio: 'inherit'
|
||||
}
|
||||
|
||||
const COMPONENTS_TO_SUITE_NAME = new Map<string, string>([
|
||||
['espresso', '/espresso'],
|
||||
['js', '/graal-js'],
|
||||
['llvm-toolchain', '/sulong'],
|
||||
['native-image', '/substratevm'],
|
||||
['nodejs', '/graal-nodejs'],
|
||||
['python', 'graalpython'],
|
||||
['R', 'fastr'],
|
||||
['ruby', 'truffleruby'],
|
||||
['wasm', '/wasm']
|
||||
])
|
||||
|
||||
export async function setUpGraalVMTrunk(
|
||||
javaVersion: string,
|
||||
components: string[]
|
||||
): Promise<string> {
|
||||
const jdkId = `labsjdk-ce-${javaVersion}`
|
||||
|
||||
core.startGroup(`Downloading GraalVM sources, mx, and ${jdkId}...`)
|
||||
|
||||
await tc.extractZip(await tc.downloadTool(GRAALVM_TRUNK_DL), c.GRAALVM_BASE)
|
||||
await mv(join(c.GRAALVM_BASE, 'graal-master'), GRAAL_REPO_DIR)
|
||||
|
||||
await tc.extractZip(await tc.downloadTool(GRAALVM_MX_DL), c.GRAALVM_BASE)
|
||||
await mv(join(c.GRAALVM_BASE, 'mx-master'), MX_DIR)
|
||||
core.addPath(MX_DIR)
|
||||
core.debug(`"${MX_DIR}" added to $PATH`)
|
||||
|
||||
const labsJDKDir = join(c.GRAALVM_BASE, 'labsjdk')
|
||||
await mkdirP(labsJDKDir)
|
||||
spawnSync(
|
||||
MX_EXEC,
|
||||
['--java-home=', 'fetch-jdk', '--jdk-id', jdkId, '--to', labsJDKDir],
|
||||
SPAWN_OPTIONS
|
||||
)
|
||||
const labsJDKHome = findJavaHomeInSubfolder(labsJDKDir)
|
||||
core.exportVariable('JAVA_HOME', labsJDKHome)
|
||||
core.debug(`$JAVA_HOME set to "${labsJDKHome}"`)
|
||||
|
||||
core.endGroup()
|
||||
|
||||
const dynamicImports = toSuiteNames(components).join(',')
|
||||
const mxArgs = [
|
||||
'--no-download-progress', // avoid cluttering the build log
|
||||
'--disable-installables=true', // installables not needed
|
||||
'--force-bash-launchers=true', // disable native launchers
|
||||
'--exclude-components=LibGraal', // avoid building libgraal to save time
|
||||
'--dynamicimports',
|
||||
dynamicImports
|
||||
]
|
||||
if (core.isDebug()) {
|
||||
spawnSync(MX_EXEC, mxArgs.concat('graalvm-show'), SPAWN_OPTIONS)
|
||||
}
|
||||
const graalvmHome = spawnSync(MX_EXEC, mxArgs.concat(['graalvm-home']), {
|
||||
...SPAWN_OPTIONS,
|
||||
stdio: 'pipe'
|
||||
})
|
||||
core.startGroup('Building GraalVM CE from source...')
|
||||
spawnSync(MX_EXEC, mxArgs.concat(['build']), SPAWN_OPTIONS)
|
||||
core.endGroup()
|
||||
const graalvmHomePath = graalvmHome.stdout.trim()
|
||||
if (core.isDebug()) {
|
||||
const cmd = c.IS_WINDOWS ? 'dir' : 'ls'
|
||||
spawnSync(cmd, [graalvmHomePath], {stdio: 'inherit'})
|
||||
}
|
||||
return graalvmHomePath
|
||||
}
|
||||
|
||||
function toSuiteNames(components: string[]): string[] {
|
||||
const names = [DEFAULT_SUITES]
|
||||
for (const component of components) {
|
||||
const suiteName = COMPONENTS_TO_SUITE_NAME.get(component)
|
||||
if (suiteName) {
|
||||
names.push(suiteName)
|
||||
} else {
|
||||
throw new Error(`Unsupported component: ${component}`)
|
||||
}
|
||||
}
|
||||
return names
|
||||
}
|
51
src/graalvm.ts
Normal file
51
src/graalvm.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import * as c from './constants'
|
||||
import {downloadAndExtractJDK, getLatestRelease} from './utils'
|
||||
|
||||
const GRAALVM_CE_DL_BASE =
|
||||
'https://github.com/graalvm/graalvm-ce-builds/releases/download'
|
||||
const GRAALVM_REPO_NIGHTLY = 'graalvm-ce-dev-builds'
|
||||
const GRAALVM_REPO_RELEASES = 'graalvm-ce-builds'
|
||||
const GRAALVM_TAG_PREFIX = 'vm-'
|
||||
|
||||
export async function setUpGraalVMLatest(javaVersion: string): Promise<string> {
|
||||
const latestRelease = await getLatestRelease(GRAALVM_REPO_RELEASES)
|
||||
const tag_name = latestRelease.tag_name
|
||||
if (tag_name.startsWith(GRAALVM_TAG_PREFIX)) {
|
||||
const latestVersion = tag_name.substring(
|
||||
GRAALVM_TAG_PREFIX.length,
|
||||
tag_name.length
|
||||
)
|
||||
return setUpGraalVMRelease(latestVersion, javaVersion)
|
||||
}
|
||||
throw new Error(`Could not find latest GraalVM release: ${tag_name}`)
|
||||
}
|
||||
|
||||
export async function setUpGraalVMNightly(
|
||||
javaVersion: string
|
||||
): Promise<string> {
|
||||
const latestNightly = await getLatestRelease(GRAALVM_REPO_NIGHTLY)
|
||||
const graalVMIdentifier = determineGraalVMIdentifier('dev', javaVersion)
|
||||
const expectedFileName = `${graalVMIdentifier}${c.GRAALVM_FILE_EXTENSION}`
|
||||
for (const asset of latestNightly.assets) {
|
||||
if (asset.name === expectedFileName) {
|
||||
return downloadAndExtractJDK(asset.browser_download_url)
|
||||
}
|
||||
}
|
||||
throw new Error('Could not find GraalVM nightly build')
|
||||
}
|
||||
|
||||
export async function setUpGraalVMRelease(
|
||||
version: string,
|
||||
javaVersion: string
|
||||
): Promise<string> {
|
||||
const graalVMIdentifier = determineGraalVMIdentifier(version, javaVersion)
|
||||
const downloadUrl = `${GRAALVM_CE_DL_BASE}/${GRAALVM_TAG_PREFIX}${version}/${graalVMIdentifier}${c.GRAALVM_FILE_EXTENSION}`
|
||||
return downloadAndExtractJDK(downloadUrl)
|
||||
}
|
||||
|
||||
function determineGraalVMIdentifier(
|
||||
version: string,
|
||||
javaVersion: string
|
||||
): string {
|
||||
return `graalvm-ce-java${javaVersion}-${c.GRAALVM_PLATFORM}-amd64-${version}`
|
||||
}
|
39
src/main.ts
39
src/main.ts
@ -1,9 +1,48 @@
|
||||
import * as c from './constants'
|
||||
import * as core from '@actions/core'
|
||||
import * as graalvm from './graalvm'
|
||||
import {join} from 'path'
|
||||
import {mkdirP} from '@actions/io'
|
||||
import {setUpGraalVMTrunk} from './graalvm-trunk'
|
||||
|
||||
async function run(): Promise<void> {
|
||||
try {
|
||||
const graalvmVersion: string = core.getInput('version', {required: true})
|
||||
const javaVersion: string = core.getInput('java-version', {required: true})
|
||||
const componentsString: string = core.getInput('components')
|
||||
const components: string[] =
|
||||
componentsString.length > 0 ? componentsString.split(',') : []
|
||||
const setJavaHome = core.getInput('set-java-home') === 'true'
|
||||
|
||||
await mkdirP(c.GRAALVM_BASE)
|
||||
|
||||
// Download or build GraalVM
|
||||
let graalVMHome
|
||||
switch (graalvmVersion) {
|
||||
case c.VERSION_LATEST:
|
||||
graalVMHome = await graalvm.setUpGraalVMLatest(javaVersion)
|
||||
break
|
||||
case c.VERSION_NIGHTLY:
|
||||
graalVMHome = await graalvm.setUpGraalVMNightly(javaVersion)
|
||||
break
|
||||
case c.VERSION_TRUNK:
|
||||
graalVMHome = await setUpGraalVMTrunk(javaVersion, components)
|
||||
break
|
||||
default:
|
||||
graalVMHome = await graalvm.setUpGraalVMRelease(
|
||||
graalvmVersion,
|
||||
javaVersion
|
||||
)
|
||||
break
|
||||
}
|
||||
|
||||
// Activate GraalVM
|
||||
core.debug(`Activating GraalVM located at '${graalVMHome}'...`)
|
||||
core.exportVariable('GRAALVM_HOME', graalVMHome)
|
||||
core.addPath(join(graalVMHome, 'bin'))
|
||||
if (setJavaHome) {
|
||||
core.exportVariable('JAVA_HOME', graalVMHome)
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error) core.setFailed(error.message)
|
||||
}
|
||||
|
55
src/utils.ts
Normal file
55
src/utils.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import * as c from './constants'
|
||||
import * as core from '@actions/core'
|
||||
import * as httpClient from '@actions/http-client'
|
||||
import * as tc from '@actions/tool-cache'
|
||||
import {Octokit} from '@octokit/core'
|
||||
import {join} from 'path'
|
||||
import {readdirSync} from 'fs'
|
||||
|
||||
// Set up Octokit in the same way as @actions/github (see https://git.io/Jy9YP)
|
||||
const baseUrl = process.env['GITHUB_API_URL'] || 'https://api.github.com'
|
||||
const GitHub = Octokit.defaults({
|
||||
baseUrl,
|
||||
request: {
|
||||
agent: new httpClient.HttpClient().getAgent(baseUrl)
|
||||
}
|
||||
})
|
||||
|
||||
export async function getLatestRelease(
|
||||
repo: string
|
||||
): Promise<c.LatestReleaseResponse['data']> {
|
||||
const githubToken = core.getInput('github-token')
|
||||
const options = githubToken.length > 0 ? {auth: githubToken} : {}
|
||||
const octokit = new GitHub(options)
|
||||
return (
|
||||
await octokit.request('GET /repos/{owner}/{repo}/releases/latest', {
|
||||
owner: c.GRAALVM_GH_USER,
|
||||
repo
|
||||
})
|
||||
).data
|
||||
}
|
||||
|
||||
export async function downloadAndExtractJDK(
|
||||
downloadUrl: string
|
||||
): Promise<string> {
|
||||
const downloadPath = await tc.downloadTool(downloadUrl)
|
||||
if (downloadUrl.endsWith('.tar.gz')) {
|
||||
await tc.extractTar(downloadPath, c.GRAALVM_BASE)
|
||||
} else if (downloadUrl.endsWith('.zip')) {
|
||||
await tc.extractZip(downloadPath, c.GRAALVM_BASE)
|
||||
} else {
|
||||
throw new Error(`Unexpected filetype downloaded: ${downloadUrl}`)
|
||||
}
|
||||
return findJavaHomeInSubfolder(c.GRAALVM_BASE)
|
||||
}
|
||||
|
||||
export function findJavaHomeInSubfolder(searchPath: string): string {
|
||||
const baseContents = readdirSync(searchPath)
|
||||
if (baseContents.length === 1) {
|
||||
return join(searchPath, baseContents[0], c.JDK_HOME_SUFFIX)
|
||||
} else {
|
||||
throw new Error(
|
||||
`Unexpected amount of directory items found: ${baseContents.length}`
|
||||
)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user