Add support for GraalVM Enterprise Edition.

Fixes #5.
This commit is contained in:
Fabio Niephaus 2022-03-03 17:24:24 +01:00 committed by Fabio Niephaus
parent 1a4a7ccb68
commit 2240cb3432
13 changed files with 415 additions and 41 deletions

View File

@ -18,8 +18,8 @@ jobs:
npm install
- run: |
npm run all
test: # make sure the action works on a clean machine without building
name: ${{ matrix.version }} + JDK${{ matrix.java-version }} on ${{ matrix.os }}
test-ce: # make sure the action works on a clean machine without building
name: CE ${{ matrix.version }} + JDK${{ matrix.java-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
@ -62,6 +62,7 @@ jobs:
echo "GRAALVM_HOME: $GRAALVM_HOME"
echo "JAVA_HOME: $JAVA_HOME"
java --version
java --version | grep "GraalVM CE" || exit 12
native-image --version
if: runner.os != 'Windows'
- name: Check Windows environment
@ -71,6 +72,41 @@ jobs:
java --version
native-image.cmd --version
if: runner.os == 'Windows'
test-ee:
name: EE ${{ matrix.version }} + JDK${{ matrix.java-version }} on ${{ matrix.os }}
if: github.event_name != 'pull_request'
runs-on: ${{ matrix.os }}
strategy:
matrix:
version: ['21.3.0', 'latest']
java-version: ['11', '17']
components: [''] # ['native-image'] (activate after 22.1.0 is released)
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- uses: actions/checkout@v2
- name: Run setup-graalvm action
uses: ./
with:
version: ${{ matrix.version }}
gds-token: ${{ secrets.GDS_TOKEN }}
java-version: ${{ matrix.java-version }}
components: ${{ matrix.components }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Check environment
run: |
echo "GRAALVM_HOME: $GRAALVM_HOME"
echo "JAVA_HOME: $JAVA_HOME"
java --version
java --version | grep "GraalVM EE" || exit 12
# native-image --version (activate after 22.1.0 is released)
if: runner.os != 'Windows'
- name: Check Windows environment
run: |
echo "GRAALVM_HOME: $env:GRAALVM_HOME"
echo "JAVA_HOME: $env:JAVA_HOME"
java --version
# native-image.cmd --version (activate after 22.1.0 is released)
if: runner.os == 'Windows'
test-native-image-musl:
name: native-image-musl on ubuntu-latest
runs-on: ubuntu-latest
@ -90,7 +126,7 @@ jobs:
javac HelloWorld.java
native-image --static --libc=musl HelloWorld
./helloworld
test-additional:
test-extensive:
name: extensive tests on ubuntu-latest
runs-on: ubuntu-latest
steps:

44
__tests__/gds.test.ts Normal file
View File

@ -0,0 +1,44 @@
import * as path from 'path'
import {downloadGraalVMEE, fetchArtifact} from '../src/gds'
import {expect, test} from '@jest/globals'
const TEST_USER_AGENT = 'GraalVMGitHubActionTest/1.0.4'
process.env['RUNNER_TEMP'] = path.join(__dirname, 'TEMP')
test('fetch artifacts', async () => {
let artifact = await fetchArtifact(
TEST_USER_AGENT,
'isBase:True',
'21.3.0',
'11'
)
expect(artifact.id).toBe('D540A9EA0F406A12E0530F15000A38C7')
expect(artifact.checksum).toBe(
'78e1ee14861eb6a58fd0d7f64878d544ad11515c237a6557452f4d3a63a070fc'
)
artifact = await fetchArtifact(TEST_USER_AGENT, 'isBase:True', '21.3.0', '17')
expect(artifact.id).toBe('D540A9EA10C26A12E0530F15000A38C7')
expect(artifact.checksum).toBe(
'173e0e2b1f80033115216ebbad574c977e74fc4a37fa30ae5e6eff0f215070f4'
)
await expect(
fetchArtifact(TEST_USER_AGENT, 'isBase:False', '21.3.0', '11')
).rejects.toThrow('Found more than one GDS artifact')
await expect(
fetchArtifact(TEST_USER_AGENT, 'isBase:True', '1.0.0', '11')
).rejects.toThrow('Unable to find JDK11-based GraalVM EE 1.0.0')
})
test('errors when downloading artifacts', async () => {
await expect(downloadGraalVMEE('invalid', '21.3.0', '11')).rejects.toThrow(
'The provided "gds-token" was rejected (reason: "Invalid download token", opc-request-id: /'
)
await expect(downloadGraalVMEE('invalid', '1.0.0', '11')).rejects.toThrow(
'Unable to find JDK11-based GraalVM EE 1.0.0'
)
await expect(downloadGraalVMEE('invalid', '21.3.0', '1')).rejects.toThrow(
'Unable to find JDK1-based GraalVM EE 21.3.0'
)
})

View File

@ -1,5 +0,0 @@
import {expect, test} from '@jest/globals'
test('dummy test', async () => {
expect(true).toBeTruthy()
})

View File

@ -1,5 +1,5 @@
name: 'GitHub Action for GraalVM'
description: 'Set up a specific version of GraalVM Community Edition'
description: 'Set up a specific version of GraalVM Enterprise Edition (EE) or Community Edition (CE)'
author: 'GraalVM Developers'
branding:
icon: 'terminal'
@ -8,6 +8,9 @@ inputs:
version:
required: true
description: 'GraalVM version (release, latest, dev).'
gds-token:
required: false
description: 'Download token for the GraalVM Download Service. Set this to use GraalVM EE.'
java-version:
required: true
description: 'Java version (11 or 17, 8 or 16 for older releases).'

28
package-lock.json generated
View File

@ -15,10 +15,12 @@
"@actions/io": "^1.1.1",
"@actions/tool-cache": "^1.7.1",
"@octokit/core": "^3.5.1",
"@octokit/types": "^6.34.0"
"@octokit/types": "^6.34.0",
"uuid": "^3.3.2"
},
"devDependencies": {
"@types/node": "^17.0.6",
"@types/uuid": "^3.4.10",
"@typescript-eslint/parser": "^5.8.1",
"@vercel/ncc": "^0.33.1",
"eslint": "^8.6.0",
@ -1309,6 +1311,12 @@
"integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
"dev": true
},
"node_modules/@types/uuid": {
"version": "3.4.10",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.10.tgz",
"integrity": "sha512-BgeaZuElf7DEYZhWYDTc/XcLZXdVgFkVSTa13BqKvbnmUrxr3TJFKofUxCtDO9UQOdhnV+HPOESdHiHKZOJV1A==",
"dev": true
},
"node_modules/@types/yargs": {
"version": "16.0.4",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
@ -6096,9 +6104,9 @@
}
},
"node_modules/uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
"deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
"bin": {
"uuid": "bin/uuid"
@ -7389,6 +7397,12 @@
"integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
"dev": true
},
"@types/uuid": {
"version": "3.4.10",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.10.tgz",
"integrity": "sha512-BgeaZuElf7DEYZhWYDTc/XcLZXdVgFkVSTa13BqKvbnmUrxr3TJFKofUxCtDO9UQOdhnV+HPOESdHiHKZOJV1A==",
"dev": true
},
"@types/yargs": {
"version": "16.0.4",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
@ -10938,9 +10952,9 @@
}
},
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
},
"v8-compile-cache": {
"version": "2.3.0",

View File

@ -32,10 +32,12 @@
"@actions/io": "^1.1.1",
"@actions/tool-cache": "^1.7.1",
"@octokit/core": "^3.5.1",
"@octokit/types": "^6.34.0"
"@octokit/types": "^6.34.0",
"uuid": "^3.3.2"
},
"devDependencies": {
"@types/node": "^17.0.6",
"@types/uuid": "^3.4.10",
"@typescript-eslint/parser": "^5.8.1",
"@vercel/ncc": "^0.33.1",
"eslint": "^8.6.0",

View File

@ -15,6 +15,9 @@ export const JDK_HOME_SUFFIX = IS_MACOS ? '/Contents/Home' : ''
export const MANDREL_NAMESPACE = 'mandrel-'
export const GDS_BASE = 'https://gds.oracle.com/api/20220101'
export const GDS_GRAALVM_PRODUCT_ID = 'D53FAE8052773FFAE0530F15000AA6C6'
export type LatestReleaseResponse =
otypes.Endpoints['GET /repos/{owner}/{repo}/releases/latest']['response']

220
src/gds.ts Normal file
View File

@ -0,0 +1,220 @@
import * as c from './constants'
import * as core from '@actions/core'
import * as fs from 'fs'
import * as httpClient from '@actions/http-client'
import * as io from '@actions/io'
import * as path from 'path'
import * as stream from 'stream'
import * as util from 'util'
import {IHeaders} from '@actions/http-client/interfaces'
import {IncomingHttpHeaders} from 'http'
import {RetryHelper} from '@actions/tool-cache/lib/retry-helper'
import {calculateSHA256} from './utils'
import {ok} from 'assert'
import uuidV4 from 'uuid/v4'
interface GDSArtifactsResponse {
readonly items: GDSArtifact[]
}
interface GDSArtifact {
readonly id: string
readonly checksum: string
}
interface GDSErrorResponse {
readonly code: string
readonly message: string
}
export async function downloadGraalVMEE(
gdsToken: string,
version: string,
javaVersion: string
): Promise<string> {
const userAgent = `GraalVMGitHubAction/1.0.4 (arch:${c.GRAALVM_ARCH}; os:${c.GRAALVM_PLATFORM}; java:${javaVersion})`
const baseArtifact = await fetchArtifact(
userAgent,
'isBase:True',
version,
javaVersion
)
return downloadArtifact(gdsToken, userAgent, baseArtifact)
}
export async function fetchArtifact(
userAgent: string,
metadata: string,
version: string,
javaVersion: string
): Promise<GDSArtifact> {
const http = new httpClient.HttpClient(userAgent)
let filter
if (version === c.VERSION_LATEST) {
filter = `sortBy=timeCreated&limit=1` // latest and only one item
} else {
filter = `metadata=version:${version}`
}
const response = await http.get(
`${c.GDS_BASE}/artifacts?productId=${c.GDS_GRAALVM_PRODUCT_ID}&${filter}&metadata=java:jdk${javaVersion}&metadata=os:${c.GRAALVM_PLATFORM}&metadata=arch:${c.GRAALVM_ARCH}&metadata=${metadata}&status=PUBLISHED&responseFields=id&responseFields=checksum`,
{accept: 'application/json'}
)
if (response.message.statusCode !== 200) {
throw new Error(
`Unable to find JDK${javaVersion}-based GraalVM EE ${version}`
)
}
const artifactResponse = JSON.parse(
await response.readBody()
) as GDSArtifactsResponse
if (artifactResponse.items.length !== 1) {
throw new Error(`Found more than one GDS artifact`)
}
return artifactResponse.items[0]
}
async function downloadArtifact(
gdsToken: string,
userAgent: string,
artifact: GDSArtifact
): Promise<string> {
let downloadPath
try {
downloadPath = await downloadTool(
`${c.GDS_BASE}/artifacts/${artifact.id}/content`,
userAgent,
{
accept: 'application/x-yaml',
'x-download-token': gdsToken
}
)
} catch (err) {
if (err instanceof HTTPError && err.httpStatusCode) {
if (err.httpStatusCode === 401) {
throw new Error(
`The provided "gds-token" was rejected (reason: "${err.gdsError.message}", opc-request-id: ${err.headers['opc-request-id']})`
)
}
}
throw err
}
const sha256 = calculateSHA256(downloadPath)
if (sha256.toLowerCase() !== artifact.checksum.toLowerCase()) {
throw new Error(
`Checksum does not match (expected: "${artifact.checksum}", got: "${sha256}")`
)
}
return downloadPath
}
/**
* Simplified fork of tool-cache's downloadTool [1] with the ability to set a custom user agent.
* [1] https://github.com/actions/toolkit/blob/2f164000dcd42fb08287824a3bc3030dbed33687/packages/tool-cache/src/tool-cache.ts
*/
class HTTPError extends Error {
constructor(
readonly httpStatusCode: number | undefined,
readonly gdsError: GDSErrorResponse,
readonly headers: IncomingHttpHeaders
) {
super(`Unexpected HTTP response: ${httpStatusCode}`)
Object.setPrototypeOf(this, new.target.prototype)
}
}
async function downloadTool(
url: string,
userAgent: string,
headers?: IHeaders
): Promise<string> {
const dest = path.join(getTempDirectory(), uuidV4())
await io.mkdirP(path.dirname(dest))
core.debug(`Downloading ${url}`)
core.debug(`Destination ${dest}`)
const maxAttempts = 3
const minSeconds = 10
const maxSeconds = 20
const retryHelper = new RetryHelper(maxAttempts, minSeconds, maxSeconds)
return await retryHelper.execute(
async () => {
return await downloadToolAttempt(url, userAgent, dest || '', headers)
},
(err: Error) => {
if (err instanceof HTTPError && err.httpStatusCode) {
// Don't retry anything less than 500, except 408 Request Timeout and 429 Too Many Requests
if (
err.httpStatusCode < 500 &&
err.httpStatusCode !== 408 &&
err.httpStatusCode !== 429
) {
return false
}
}
// Otherwise retry
return true
}
)
}
async function downloadToolAttempt(
url: string,
userAgent: string,
dest: string,
headers?: IHeaders
): Promise<string> {
if (fs.existsSync(dest)) {
throw new Error(`Destination file path ${dest} already exists`)
}
// Get the response headers
const http = new httpClient.HttpClient(userAgent, [], {
allowRetries: false
})
const response: httpClient.HttpClientResponse = await http.get(url, headers)
if (response.message.statusCode !== 200) {
const errorResponse = JSON.parse(
await response.readBody()
) as GDSErrorResponse
const err = new HTTPError(
response.message.statusCode,
errorResponse,
response.message.headers
)
core.debug(
`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`
)
throw err
}
// Download the response body
const pipeline = util.promisify(stream.pipeline)
let succeeded = false
try {
await pipeline(response.message, fs.createWriteStream(dest))
core.debug('Download complete')
succeeded = true
return dest
} finally {
// Error, delete dest before retry
if (!succeeded) {
core.debug('Download failed')
try {
await io.rmRF(dest)
} catch (err) {
core.debug(`Failed to delete '${dest}'. ${err}`)
}
}
}
}
function getTempDirectory(): string {
const tempDirectory = process.env['RUNNER_TEMP'] || ''
ok(tempDirectory, 'Expected RUNNER_TEMP to be defined')
return tempDirectory
}

View File

@ -4,6 +4,8 @@ import {
downloadExtractAndCacheJDK,
getLatestRelease
} from './utils'
import {downloadGraalVMEE} from './gds'
import {downloadTool} from '@actions/tool-cache'
const GRAALVM_CE_DL_BASE =
'https://github.com/graalvm/graalvm-ce-builds/releases/download'
@ -11,7 +13,13 @@ const GRAALVM_REPO_DEV_BUILDS = 'graalvm-ce-dev-builds'
const GRAALVM_REPO_RELEASES = 'graalvm-ce-builds'
const GRAALVM_TAG_PREFIX = 'vm-'
export async function setUpGraalVMLatest(javaVersion: string): Promise<string> {
export async function setUpGraalVMLatest(
gdsToken: string,
javaVersion: string
): Promise<string> {
if (gdsToken.length > 0) {
return setUpGraalVMRelease(gdsToken, c.VERSION_LATEST, javaVersion)
}
const latestRelease = await getLatestRelease(GRAALVM_REPO_RELEASES)
const tag_name = latestRelease.tag_name
if (tag_name.startsWith(GRAALVM_TAG_PREFIX)) {
@ -19,16 +27,24 @@ export async function setUpGraalVMLatest(javaVersion: string): Promise<string> {
GRAALVM_TAG_PREFIX.length,
tag_name.length
)
return setUpGraalVMRelease(latestVersion, javaVersion)
return setUpGraalVMRelease(gdsToken, latestVersion, javaVersion)
}
throw new Error(`Could not find latest GraalVM release: ${tag_name}`)
}
export async function setUpGraalVMDevBuild(
gdsToken: string,
javaVersion: string
): Promise<string> {
if (gdsToken.length > 0) {
throw new Error('Downloading GraalVM EE dev builds is not supported')
}
const latestDevBuild = await getLatestRelease(GRAALVM_REPO_DEV_BUILDS)
const graalVMIdentifier = determineGraalVMIdentifier('dev', javaVersion)
const graalVMIdentifier = determineGraalVMIdentifier(
false,
'dev',
javaVersion
)
const expectedFileName = `${graalVMIdentifier}${c.GRAALVM_FILE_EXTENSION}`
for (const asset of latestDevBuild.assets) {
if (asset.name === expectedFileName) {
@ -39,22 +55,39 @@ export async function setUpGraalVMDevBuild(
}
export async function setUpGraalVMRelease(
gdsToken: string,
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}`
const toolName = determineToolName(javaVersion)
return downloadExtractAndCacheJDK(downloadUrl, toolName, version)
const isEE = gdsToken.length > 0
const graalVMIdentifier = determineGraalVMIdentifier(
isEE,
version,
javaVersion
)
const toolName = determineToolName(isEE, javaVersion)
let downloader: () => Promise<string>
if (isEE) {
downloader = async () => downloadGraalVMEE(gdsToken, version, javaVersion)
} else {
const downloadUrl = `${GRAALVM_CE_DL_BASE}/${GRAALVM_TAG_PREFIX}${version}/${graalVMIdentifier}${c.GRAALVM_FILE_EXTENSION}`
downloader = async () => downloadTool(downloadUrl)
}
return downloadExtractAndCacheJDK(downloader, toolName, version)
}
function determineGraalVMIdentifier(
isEE: boolean,
version: string,
javaVersion: string
): string {
return `graalvm-ce-java${javaVersion}-${c.GRAALVM_PLATFORM}-${c.GRAALVM_ARCH}-${version}`
return `graalvm-${isEE ? 'ee' : 'ce'}-java${javaVersion}-${
c.GRAALVM_PLATFORM
}-${c.GRAALVM_ARCH}-${version}`
}
function determineToolName(javaVersion: string): string {
return `graalvm-ce-java${javaVersion}-${c.GRAALVM_PLATFORM}`
function determineToolName(isEE: boolean, javaVersion: string): string {
return `graalvm-${isEE ? 'ee' : 'ce'}-java${javaVersion}-${
c.GRAALVM_PLATFORM
}`
}

View File

@ -2,6 +2,7 @@ import {GRAALVM_PLATFORM} from './constants'
import {exec} from '@actions/exec'
import {join} from 'path'
const BASE_FLAGS = ['--non-interactive', 'install', '--no-progress']
const COMPONENT_TO_POST_INSTALL_HOOK = new Map<string, Map<string, string>>([
[
'linux',
@ -21,10 +22,16 @@ const COMPONENT_TO_POST_INSTALL_HOOK = new Map<string, Map<string, string>>([
])
export async function setUpGUComponents(
gdsToken: string,
graalVMHome: string,
components: string[]
): Promise<void> {
await exec('gu', ['install', '--no-progress'].concat(components))
const optionalFlags = []
if (gdsToken.length > 0) {
optionalFlags.push('--token', gdsToken)
}
await exec('gu', BASE_FLAGS.concat(optionalFlags, components))
const platformHooks = COMPONENT_TO_POST_INSTALL_HOOK.get(GRAALVM_PLATFORM)
if (platformHooks) {

View File

@ -11,6 +11,7 @@ import {setUpWindowsEnvironment} from './msvc'
async function run(): Promise<void> {
try {
const graalvmVersion = core.getInput('version', {required: true})
const gdsToken = core.getInput('gds-token')
const javaVersion = core.getInput('java-version', {required: true})
const componentsString: string = core.getInput('components')
const components: string[] =
@ -30,16 +31,17 @@ async function run(): Promise<void> {
let graalVMHome
switch (graalvmVersion) {
case c.VERSION_LATEST:
graalVMHome = await graalvm.setUpGraalVMLatest(javaVersion)
graalVMHome = await graalvm.setUpGraalVMLatest(gdsToken, javaVersion)
break
case c.VERSION_DEV:
graalVMHome = await graalvm.setUpGraalVMDevBuild(javaVersion)
graalVMHome = await graalvm.setUpGraalVMDevBuild(gdsToken, javaVersion)
break
default:
if (graalvmVersion.startsWith(c.MANDREL_NAMESPACE)) {
graalVMHome = await setUpMandrel(graalvmVersion, javaVersion)
} else {
graalVMHome = await graalvm.setUpGraalVMRelease(
gdsToken,
graalvmVersion,
javaVersion
)
@ -62,7 +64,7 @@ async function run(): Promise<void> {
`Mandrel does not support GraalVM components: ${componentsString}`
)
} else {
await setUpGUComponents(graalVMHome, components)
await setUpGUComponents(gdsToken, graalVMHome, components)
}
}
} catch (error) {

View File

@ -1,5 +1,6 @@
import * as c from './constants'
import {downloadExtractAndCacheJDK, getLatestRelease} from './utils'
import {downloadTool} from '@actions/tool-cache'
const MANDREL_REPO = 'mandrel'
const MANDREL_TAG_PREFIX = c.MANDREL_NAMESPACE
@ -47,7 +48,11 @@ async function setUpMandrelRelease(
const identifier = determineMandrelIdentifier(version, javaVersion)
const downloadUrl = `${MANDREL_DL_BASE}/${MANDREL_TAG_PREFIX}${version}/${identifier}${c.GRAALVM_FILE_EXTENSION}`
const toolName = determineToolName(javaVersion)
return downloadExtractAndCacheJDK(downloadUrl, toolName, version)
return downloadExtractAndCacheJDK(
async () => downloadTool(downloadUrl),
toolName,
version
)
}
function determineMandrelIdentifier(

View File

@ -2,9 +2,10 @@ 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 {readFileSync, readdirSync} from 'fs'
import {Octokit} from '@octokit/core'
import {createHash} from 'crypto'
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'
@ -32,11 +33,13 @@ export async function getLatestRelease(
export async function downloadAndExtractJDK(
downloadUrl: string
): Promise<string> {
return findJavaHomeInSubfolder(await downloadAndExtract(downloadUrl))
return findJavaHomeInSubfolder(
await extract(await tc.downloadTool(downloadUrl))
)
}
export async function downloadExtractAndCacheJDK(
downloadUrl: string,
downloader: () => Promise<string>,
toolName: string,
version: string
): Promise<string> {
@ -45,21 +48,28 @@ export async function downloadExtractAndCacheJDK(
if (toolPath) {
core.info(`Found ${toolName} ${version} in tool-cache @ ${toolPath}`)
} else {
const extractDir = await downloadAndExtract(downloadUrl)
const extractDir = await extract(await downloader())
core.info(`Adding ${toolName} ${version} to tool-cache ...`)
toolPath = await tc.cacheDir(extractDir, toolName, semVersion)
}
return findJavaHomeInSubfolder(toolPath)
}
async function downloadAndExtract(downloadUrl: string): Promise<string> {
const downloadPath = await tc.downloadTool(downloadUrl)
if (downloadUrl.endsWith('.tar.gz')) {
export function calculateSHA256(filePath: string): string {
const hashSum = createHash('sha256')
hashSum.update(readFileSync(filePath))
return hashSum.digest('hex')
}
async function extract(downloadPath: string): Promise<string> {
if (c.GRAALVM_FILE_EXTENSION === '.tar.gz') {
return await tc.extractTar(downloadPath)
} else if (downloadUrl.endsWith('.zip')) {
} else if (c.GRAALVM_FILE_EXTENSION === '.zip') {
return await tc.extractZip(downloadPath)
} else {
throw new Error(`Unexpected filetype downloaded: ${downloadUrl}`)
throw new Error(
`Unexpected filetype downloaded: ${c.GRAALVM_FILE_EXTENSION}`
)
}
}