Adjust printWidth to 120.

This commit is contained in:
Fabio Niephaus 2025-02-10 09:16:33 +01:00 committed by Fabio Niephaus
parent 93a3b57d30
commit 9b77b7e1c6
33 changed files with 373 additions and 957 deletions

View File

@ -1,6 +1,6 @@
# See: https://prettier.io/docs/en/configuration # See: https://prettier.io/docs/en/configuration
printWidth: 80 printWidth: 120
tabWidth: 2 tabWidth: 2
useTabs: false useTabs: false
semi: false semi: false

View File

@ -24,10 +24,10 @@
* Forked from https://github.com/actions/setup-java/blob/5b36705a13905facb447b6812d613a06a07e371d/__tests__/cache.test.ts * Forked from https://github.com/actions/setup-java/blob/5b36705a13905facb447b6812d613a06a07e371d/__tests__/cache.test.ts
*/ */
import {mkdtempSync} from 'fs' import { mkdtempSync } from 'fs'
import {tmpdir} from 'os' import { tmpdir } from 'os'
import {join} from 'path' import { join } from 'path'
import {restore, save} from '../src/features/cache' import { restore, save } from '../src/features/cache'
import * as fs from 'fs' import * as fs from 'fs'
import * as os from 'os' import * as os from 'os'
import * as core from '@actions/core' import * as core from '@actions/core'
@ -86,24 +86,17 @@ describe('dependency cache', () => {
}) })
describe('restore', () => { describe('restore', () => {
let spyCacheRestore: jest.SpyInstance< let spyCacheRestore: jest.SpyInstance<ReturnType<typeof cache.restoreCache>, Parameters<typeof cache.restoreCache>>
ReturnType<typeof cache.restoreCache>,
Parameters<typeof cache.restoreCache>
>
beforeEach(() => { beforeEach(() => {
spyCacheRestore = jest spyCacheRestore = jest
.spyOn(cache, 'restoreCache') .spyOn(cache, 'restoreCache')
.mockImplementation((_paths: string[], _primaryKey: string) => .mockImplementation((_paths: string[], _primaryKey: string) => Promise.resolve(undefined))
Promise.resolve(undefined)
)
spyWarning.mockImplementation(() => null) spyWarning.mockImplementation(() => null)
}) })
it('throws error if unsupported package manager specified', () => { it('throws error if unsupported package manager specified', () => {
return expect(restore('ant')).rejects.toThrow( return expect(restore('ant')).rejects.toThrow('unknown package manager specified: ant')
'unknown package manager specified: ant'
)
}) })
describe('for maven', () => { describe('for maven', () => {
@ -176,24 +169,17 @@ describe('dependency cache', () => {
}) })
}) })
describe('save', () => { describe('save', () => {
let spyCacheSave: jest.SpyInstance< let spyCacheSave: jest.SpyInstance<ReturnType<typeof cache.saveCache>, Parameters<typeof cache.saveCache>>
ReturnType<typeof cache.saveCache>,
Parameters<typeof cache.saveCache>
>
beforeEach(() => { beforeEach(() => {
spyCacheSave = jest spyCacheSave = jest
.spyOn(cache, 'saveCache') .spyOn(cache, 'saveCache')
.mockImplementation((_paths: string[], _key: string) => .mockImplementation((_paths: string[], _key: string) => Promise.resolve(0))
Promise.resolve(0)
)
spyWarning.mockImplementation(() => null) spyWarning.mockImplementation(() => null)
}) })
it('throws error if unsupported package manager specified', () => { it('throws error if unsupported package manager specified', () => {
return expect(save('ant')).rejects.toThrow( return expect(save('ant')).rejects.toThrow('unknown package manager specified: ant')
'unknown package manager specified: ant'
)
}) })
it('save with -1 cacheId , should not fail workflow', async () => { it('save with -1 cacheId , should not fail workflow', async () => {
@ -204,21 +190,15 @@ describe('dependency cache', () => {
expect(spyCacheSave).toHaveBeenCalled() expect(spyCacheSave).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled() expect(spyWarning).not.toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalled() expect(spyInfo).toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalledWith( expect(spyInfo).toHaveBeenCalledWith(expect.stringMatching(/^Cache saved with the key:.*/))
expect.stringMatching(/^Cache saved with the key:.*/)
)
}) })
it('saves with error from toolkit, should fail workflow', async () => { it('saves with error from toolkit, should fail workflow', async () => {
spyCacheSave.mockImplementation(() => spyCacheSave.mockImplementation(() => Promise.reject(new cache.ValidationError('Validation failed')))
Promise.reject(new cache.ValidationError('Validation failed'))
)
createStateForMissingBuildFile() createStateForMissingBuildFile()
expect.assertions(1) expect.assertions(1)
await expect(save('maven')).rejects.toEqual( await expect(save('maven')).rejects.toEqual(new cache.ValidationError('Validation failed'))
new cache.ValidationError('Validation failed')
)
}) })
describe('for maven', () => { describe('for maven', () => {
@ -233,9 +213,7 @@ describe('dependency cache', () => {
await save('maven') await save('maven')
expect(spyCacheSave).not.toHaveBeenCalled() expect(spyCacheSave).not.toHaveBeenCalled()
expect(spyWarning).toHaveBeenCalledWith( expect(spyWarning).toHaveBeenCalledWith('Error retrieving key from state.')
'Error retrieving key from state.'
)
}) })
it('uploads cache', async () => { it('uploads cache', async () => {
createFile(join(workspace, 'pom.xml')) createFile(join(workspace, 'pom.xml'))
@ -244,9 +222,7 @@ describe('dependency cache', () => {
await save('maven') await save('maven')
expect(spyCacheSave).toHaveBeenCalled() expect(spyCacheSave).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled() expect(spyWarning).not.toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalledWith( expect(spyInfo).toHaveBeenCalledWith(expect.stringMatching(/^Cache saved with the key:.*/))
expect.stringMatching(/^Cache saved with the key:.*/)
)
}) })
}) })
describe('for gradle', () => { describe('for gradle', () => {
@ -262,9 +238,7 @@ describe('dependency cache', () => {
await save('gradle') await save('gradle')
expect(spyCacheSave).not.toHaveBeenCalled() expect(spyCacheSave).not.toHaveBeenCalled()
expect(spyWarning).toHaveBeenCalledWith( expect(spyWarning).toHaveBeenCalledWith('Error retrieving key from state.')
'Error retrieving key from state.'
)
}) })
it('uploads cache based on build.gradle', async () => { it('uploads cache based on build.gradle', async () => {
createFile(join(workspace, 'build.gradle')) createFile(join(workspace, 'build.gradle'))
@ -273,9 +247,7 @@ describe('dependency cache', () => {
await save('gradle') await save('gradle')
expect(spyCacheSave).toHaveBeenCalled() expect(spyCacheSave).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled() expect(spyWarning).not.toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalledWith( expect(spyInfo).toHaveBeenCalledWith(expect.stringMatching(/^Cache saved with the key:.*/))
expect.stringMatching(/^Cache saved with the key:.*/)
)
}) })
it('uploads cache based on build.gradle.kts', async () => { it('uploads cache based on build.gradle.kts', async () => {
createFile(join(workspace, 'build.gradle.kts')) createFile(join(workspace, 'build.gradle.kts'))
@ -284,9 +256,7 @@ describe('dependency cache', () => {
await save('gradle') await save('gradle')
expect(spyCacheSave).toHaveBeenCalled() expect(spyCacheSave).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled() expect(spyWarning).not.toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalledWith( expect(spyInfo).toHaveBeenCalledWith(expect.stringMatching(/^Cache saved with the key:.*/))
expect.stringMatching(/^Cache saved with the key:.*/)
)
}) })
it('uploads cache based on buildSrc/Versions.kt', async () => { it('uploads cache based on buildSrc/Versions.kt', async () => {
createDirectory(join(workspace, 'buildSrc')) createDirectory(join(workspace, 'buildSrc'))
@ -296,9 +266,7 @@ describe('dependency cache', () => {
await save('gradle') await save('gradle')
expect(spyCacheSave).toHaveBeenCalled() expect(spyCacheSave).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled() expect(spyWarning).not.toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalledWith( expect(spyInfo).toHaveBeenCalledWith(expect.stringMatching(/^Cache saved with the key:.*/))
expect.stringMatching(/^Cache saved with the key:.*/)
)
}) })
}) })
describe('for sbt', () => { describe('for sbt', () => {
@ -313,9 +281,7 @@ describe('dependency cache', () => {
await save('sbt') await save('sbt')
expect(spyCacheSave).not.toHaveBeenCalled() expect(spyCacheSave).not.toHaveBeenCalled()
expect(spyWarning).toHaveBeenCalledWith( expect(spyWarning).toHaveBeenCalledWith('Error retrieving key from state.')
'Error retrieving key from state.'
)
}) })
it('uploads cache', async () => { it('uploads cache', async () => {
createFile(join(workspace, 'build.sbt')) createFile(join(workspace, 'build.sbt'))
@ -324,9 +290,7 @@ describe('dependency cache', () => {
await save('sbt') await save('sbt')
expect(spyCacheSave).toHaveBeenCalled() expect(spyCacheSave).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled() expect(spyWarning).not.toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalledWith( expect(spyInfo).toHaveBeenCalledWith(expect.stringMatching(/^Cache saved with the key:.*/))
expect.stringMatching(/^Cache saved with the key:.*/)
)
}) })
}) })
}) })
@ -340,7 +304,7 @@ function resetState() {
* Create states to emulate a restore process without build file. * Create states to emulate a restore process without build file.
*/ */
function createStateForMissingBuildFile() { function createStateForMissingBuildFile() {
jest.spyOn(core, 'getState').mockImplementation(name => { jest.spyOn(core, 'getState').mockImplementation((name) => {
switch (name) { switch (name) {
case 'cache-primary-key': case 'cache-primary-key':
return 'setup-graalvm-cache-' return 'setup-graalvm-cache-'
@ -354,7 +318,7 @@ function createStateForMissingBuildFile() {
* Create states to emulate a successful restore process. * Create states to emulate a successful restore process.
*/ */
function createStateForSuccessfulRestore() { function createStateForSuccessfulRestore() {
jest.spyOn(core, 'getState').mockImplementation(name => { jest.spyOn(core, 'getState').mockImplementation((name) => {
switch (name) { switch (name) {
case 'cache-primary-key': case 'cache-primary-key':
return 'setup-graalvm-cache-primary-key' return 'setup-graalvm-cache-primary-key'

View File

@ -24,17 +24,14 @@
* Forked from https://github.com/actions/setup-java/blob/5b36705a13905facb447b6812d613a06a07e371d/__tests__/cleanup-java.test.ts * Forked from https://github.com/actions/setup-java/blob/5b36705a13905facb447b6812d613a06a07e371d/__tests__/cleanup-java.test.ts
*/ */
import {run as cleanup} from '../src/cleanup' import { run as cleanup } from '../src/cleanup'
import * as core from '@actions/core' import * as core from '@actions/core'
import * as cache from '@actions/cache' import * as cache from '@actions/cache'
describe('cleanup', () => { describe('cleanup', () => {
let spyWarning: jest.SpyInstance<void, Parameters<typeof core.warning>> let spyWarning: jest.SpyInstance<void, Parameters<typeof core.warning>>
let spyInfo: jest.SpyInstance<void, Parameters<typeof core.info>> let spyInfo: jest.SpyInstance<void, Parameters<typeof core.info>>
let spyCacheSave: jest.SpyInstance< let spyCacheSave: jest.SpyInstance<ReturnType<typeof cache.saveCache>, Parameters<typeof cache.saveCache>>
ReturnType<typeof cache.saveCache>,
Parameters<typeof cache.saveCache>
>
beforeEach(() => { beforeEach(() => {
spyWarning = jest.spyOn(core, 'warning') spyWarning = jest.spyOn(core, 'warning')
@ -51,9 +48,7 @@ describe('cleanup', () => {
it('does not fail nor warn even when the save process throws a ReserveCacheError', async () => { it('does not fail nor warn even when the save process throws a ReserveCacheError', async () => {
spyCacheSave.mockImplementation((_paths: string[], _key: string) => spyCacheSave.mockImplementation((_paths: string[], _key: string) =>
Promise.reject( Promise.reject(
new cache.ReserveCacheError( new cache.ReserveCacheError('Unable to reserve cache with key, another job may be creating this cache.')
'Unable to reserve cache with key, another job may be creating this cache.'
)
) )
) )
jest.spyOn(core, 'getInput').mockImplementation((name: string) => { jest.spyOn(core, 'getInput').mockImplementation((name: string) => {
@ -65,9 +60,7 @@ describe('cleanup', () => {
}) })
it('does not fail even though the save process throws error', async () => { it('does not fail even though the save process throws error', async () => {
spyCacheSave.mockImplementation((_paths: string[], _key: string) => spyCacheSave.mockImplementation((_paths: string[], _key: string) => Promise.reject(new Error('Unexpected error')))
Promise.reject(new Error('Unexpected error'))
)
jest.spyOn(core, 'getInput').mockImplementation((name: string) => { jest.spyOn(core, 'getInput').mockImplementation((name: string) => {
return name === 'cache' ? 'gradle' : '' return name === 'cache' ? 'gradle' : ''
}) })
@ -84,7 +77,7 @@ function resetState() {
* Create states to emulate a successful restore process. * Create states to emulate a successful restore process.
*/ */
function createStateForSuccessfulRestore() { function createStateForSuccessfulRestore() {
jest.spyOn(core, 'getState').mockImplementation(name => { jest.spyOn(core, 'getState').mockImplementation((name) => {
switch (name) { switch (name) {
case 'cache-primary-key': case 'cache-primary-key':
return 'setup-java-cache-primary-key' return 'setup-java-cache-primary-key'

View File

@ -1,11 +1,6 @@
import * as path from 'path' import * as path from 'path'
import { import { downloadGraalVM, downloadGraalVMEELegacy, fetchArtifact, fetchArtifactEE } from '../src/gds'
downloadGraalVM, import { expect, test } from '@jest/globals'
downloadGraalVMEELegacy,
fetchArtifact,
fetchArtifactEE
} from '../src/gds'
import {expect, test} from '@jest/globals'
const TEST_USER_AGENT = 'GraalVMGitHubActionTest/1.0.4' const TEST_USER_AGENT = 'GraalVMGitHubActionTest/1.0.4'
@ -14,64 +9,42 @@ process.env['RUNNER_TEMP'] = path.join(__dirname, 'TEMP')
test('fetch artifacts', async () => { test('fetch artifacts', async () => {
let artifact = await fetchArtifact(TEST_USER_AGENT, 'isBase:True', '17.0.12') let artifact = await fetchArtifact(TEST_USER_AGENT, 'isBase:True', '17.0.12')
expect(artifact.id).toBe('1C351E8F41BB8E9EE0631518000AE5F2') expect(artifact.id).toBe('1C351E8F41BB8E9EE0631518000AE5F2')
expect(artifact.checksum).toBe( expect(artifact.checksum).toBe('b6f3dace24cf1960ec790216f4c86f00d4f43df64e4e8b548f6382f04894713f')
'b6f3dace24cf1960ec790216f4c86f00d4f43df64e4e8b548f6382f04894713f'
)
artifact = await fetchArtifact(TEST_USER_AGENT, 'isBase:True', '17') artifact = await fetchArtifact(TEST_USER_AGENT, 'isBase:True', '17')
expect(artifact.checksum).toHaveLength( expect(artifact.checksum).toHaveLength('b6f3dace24cf1960ec790216f4c86f00d4f43df64e4e8b548f6382f04894713f'.length)
'b6f3dace24cf1960ec790216f4c86f00d4f43df64e4e8b548f6382f04894713f'.length
)
}) })
test('errors when downloading artifacts', async () => { test('errors when downloading artifacts', async () => {
await expect(downloadGraalVM('invalid', '17')).rejects.toThrow( await expect(downloadGraalVM('invalid', '17')).rejects.toThrow(
'The provided "gds-token" was rejected (reason: "Invalid download token", opc-request-id: ' 'The provided "gds-token" was rejected (reason: "Invalid download token", opc-request-id: '
) )
await expect(downloadGraalVM('invalid', '1')).rejects.toThrow( await expect(downloadGraalVM('invalid', '1')).rejects.toThrow('Unable to find GraalVM for JDK 1')
'Unable to find GraalVM for JDK 1'
)
}) })
test('fetch legacy artifacts', async () => { test('fetch legacy artifacts', async () => {
let artifact = await fetchArtifactEE( let artifact = await fetchArtifactEE(TEST_USER_AGENT, 'isBase:True', '22.1.0', '11')
TEST_USER_AGENT,
'isBase:True',
'22.1.0',
'11'
)
expect(artifact.id).toBe('DCECD1C1B0B5B8DBE0536E16000A5C74') expect(artifact.id).toBe('DCECD1C1B0B5B8DBE0536E16000A5C74')
expect(artifact.checksum).toBe( expect(artifact.checksum).toBe('4280782f6c7fcabe0ba707e8389cbfaf7bbe6b0cf634d309e6efcd1b172e3ce6')
'4280782f6c7fcabe0ba707e8389cbfaf7bbe6b0cf634d309e6efcd1b172e3ce6' artifact = await fetchArtifactEE(TEST_USER_AGENT, 'isBase:True', '22.1.0', '17')
)
artifact = await fetchArtifactEE(
TEST_USER_AGENT,
'isBase:True',
'22.1.0',
'17'
)
expect(artifact.id).toBe('DCECD2068882A0E9E0536E16000A9504') expect(artifact.id).toBe('DCECD2068882A0E9E0536E16000A9504')
expect(artifact.checksum).toBe( expect(artifact.checksum).toBe('e897add7d94bc456a61e6f927e831dff759efa3392a4b69c720dd3debc8f947d')
'e897add7d94bc456a61e6f927e831dff759efa3392a4b69c720dd3debc8f947d'
)
await expect( await expect(fetchArtifactEE(TEST_USER_AGENT, 'isBase:False', '22.1.0', '11')).rejects.toThrow(
fetchArtifactEE(TEST_USER_AGENT, 'isBase:False', '22.1.0', '11') 'Found more than one GDS artifact'
).rejects.toThrow('Found more than one GDS artifact') )
await expect( await expect(fetchArtifactEE(TEST_USER_AGENT, 'isBase:True', '1.0.0', '11')).rejects.toThrow(
fetchArtifactEE(TEST_USER_AGENT, 'isBase:True', '1.0.0', '11') 'Unable to find JDK11-based GraalVM EE 1.0.0'
).rejects.toThrow('Unable to find JDK11-based GraalVM EE 1.0.0') )
}) })
test('errors when downloading legacy artifacts', async () => { test('errors when downloading legacy artifacts', async () => {
await expect( await expect(downloadGraalVMEELegacy('invalid', '22.1.0', '11')).rejects.toThrow(
downloadGraalVMEELegacy('invalid', '22.1.0', '11')
).rejects.toThrow(
'The provided "gds-token" was rejected (reason: "Invalid download token", opc-request-id: ' 'The provided "gds-token" was rejected (reason: "Invalid download token", opc-request-id: '
) )
await expect( await expect(downloadGraalVMEELegacy('invalid', '1.0.0', '11')).rejects.toThrow(
downloadGraalVMEELegacy('invalid', '1.0.0', '11') 'Unable to find JDK11-based GraalVM EE 1.0.0'
).rejects.toThrow('Unable to find JDK11-based GraalVM EE 1.0.0') )
await expect( await expect(downloadGraalVMEELegacy('invalid', '22.1.0', '1')).rejects.toThrow(
downloadGraalVMEELegacy('invalid', '22.1.0', '1') 'Unable to find JDK1-based GraalVM EE 22.1.0'
).rejects.toThrow('Unable to find JDK1-based GraalVM EE 22.1.0') )
}) })

View File

@ -1,13 +1,9 @@
import * as path from 'path' import * as path from 'path'
import * as graalvm from '../src/graalvm' import * as graalvm from '../src/graalvm'
import {expect, test} from '@jest/globals' import { expect, test } from '@jest/globals'
import {getTaggedRelease} from '../src/utils' import { getTaggedRelease } from '../src/utils'
import { import { findGraalVMVersion, findHighestJavaVersion, findLatestEABuildDownloadUrl } from '../src/graalvm'
findGraalVMVersion, import { GRAALVM_GH_USER, GRAALVM_RELEASES_REPO } from '../src/constants'
findHighestJavaVersion,
findLatestEABuildDownloadUrl
} from '../src/graalvm'
import {GRAALVM_GH_USER, GRAALVM_RELEASES_REPO} from '../src/constants'
process.env['RUNNER_TOOL_CACHE'] = path.join(__dirname, 'TOOL_CACHE') process.env['RUNNER_TOOL_CACHE'] = path.join(__dirname, 'TOOL_CACHE')
process.env['RUNNER_TEMP'] = path.join(__dirname, 'TEMP') process.env['RUNNER_TEMP'] = path.join(__dirname, 'TEMP')
@ -52,11 +48,7 @@ test('find version/javaVersion', async () => {
} }
expect(error.message).toContain('Unable to find the latest Java version for') expect(error.message).toContain('Unable to find the latest Java version for')
const latestRelease = await getTaggedRelease( const latestRelease = await getTaggedRelease(GRAALVM_GH_USER, GRAALVM_RELEASES_REPO, 'vm-22.3.1')
GRAALVM_GH_USER,
GRAALVM_RELEASES_REPO,
'vm-22.3.1'
)
const latestVersion = findGraalVMVersion(latestRelease) const latestVersion = findGraalVMVersion(latestRelease)
expect(latestVersion).not.toBe('') expect(latestVersion).not.toBe('')
const latestJavaVersion = findHighestJavaVersion(latestRelease, latestVersion) const latestJavaVersion = findHighestJavaVersion(latestRelease, latestVersion)
@ -64,7 +56,7 @@ test('find version/javaVersion', async () => {
error = new Error('unexpected') error = new Error('unexpected')
try { try {
const invalidRelease = {...latestRelease, tag_name: 'invalid'} const invalidRelease = { ...latestRelease, tag_name: 'invalid' }
findGraalVMVersion(invalidRelease) findGraalVMVersion(invalidRelease)
} catch (err) { } catch (err) {
if (!(err instanceof Error)) { if (!(err instanceof Error)) {

View File

@ -2,7 +2,7 @@ import * as liberica from '../src/liberica'
import * as c from '../src/constants' import * as c from '../src/constants'
import * as path from 'path' import * as path from 'path'
import * as semver from 'semver' import * as semver from 'semver'
import {expect, test} from '@jest/globals' import { expect, test } from '@jest/globals'
process.env['RUNNER_TOOL_CACHE'] = path.join(__dirname, 'TOOL_CACHE') process.env['RUNNER_TOOL_CACHE'] = path.join(__dirname, 'TOOL_CACHE')
process.env['RUNNER_TEMP'] = path.join(__dirname, 'TEMP') process.env['RUNNER_TEMP'] = path.join(__dirname, 'TEMP')
@ -43,29 +43,15 @@ test('find asset URL', async () => {
if (!c.IS_LINUX) { if (!c.IS_LINUX) {
// This check can fail on Linux because there's no `jdk+fx` package for aarch64 and/or musl // This check can fail on Linux because there's no `jdk+fx` package for aarch64 and/or musl
await expectURL( await expectURL('21.0.2+14', 'jdk+fx', 'bellsoft-liberica-vm-full-openjdk21.0.2')
'21.0.2+14',
'jdk+fx',
'bellsoft-liberica-vm-full-openjdk21.0.2'
)
} }
}, 10000) }, 10000)
type verifier = ( type verifier = (version: string, major: number, minor: number, patch: number) => void
version: string,
major: number,
minor: number,
patch: number
) => void
function atLeast(expectedMinVersion: string): verifier { function atLeast(expectedMinVersion: string): verifier {
const expectedMajor = semver.major(expectedMinVersion) const expectedMajor = semver.major(expectedMinVersion)
return function ( return function (version: string, major: number, _minor: number, _patch: number) {
version: string,
major: number,
_minor: number,
_patch: number
) {
expect(major).toBe(expectedMajor) expect(major).toBe(expectedMajor)
if (semver.compareBuild(version, expectedMinVersion) < 0) { if (semver.compareBuild(version, expectedMinVersion) < 0) {
throw new Error(`Version ${version} is older than ${expectedMinVersion}`) throw new Error(`Version ${version} is older than ${expectedMinVersion}`)
@ -77,12 +63,7 @@ function upToBuild(expectedMinVersion: string): verifier {
const expectedMinor = semver.minor(expectedMinVersion) const expectedMinor = semver.minor(expectedMinVersion)
const expectedPatch = semver.patch(expectedMinVersion) const expectedPatch = semver.patch(expectedMinVersion)
const atLeastVerifier = atLeast(expectedMinVersion) const atLeastVerifier = atLeast(expectedMinVersion)
return function ( return function (version: string, major: number, minor: number, patch: number) {
version: string,
major: number,
minor: number,
patch: number
) {
atLeastVerifier(version, major, minor, patch) atLeastVerifier(version, major, minor, patch)
expect(minor).toBe(expectedMinor) expect(minor).toBe(expectedMinor)
expect(patch).toBe(expectedPatch) expect(patch).toBe(expectedPatch)
@ -90,12 +71,7 @@ function upToBuild(expectedMinVersion: string): verifier {
} }
function exactly(expectedVersion: string): verifier { function exactly(expectedVersion: string): verifier {
return function ( return function (version: string, _major: number, _minor: number, _patch: number) {
version: string,
_major: number,
_minor: number,
_patch: number
) {
if (semver.compareBuild(version, expectedVersion) != 0) { if (semver.compareBuild(version, expectedVersion) != 0) {
throw new Error(`Expected version ${expectedVersion} but got ${version}`) throw new Error(`Expected version ${expectedVersion} but got ${version}`)
} }
@ -114,24 +90,16 @@ async function expectLatestToBe(pattern: string, verify: verifier) {
async function expectLatestToFail(pattern: string) { async function expectLatestToFail(pattern: string) {
try { try {
const result = await liberica.findLatestLibericaJavaVersion(pattern) const result = await liberica.findLatestLibericaJavaVersion(pattern)
throw new Error( throw new Error(`findLatest(${pattern}) should have failed but returned ${result}`)
`findLatest(${pattern}) should have failed but returned ${result}`
)
} catch (err) { } catch (err) {
if (!(err instanceof Error)) { if (!(err instanceof Error)) {
throw new Error(`Unexpected non-Error: ${err}`) throw new Error(`Unexpected non-Error: ${err}`)
} }
expect(err.message).toContain( expect(err.message).toContain(`Unable to find the latest version for JDK${pattern}`)
`Unable to find the latest version for JDK${pattern}`
)
} }
} }
async function expectURL( async function expectURL(javaVersion: string, javaPackage: string, expectedPrefix: string) {
javaVersion: string,
javaPackage: string,
expectedPrefix: string
) {
const url = await liberica.findLibericaURL(javaVersion, javaPackage) const url = await liberica.findLibericaURL(javaVersion, javaPackage)
expect(url).toBeDefined() expect(url).toBeDefined()
const parts = url.split('/') const parts = url.split('/')

View File

@ -1,7 +1,7 @@
import * as path from 'path' import * as path from 'path'
import * as mandrel from '../src/mandrel' import * as mandrel from '../src/mandrel'
import {expect, test} from '@jest/globals' import { expect, test } from '@jest/globals'
import {getLatestRelease} from '../src/utils' import { getLatestRelease } from '../src/utils'
process.env['RUNNER_TOOL_CACHE'] = path.join(__dirname, 'TOOL_CACHE') process.env['RUNNER_TOOL_CACHE'] = path.join(__dirname, 'TOOL_CACHE')
process.env['RUNNER_TEMP'] = path.join(__dirname, 'TEMP') process.env['RUNNER_TEMP'] = path.join(__dirname, 'TEMP')

View File

@ -1,22 +1,13 @@
import * as path from 'path' import * as path from 'path'
import {expect, test} from '@jest/globals' import { expect, test } from '@jest/globals'
import {needsWindowsEnvironmentSetup} from '../src/msvc' import { needsWindowsEnvironmentSetup } from '../src/msvc'
import {VERSION_DEV, VERSION_LATEST} from '../src/constants' import { VERSION_DEV, VERSION_LATEST } from '../src/constants'
process.env['RUNNER_TOOL_CACHE'] = path.join(__dirname, 'TOOL_CACHE') process.env['RUNNER_TOOL_CACHE'] = path.join(__dirname, 'TOOL_CACHE')
process.env['RUNNER_TEMP'] = path.join(__dirname, 'TEMP') process.env['RUNNER_TEMP'] = path.join(__dirname, 'TEMP')
test('decide whether Window env must be set up for GraalVM for JDK', async () => { test('decide whether Window env must be set up for GraalVM for JDK', async () => {
for (const javaVersion of [ for (const javaVersion of ['17', '17.0.8', '17.0', '21', '22', '22-ea', '23-ea', VERSION_DEV]) {
'17',
'17.0.8',
'17.0',
'21',
'22',
'22-ea',
'23-ea',
VERSION_DEV
]) {
expect(needsWindowsEnvironmentSetup(javaVersion, '', true)).toBe(false) expect(needsWindowsEnvironmentSetup(javaVersion, '', true)).toBe(false)
} }
}) })
@ -29,8 +20,6 @@ test('decide whether Window env must be set up for legacy GraalVM', async () =>
['7', VERSION_DEV], ['7', VERSION_DEV],
['17', VERSION_LATEST] ['17', VERSION_LATEST]
]) { ]) {
expect( expect(needsWindowsEnvironmentSetup(combination[0], combination[1], false)).toBe(combination[1] !== VERSION_DEV)
needsWindowsEnvironmentSetup(combination[0], combination[1], false)
).toBe(combination[1] !== VERSION_DEV)
} }
}) })

View File

@ -1,11 +1,11 @@
import * as c from '../src/constants' import * as c from '../src/constants'
import {setUpSBOMSupport, processSBOM} from '../src/features/sbom' import { setUpSBOMSupport, processSBOM } from '../src/features/sbom'
import * as core from '@actions/core' import * as core from '@actions/core'
import * as github from '@actions/github' import * as github from '@actions/github'
import * as glob from '@actions/glob' import * as glob from '@actions/glob'
import {join} from 'path' import { join } from 'path'
import {tmpdir} from 'os' import { tmpdir } from 'os'
import {mkdtempSync, writeFileSync, rmSync} from 'fs' import { mkdtempSync, writeFileSync, rmSync } from 'fs'
jest.mock('@actions/glob') jest.mock('@actions/glob')
jest.mock('@actions/github', () => ({ jest.mock('@actions/github', () => ({
@ -37,9 +37,7 @@ function mockFindSBOM(files: string[]) {
function mockGithubAPIReturnValue(returnValue: Error | undefined = undefined) { function mockGithubAPIReturnValue(returnValue: Error | undefined = undefined) {
const mockOctokit = { const mockOctokit = {
request: request:
returnValue === undefined returnValue === undefined ? jest.fn().mockResolvedValue(returnValue) : jest.fn().mockRejectedValue(returnValue)
? jest.fn().mockResolvedValue(returnValue)
: jest.fn().mockRejectedValue(returnValue)
} }
;(github.getOctokit as jest.Mock).mockReturnValue(mockOctokit) ;(github.getOctokit as jest.Mock).mockReturnValue(mockOctokit)
return mockOctokit return mockOctokit
@ -48,10 +46,7 @@ function mockGithubAPIReturnValue(returnValue: Error | undefined = undefined) {
describe('sbom feature', () => { describe('sbom feature', () => {
let spyInfo: jest.SpyInstance<void, Parameters<typeof core.info>> let spyInfo: jest.SpyInstance<void, Parameters<typeof core.info>>
let spyWarning: jest.SpyInstance<void, Parameters<typeof core.warning>> let spyWarning: jest.SpyInstance<void, Parameters<typeof core.warning>>
let spyExportVariable: jest.SpyInstance< let spyExportVariable: jest.SpyInstance<void, Parameters<typeof core.exportVariable>>
void,
Parameters<typeof core.exportVariable>
>
let workspace: string let workspace: string
let originalEnv: NodeJS.ProcessEnv let originalEnv: NodeJS.ProcessEnv
const javaVersion = '24.0.0' const javaVersion = '24.0.0'
@ -71,9 +66,7 @@ describe('sbom feature', () => {
spyInfo = jest.spyOn(core, 'info').mockImplementation(() => null) spyInfo = jest.spyOn(core, 'info').mockImplementation(() => null)
spyWarning = jest.spyOn(core, 'warning').mockImplementation(() => null) spyWarning = jest.spyOn(core, 'warning').mockImplementation(() => null)
spyExportVariable = jest spyExportVariable = jest.spyOn(core, 'exportVariable').mockImplementation(() => null)
.spyOn(core, 'exportVariable')
.mockImplementation(() => null)
jest.spyOn(core, 'getInput').mockImplementation((name: string) => { jest.spyOn(core, 'getInput').mockImplementation((name: string) => {
if (name === 'native-image-enable-sbom') { if (name === 'native-image-enable-sbom') {
return 'true' return 'true'
@ -91,7 +84,7 @@ describe('sbom feature', () => {
spyInfo.mockRestore() spyInfo.mockRestore()
spyWarning.mockRestore() spyWarning.mockRestore()
spyExportVariable.mockRestore() spyExportVariable.mockRestore()
rmSync(workspace, {recursive: true, force: true}) rmSync(workspace, { recursive: true, force: true })
}) })
describe('setup', () => { describe('setup', () => {
@ -128,9 +121,7 @@ describe('sbom feature', () => {
c.NATIVE_IMAGE_OPTIONS_ENV, c.NATIVE_IMAGE_OPTIONS_ENV,
expect.stringContaining('--enable-sbom=export') expect.stringContaining('--enable-sbom=export')
) )
expect(spyInfo).toHaveBeenCalledWith( expect(spyInfo).toHaveBeenCalledWith('Enabled SBOM generation for Native Image build')
'Enabled SBOM generation for Native Image build'
)
expect(spyWarning).not.toHaveBeenCalled() expect(spyWarning).not.toHaveBeenCalled()
}) })
@ -202,17 +193,11 @@ describe('sbom feature', () => {
it('should process SBOM and display components', async () => { it('should process SBOM and display components', async () => {
await setUpAndProcessSBOM(sampleSBOM) await setUpAndProcessSBOM(sampleSBOM)
expect(spyInfo).toHaveBeenCalledWith( expect(spyInfo).toHaveBeenCalledWith('Found SBOM: ' + join(workspace, 'test.sbom.json'))
'Found SBOM: ' + join(workspace, 'test.sbom.json')
)
expect(spyInfo).toHaveBeenCalledWith('=== SBOM Content ===') expect(spyInfo).toHaveBeenCalledWith('=== SBOM Content ===')
expect(spyInfo).toHaveBeenCalledWith('- pkg:maven/org.json/json@20241224') expect(spyInfo).toHaveBeenCalledWith('- pkg:maven/org.json/json@20241224')
expect(spyInfo).toHaveBeenCalledWith( expect(spyInfo).toHaveBeenCalledWith('- pkg:maven/com.oracle/main-test-app@1.0-SNAPSHOT')
'- pkg:maven/com.oracle/main-test-app@1.0-SNAPSHOT' expect(spyInfo).toHaveBeenCalledWith(' depends on: pkg:maven/org.json/json@20241224')
)
expect(spyInfo).toHaveBeenCalledWith(
' depends on: pkg:maven/org.json/json@20241224'
)
expect(spyWarning).not.toHaveBeenCalled() expect(spyWarning).not.toHaveBeenCalled()
}) })
@ -284,8 +269,7 @@ describe('sbom feature', () => {
dependencies: [] dependencies: []
}), }),
'main-test-app': expect.objectContaining({ 'main-test-app': expect.objectContaining({
package_url: package_url: 'pkg:maven/com.oracle/main-test-app@1.0-SNAPSHOT',
'pkg:maven/com.oracle/main-test-app@1.0-SNAPSHOT',
dependencies: ['pkg:maven/org.json/json@20241224'] dependencies: ['pkg:maven/org.json/json@20241224']
}) })
}) })
@ -293,17 +277,13 @@ describe('sbom feature', () => {
}) })
}) })
) )
expect(spyInfo).toHaveBeenCalledWith( expect(spyInfo).toHaveBeenCalledWith('Dependency snapshot submitted successfully.')
'Dependency snapshot submitted successfully.'
)
}) })
it('should handle GitHub API submission errors gracefully', async () => { it('should handle GitHub API submission errors gracefully', async () => {
mockGithubAPIReturnValue(new Error('API submission failed')) mockGithubAPIReturnValue(new Error('API submission failed'))
await expect(setUpAndProcessSBOM(sampleSBOM)).rejects.toBeInstanceOf( await expect(setUpAndProcessSBOM(sampleSBOM)).rejects.toBeInstanceOf(Error)
Error
)
}) })
}) })
}) })

View File

@ -1,5 +1,5 @@
import {expect, test} from '@jest/globals' import { expect, test } from '@jest/globals'
import {toSemVer} from '../src/utils' import { toSemVer } from '../src/utils'
test('convert version', async () => { test('convert version', async () => {
for (const inputAndExpectedOutput of [ for (const inputAndExpectedOutput of [

View File

@ -22,7 +22,8 @@ inputs:
default: '' default: ''
github-token: github-token:
required: false required: false
description: 'Set it to secrets.GITHUB_TOKEN to increase rate limits when accessing the GitHub API. Defaults to github.token.' description:
'Set it to secrets.GITHUB_TOKEN to increase rate limits when accessing the GitHub API. Defaults to github.token.'
default: ${{ github.token }} default: ${{ github.token }}
set-java-home: set-java-home:
required: false required: false
@ -49,11 +50,14 @@ inputs:
default: 'false' default: 'false'
native-image-pr-reports-update-existing: native-image-pr-reports-update-existing:
required: false required: false
description: 'Instead of posting another comment, update an existing PR comment with the latest Native Image build report.' description:
'Instead of posting another comment, update an existing PR comment with the latest Native Image build report.'
default: 'false' default: 'false'
native-image-enable-sbom: native-image-enable-sbom:
required: false required: false
description: 'Automatically generate an SBOM and submit it to the GitHub dependency submission API for vulnerability and dependency tracking.' description:
'Automatically generate an SBOM and submit it to the GitHub dependency submission API for vulnerability and
dependency tracking.'
default: 'false' default: 'false'
version: version:
required: false required: false
@ -61,7 +65,8 @@ inputs:
default: '' default: ''
gds-token: gds-token:
required: false required: false
description: 'Download token for the GraalVM Download Service. If provided, the action will set up GraalVM Enterprise Edition.' description:
'Download token for the GraalVM Download Service. If provided, the action will set up GraalVM Enterprise Edition.'
outputs: outputs:
cache-hit: cache-hit:
description: 'A boolean value to indicate an exact match was found for the primary key' description: 'A boolean value to indicate an exact match was found for the primary key'

34
dist/cleanup.js generated vendored
View File

@ -78569,17 +78569,9 @@ const supportedPackageManager = [
}, },
{ {
id: 'gradle', id: 'gradle',
path: [ path: [join(os$1.homedir(), '.gradle', 'caches'), join(os$1.homedir(), '.gradle', 'wrapper')],
join(os$1.homedir(), '.gradle', 'caches'),
join(os$1.homedir(), '.gradle', 'wrapper')
],
// https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---gradle // https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---gradle
pattern: [ pattern: ['**/*.gradle*', '**/gradle-wrapper.properties', 'buildSrc/**/Versions.kt', 'buildSrc/**/Dependencies.kt']
'**/*.gradle*',
'**/gradle-wrapper.properties',
'buildSrc/**/Versions.kt',
'buildSrc/**/Dependencies.kt'
]
}, },
{ {
id: 'sbt', id: 'sbt',
@ -78592,11 +78584,7 @@ const supportedPackageManager = [
`!${join(os$1.homedir(), '.sbt', '*.lock')}`, `!${join(os$1.homedir(), '.sbt', '*.lock')}`,
`!${join(os$1.homedir(), '**', 'ivydata-*.properties')}` `!${join(os$1.homedir(), '**', 'ivydata-*.properties')}`
], ],
pattern: [ pattern: ['**/*.sbt', '**/project/build.properties', '**/project/**.{scala,sbt}']
'**/*.sbt',
'**/project/build.properties',
'**/project/**.{scala,sbt}'
]
} }
]; ];
function getCoursierCachePath() { function getCoursierCachePath() {
@ -78607,7 +78595,7 @@ function getCoursierCachePath() {
return join(os$1.homedir(), 'AppData', 'Local', 'Coursier', 'Cache'); return join(os$1.homedir(), 'AppData', 'Local', 'Coursier', 'Cache');
} }
function findPackageManager(id) { function findPackageManager(id) {
const packageManager = supportedPackageManager.find(pm => pm.id === id); const packageManager = supportedPackageManager.find((pm) => pm.id === id);
if (packageManager === undefined) { if (packageManager === undefined) {
throw new Error(`unknown package manager specified: ${id}`); throw new Error(`unknown package manager specified: ${id}`);
} }
@ -78658,8 +78646,7 @@ async function save(id) {
* @see {@link https://github.com/actions/cache/issues/454#issuecomment-840493935|why --no-daemon is necessary} * @see {@link https://github.com/actions/cache/issues/454#issuecomment-840493935|why --no-daemon is necessary}
*/ */
function isProbablyGradleDaemonProblem(packageManager, error) { function isProbablyGradleDaemonProblem(packageManager, error) {
if (packageManager.id !== 'gradle' || if (packageManager.id !== 'gradle' || process.env['RUNNER_OS'] !== 'Windows') {
process.env['RUNNER_OS'] !== 'Windows') {
return false; return false;
} }
const message = error.message || ''; const message = error.message || '';
@ -87864,7 +87851,7 @@ async function findExistingPRCommentId(bodyStartsWith) {
...context.repo, ...context.repo,
issue_number: context.payload.pull_request?.number issue_number: context.payload.pull_request?.number
}); });
const matchingComment = comments.reverse().find(comment => { const matchingComment = comments.reverse().find((comment) => {
return comment.body && comment.body.startsWith(bodyStartsWith); return comment.body && comment.body.startsWith(bodyStartsWith);
}); });
return matchingComment ? matchingComment.id : undefined; return matchingComment ? matchingComment.id : undefined;
@ -87964,10 +87951,7 @@ function createReport(data) {
objectCount = `${details.image_heap.objects.count.toLocaleString()} objects, `; objectCount = `${details.image_heap.objects.count.toLocaleString()} objects, `;
} }
const debugInfoBytes = details.debug_info ? details.debug_info.bytes : 0; const debugInfoBytes = details.debug_info ? details.debug_info.bytes : 0;
const otherBytes = details.total_bytes - const otherBytes = details.total_bytes - details.code_area.bytes - details.image_heap.bytes - debugInfoBytes;
details.code_area.bytes -
details.image_heap.bytes -
debugInfoBytes;
let debugInfoLine = ''; let debugInfoLine = '';
if (details.debug_info) { if (details.debug_info) {
debugInfoLine = ` debugInfoLine = `
@ -88232,9 +88216,9 @@ async function saveCache() {
* @returns Promise that will ignore error reported by the given promise * @returns Promise that will ignore error reported by the given promise
*/ */
async function ignoreErrors(promise) { async function ignoreErrors(promise) {
return new Promise(resolve => { return new Promise((resolve) => {
promise promise
.catch(error => { .catch((error) => {
coreExports.warning(error); coreExports.warning(error);
resolve(void 0); resolve(void 0);
}) })

2
dist/cleanup.js.map generated vendored

File diff suppressed because one or more lines are too long

76
dist/main.js generated vendored
View File

@ -36551,9 +36551,7 @@ const GitHubDotCom = Octokit.defaults({
async function exec(commandLine, args, options) { async function exec(commandLine, args, options) {
const exitCode = await execExports.exec(commandLine, args, options); const exitCode = await execExports.exec(commandLine, args, options);
if (exitCode !== 0) { if (exitCode !== 0) {
throw new Error(`'${[commandLine] throw new Error(`'${[commandLine].concat(args || []).join(' ')}' exited with a non-zero code: ${exitCode}`);
.concat(args || [])
.join(' ')}' exited with a non-zero code: ${exitCode}`);
} }
} }
async function getLatestRelease(repo) { async function getLatestRelease(repo) {
@ -36664,8 +36662,7 @@ function tmpfile(fileName) {
} }
function setNativeImageOption(javaVersionOrDev, optionValue) { function setNativeImageOption(javaVersionOrDev, optionValue) {
const coercedJavaVersionOrDev = semverExports.coerce(javaVersionOrDev); const coercedJavaVersionOrDev = semverExports.coerce(javaVersionOrDev);
if ((coercedJavaVersionOrDev && if ((coercedJavaVersionOrDev && semverExports.gte(coercedJavaVersionOrDev, '22.0.0')) ||
semverExports.gte(coercedJavaVersionOrDev, '22.0.0')) ||
javaVersionOrDev === VERSION_DEV || javaVersionOrDev === VERSION_DEV ||
javaVersionOrDev.endsWith('-ea')) { javaVersionOrDev.endsWith('-ea')) {
/* NATIVE_IMAGE_OPTIONS was introduced in GraalVM for JDK 22 (so were EA builds). */ /* NATIVE_IMAGE_OPTIONS was introduced in GraalVM for JDK 22 (so were EA builds). */
@ -36874,9 +36871,7 @@ async function downloadTool(url, userAgent, headers) {
}, (err) => { }, (err) => {
if (err instanceof HTTPError && err.httpStatusCode) { if (err instanceof HTTPError && err.httpStatusCode) {
// Don't retry anything less than 500, except 408 Request Timeout and 429 Too Many Requests // Don't retry anything less than 500, except 408 Request Timeout and 429 Too Many Requests
if (err.httpStatusCode < 500 && if (err.httpStatusCode < 500 && err.httpStatusCode !== 408 && err.httpStatusCode !== 429) {
err.httpStatusCode !== 408 &&
err.httpStatusCode !== 429) {
return false; return false;
} }
} }
@ -36994,9 +36989,7 @@ async function findLatestEABuildDownloadUrl(javaEaVersion) {
catch (error) { catch (error) {
throw new Error(`Unable to resolve download URL for '${javaEaVersion}' (reason: ${error}). Please make sure the java-version is set correctly. ${ERROR_HINT}`); throw new Error(`Unable to resolve download URL for '${javaEaVersion}' (reason: ${error}). Please make sure the java-version is set correctly. ${ERROR_HINT}`);
} }
if (Array.isArray(response) || if (Array.isArray(response) || response.type !== 'file' || !response.content) {
response.type !== 'file' ||
!response.content) {
throw new Error(`Unexpected response when resolving download URL for '${javaEaVersion}'. ${ERROR_REQUEST}`); throw new Error(`Unexpected response when resolving download URL for '${javaEaVersion}'. ${ERROR_REQUEST}`);
} }
const versionData = JSON.parse(Buffer.from(response.content, 'base64').toString('utf-8')); const versionData = JSON.parse(Buffer.from(response.content, 'base64').toString('utf-8'));
@ -37005,12 +36998,12 @@ async function findLatestEABuildDownloadUrl(javaEaVersion) {
latestVersion = versionData; latestVersion = versionData;
} }
else { else {
latestVersion = versionData.find(v => v.latest); latestVersion = versionData.find((v) => v.latest);
if (!latestVersion) { if (!latestVersion) {
throw new Error(`Unable to find latest version for '${javaEaVersion}'. ${ERROR_REQUEST}`); throw new Error(`Unable to find latest version for '${javaEaVersion}'. ${ERROR_REQUEST}`);
} }
} }
const file = latestVersion.files.find(f => f.arch === JDK_ARCH && f.platform === GRAALVM_PLATFORM); const file = latestVersion.files.find((f) => f.arch === JDK_ARCH && f.platform === GRAALVM_PLATFORM);
if (!file || !file.filename.startsWith('graalvm-jdk-')) { if (!file || !file.filename.startsWith('graalvm-jdk-')) {
throw new Error(`Unable to find file metadata for '${javaEaVersion}'. ${ERROR_REQUEST}`); throw new Error(`Unable to find file metadata for '${javaEaVersion}'. ${ERROR_REQUEST}`);
} }
@ -37039,8 +37032,7 @@ async function findLatestGraalVMJDKCEJavaVersion(majorJavaVersion) {
const versionNumberStartIndex = `refs/tags/${GRAALVM_JDK_TAG_PREFIX}`.length; const versionNumberStartIndex = `refs/tags/${GRAALVM_JDK_TAG_PREFIX}`.length;
for (const matchingRef of matchingRefs) { for (const matchingRef of matchingRefs) {
const currentVersion = matchingRef.ref.substring(versionNumberStartIndex); const currentVersion = matchingRef.ref.substring(versionNumberStartIndex);
if (semverExports.valid(currentVersion) && if (semverExports.valid(currentVersion) && semverExports.gt(currentVersion, highestVersion)) {
semverExports.gt(currentVersion, highestVersion)) {
highestVersion = currentVersion; highestVersion = currentVersion;
} }
} }
@ -88384,17 +88376,9 @@ const supportedPackageManager = [
}, },
{ {
id: 'gradle', id: 'gradle',
path: [ path: [join(os$1.homedir(), '.gradle', 'caches'), join(os$1.homedir(), '.gradle', 'wrapper')],
join(os$1.homedir(), '.gradle', 'caches'),
join(os$1.homedir(), '.gradle', 'wrapper')
],
// https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---gradle // https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---gradle
pattern: [ pattern: ['**/*.gradle*', '**/gradle-wrapper.properties', 'buildSrc/**/Versions.kt', 'buildSrc/**/Dependencies.kt']
'**/*.gradle*',
'**/gradle-wrapper.properties',
'buildSrc/**/Versions.kt',
'buildSrc/**/Dependencies.kt'
]
}, },
{ {
id: 'sbt', id: 'sbt',
@ -88407,11 +88391,7 @@ const supportedPackageManager = [
`!${join(os$1.homedir(), '.sbt', '*.lock')}`, `!${join(os$1.homedir(), '.sbt', '*.lock')}`,
`!${join(os$1.homedir(), '**', 'ivydata-*.properties')}` `!${join(os$1.homedir(), '**', 'ivydata-*.properties')}`
], ],
pattern: [ pattern: ['**/*.sbt', '**/project/build.properties', '**/project/**.{scala,sbt}']
'**/*.sbt',
'**/project/build.properties',
'**/project/**.{scala,sbt}'
]
} }
]; ];
function getCoursierCachePath() { function getCoursierCachePath() {
@ -88422,7 +88402,7 @@ function getCoursierCachePath() {
return join(os$1.homedir(), 'AppData', 'Local', 'Coursier', 'Cache'); return join(os$1.homedir(), 'AppData', 'Local', 'Coursier', 'Cache');
} }
function findPackageManager(id) { function findPackageManager(id) {
const packageManager = supportedPackageManager.find(pm => pm.id === id); const packageManager = supportedPackageManager.find((pm) => pm.id === id);
if (packageManager === undefined) { if (packageManager === undefined) {
throw new Error(`unknown package manager specified: ${id}`); throw new Error(`unknown package manager specified: ${id}`);
} }
@ -88470,10 +88450,7 @@ const COMPONENT_TO_DEPS = new Map([
new Map([ new Map([
['nodejs', `${APT_GET_INSTALL_BASE} g++ make`], ['nodejs', `${APT_GET_INSTALL_BASE} g++ make`],
['ruby', `${APT_GET_INSTALL_BASE} make gcc libssl-dev libz-dev`], ['ruby', `${APT_GET_INSTALL_BASE} make gcc libssl-dev libz-dev`],
[ ['R', `${APT_GET_INSTALL_BASE} libgomp1 build-essential gfortran libxml2 libc++-dev`]
'R',
`${APT_GET_INSTALL_BASE} libgomp1 build-essential gfortran libxml2 libc++-dev`
]
]) ])
], ],
['darwin', new Map([['ruby', 'brew install openssl']])] ['darwin', new Map([['ruby', 'brew install openssl']])]
@ -88669,8 +88646,7 @@ async function findLatestLibericaJavaVersion(javaVersion) {
const version = matchingRef.ref.substring(prefixLength); const version = matchingRef.ref.substring(prefixLength);
if (semverExports.valid(version) && if (semverExports.valid(version) &&
// pattern '17.0.1' should match '17.0.1+12' but not '17.0.10' // pattern '17.0.1' should match '17.0.1+12' but not '17.0.10'
(version.length <= patternLength || (version.length <= patternLength || !isDigit(version.charAt(patternLength))) &&
!isDigit(version.charAt(patternLength))) &&
semverExports.compareBuild(version, bestMatch) == 1) { semverExports.compareBuild(version, bestMatch) == 1) {
bestMatch = version; bestMatch = version;
} }
@ -88686,8 +88662,7 @@ async function findLibericaURL(javaVersion, javaPackage) {
const assetPrefix = `${LIBERICA_VM_PREFIX}${determineVariantPart(javaPackage)}openjdk${javaVersion}`; const assetPrefix = `${LIBERICA_VM_PREFIX}${determineVariantPart(javaPackage)}openjdk${javaVersion}`;
const assetSuffix = `-${platform}${GRAALVM_FILE_EXTENSION}`; const assetSuffix = `-${platform}${GRAALVM_FILE_EXTENSION}`;
for (const asset of release.assets) { for (const asset of release.assets) {
if (asset.name.startsWith(assetPrefix) && if (asset.name.startsWith(assetPrefix) && asset.name.endsWith(assetSuffix)) {
asset.name.endsWith(assetSuffix)) {
return asset.browser_download_url; return asset.browser_download_url;
} }
} }
@ -88727,8 +88702,7 @@ function checkForUpdates(graalVMVersion, javaVersion) {
coreExports.notice('A new GraalVM release is available! Please consider upgrading to GraalVM for JDK 21: https://medium.com/graalvm/graalvm-for-jdk-21-is-here-ee01177dd12d'); coreExports.notice('A new GraalVM release is available! Please consider upgrading to GraalVM for JDK 21: https://medium.com/graalvm/graalvm-for-jdk-21-is-here-ee01177dd12d');
return; return;
} }
if (graalVMVersion.length > 0 && if (graalVMVersion.length > 0 && (javaVersion === '17' || javaVersion === '19')) {
(javaVersion === '17' || javaVersion === '19')) {
const recommendedJDK = javaVersion === '17' ? '17' : '21'; const recommendedJDK = javaVersion === '17' ? '17' : '21';
coreExports.notice(`A new GraalVM release is available! Please consider upgrading to GraalVM for JDK ${recommendedJDK}. Instructions: https://github.com/graalvm/setup-graalvm#migrating-from-graalvm-223-or-earlier-to-the-new-graalvm-for-jdk-17-and-later`); coreExports.notice(`A new GraalVM release is available! Please consider upgrading to GraalVM for JDK ${recommendedJDK}. Instructions: https://github.com/graalvm/setup-graalvm#migrating-from-graalvm-223-or-earlier-to-the-new-graalvm-for-jdk-17-and-later`);
return; return;
@ -88813,7 +88787,9 @@ function setUpWindowsEnvironment(javaVersion, graalVMVersion, isGraalVMforJDK17O
coreExports.startGroup('Updating Windows environment...'); coreExports.startGroup('Updating Windows environment...');
const vcvarsallPath = findVcvarsallPath(); const vcvarsallPath = findVcvarsallPath();
coreExports.debug(`Calling "${vcvarsallPath}"...`); coreExports.debug(`Calling "${vcvarsallPath}"...`);
const [originalEnv, vcvarsallOutput, updatedEnv] = execSync(`set && cls && "${vcvarsallPath}" x64 && cls && set`, { shell: 'cmd' }) const [originalEnv, vcvarsallOutput, updatedEnv] = execSync(`set && cls && "${vcvarsallPath}" x64 && cls && set`, {
shell: 'cmd'
})
.toString() .toString()
.split('\f'); // form feed page break (printed by `cls`) .split('\f'); // form feed page break (printed by `cls`)
coreExports.debug(vcvarsallOutput); coreExports.debug(vcvarsallOutput);
@ -88854,8 +88830,7 @@ async function setUpNativeImageBuildReports(isGraalVMforJDK17OrLater, javaVersio
const isSupported = isGraalVMforJDK17OrLater || const isSupported = isGraalVMforJDK17OrLater ||
graalVMVersion === VERSION_LATEST || graalVMVersion === VERSION_LATEST ||
graalVMVersion === VERSION_DEV || graalVMVersion === VERSION_DEV ||
(!graalVMVersion.startsWith(MANDREL_NAMESPACE) && (!graalVMVersion.startsWith(MANDREL_NAMESPACE) && semverExports.gte(toSemVer(graalVMVersion), '22.2.0'));
semverExports.gte(toSemVer(graalVMVersion), '22.2.0'));
if (!isSupported) { if (!isSupported) {
coreExports.warning(`Build reports for PRs and job summaries are only available in GraalVM 22.2.0 or later. This build job uses GraalVM ${graalVMVersion}.`); coreExports.warning(`Build reports for PRs and job summaries are only available in GraalVM 22.2.0 or later. This build job uses GraalVM ${graalVMVersion}.`);
return; return;
@ -88908,9 +88883,7 @@ async function run() {
const graalVMVersion = coreExports.getInput(INPUT_VERSION); const graalVMVersion = coreExports.getInput(INPUT_VERSION);
const gdsToken = coreExports.getInput(INPUT_GDS_TOKEN); const gdsToken = coreExports.getInput(INPUT_GDS_TOKEN);
const componentsString = coreExports.getInput(INPUT_COMPONENTS); const componentsString = coreExports.getInput(INPUT_COMPONENTS);
const components = componentsString.length > 0 const components = componentsString.length > 0 ? componentsString.split(',').map((x) => x.trim()) : [];
? componentsString.split(',').map(x => x.trim())
: [];
const setJavaHome = coreExports.getInput(INPUT_SET_JAVA_HOME) === 'true'; const setJavaHome = coreExports.getInput(INPUT_SET_JAVA_HOME) === 'true';
const cache = coreExports.getInput(INPUT_CACHE); const cache = coreExports.getInput(INPUT_CACHE);
const enableCheckForUpdates = coreExports.getInput(INPUT_CHECK_FOR_UPDATES) === 'true'; const enableCheckForUpdates = coreExports.getInput(INPUT_CHECK_FOR_UPDATES) === 'true';
@ -88927,8 +88900,7 @@ async function run() {
let graalVMHome; let graalVMHome;
if (isGraalVMforJDK17OrLater) { if (isGraalVMforJDK17OrLater) {
if (enableCheckForUpdates && if (enableCheckForUpdates &&
(distribution === DISTRIBUTION_GRAALVM || (distribution === DISTRIBUTION_GRAALVM || distribution === DISTRIBUTION_GRAALVM_COMMUNITY)) {
distribution === DISTRIBUTION_GRAALVM_COMMUNITY)) {
checkForUpdates(graalVMVersion, javaVersion); checkForUpdates(graalVMVersion, javaVersion);
} }
switch (distribution) { switch (distribution) {
@ -88963,8 +88935,7 @@ async function run() {
switch (graalVMVersion) { switch (graalVMVersion) {
case VERSION_LATEST: case VERSION_LATEST:
if (javaVersion.startsWith('17') || if (javaVersion.startsWith('17') ||
(coercedJavaVersion !== null && (coercedJavaVersion !== null && semverExports.gte(coercedJavaVersion, '20.0.0'))) {
semverExports.gte(coercedJavaVersion, '20.0.0'))) {
coreExports.info(`This build is using the new Oracle GraalVM. To select a specific distribution, use the 'distribution' option (see https://github.com/graalvm/setup-graalvm/tree/main#options).`); coreExports.info(`This build is using the new Oracle GraalVM. To select a specific distribution, use the 'distribution' option (see https://github.com/graalvm/setup-graalvm/tree/main#options).`);
graalVMHome = await setUpGraalVMJDK(javaVersion, gdsToken); graalVMHome = await setUpGraalVMJDK(javaVersion, gdsToken);
} }
@ -88976,8 +88947,7 @@ async function run() {
if (gdsToken.length > 0) { if (gdsToken.length > 0) {
throw new Error('Downloading GraalVM EE dev builds is not supported'); throw new Error('Downloading GraalVM EE dev builds is not supported');
} }
if (coercedJavaVersion !== null && if (coercedJavaVersion !== null && !semverExports.gte(coercedJavaVersion, '21.0.0')) {
!semverExports.gte(coercedJavaVersion, '21.0.0')) {
coreExports.warning(`GraalVM dev builds are only available for JDK 21. This build is now using a stable release of GraalVM for JDK ${javaVersion}.`); coreExports.warning(`GraalVM dev builds are only available for JDK 21. This build is now using a stable release of GraalVM for JDK ${javaVersion}.`);
graalVMHome = await setUpGraalVMJDK(javaVersion, gdsToken); graalVMHome = await setUpGraalVMJDK(javaVersion, gdsToken);
} }

2
dist/main.js.map generated vendored

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
// See: https://eslint.org/docs/latest/use/configure/configuration-files // See: https://eslint.org/docs/latest/use/configure/configuration-files
import {fixupPluginRules} from '@eslint/compat' import { fixupPluginRules } from '@eslint/compat'
import {FlatCompat} from '@eslint/eslintrc' import { FlatCompat } from '@eslint/eslintrc'
import js from '@eslint/js' import js from '@eslint/js'
import typescriptEslint from '@typescript-eslint/eslint-plugin' import typescriptEslint from '@typescript-eslint/eslint-plugin'
import tsParser from '@typescript-eslint/parser' import tsParser from '@typescript-eslint/parser'
@ -10,7 +10,7 @@ import jest from 'eslint-plugin-jest'
import prettier from 'eslint-plugin-prettier' import prettier from 'eslint-plugin-prettier'
import globals from 'globals' import globals from 'globals'
import path from 'node:path' import path from 'node:path'
import {fileURLToPath} from 'node:url' import { fileURLToPath } from 'node:url'
const __filename = fileURLToPath(import.meta.url) const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename) const __dirname = path.dirname(__filename)
@ -70,7 +70,7 @@ export default [
camelcase: 'off', camelcase: 'off',
'eslint-comments/no-use': 'off', 'eslint-comments/no-use': 'off',
'eslint-comments/no-unused-disable': 'off', 'eslint-comments/no-unused-disable': 'off',
'@typescript-eslint/no-unused-vars': ['error', {argsIgnorePattern: '^_'}], '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'i18n-text/no-en': 'off', 'i18n-text/no-en': 'off',
'import/no-namespace': 'off', 'import/no-namespace': 'off',
'no-console': 'off', 'no-console': 'off',

View File

@ -26,4 +26,4 @@ export default {
] ]
}, },
verbose: true verbose: true
} }

View File

@ -26,9 +26,9 @@
import * as core from '@actions/core' import * as core from '@actions/core'
import * as constants from './constants.js' import * as constants from './constants.js'
import {save} from './features/cache.js' import { save } from './features/cache.js'
import {generateReports} from './features/reports.js' import { generateReports } from './features/reports.js'
import {processSBOM} from './features/sbom.js' import { processSBOM } from './features/sbom.js'
/** /**
* Check given input and run a save process for the specified package manager * Check given input and run a save process for the specified package manager
@ -46,9 +46,9 @@ async function saveCache(): Promise<void> {
* @returns Promise that will ignore error reported by the given promise * @returns Promise that will ignore error reported by the given promise
*/ */
async function ignoreErrors(promise: Promise<void>): Promise<unknown> { async function ignoreErrors(promise: Promise<void>): Promise<unknown> {
return new Promise(resolve => { return new Promise((resolve) => {
promise promise
.catch(error => { .catch((error) => {
core.warning(error) core.warning(error)
resolve(void 0) resolve(void 0)
}) })

View File

@ -48,23 +48,18 @@ export const GDS_GRAALVM_PRODUCT_ID = 'D53FAE8052773FFAE0530F15000AA6C6'
export const ENV_GITHUB_EVENT_NAME = 'GITHUB_EVENT_NAME' export const ENV_GITHUB_EVENT_NAME = 'GITHUB_EVENT_NAME'
export const EVENT_NAME_PULL_REQUEST = 'pull_request' export const EVENT_NAME_PULL_REQUEST = 'pull_request'
export const ERROR_REQUEST = export const ERROR_REQUEST = 'Please file an issue at: https://github.com/graalvm/setup-graalvm/issues.'
'Please file an issue at: https://github.com/graalvm/setup-graalvm/issues.'
export const ERROR_HINT = export const ERROR_HINT =
'If you think this is a mistake, please file an issue at: https://github.com/graalvm/setup-graalvm/issues.' 'If you think this is a mistake, please file an issue at: https://github.com/graalvm/setup-graalvm/issues.'
export type LatestReleaseResponse = export type LatestReleaseResponse = otypes.Endpoints['GET /repos/{owner}/{repo}/releases/latest']['response']
otypes.Endpoints['GET /repos/{owner}/{repo}/releases/latest']['response']
export type MatchingRefsResponse = export type MatchingRefsResponse = otypes.Endpoints['GET /repos/{owner}/{repo}/git/matching-refs/{ref}']['response']
otypes.Endpoints['GET /repos/{owner}/{repo}/git/matching-refs/{ref}']['response']
export type ReleasesResponse = export type ReleasesResponse = otypes.Endpoints['GET /repos/{owner}/{repo}/releases']['response']
otypes.Endpoints['GET /repos/{owner}/{repo}/releases']['response']
export type ContentsResponse = export type ContentsResponse = otypes.Endpoints['GET /repos/{owner}/{repo}/contents/{path}']['response']
otypes.Endpoints['GET /repos/{owner}/{repo}/contents/{path}']['response']
export interface OracleGraalVMEAFile { export interface OracleGraalVMEAFile {
filename: string filename: string

View File

@ -1,6 +1,6 @@
import * as core from '@actions/core' import * as core from '@actions/core'
import {GRAALVM_PLATFORM} from './constants.js' import { GRAALVM_PLATFORM } from './constants.js'
import {exec} from './utils.js' import { exec } from './utils.js'
const APT_GET_INSTALL_BASE = 'sudo apt-get -y --no-upgrade install' const APT_GET_INSTALL_BASE = 'sudo apt-get -y --no-upgrade install'
const COMPONENT_TO_DEPS = new Map<string, Map<string, string>>([ const COMPONENT_TO_DEPS = new Map<string, Map<string, string>>([
@ -9,10 +9,7 @@ const COMPONENT_TO_DEPS = new Map<string, Map<string, string>>([
new Map<string, string>([ new Map<string, string>([
['nodejs', `${APT_GET_INSTALL_BASE} g++ make`], ['nodejs', `${APT_GET_INSTALL_BASE} g++ make`],
['ruby', `${APT_GET_INSTALL_BASE} make gcc libssl-dev libz-dev`], ['ruby', `${APT_GET_INSTALL_BASE} make gcc libssl-dev libz-dev`],
[ ['R', `${APT_GET_INSTALL_BASE} libgomp1 build-essential gfortran libxml2 libc++-dev`]
'R',
`${APT_GET_INSTALL_BASE} libgomp1 build-essential gfortran libxml2 libc++-dev`
]
]) ])
], ],
['darwin', new Map<string, string>([['ruby', 'brew install openssl']])] ['darwin', new Map<string, string>([['ruby', 'brew install openssl']])]

View File

@ -26,7 +26,7 @@
* @fileoverview this file provides methods handling dependency cache * @fileoverview this file provides methods handling dependency cache
*/ */
import {join} from 'path' import { join } from 'path'
import os from 'os' import os from 'os'
import * as cache from '@actions/cache' import * as cache from '@actions/cache'
import * as core from '@actions/core' import * as core from '@actions/core'
@ -53,17 +53,9 @@ const supportedPackageManager: PackageManager[] = [
}, },
{ {
id: 'gradle', id: 'gradle',
path: [ path: [join(os.homedir(), '.gradle', 'caches'), join(os.homedir(), '.gradle', 'wrapper')],
join(os.homedir(), '.gradle', 'caches'),
join(os.homedir(), '.gradle', 'wrapper')
],
// https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---gradle // https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---gradle
pattern: [ pattern: ['**/*.gradle*', '**/gradle-wrapper.properties', 'buildSrc/**/Versions.kt', 'buildSrc/**/Dependencies.kt']
'**/*.gradle*',
'**/gradle-wrapper.properties',
'buildSrc/**/Versions.kt',
'buildSrc/**/Dependencies.kt'
]
}, },
{ {
id: 'sbt', id: 'sbt',
@ -76,23 +68,18 @@ const supportedPackageManager: PackageManager[] = [
`!${join(os.homedir(), '.sbt', '*.lock')}`, `!${join(os.homedir(), '.sbt', '*.lock')}`,
`!${join(os.homedir(), '**', 'ivydata-*.properties')}` `!${join(os.homedir(), '**', 'ivydata-*.properties')}`
], ],
pattern: [ pattern: ['**/*.sbt', '**/project/build.properties', '**/project/**.{scala,sbt}']
'**/*.sbt',
'**/project/build.properties',
'**/project/**.{scala,sbt}'
]
} }
] ]
function getCoursierCachePath(): string { function getCoursierCachePath(): string {
if (os.type() === 'Linux') return join(os.homedir(), '.cache', 'coursier') if (os.type() === 'Linux') return join(os.homedir(), '.cache', 'coursier')
if (os.type() === 'Darwin') if (os.type() === 'Darwin') return join(os.homedir(), 'Library', 'Caches', 'Coursier')
return join(os.homedir(), 'Library', 'Caches', 'Coursier')
return join(os.homedir(), 'AppData', 'Local', 'Coursier', 'Cache') return join(os.homedir(), 'AppData', 'Local', 'Coursier', 'Cache')
} }
function findPackageManager(id: string): PackageManager { function findPackageManager(id: string): PackageManager {
const packageManager = supportedPackageManager.find(pm => pm.id === id) const packageManager = supportedPackageManager.find((pm) => pm.id === id)
if (packageManager === undefined) { if (packageManager === undefined) {
throw new Error(`unknown package manager specified: ${id}`) throw new Error(`unknown package manager specified: ${id}`)
} }
@ -105,9 +92,7 @@ function findPackageManager(id: string): PackageManager {
* If there is no file matched to {@link PackageManager.path}, the generated key ends with a dash (-). * If there is no file matched to {@link PackageManager.path}, the generated key ends with a dash (-).
* @see {@link https://docs.github.com/en/actions/guides/caching-dependencies-to-speed-up-workflows#matching-a-cache-key|spec of cache key} * @see {@link https://docs.github.com/en/actions/guides/caching-dependencies-to-speed-up-workflows#matching-a-cache-key|spec of cache key}
*/ */
async function computeCacheKey( async function computeCacheKey(packageManager: PackageManager): Promise<string> {
packageManager: PackageManager
): Promise<string> {
const hash = await glob.hashFiles(packageManager.pattern.join('\n')) const hash = await glob.hashFiles(packageManager.pattern.join('\n'))
return `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${packageManager.id}-${hash}` return `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${packageManager.id}-${hash}`
} }
@ -158,9 +143,7 @@ export async function save(id: string): Promise<void> {
return return
} else if (matchedKey === primaryKey) { } else if (matchedKey === primaryKey) {
// no change in target directories // no change in target directories
core.info( core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`)
`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`
)
return return
} }
try { try {
@ -190,14 +173,8 @@ export async function save(id: string): Promise<void> {
* @returns true if the given error seems related to the {@link https://github.com/actions/cache/issues/454|running Gradle Daemon issue}. * @returns true if the given error seems related to the {@link https://github.com/actions/cache/issues/454|running Gradle Daemon issue}.
* @see {@link https://github.com/actions/cache/issues/454#issuecomment-840493935|why --no-daemon is necessary} * @see {@link https://github.com/actions/cache/issues/454#issuecomment-840493935|why --no-daemon is necessary}
*/ */
function isProbablyGradleDaemonProblem( function isProbablyGradleDaemonProblem(packageManager: PackageManager, error: Error): boolean {
packageManager: PackageManager, if (packageManager.id !== 'gradle' || process.env['RUNNER_OS'] !== 'Windows') {
error: Error
): boolean {
if (
packageManager.id !== 'gradle' ||
process.env['RUNNER_OS'] !== 'Windows'
) {
return false return false
} }
const message = error.message || '' const message = error.message || ''

View File

@ -1,19 +1,13 @@
import * as core from '@actions/core' import * as core from '@actions/core'
export function checkForUpdates( export function checkForUpdates(graalVMVersion: string, javaVersion: string): void {
graalVMVersion: string,
javaVersion: string
): void {
if (javaVersion === '20') { if (javaVersion === '20') {
core.notice( core.notice(
'A new GraalVM release is available! Please consider upgrading to GraalVM for JDK 21: https://medium.com/graalvm/graalvm-for-jdk-21-is-here-ee01177dd12d' 'A new GraalVM release is available! Please consider upgrading to GraalVM for JDK 21: https://medium.com/graalvm/graalvm-for-jdk-21-is-here-ee01177dd12d'
) )
return return
} }
if ( if (graalVMVersion.length > 0 && (javaVersion === '17' || javaVersion === '19')) {
graalVMVersion.length > 0 &&
(javaVersion === '17' || javaVersion === '19')
) {
const recommendedJDK = javaVersion === '17' ? '17' : '21' const recommendedJDK = javaVersion === '17' ? '17' : '21'
core.notice( core.notice(
`A new GraalVM release is available! Please consider upgrading to GraalVM for JDK ${recommendedJDK}. Instructions: https://github.com/graalvm/setup-graalvm#migrating-from-graalvm-223-or-earlier-to-the-new-graalvm-for-jdk-17-and-later` `A new GraalVM release is available! Please consider upgrading to GraalVM for JDK ${recommendedJDK}. Instructions: https://github.com/graalvm/setup-graalvm#migrating-from-graalvm-223-or-earlier-to-the-new-graalvm-for-jdk-17-and-later`

View File

@ -1,8 +1,8 @@
import * as c from '../constants.js' import * as c from '../constants.js'
import * as core from '@actions/core' import * as core from '@actions/core'
import * as tc from '@actions/tool-cache' import * as tc from '@actions/tool-cache'
import {exec} from '../utils.js' import { exec } from '../utils.js'
import {join} from 'path' import { join } from 'path'
const MUSL_NAME = 'x86_64-linux-musl-native' const MUSL_NAME = 'x86_64-linux-musl-native'
const MUSL_VERSION = '10.2.1' const MUSL_VERSION = '10.2.1'
@ -24,9 +24,7 @@ export async function setUpNativeImageMusl(): Promise<void> {
const muslPath = join(muslExtractPath, MUSL_NAME) const muslPath = join(muslExtractPath, MUSL_NAME)
const zlibCommit = 'ec3df00224d4b396e2ac6586ab5d25f673caa4c2' const zlibCommit = 'ec3df00224d4b396e2ac6586ab5d25f673caa4c2'
const zlibDownloadPath = await tc.downloadTool( const zlibDownloadPath = await tc.downloadTool(`https://github.com/madler/zlib/archive/${zlibCommit}.tar.gz`)
`https://github.com/madler/zlib/archive/${zlibCommit}.tar.gz`
)
const zlibExtractPath = await tc.extractTar(zlibDownloadPath) const zlibExtractPath = await tc.extractTar(zlibDownloadPath)
const zlibPath = join(zlibExtractPath, `zlib-${zlibCommit}`) const zlibPath = join(zlibExtractPath, `zlib-${zlibCommit}`)
const zlibBuildOptions = { const zlibBuildOptions = {
@ -36,13 +34,9 @@ export async function setUpNativeImageMusl(): Promise<void> {
CC: join(muslPath, 'bin', 'gcc') CC: join(muslPath, 'bin', 'gcc')
} }
} }
await exec( await exec('./configure', [`--prefix=${muslPath}`, '--static'], zlibBuildOptions)
'./configure',
[`--prefix=${muslPath}`, '--static'],
zlibBuildOptions
)
await exec('make', [], zlibBuildOptions) await exec('make', [], zlibBuildOptions)
await exec('make', ['install'], {cwd: zlibPath}) await exec('make', ['install'], { cwd: zlibPath })
core.info(`Adding ${MUSL_NAME} ${MUSL_VERSION} to tool-cache ...`) core.info(`Adding ${MUSL_NAME} ${MUSL_VERSION} to tool-cache ...`)
toolPath = await tc.cacheDir(muslPath, MUSL_NAME, MUSL_VERSION) toolPath = await tc.cacheDir(muslPath, MUSL_NAME, MUSL_VERSION)

View File

@ -17,8 +17,7 @@ const BUILD_OUTPUT_JSON_PATH = tmpfile('native-image-build-output.json')
const BYTES_TO_KiB = 1024 const BYTES_TO_KiB = 1024
const BYTES_TO_MiB = 1024 * 1024 const BYTES_TO_MiB = 1024 * 1024
const BYTES_TO_GiB = 1024 * 1024 * 1024 const BYTES_TO_GiB = 1024 * 1024 * 1024
const DOCS_BASE = const DOCS_BASE = 'https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/BuildOutput.md'
'https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/BuildOutput.md'
const INPUT_NI_JOB_REPORTS = 'native-image-job-reports' const INPUT_NI_JOB_REPORTS = 'native-image-job-reports'
const INPUT_NI_PR_REPORTS = 'native-image-pr-reports' const INPUT_NI_PR_REPORTS = 'native-image-pr-reports'
const INPUT_NI_PR_REPORTS_UPDATE = 'native-image-pr-reports-update-existing' const INPUT_NI_PR_REPORTS_UPDATE = 'native-image-pr-reports-update-existing'
@ -105,18 +104,14 @@ export async function setUpNativeImageBuildReports(
isGraalVMforJDK17OrLater || isGraalVMforJDK17OrLater ||
graalVMVersion === c.VERSION_LATEST || graalVMVersion === c.VERSION_LATEST ||
graalVMVersion === c.VERSION_DEV || graalVMVersion === c.VERSION_DEV ||
(!graalVMVersion.startsWith(c.MANDREL_NAMESPACE) && (!graalVMVersion.startsWith(c.MANDREL_NAMESPACE) && semver.gte(toSemVer(graalVMVersion), '22.2.0'))
semver.gte(toSemVer(graalVMVersion), '22.2.0'))
if (!isSupported) { if (!isSupported) {
core.warning( core.warning(
`Build reports for PRs and job summaries are only available in GraalVM 22.2.0 or later. This build job uses GraalVM ${graalVMVersion}.` `Build reports for PRs and job summaries are only available in GraalVM 22.2.0 or later. This build job uses GraalVM ${graalVMVersion}.`
) )
return return
} }
setNativeImageOption( setNativeImageOption(javaVersionOrDev, `-H:BuildOutputJSONFile=${BUILD_OUTPUT_JSON_PATH.replace(/\\/g, '\\\\')}`) // Escape backslashes for Windows
javaVersionOrDev,
`-H:BuildOutputJSONFile=${BUILD_OUTPUT_JSON_PATH.replace(/\\/g, '\\\\')}`
) // Escape backslashes for Windows
} }
export async function generateReports(): Promise<void> { export async function generateReports(): Promise<void> {
@ -127,9 +122,7 @@ export async function generateReports(): Promise<void> {
) )
return return
} }
const buildOutput: BuildOutput = JSON.parse( const buildOutput: BuildOutput = JSON.parse(fs.readFileSync(BUILD_OUTPUT_JSON_PATH, 'utf8'))
fs.readFileSync(BUILD_OUTPUT_JSON_PATH, 'utf8')
)
const report = createReport(buildOutput) const report = createReport(buildOutput)
if (areJobReportsEnabled()) { if (areJobReportsEnabled()) {
core.summary.addRaw(report) core.summary.addRaw(report)
@ -144,9 +137,7 @@ export async function generateReports(): Promise<void> {
} }
return createPRComment(report) return createPRComment(report)
} else if (arePRReportsUpdateEnabled()) { } else if (arePRReportsUpdateEnabled()) {
throw new Error( throw new Error(`'${INPUT_NI_PR_REPORTS_UPDATE}' option requires '${INPUT_NI_PR_REPORTS}' to be set 'true'`)
`'${INPUT_NI_PR_REPORTS_UPDATE}' option requires '${INPUT_NI_PR_REPORTS}' to be set 'true'`
)
} }
} }
} }
@ -174,11 +165,7 @@ function createReport(data: BuildOutput): string {
objectCount = `${details.image_heap.objects.count.toLocaleString()} objects, ` objectCount = `${details.image_heap.objects.count.toLocaleString()} objects, `
} }
const debugInfoBytes = details.debug_info ? details.debug_info.bytes : 0 const debugInfoBytes = details.debug_info ? details.debug_info.bytes : 0
const otherBytes = const otherBytes = details.total_bytes - details.code_area.bytes - details.image_heap.bytes - debugInfoBytes
details.total_bytes -
details.code_area.bytes -
details.image_heap.bytes -
debugInfoBytes
let debugInfoLine = '' let debugInfoLine = ''
if (details.debug_info) { if (details.debug_info) {
debugInfoLine = ` debugInfoLine = `
@ -210,8 +197,7 @@ function createReport(data: BuildOutput): string {
let graalLine let graalLine
if (info.graal_compiler) { if (info.graal_compiler) {
let pgoSuffix = '' let pgoSuffix = ''
const isOracleGraalVM = const isOracleGraalVM = info.vendor_version && info.vendor_version.includes('Oracle GraalVM')
info.vendor_version && info.vendor_version.includes('Oracle GraalVM')
if (isOracleGraalVM) { if (isOracleGraalVM) {
const pgo = info.graal_compiler.pgo const pgo = info.graal_compiler.pgo
const pgoText = pgo ? pgo.join('+') : 'off' const pgoText = pgo ? pgo.join('+') : 'off'
@ -233,10 +219,7 @@ function createReport(data: BuildOutput): string {
let gcTotalTimeRatio = '' let gcTotalTimeRatio = ''
if (resources.total_secs) { if (resources.total_secs) {
totalTime = ` in ${secondsToHuman(resources.total_secs)}` totalTime = ` in ${secondsToHuman(resources.total_secs)}`
gcTotalTimeRatio = ` (${toPercent( gcTotalTimeRatio = ` (${toPercent(resources.garbage_collection.total_secs, resources.total_secs)} of total time)`
resources.garbage_collection.total_secs,
resources.total_secs
)} of total time)`
} }
return `${PR_COMMENT_TITLE} return `${PR_COMMENT_TITLE}
@ -278,56 +261,29 @@ function createReport(data: BuildOutput): string {
<tr> <tr>
<td align="left"><a href="${DOCS_BASE}#glossary-reachability" target="_blank">Reachable</a></td> <td align="left"><a href="${DOCS_BASE}#glossary-reachability" target="_blank">Reachable</a></td>
<td align="right">${analysisTypes.reachable.toLocaleString()}</td> <td align="right">${analysisTypes.reachable.toLocaleString()}</td>
<td align="right">${toPercent( <td align="right">${toPercent(analysisTypes.reachable, analysisTypes.total)}</td>
analysisTypes.reachable,
analysisTypes.total
)}</td>
<td align="right">${analysis.fields.reachable.toLocaleString()}</td> <td align="right">${analysis.fields.reachable.toLocaleString()}</td>
<td align="right">${toPercent( <td align="right">${toPercent(analysis.fields.reachable, analysis.fields.total)}</td>
analysis.fields.reachable,
analysis.fields.total
)}</td>
<td align="right">${analysis.methods.reachable.toLocaleString()}</td> <td align="right">${analysis.methods.reachable.toLocaleString()}</td>
<td align="right">${toPercent( <td align="right">${toPercent(analysis.methods.reachable, analysis.methods.total)}</td>
analysis.methods.reachable,
analysis.methods.total
)}</td>
</tr> </tr>
<tr> <tr>
<td align="left"><a href="${DOCS_BASE}#glossary-reflection-registrations" target="_blank">Reflection</a></td> <td align="left"><a href="${DOCS_BASE}#glossary-reflection-registrations" target="_blank">Reflection</a></td>
<td align="right">${analysisTypes.reflection.toLocaleString()}</td> <td align="right">${analysisTypes.reflection.toLocaleString()}</td>
<td align="right">${toPercent( <td align="right">${toPercent(analysisTypes.reflection, analysisTypes.total)}</td>
analysisTypes.reflection,
analysisTypes.total
)}</td>
<td align="right">${analysis.fields.reflection.toLocaleString()}</td> <td align="right">${analysis.fields.reflection.toLocaleString()}</td>
<td align="right">${toPercent( <td align="right">${toPercent(analysis.fields.reflection, analysis.fields.total)}</td>
analysis.fields.reflection,
analysis.fields.total
)}</td>
<td align="right">${analysis.methods.reflection.toLocaleString()}</td> <td align="right">${analysis.methods.reflection.toLocaleString()}</td>
<td align="right">${toPercent( <td align="right">${toPercent(analysis.methods.reflection, analysis.methods.total)}</td>
analysis.methods.reflection,
analysis.methods.total
)}</td>
</tr> </tr>
<tr> <tr>
<td align="left"><a href="${DOCS_BASE}#glossary-jni-access-registrations" target="_blank">JNI</a></td> <td align="left"><a href="${DOCS_BASE}#glossary-jni-access-registrations" target="_blank">JNI</a></td>
<td align="right">${analysisTypes.jni.toLocaleString()}</td> <td align="right">${analysisTypes.jni.toLocaleString()}</td>
<td align="right">${toPercent( <td align="right">${toPercent(analysisTypes.jni, analysisTypes.total)}</td>
analysisTypes.jni,
analysisTypes.total
)}</td>
<td align="right">${analysis.fields.jni.toLocaleString()}</td> <td align="right">${analysis.fields.jni.toLocaleString()}</td>
<td align="right">${toPercent( <td align="right">${toPercent(analysis.fields.jni, analysis.fields.total)}</td>
analysis.fields.jni,
analysis.fields.total
)}</td>
<td align="right">${analysis.methods.jni.toLocaleString()}</td> <td align="right">${analysis.methods.jni.toLocaleString()}</td>
<td align="right">${toPercent( <td align="right">${toPercent(analysis.methods.jni, analysis.methods.total)}</td>
analysis.methods.jni,
analysis.methods.total
)}</td>
</tr> </tr>
<tr> <tr>
<td align="left"><a href="${DOCS_BASE}#glossary-reachability" target="_blank">Loaded</a></td> <td align="left"><a href="${DOCS_BASE}#glossary-reachability" target="_blank">Loaded</a></td>
@ -356,19 +312,13 @@ function createReport(data: BuildOutput): string {
<tr> <tr>
<td align="left"><a href="${DOCS_BASE}#glossary-code-area" target="_blank">Code area</a></td> <td align="left"><a href="${DOCS_BASE}#glossary-code-area" target="_blank">Code area</a></td>
<td align="right">${bytesToHuman(details.code_area.bytes)}</td> <td align="right">${bytesToHuman(details.code_area.bytes)}</td>
<td align="right">${toPercent( <td align="right">${toPercent(details.code_area.bytes, details.total_bytes)}</td>
details.code_area.bytes,
details.total_bytes
)}</td>
<td align="left">${details.code_area.compilation_units.toLocaleString()} compilation units</td> <td align="left">${details.code_area.compilation_units.toLocaleString()} compilation units</td>
</tr> </tr>
<tr> <tr>
<td align="left"><a href="${DOCS_BASE}#glossary-image-heap" target="_blank">Image heap</a></td> <td align="left"><a href="${DOCS_BASE}#glossary-image-heap" target="_blank">Image heap</a></td>
<td align="right">${bytesToHuman(details.image_heap.bytes)}</td> <td align="right">${bytesToHuman(details.image_heap.bytes)}</td>
<td align="right">${toPercent( <td align="right">${toPercent(details.image_heap.bytes, details.total_bytes)}</td>
details.image_heap.bytes,
details.total_bytes
)}</td>
<td align="left">${objectCount}${bytesToHuman( <td align="left">${objectCount}${bytesToHuman(
details.image_heap.resources.bytes details.image_heap.resources.bytes
)} for ${details.image_heap.resources.count.toLocaleString()} resources</td> )} for ${details.image_heap.resources.count.toLocaleString()} resources</td>
@ -381,9 +331,7 @@ function createReport(data: BuildOutput): string {
</tr> </tr>
<tr> <tr>
<td align="left">Total</td> <td align="left">Total</td>
<td align="right"><strong>${bytesToHuman( <td align="right"><strong>${bytesToHuman(details.total_bytes)}</strong></td>
details.total_bytes
)}</strong></td>
<td align="right">100.000%</td> <td align="right">100.000%</td>
<td align="left"></td> <td align="left"></td>
</tr> </tr>
@ -402,9 +350,7 @@ function createReport(data: BuildOutput): string {
</tr> </tr>
<tr> <tr>
<td align="left"><a href="${DOCS_BASE}#glossary-peak-rss" target="_blank">Peak RSS</a></td> <td align="left"><a href="${DOCS_BASE}#glossary-peak-rss" target="_blank">Peak RSS</a></td>
<td align="left">${bytesToHuman( <td align="left">${bytesToHuman(resources.memory.peak_rss_bytes)} (${toPercent(
resources.memory.peak_rss_bytes
)} (${toPercent(
resources.memory.peak_rss_bytes, resources.memory.peak_rss_bytes,
resources.memory.system_total resources.memory.system_total
)} of ${bytesToHuman(resources.memory.system_total)} system memory)</td> )} of ${bytesToHuman(resources.memory.system_total)} system memory)</td>

View File

@ -3,9 +3,9 @@ import * as core from '@actions/core'
import * as fs from 'fs' import * as fs from 'fs'
import * as github from '@actions/github' import * as github from '@actions/github'
import * as glob from '@actions/glob' import * as glob from '@actions/glob'
import {basename} from 'path' import { basename } from 'path'
import * as semver from 'semver' import * as semver from 'semver'
import {setNativeImageOption} from '../utils.js' import { setNativeImageOption } from '../utils.js'
const INPUT_NI_SBOM = 'native-image-enable-sbom' const INPUT_NI_SBOM = 'native-image-enable-sbom'
const SBOM_FILE_SUFFIX = '.sbom.json' const SBOM_FILE_SUFFIX = '.sbom.json'
@ -67,10 +67,7 @@ interface DependencySnapshot {
> >
} }
export function setUpSBOMSupport( export function setUpSBOMSupport(javaVersionOrDev: string, distribution: string): void {
javaVersionOrDev: string,
distribution: string
): void {
if (!isFeatureEnabled()) { if (!isFeatureEnabled()) {
return return
} }
@ -81,10 +78,7 @@ export function setUpSBOMSupport(
core.info('Enabled SBOM generation for Native Image build') core.info('Enabled SBOM generation for Native Image build')
} }
function validateJavaVersionAndDistribution( function validateJavaVersionAndDistribution(javaVersionOrDev: string, distribution: string): void {
javaVersionOrDev: string,
distribution: string
): void {
if (distribution !== c.DISTRIBUTION_GRAALVM) { if (distribution !== c.DISTRIBUTION_GRAALVM) {
throw new Error( throw new Error(
`The '${INPUT_NI_SBOM}' option is only supported for Oracle GraalVM (distribution '${c.DISTRIBUTION_GRAALVM}'), but found distribution '${distribution}'.` `The '${INPUT_NI_SBOM}' option is only supported for Oracle GraalVM (distribution '${c.DISTRIBUTION_GRAALVM}'), but found distribution '${distribution}'.`
@ -92,9 +86,7 @@ function validateJavaVersionAndDistribution(
} }
if (javaVersionOrDev === 'dev') { if (javaVersionOrDev === 'dev') {
throw new Error( throw new Error(`The '${INPUT_NI_SBOM}' option is not supported for java-version 'dev'.`)
`The '${INPUT_NI_SBOM}' option is not supported for java-version 'dev'.`
)
} }
if (javaVersionOrDev === 'latest-ea') { if (javaVersionOrDev === 'latest-ea') {
@ -142,15 +134,11 @@ async function findSBOMFilePath(): Promise<string> {
const sbomFiles = await globber.glob() const sbomFiles = await globber.glob()
if (sbomFiles.length === 0) { if (sbomFiles.length === 0) {
throw new Error( throw new Error('No SBOM found. Make sure native-image build completed successfully.')
'No SBOM found. Make sure native-image build completed successfully.'
)
} }
if (sbomFiles.length > 1) { if (sbomFiles.length > 1) {
throw new Error( throw new Error(`Expected one SBOM but found multiple: ${sbomFiles.join(', ')}.`)
`Expected one SBOM but found multiple: ${sbomFiles.join(', ')}.`
)
} }
core.info(`Found SBOM: ${sbomFiles[0]}`) core.info(`Found SBOM: ${sbomFiles[0]}`)
@ -162,9 +150,7 @@ function parseSBOM(jsonString: string): SBOM {
const sbomData: SBOM = JSON.parse(jsonString) const sbomData: SBOM = JSON.parse(jsonString)
return sbomData return sbomData
} catch (error) { } catch (error) {
throw new Error( throw new Error(`Failed to parse SBOM JSON: ${error instanceof Error ? error.message : String(error)}`)
`Failed to parse SBOM JSON: ${error instanceof Error ? error.message : String(error)}`
)
} }
} }
@ -175,10 +161,7 @@ function mapToComponentsWithDependencies(sbom: SBOM): Component[] {
} }
return sbom.components.map((component: Component) => { return sbom.components.map((component: Component) => {
const dependencies = const dependencies = sbom.dependencies?.find((dep: Dependency) => dep.ref === component['bom-ref'])?.dependsOn || []
sbom.dependencies?.find(
(dep: Dependency) => dep.ref === component['bom-ref']
)?.dependsOn || []
return { return {
name: component.name, name: component.name,
@ -201,17 +184,12 @@ function printSBOMContent(components: Component[]): void {
core.info('==================') core.info('==================')
} }
function convertSBOMToSnapshot( function convertSBOMToSnapshot(sbomPath: string, components: Component[]): DependencySnapshot {
sbomPath: string,
components: Component[]
): DependencySnapshot {
const context = github.context const context = github.context
const sbomFileName = basename(sbomPath) const sbomFileName = basename(sbomPath)
if (!sbomFileName.endsWith(SBOM_FILE_SUFFIX)) { if (!sbomFileName.endsWith(SBOM_FILE_SUFFIX)) {
throw new Error( throw new Error(`Invalid SBOM file name: ${sbomFileName}. Expected a file ending with ${SBOM_FILE_SUFFIX}.`)
`Invalid SBOM file name: ${sbomFileName}. Expected a file ending with ${SBOM_FILE_SUFFIX}.`
)
} }
return { return {
@ -244,18 +222,16 @@ function convertSBOMToSnapshot(
function mapComponentsToGithubAPIFormat( function mapComponentsToGithubAPIFormat(
components: Component[] components: Component[]
): Record<string, {package_url: string; dependencies?: string[]}> { ): Record<string, { package_url: string; dependencies?: string[] }> {
return Object.fromEntries( return Object.fromEntries(
components components
.filter(component => { .filter((component) => {
if (!component.purl) { if (!component.purl) {
core.info( core.info(`Component ${component.name} does not have a valid package URL (purl). Skipping.`)
`Component ${component.name} does not have a valid package URL (purl). Skipping.`
)
} }
return component.purl return component.purl
}) })
.map(component => [ .map((component) => [
component.name, component.name,
{ {
package_url: component.purl as string, package_url: component.purl as string,
@ -265,32 +241,27 @@ function mapComponentsToGithubAPIFormat(
) )
} }
async function submitDependencySnapshot( async function submitDependencySnapshot(snapshotData: DependencySnapshot): Promise<void> {
snapshotData: DependencySnapshot const token = core.getInput(c.INPUT_GITHUB_TOKEN, { required: true })
): Promise<void> {
const token = core.getInput(c.INPUT_GITHUB_TOKEN, {required: true})
const octokit = github.getOctokit(token) const octokit = github.getOctokit(token)
const context = github.context const context = github.context
try { try {
await octokit.request( await octokit.request('POST /repos/{owner}/{repo}/dependency-graph/snapshots', {
'POST /repos/{owner}/{repo}/dependency-graph/snapshots', owner: context.repo.owner,
{ repo: context.repo.repo,
owner: context.repo.owner, version: snapshotData.version,
repo: context.repo.repo, sha: snapshotData.sha,
version: snapshotData.version, ref: snapshotData.ref,
sha: snapshotData.sha, job: snapshotData.job,
ref: snapshotData.ref, detector: snapshotData.detector,
job: snapshotData.job, metadata: {},
detector: snapshotData.detector, scanned: snapshotData.scanned,
metadata: {}, manifests: snapshotData.manifests,
scanned: snapshotData.scanned, headers: {
manifests: snapshotData.manifests, 'X-GitHub-Api-Version': '2022-11-28'
headers: {
'X-GitHub-Api-Version': '2022-11-28'
}
} }
) })
core.info('Dependency snapshot submitted successfully.') core.info('Dependency snapshot submitted successfully.')
} catch (error) { } catch (error) {
throw new Error( throw new Error(

View File

@ -7,11 +7,11 @@ import * as path from 'path'
import * as stream from 'stream' import * as stream from 'stream'
import * as util from 'util' import * as util from 'util'
import * as semver from 'semver' import * as semver from 'semver'
import {IncomingHttpHeaders, OutgoingHttpHeaders} from 'http' import { IncomingHttpHeaders, OutgoingHttpHeaders } from 'http'
import {RetryHelper} from '@actions/tool-cache/lib/retry-helper.js' import { RetryHelper } from '@actions/tool-cache/lib/retry-helper.js'
import {calculateSHA256} from './utils.js' import { calculateSHA256 } from './utils.js'
import {ok} from 'assert' import { ok } from 'assert'
import {v4 as uuidv4} from 'uuid' import { v4 as uuidv4 } from 'uuid'
interface GDSArtifactsResponse { interface GDSArtifactsResponse {
readonly items: GDSArtifact[] readonly items: GDSArtifact[]
@ -27,39 +27,19 @@ interface GDSErrorResponse {
readonly message: string readonly message: string
} }
export async function downloadGraalVM( export async function downloadGraalVM(gdsToken: string, javaVersion: string): Promise<string> {
gdsToken: string,
javaVersion: string
): Promise<string> {
const userAgent = `GraalVMGitHubAction/${c.ACTION_VERSION} (arch:${c.GRAALVM_ARCH}; os:${c.GRAALVM_PLATFORM}; java:${javaVersion})` const userAgent = `GraalVMGitHubAction/${c.ACTION_VERSION} (arch:${c.GRAALVM_ARCH}; os:${c.GRAALVM_PLATFORM}; java:${javaVersion})`
const baseArtifact = await fetchArtifact( const baseArtifact = await fetchArtifact(userAgent, 'isBase:True', javaVersion)
userAgent,
'isBase:True',
javaVersion
)
return downloadArtifact(gdsToken, userAgent, baseArtifact) return downloadArtifact(gdsToken, userAgent, baseArtifact)
} }
export async function downloadGraalVMEELegacy( export async function downloadGraalVMEELegacy(gdsToken: string, version: string, javaVersion: string): Promise<string> {
gdsToken: string,
version: string,
javaVersion: string
): Promise<string> {
const userAgent = `GraalVMGitHubAction/${c.ACTION_VERSION} (arch:${c.GRAALVM_ARCH}; os:${c.GRAALVM_PLATFORM}; java:${javaVersion})` const userAgent = `GraalVMGitHubAction/${c.ACTION_VERSION} (arch:${c.GRAALVM_ARCH}; os:${c.GRAALVM_PLATFORM}; java:${javaVersion})`
const baseArtifact = await fetchArtifactEE( const baseArtifact = await fetchArtifactEE(userAgent, 'isBase:True', version, javaVersion)
userAgent,
'isBase:True',
version,
javaVersion
)
return downloadArtifact(gdsToken, userAgent, baseArtifact) return downloadArtifact(gdsToken, userAgent, baseArtifact)
} }
export async function fetchArtifact( export async function fetchArtifact(userAgent: string, metadata: string, javaVersion: string): Promise<GDSArtifact> {
userAgent: string,
metadata: string,
javaVersion: string
): Promise<GDSArtifact> {
const http = new httpClient.HttpClient(userAgent) const http = new httpClient.HttpClient(userAgent)
let filter let filter
@ -79,15 +59,13 @@ export async function fetchArtifact(
const catalogOS = c.IS_MACOS ? 'macos' : c.GRAALVM_PLATFORM const catalogOS = c.IS_MACOS ? 'macos' : c.GRAALVM_PLATFORM
const requestUrl = `${c.GDS_BASE}/artifacts?productId=${c.GDS_GRAALVM_PRODUCT_ID}&displayName=Oracle%20GraalVM&${filter}&metadata=java:jdk${majorJavaVersion}&metadata=os:${catalogOS}&metadata=arch:${c.GRAALVM_ARCH}&metadata=${metadata}&status=PUBLISHED&responseFields=id&responseFields=checksum` const requestUrl = `${c.GDS_BASE}/artifacts?productId=${c.GDS_GRAALVM_PRODUCT_ID}&displayName=Oracle%20GraalVM&${filter}&metadata=java:jdk${majorJavaVersion}&metadata=os:${catalogOS}&metadata=arch:${c.GRAALVM_ARCH}&metadata=${metadata}&status=PUBLISHED&responseFields=id&responseFields=checksum`
core.debug(`Requesting ${requestUrl}`) core.debug(`Requesting ${requestUrl}`)
const response = await http.get(requestUrl, {accept: 'application/json'}) const response = await http.get(requestUrl, { accept: 'application/json' })
if (response.message.statusCode !== 200) { if (response.message.statusCode !== 200) {
throw new Error( throw new Error(
`Unable to find GraalVM for JDK ${javaVersion}. Are you sure java-version: '${javaVersion}' is correct?` `Unable to find GraalVM for JDK ${javaVersion}. Are you sure java-version: '${javaVersion}' is correct?`
) )
} }
const artifactResponse = JSON.parse( const artifactResponse = JSON.parse(await response.readBody()) as GDSArtifactsResponse
await response.readBody()
) as GDSArtifactsResponse
if (artifactResponse.items.length !== 1) { if (artifactResponse.items.length !== 1) {
throw new Error( throw new Error(
artifactResponse.items.length > 1 artifactResponse.items.length > 1
@ -116,15 +94,11 @@ export async function fetchArtifactEE(
const catalogOS = c.IS_MACOS ? 'macos' : c.GRAALVM_PLATFORM const catalogOS = c.IS_MACOS ? 'macos' : c.GRAALVM_PLATFORM
const requestUrl = `${c.GDS_BASE}/artifacts?productId=${c.GDS_GRAALVM_PRODUCT_ID}&${filter}&metadata=java:jdk${javaVersion}&metadata=os:${catalogOS}&metadata=arch:${c.GRAALVM_ARCH}&metadata=${metadata}&status=PUBLISHED&responseFields=id&responseFields=checksum` const requestUrl = `${c.GDS_BASE}/artifacts?productId=${c.GDS_GRAALVM_PRODUCT_ID}&${filter}&metadata=java:jdk${javaVersion}&metadata=os:${catalogOS}&metadata=arch:${c.GRAALVM_ARCH}&metadata=${metadata}&status=PUBLISHED&responseFields=id&responseFields=checksum`
core.debug(`Requesting ${requestUrl}`) core.debug(`Requesting ${requestUrl}`)
const response = await http.get(requestUrl, {accept: 'application/json'}) const response = await http.get(requestUrl, { accept: 'application/json' })
if (response.message.statusCode !== 200) { if (response.message.statusCode !== 200) {
throw new Error( throw new Error(`Unable to find JDK${javaVersion}-based GraalVM EE ${version}`)
`Unable to find JDK${javaVersion}-based GraalVM EE ${version}`
)
} }
const artifactResponse = JSON.parse( const artifactResponse = JSON.parse(await response.readBody()) as GDSArtifactsResponse
await response.readBody()
) as GDSArtifactsResponse
if (artifactResponse.items.length !== 1) { if (artifactResponse.items.length !== 1) {
throw new Error( throw new Error(
artifactResponse.items.length > 1 artifactResponse.items.length > 1
@ -135,21 +109,13 @@ export async function fetchArtifactEE(
return artifactResponse.items[0] return artifactResponse.items[0]
} }
async function downloadArtifact( async function downloadArtifact(gdsToken: string, userAgent: string, artifact: GDSArtifact): Promise<string> {
gdsToken: string,
userAgent: string,
artifact: GDSArtifact
): Promise<string> {
let downloadPath let downloadPath
try { try {
downloadPath = await downloadTool( downloadPath = await downloadTool(`${c.GDS_BASE}/artifacts/${artifact.id}/content`, userAgent, {
`${c.GDS_BASE}/artifacts/${artifact.id}/content`, accept: 'application/x-yaml',
userAgent, 'x-download-token': gdsToken
{ })
accept: 'application/x-yaml',
'x-download-token': gdsToken
}
)
} catch (err) { } catch (err) {
if (err instanceof HTTPError && err.httpStatusCode) { if (err instanceof HTTPError && err.httpStatusCode) {
if (err.httpStatusCode === 401) { if (err.httpStatusCode === 401) {
@ -162,9 +128,7 @@ async function downloadArtifact(
} }
const sha256 = calculateSHA256(downloadPath) const sha256 = calculateSHA256(downloadPath)
if (sha256.toLowerCase() !== artifact.checksum.toLowerCase()) { if (sha256.toLowerCase() !== artifact.checksum.toLowerCase()) {
throw new Error( throw new Error(`Checksum does not match (expected: "${artifact.checksum}", got: "${sha256}")`)
`Checksum does not match (expected: "${artifact.checksum}", got: "${sha256}")`
)
} }
return downloadPath return downloadPath
} }
@ -185,11 +149,7 @@ class HTTPError extends Error {
} }
} }
async function downloadTool( async function downloadTool(url: string, userAgent: string, headers?: OutgoingHttpHeaders): Promise<string> {
url: string,
userAgent: string,
headers?: OutgoingHttpHeaders
): Promise<string> {
const dest = path.join(getTempDirectory(), uuidv4()) const dest = path.join(getTempDirectory(), uuidv4())
await io.mkdirP(path.dirname(dest)) await io.mkdirP(path.dirname(dest))
core.debug(`Downloading ${url}`) core.debug(`Downloading ${url}`)
@ -206,11 +166,7 @@ async function downloadTool(
(err: Error) => { (err: Error) => {
if (err instanceof HTTPError && err.httpStatusCode) { if (err instanceof HTTPError && err.httpStatusCode) {
// Don't retry anything less than 500, except 408 Request Timeout and 429 Too Many Requests // Don't retry anything less than 500, except 408 Request Timeout and 429 Too Many Requests
if ( if (err.httpStatusCode < 500 && err.httpStatusCode !== 408 && err.httpStatusCode !== 429) {
err.httpStatusCode < 500 &&
err.httpStatusCode !== 408 &&
err.httpStatusCode !== 429
) {
return false return false
} }
} }
@ -238,14 +194,8 @@ async function downloadToolAttempt(
const response: httpClient.HttpClientResponse = await http.get(url, headers) const response: httpClient.HttpClientResponse = await http.get(url, headers)
if (response.message.statusCode !== 200) { if (response.message.statusCode !== 200) {
const errorResponse = JSON.parse( const errorResponse = JSON.parse(await response.readBody()) as GDSErrorResponse
await response.readBody() const err = new HTTPError(response.message.statusCode, errorResponse, response.message.headers)
) as GDSErrorResponse
const err = new HTTPError(
response.message.statusCode,
errorResponse,
response.message.headers
)
core.debug( core.debug(
`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})` `Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`
) )

View File

@ -9,9 +9,9 @@ import {
getMatchingTags, getMatchingTags,
getTaggedRelease getTaggedRelease
} from './utils.js' } from './utils.js'
import {downloadGraalVM, downloadGraalVMEELegacy} from './gds.js' import { downloadGraalVM, downloadGraalVMEELegacy } from './gds.js'
import {downloadTool} from '@actions/tool-cache' import { downloadTool } from '@actions/tool-cache'
import {basename} from 'path' import { basename } from 'path'
const GRAALVM_DL_BASE = 'https://download.oracle.com/graalvm' const GRAALVM_DL_BASE = 'https://download.oracle.com/graalvm'
const GRAALVM_CE_DL_BASE = `https://github.com/graalvm/${c.GRAALVM_RELEASES_REPO}/releases/download` const GRAALVM_CE_DL_BASE = `https://github.com/graalvm/${c.GRAALVM_RELEASES_REPO}/releases/download`
@ -23,10 +23,7 @@ const GRAALVM_TAG_PREFIX = 'vm-'
// Support for GraalVM for JDK 17 and later // Support for GraalVM for JDK 17 and later
export async function setUpGraalVMJDK( export async function setUpGraalVMJDK(javaVersionOrDev: string, gdsToken: string): Promise<string> {
javaVersionOrDev: string,
gdsToken: string
): Promise<string> {
if (javaVersionOrDev === c.VERSION_DEV) { if (javaVersionOrDev === c.VERSION_DEV) {
return setUpGraalVMJDKDevBuild() return setUpGraalVMJDKDevBuild()
} }
@ -52,9 +49,7 @@ export async function setUpGraalVMJDK(
const filename = basename(downloadUrl) const filename = basename(downloadUrl)
const resolvedVersion = semver.valid(semver.coerce(filename)) const resolvedVersion = semver.valid(semver.coerce(filename))
if (!resolvedVersion) { if (!resolvedVersion) {
throw new Error( throw new Error(`Unable to determine resolved version based on '${filename}'. ${c.ERROR_REQUEST}`)
`Unable to determine resolved version based on '${filename}'. ${c.ERROR_REQUEST}`
)
} }
javaVersion = resolvedVersion javaVersion = resolvedVersion
} else if (javaVersion.includes('.')) { } else if (javaVersion.includes('.')) {
@ -80,9 +75,7 @@ export async function setUpGraalVMJDK(
return downloadExtractAndCacheJDK(downloader, toolName, javaVersion) return downloadExtractAndCacheJDK(downloader, toolName, javaVersion)
} }
export async function findLatestEABuildDownloadUrl( export async function findLatestEABuildDownloadUrl(javaEaVersion: string): Promise<string> {
javaEaVersion: string
): Promise<string> {
const filePath = `versions/${javaEaVersion}.json` const filePath = `versions/${javaEaVersion}.json`
let response let response
try { try {
@ -92,45 +85,27 @@ export async function findLatestEABuildDownloadUrl(
`Unable to resolve download URL for '${javaEaVersion}' (reason: ${error}). Please make sure the java-version is set correctly. ${c.ERROR_HINT}` `Unable to resolve download URL for '${javaEaVersion}' (reason: ${error}). Please make sure the java-version is set correctly. ${c.ERROR_HINT}`
) )
} }
if ( if (Array.isArray(response) || response.type !== 'file' || !response.content) {
Array.isArray(response) || throw new Error(`Unexpected response when resolving download URL for '${javaEaVersion}'. ${c.ERROR_REQUEST}`)
response.type !== 'file' ||
!response.content
) {
throw new Error(
`Unexpected response when resolving download URL for '${javaEaVersion}'. ${c.ERROR_REQUEST}`
)
} }
const versionData = JSON.parse( const versionData = JSON.parse(Buffer.from(response.content, 'base64').toString('utf-8'))
Buffer.from(response.content, 'base64').toString('utf-8')
)
let latestVersion let latestVersion
if (javaEaVersion === ORACLE_GRAALVM_REPO_EA_BUILDS_LATEST_SYMBOL) { if (javaEaVersion === ORACLE_GRAALVM_REPO_EA_BUILDS_LATEST_SYMBOL) {
latestVersion = versionData as c.OracleGraalVMEAVersion latestVersion = versionData as c.OracleGraalVMEAVersion
} else { } else {
latestVersion = (versionData as c.OracleGraalVMEAVersion[]).find( latestVersion = (versionData as c.OracleGraalVMEAVersion[]).find((v) => v.latest)
v => v.latest
)
if (!latestVersion) { if (!latestVersion) {
throw new Error( throw new Error(`Unable to find latest version for '${javaEaVersion}'. ${c.ERROR_REQUEST}`)
`Unable to find latest version for '${javaEaVersion}'. ${c.ERROR_REQUEST}`
)
} }
} }
const file = latestVersion.files.find( const file = latestVersion.files.find((f) => f.arch === c.JDK_ARCH && f.platform === c.GRAALVM_PLATFORM)
f => f.arch === c.JDK_ARCH && f.platform === c.GRAALVM_PLATFORM
)
if (!file || !file.filename.startsWith('graalvm-jdk-')) { if (!file || !file.filename.startsWith('graalvm-jdk-')) {
throw new Error( throw new Error(`Unable to find file metadata for '${javaEaVersion}'. ${c.ERROR_REQUEST}`)
`Unable to find file metadata for '${javaEaVersion}'. ${c.ERROR_REQUEST}`
)
} }
return `${latestVersion.download_base_url}${file.filename}` return `${latestVersion.download_base_url}${file.filename}`
} }
export async function setUpGraalVMJDKCE( export async function setUpGraalVMJDKCE(javaVersionOrDev: string): Promise<string> {
javaVersionOrDev: string
): Promise<string> {
if (javaVersionOrDev === c.VERSION_DEV) { if (javaVersionOrDev === c.VERSION_DEV) {
return setUpGraalVMJDKDevBuild() return setUpGraalVMJDKDevBuild()
} }
@ -149,9 +124,7 @@ export async function setUpGraalVMJDKCE(
return downloadExtractAndCacheJDK(downloader, toolName, javaVersion) return downloadExtractAndCacheJDK(downloader, toolName, javaVersion)
} }
export async function findLatestGraalVMJDKCEJavaVersion( export async function findLatestGraalVMJDKCEJavaVersion(majorJavaVersion: string): Promise<string> {
majorJavaVersion: string
): Promise<string> {
const matchingRefs = await getMatchingTags( const matchingRefs = await getMatchingTags(
c.GRAALVM_GH_USER, c.GRAALVM_GH_USER,
c.GRAALVM_RELEASES_REPO, c.GRAALVM_RELEASES_REPO,
@ -162,10 +135,7 @@ export async function findLatestGraalVMJDKCEJavaVersion(
const versionNumberStartIndex = `refs/tags/${GRAALVM_JDK_TAG_PREFIX}`.length const versionNumberStartIndex = `refs/tags/${GRAALVM_JDK_TAG_PREFIX}`.length
for (const matchingRef of matchingRefs) { for (const matchingRef of matchingRefs) {
const currentVersion = matchingRef.ref.substring(versionNumberStartIndex) const currentVersion = matchingRef.ref.substring(versionNumberStartIndex)
if ( if (semver.valid(currentVersion) && semver.gt(currentVersion, highestVersion)) {
semver.valid(currentVersion) &&
semver.gt(currentVersion, highestVersion)
) {
highestVersion = currentVersion highestVersion = currentVersion
} }
} }
@ -178,29 +148,20 @@ export async function findLatestGraalVMJDKCEJavaVersion(
} }
function determineToolName(javaVersion: string, isCommunity: boolean) { function determineToolName(javaVersion: string, isCommunity: boolean) {
return `graalvm${isCommunity ? '-community' : ''}-jdk-${javaVersion}_${ return `graalvm${isCommunity ? '-community' : ''}-jdk-${javaVersion}_${c.JDK_PLATFORM}-${c.JDK_ARCH}_bin`
c.JDK_PLATFORM
}-${c.JDK_ARCH}_bin`
} }
async function downloadGraalVMJDK( async function downloadGraalVMJDK(downloadUrl: string, javaVersion: string): Promise<string> {
downloadUrl: string,
javaVersion: string
): Promise<string> {
try { try {
return await downloadTool(downloadUrl) return await downloadTool(downloadUrl)
} catch (error) { } catch (error) {
if (error instanceof Error && error.message.includes('404')) { if (error instanceof Error && error.message.includes('404')) {
// Not Found // Not Found
throw new Error( throw new Error(
`Failed to download ${basename( `Failed to download ${basename(downloadUrl)}. Are you sure java-version: '${javaVersion}' is correct?`
downloadUrl
)}. Are you sure java-version: '${javaVersion}' is correct?`
) )
} }
throw new Error( throw new Error(`Failed to download ${basename(downloadUrl)} (error: ${error}).`)
`Failed to download ${basename(downloadUrl)} (error: ${error}).`
)
} }
} }
@ -208,28 +169,15 @@ async function downloadGraalVMJDK(
export async function setUpGraalVMJDKDevBuild(): Promise<string> { export async function setUpGraalVMJDKDevBuild(): Promise<string> {
const latestDevBuild = await getLatestRelease(GRAALVM_REPO_DEV_BUILDS) const latestDevBuild = await getLatestRelease(GRAALVM_REPO_DEV_BUILDS)
const resolvedJavaVersion = findHighestJavaVersion( const resolvedJavaVersion = findHighestJavaVersion(latestDevBuild, c.VERSION_DEV)
latestDevBuild,
c.VERSION_DEV
)
const downloadUrl = findDownloadUrl(latestDevBuild, resolvedJavaVersion) const downloadUrl = findDownloadUrl(latestDevBuild, resolvedJavaVersion)
return downloadAndExtractJDK(downloadUrl) return downloadAndExtractJDK(downloadUrl)
} }
export function findHighestJavaVersion( export function findHighestJavaVersion(release: c.LatestReleaseResponse['data'], version: string): string {
release: c.LatestReleaseResponse['data'], const graalVMIdentifierPattern = determineGraalVMLegacyIdentifier(false, version, '(\\d+)')
version: string
): string {
const graalVMIdentifierPattern = determineGraalVMLegacyIdentifier(
false,
version,
'(\\d+)'
)
const expectedFileNameRegExp = new RegExp( const expectedFileNameRegExp = new RegExp(
`^${graalVMIdentifierPattern}${c.GRAALVM_FILE_EXTENSION.replace( `^${graalVMIdentifierPattern}${c.GRAALVM_FILE_EXTENSION.replace(/\./g, '\\.')}$`
/\./g,
'\\.'
)}$`
) )
let highestJavaVersion = 0 let highestJavaVersion = 0
for (const asset of release.assets) { for (const asset of release.assets) {
@ -252,10 +200,7 @@ export function findHighestJavaVersion(
// Support for GraalVM 22.X releases and earlier // Support for GraalVM 22.X releases and earlier
export async function setUpGraalVMLatest_22_X( export async function setUpGraalVMLatest_22_X(gdsToken: string, javaVersion: string): Promise<string> {
gdsToken: string,
javaVersion: string
): Promise<string> {
const lockedVersion = javaVersion === '19' ? '22.3.1' : '22.3.3' const lockedVersion = javaVersion === '19' ? '22.3.1' : '22.3.3'
if (gdsToken.length > 0) { if (gdsToken.length > 0) {
return setUpGraalVMRelease(gdsToken, lockedVersion, javaVersion) return setUpGraalVMRelease(gdsToken, lockedVersion, javaVersion)
@ -277,32 +222,20 @@ export function findGraalVMVersion(release: c.LatestReleaseResponse['data']) {
return tag_name.substring(GRAALVM_TAG_PREFIX.length, tag_name.length) return tag_name.substring(GRAALVM_TAG_PREFIX.length, tag_name.length)
} }
export async function setUpGraalVMRelease( export async function setUpGraalVMRelease(gdsToken: string, version: string, javaVersion: string): Promise<string> {
gdsToken: string,
version: string,
javaVersion: string
): Promise<string> {
const isEE = gdsToken.length > 0 const isEE = gdsToken.length > 0
const toolName = determineLegacyToolName(isEE, version, javaVersion) const toolName = determineLegacyToolName(isEE, version, javaVersion)
let downloader: () => Promise<string> let downloader: () => Promise<string>
if (isEE) { if (isEE) {
downloader = async () => downloader = async () => downloadGraalVMEELegacy(gdsToken, version, javaVersion)
downloadGraalVMEELegacy(gdsToken, version, javaVersion)
} else { } else {
downloader = async () => downloadGraalVMCELegacy(version, javaVersion) downloader = async () => downloadGraalVMCELegacy(version, javaVersion)
} }
return downloadExtractAndCacheJDK(downloader, toolName, version) return downloadExtractAndCacheJDK(downloader, toolName, version)
} }
function findDownloadUrl( function findDownloadUrl(release: c.LatestReleaseResponse['data'], javaVersion: string): string {
release: c.LatestReleaseResponse['data'], const graalVMIdentifier = determineGraalVMLegacyIdentifier(false, c.VERSION_DEV, javaVersion)
javaVersion: string
): string {
const graalVMIdentifier = determineGraalVMLegacyIdentifier(
false,
c.VERSION_DEV,
javaVersion
)
const expectedFileName = `${graalVMIdentifier}${c.GRAALVM_FILE_EXTENSION}` const expectedFileName = `${graalVMIdentifier}${c.GRAALVM_FILE_EXTENSION}`
for (const asset of release.assets) { for (const asset of release.assets) {
if (asset.name === expectedFileName) { if (asset.name === expectedFileName) {
@ -314,34 +247,17 @@ function findDownloadUrl(
) )
} }
function determineGraalVMLegacyIdentifier( function determineGraalVMLegacyIdentifier(isEE: boolean, version: string, javaVersion: string): string {
isEE: boolean, return `${determineLegacyToolName(isEE, version, javaVersion)}-${c.GRAALVM_ARCH}-${version}`
version: string,
javaVersion: string
): string {
return `${determineLegacyToolName(isEE, version, javaVersion)}-${
c.GRAALVM_ARCH
}-${version}`
} }
function determineLegacyToolName( function determineLegacyToolName(isEE: boolean, version: string, javaVersion: string): string {
isEE: boolean,
version: string,
javaVersion: string
): string {
const infix = isEE ? 'ee' : version === c.VERSION_DEV ? 'community' : 'ce' const infix = isEE ? 'ee' : version === c.VERSION_DEV ? 'community' : 'ce'
return `graalvm-${infix}-java${javaVersion}-${c.GRAALVM_PLATFORM}` return `graalvm-${infix}-java${javaVersion}-${c.GRAALVM_PLATFORM}`
} }
async function downloadGraalVMCELegacy( async function downloadGraalVMCELegacy(version: string, javaVersion: string): Promise<string> {
version: string, const graalVMIdentifier = determineGraalVMLegacyIdentifier(false, version, javaVersion)
javaVersion: string
): Promise<string> {
const graalVMIdentifier = determineGraalVMLegacyIdentifier(
false,
version,
javaVersion
)
const downloadUrl = `${GRAALVM_CE_DL_BASE}/${GRAALVM_TAG_PREFIX}${version}/${graalVMIdentifier}${c.GRAALVM_FILE_EXTENSION}` const downloadUrl = `${GRAALVM_CE_DL_BASE}/${GRAALVM_TAG_PREFIX}${version}/${graalVMIdentifier}${c.GRAALVM_FILE_EXTENSION}`
try { try {
return await downloadTool(downloadUrl) return await downloadTool(downloadUrl)
@ -352,8 +268,6 @@ async function downloadGraalVMCELegacy(
`Failed to download ${graalVMIdentifier}. Are you sure version: '${version}' and java-version: '${javaVersion}' are correct?` `Failed to download ${graalVMIdentifier}. Are you sure version: '${version}' and java-version: '${javaVersion}' are correct?`
) )
} }
throw new Error( throw new Error(`Failed to download ${graalVMIdentifier} (error: ${error}).`)
`Failed to download ${graalVMIdentifier} (error: ${error}).`
)
} }
} }

View File

@ -1,9 +1,9 @@
import * as c from './constants.js' import * as c from './constants.js'
import * as core from '@actions/core' import * as core from '@actions/core'
import * as semver from 'semver' import * as semver from 'semver'
import {GRAALVM_PLATFORM} from './constants.js' import { GRAALVM_PLATFORM } from './constants.js'
import {exec} from './utils.js' import { exec } from './utils.js'
import {join} from 'path' import { join } from 'path'
const BASE_FLAGS = ['--non-interactive', 'install', '--no-progress'] const BASE_FLAGS = ['--non-interactive', 'install', '--no-progress']
const COMPONENT_TO_POST_INSTALL_HOOK = new Map<string, Map<string, string>>([ const COMPONENT_TO_POST_INSTALL_HOOK = new Map<string, Map<string, string>>([
@ -52,19 +52,13 @@ export async function setUpGUComponents(
) )
} }
} else if (graalVMVersion.startsWith(c.MANDREL_NAMESPACE)) { } else if (graalVMVersion.startsWith(c.MANDREL_NAMESPACE)) {
core.warning( core.warning(`Mandrel does not support GraalVM component(s): '${components.join(',')}'`)
`Mandrel does not support GraalVM component(s): '${components.join(',')}'`
)
} else { } else {
await installGUComponents(gdsToken, graalVMHome, components) await installGUComponents(gdsToken, graalVMHome, components)
} }
} }
async function installGUComponents( async function installGUComponents(gdsToken: string, graalVMHome: string, components: string[]): Promise<void> {
gdsToken: string,
graalVMHome: string,
components: string[]
): Promise<void> {
await exec('gu', BASE_FLAGS.concat(components), { await exec('gu', BASE_FLAGS.concat(components), {
env: { env: {
...process.env, ...process.env,

View File

@ -1,35 +1,22 @@
import * as c from './constants.js' import * as c from './constants.js'
import * as semver from 'semver' import * as semver from 'semver'
import { import { downloadExtractAndCacheJDK, getTaggedRelease, getMatchingTags } from './utils.js'
downloadExtractAndCacheJDK, import { downloadTool } from '@actions/tool-cache'
getTaggedRelease, import { spawnSync } from 'child_process'
getMatchingTags
} from './utils.js'
import {downloadTool} from '@actions/tool-cache'
import {spawnSync} from 'child_process'
const LIBERICA_GH_USER = 'bell-sw' const LIBERICA_GH_USER = 'bell-sw'
const LIBERICA_RELEASES_REPO = 'LibericaNIK' const LIBERICA_RELEASES_REPO = 'LibericaNIK'
const LIBERICA_JDK_TAG_PREFIX = 'jdk-' const LIBERICA_JDK_TAG_PREFIX = 'jdk-'
const LIBERICA_VM_PREFIX = 'bellsoft-liberica-vm-' const LIBERICA_VM_PREFIX = 'bellsoft-liberica-vm-'
export async function setUpLiberica( export async function setUpLiberica(javaVersion: string, javaPackage: string): Promise<string> {
javaVersion: string,
javaPackage: string
): Promise<string> {
const resolvedJavaVersion = await findLatestLibericaJavaVersion(javaVersion) const resolvedJavaVersion = await findLatestLibericaJavaVersion(javaVersion)
const downloadUrl = await findLibericaURL(resolvedJavaVersion, javaPackage) const downloadUrl = await findLibericaURL(resolvedJavaVersion, javaPackage)
const toolName = determineToolName(javaVersion, javaPackage) const toolName = determineToolName(javaVersion, javaPackage)
return downloadExtractAndCacheJDK( return downloadExtractAndCacheJDK(async () => downloadTool(downloadUrl), toolName, javaVersion)
async () => downloadTool(downloadUrl),
toolName,
javaVersion
)
} }
export async function findLatestLibericaJavaVersion( export async function findLatestLibericaJavaVersion(javaVersion: string): Promise<string> {
javaVersion: string
): Promise<string> {
const matchingRefs = await getMatchingTags( const matchingRefs = await getMatchingTags(
LIBERICA_GH_USER, LIBERICA_GH_USER,
LIBERICA_RELEASES_REPO, LIBERICA_RELEASES_REPO,
@ -44,8 +31,7 @@ export async function findLatestLibericaJavaVersion(
if ( if (
semver.valid(version) && semver.valid(version) &&
// pattern '17.0.1' should match '17.0.1+12' but not '17.0.10' // pattern '17.0.1' should match '17.0.1+12' but not '17.0.10'
(version.length <= patternLength || (version.length <= patternLength || !isDigit(version.charAt(patternLength))) &&
!isDigit(version.charAt(patternLength))) &&
semver.compareBuild(version, bestMatch) == 1 semver.compareBuild(version, bestMatch) == 1
) { ) {
bestMatch = version bestMatch = version
@ -59,25 +45,17 @@ export async function findLatestLibericaJavaVersion(
return bestMatch return bestMatch
} }
export async function findLibericaURL( export async function findLibericaURL(javaVersion: string, javaPackage: string): Promise<string> {
javaVersion: string,
javaPackage: string
): Promise<string> {
const release = await getTaggedRelease( const release = await getTaggedRelease(
LIBERICA_GH_USER, LIBERICA_GH_USER,
LIBERICA_RELEASES_REPO, LIBERICA_RELEASES_REPO,
LIBERICA_JDK_TAG_PREFIX + javaVersion LIBERICA_JDK_TAG_PREFIX + javaVersion
) )
const platform = determinePlatformPart() const platform = determinePlatformPart()
const assetPrefix = `${LIBERICA_VM_PREFIX}${determineVariantPart( const assetPrefix = `${LIBERICA_VM_PREFIX}${determineVariantPart(javaPackage)}openjdk${javaVersion}`
javaPackage
)}openjdk${javaVersion}`
const assetSuffix = `-${platform}${c.GRAALVM_FILE_EXTENSION}` const assetSuffix = `-${platform}${c.GRAALVM_FILE_EXTENSION}`
for (const asset of release.assets) { for (const asset of release.assets) {
if ( if (asset.name.startsWith(assetPrefix) && asset.name.endsWith(assetSuffix)) {
asset.name.startsWith(assetPrefix) &&
asset.name.endsWith(assetSuffix)
) {
return asset.browser_download_url return asset.browser_download_url
} }
} }

View File

@ -2,46 +2,37 @@ import * as c from './constants.js'
import * as core from '@actions/core' import * as core from '@actions/core'
import * as graalvm from './graalvm.js' import * as graalvm from './graalvm.js'
import * as semver from 'semver' import * as semver from 'semver'
import {isFeatureAvailable as isCacheAvailable} from '@actions/cache' import { isFeatureAvailable as isCacheAvailable } from '@actions/cache'
import {basename, join} from 'path' import { basename, join } from 'path'
import {restore} from './features/cache.js' import { restore } from './features/cache.js'
import {setUpDependencies} from './dependencies.js' import { setUpDependencies } from './dependencies.js'
import {setUpGUComponents} from './gu.js' import { setUpGUComponents } from './gu.js'
import {setUpMandrel} from './mandrel.js' import { setUpMandrel } from './mandrel.js'
import {setUpLiberica} from './liberica.js' import { setUpLiberica } from './liberica.js'
import {checkForUpdates} from './features/check-for-updates.js' import { checkForUpdates } from './features/check-for-updates.js'
import {setUpNativeImageMusl} from './features/musl.js' import { setUpNativeImageMusl } from './features/musl.js'
import {setUpWindowsEnvironment} from './msvc.js' import { setUpWindowsEnvironment } from './msvc.js'
import {setUpNativeImageBuildReports} from './features/reports.js' import { setUpNativeImageBuildReports } from './features/reports.js'
import {exec} from '@actions/exec' import { exec } from '@actions/exec'
import {setUpSBOMSupport} from './features/sbom.js' import { setUpSBOMSupport } from './features/sbom.js'
async function run(): Promise<void> { async function run(): Promise<void> {
try { try {
const javaVersion = core.getInput(c.INPUT_JAVA_VERSION, {required: true}) const javaVersion = core.getInput(c.INPUT_JAVA_VERSION, { required: true })
const javaPackage = core.getInput(c.INPUT_JAVA_PACKAGE) const javaPackage = core.getInput(c.INPUT_JAVA_PACKAGE)
const distribution = core.getInput(c.INPUT_DISTRIBUTION) const distribution = core.getInput(c.INPUT_DISTRIBUTION)
const graalVMVersion = core.getInput(c.INPUT_VERSION) const graalVMVersion = core.getInput(c.INPUT_VERSION)
const gdsToken = core.getInput(c.INPUT_GDS_TOKEN) const gdsToken = core.getInput(c.INPUT_GDS_TOKEN)
const componentsString: string = core.getInput(c.INPUT_COMPONENTS) const componentsString: string = core.getInput(c.INPUT_COMPONENTS)
const components: string[] = const components: string[] = componentsString.length > 0 ? componentsString.split(',').map((x) => x.trim()) : []
componentsString.length > 0
? componentsString.split(',').map(x => x.trim())
: []
const setJavaHome = core.getInput(c.INPUT_SET_JAVA_HOME) === 'true' const setJavaHome = core.getInput(c.INPUT_SET_JAVA_HOME) === 'true'
const cache = core.getInput(c.INPUT_CACHE) const cache = core.getInput(c.INPUT_CACHE)
const enableCheckForUpdates = const enableCheckForUpdates = core.getInput(c.INPUT_CHECK_FOR_UPDATES) === 'true'
core.getInput(c.INPUT_CHECK_FOR_UPDATES) === 'true'
const enableNativeImageMusl = core.getInput(c.INPUT_NI_MUSL) === 'true' const enableNativeImageMusl = core.getInput(c.INPUT_NI_MUSL) === 'true'
const isGraalVMforJDK17OrLater = const isGraalVMforJDK17OrLater = distribution.length > 0 || graalVMVersion.length == 0
distribution.length > 0 || graalVMVersion.length == 0
if (c.IS_WINDOWS) { if (c.IS_WINDOWS) {
setUpWindowsEnvironment( setUpWindowsEnvironment(javaVersion, graalVMVersion, isGraalVMforJDK17OrLater)
javaVersion,
graalVMVersion,
isGraalVMforJDK17OrLater
)
} }
await setUpDependencies(components) await setUpDependencies(components)
if (enableNativeImageMusl) { if (enableNativeImageMusl) {
@ -53,8 +44,7 @@ async function run(): Promise<void> {
if (isGraalVMforJDK17OrLater) { if (isGraalVMforJDK17OrLater) {
if ( if (
enableCheckForUpdates && enableCheckForUpdates &&
(distribution === c.DISTRIBUTION_GRAALVM || (distribution === c.DISTRIBUTION_GRAALVM || distribution === c.DISTRIBUTION_GRAALVM_COMMUNITY)
distribution === c.DISTRIBUTION_GRAALVM_COMMUNITY)
) { ) {
checkForUpdates(graalVMVersion, javaVersion) checkForUpdates(graalVMVersion, javaVersion)
} }
@ -93,30 +83,21 @@ async function run(): Promise<void> {
case c.VERSION_LATEST: case c.VERSION_LATEST:
if ( if (
javaVersion.startsWith('17') || javaVersion.startsWith('17') ||
(coercedJavaVersion !== null && (coercedJavaVersion !== null && semver.gte(coercedJavaVersion, '20.0.0'))
semver.gte(coercedJavaVersion, '20.0.0'))
) { ) {
core.info( core.info(
`This build is using the new Oracle GraalVM. To select a specific distribution, use the 'distribution' option (see https://github.com/graalvm/setup-graalvm/tree/main#options).` `This build is using the new Oracle GraalVM. To select a specific distribution, use the 'distribution' option (see https://github.com/graalvm/setup-graalvm/tree/main#options).`
) )
graalVMHome = await graalvm.setUpGraalVMJDK(javaVersion, gdsToken) graalVMHome = await graalvm.setUpGraalVMJDK(javaVersion, gdsToken)
} else { } else {
graalVMHome = await graalvm.setUpGraalVMLatest_22_X( graalVMHome = await graalvm.setUpGraalVMLatest_22_X(gdsToken, javaVersion)
gdsToken,
javaVersion
)
} }
break break
case c.VERSION_DEV: case c.VERSION_DEV:
if (gdsToken.length > 0) { if (gdsToken.length > 0) {
throw new Error( throw new Error('Downloading GraalVM EE dev builds is not supported')
'Downloading GraalVM EE dev builds is not supported'
)
} }
if ( if (coercedJavaVersion !== null && !semver.gte(coercedJavaVersion, '21.0.0')) {
coercedJavaVersion !== null &&
!semver.gte(coercedJavaVersion, '21.0.0')
) {
core.warning( core.warning(
`GraalVM dev builds are only available for JDK 21. This build is now using a stable release of GraalVM for JDK ${javaVersion}.` `GraalVM dev builds are only available for JDK 21. This build is now using a stable release of GraalVM for JDK ${javaVersion}.`
) )
@ -132,11 +113,7 @@ async function run(): Promise<void> {
if (enableCheckForUpdates) { if (enableCheckForUpdates) {
checkForUpdates(graalVMVersion, javaVersion) checkForUpdates(graalVMVersion, javaVersion)
} }
graalVMHome = await graalvm.setUpGraalVMRelease( graalVMHome = await graalvm.setUpGraalVMRelease(gdsToken, graalVMVersion, javaVersion)
gdsToken,
graalVMVersion,
javaVersion
)
} }
break break
} }
@ -149,22 +126,12 @@ async function run(): Promise<void> {
if (setJavaHome) { if (setJavaHome) {
core.exportVariable('JAVA_HOME', graalVMHome) core.exportVariable('JAVA_HOME', graalVMHome)
} }
await setUpGUComponents( await setUpGUComponents(javaVersion, graalVMVersion, graalVMHome, components, gdsToken)
javaVersion,
graalVMVersion,
graalVMHome,
components,
gdsToken
)
if (cache && isCacheAvailable()) { if (cache && isCacheAvailable()) {
await restore(cache) await restore(cache)
} }
setUpNativeImageBuildReports( setUpNativeImageBuildReports(isGraalVMforJDK17OrLater, javaVersion, graalVMVersion)
isGraalVMforJDK17OrLater,
javaVersion,
graalVMVersion
)
setUpSBOMSupport(javaVersion, distribution) setUpSBOMSupport(javaVersion, distribution)
core.startGroup(`Successfully set up '${basename(graalVMHome)}'`) core.startGroup(`Successfully set up '${basename(graalVMHome)}'`)

View File

@ -1,8 +1,8 @@
import * as c from './constants.js' import * as c from './constants.js'
import * as httpClient from '@actions/http-client' import * as httpClient from '@actions/http-client'
import {downloadExtractAndCacheJDK} from './utils.js' import { downloadExtractAndCacheJDK } from './utils.js'
import {downloadTool} from '@actions/tool-cache' import { downloadTool } from '@actions/tool-cache'
import {basename} from 'path' import { basename } from 'path'
export const MANDREL_REPO = 'mandrel' export const MANDREL_REPO = 'mandrel'
export const MANDREL_TAG_PREFIX = c.MANDREL_NAMESPACE export const MANDREL_TAG_PREFIX = c.MANDREL_NAMESPACE
@ -16,10 +16,7 @@ interface JdkData {
/* eslint-enable @typescript-eslint/no-explicit-any */ /* eslint-enable @typescript-eslint/no-explicit-any */
} }
export async function setUpMandrel( export async function setUpMandrel(mandrelVersion: string, javaVersion: string): Promise<string> {
mandrelVersion: string,
javaVersion: string
): Promise<string> {
const version = stripMandrelNamespace(mandrelVersion) const version = stripMandrelNamespace(mandrelVersion)
let mandrelHome let mandrelHome
switch (version) { switch (version) {
@ -44,11 +41,7 @@ async function setUpMandrelLatest(javaVersion: string): Promise<string> {
const version = stripMandrelNamespace(version_tag) const version = stripMandrelNamespace(version_tag)
const toolName = determineToolName(javaVersion) const toolName = determineToolName(javaVersion)
return downloadExtractAndCacheJDK( return downloadExtractAndCacheJDK(async () => downloadTool(latest_release_url), toolName, version)
async () => downloadTool(latest_release_url),
toolName,
version
)
} }
// Download URIs are of the form https://github.com/graalvm/mandrel/releases/download/<tag>/<archive-name> // Download URIs are of the form https://github.com/graalvm/mandrel/releases/download/<tag>/<archive-name>
@ -61,29 +54,19 @@ function getTagFromURI(uri: string): string {
} }
} }
export async function getLatestMandrelReleaseUrl( export async function getLatestMandrelReleaseUrl(javaVersion: string): Promise<string> {
javaVersion: string
): Promise<string> {
const url = `${DISCO_API_BASE}?jdk_version=${javaVersion}&distribution=${c.DISTRIBUTION_MANDREL}&architecture=${c.JDK_ARCH}&operating_system=${c.JDK_PLATFORM}&latest=per_distro` const url = `${DISCO_API_BASE}?jdk_version=${javaVersion}&distribution=${c.DISTRIBUTION_MANDREL}&architecture=${c.JDK_ARCH}&operating_system=${c.JDK_PLATFORM}&latest=per_distro`
const _http = new httpClient.HttpClient() const _http = new httpClient.HttpClient()
const response = await _http.getJson<JdkData>(url) const response = await _http.getJson<JdkData>(url)
if (response.statusCode !== 200) { if (response.statusCode !== 200) {
throw new Error( throw new Error(`Failed to fetch latest Mandrel release for Java ${javaVersion} from DISCO API: ${response.result}`)
`Failed to fetch latest Mandrel release for Java ${javaVersion} from DISCO API: ${response.result}`
)
} }
const result = response.result?.result[0] const result = response.result?.result[0]
try { try {
const pkg_info_uri = result.links.pkg_info_uri const pkg_info_uri = result.links.pkg_info_uri
return await getLatestMandrelReleaseUrlHelper( return await getLatestMandrelReleaseUrlHelper(_http, javaVersion, pkg_info_uri)
_http,
javaVersion,
pkg_info_uri
)
} catch (error) { } catch (error) {
throw new Error( throw new Error(`Failed to get latest Mandrel release for Java ${javaVersion} from DISCO API: ${error}`)
`Failed to get latest Mandrel release for Java ${javaVersion} from DISCO API: ${error}`
)
} }
} }
@ -108,22 +91,12 @@ async function getLatestMandrelReleaseUrlHelper(
} }
} }
async function setUpMandrelRelease( async function setUpMandrelRelease(version: string, javaVersion: string): Promise<string> {
version: string,
javaVersion: string
): Promise<string> {
const toolName = determineToolName(javaVersion) const toolName = determineToolName(javaVersion)
return downloadExtractAndCacheJDK( return downloadExtractAndCacheJDK(async () => downloadMandrelJDK(version, javaVersion), toolName, version)
async () => downloadMandrelJDK(version, javaVersion),
toolName,
version
)
} }
async function downloadMandrelJDK( async function downloadMandrelJDK(version: string, javaVersion: string): Promise<string> {
version: string,
javaVersion: string
): Promise<string> {
const identifier = determineMandrelIdentifier(version, javaVersion) const identifier = determineMandrelIdentifier(version, javaVersion)
const downloadUrl = `${MANDREL_DL_BASE}/${MANDREL_TAG_PREFIX}${version}/${identifier}${c.GRAALVM_FILE_EXTENSION}` const downloadUrl = `${MANDREL_DL_BASE}/${MANDREL_TAG_PREFIX}${version}/${identifier}${c.GRAALVM_FILE_EXTENSION}`
try { try {
@ -137,16 +110,11 @@ async function downloadMandrelJDK(
)}. Are you sure version: '${version}' and java-version: '${javaVersion}' are correct?` )}. Are you sure version: '${version}' and java-version: '${javaVersion}' are correct?`
) )
} }
throw new Error( throw new Error(`Failed to download ${basename(downloadUrl)} (error: ${error}).`)
`Failed to download ${basename(downloadUrl)} (error: ${error}).`
)
} }
} }
function determineMandrelIdentifier( function determineMandrelIdentifier(version: string, javaVersion: string): string {
version: string,
javaVersion: string
): string {
return `mandrel-java${javaVersion}-${c.GRAALVM_PLATFORM}-${c.GRAALVM_ARCH}-${version}` return `mandrel-java${javaVersion}-${c.GRAALVM_PLATFORM}-${c.GRAALVM_ARCH}-${version}`
} }
@ -156,10 +124,7 @@ function determineToolName(javaVersion: string): string {
export function stripMandrelNamespace(graalVMVersion: string) { export function stripMandrelNamespace(graalVMVersion: string) {
if (graalVMVersion.startsWith(c.MANDREL_NAMESPACE)) { if (graalVMVersion.startsWith(c.MANDREL_NAMESPACE)) {
return graalVMVersion.substring( return graalVMVersion.substring(c.MANDREL_NAMESPACE.length, graalVMVersion.length)
c.MANDREL_NAMESPACE.length,
graalVMVersion.length
)
} else { } else {
return graalVMVersion return graalVMVersion
} }

View File

@ -1,7 +1,7 @@
import * as core from '@actions/core' import * as core from '@actions/core'
import {execSync} from 'child_process' import { execSync } from 'child_process'
import {existsSync} from 'fs' import { existsSync } from 'fs'
import {VERSION_DEV} from './constants.js' import { VERSION_DEV } from './constants.js'
// Keep in sync with https://github.com/actions/virtual-environments // Keep in sync with https://github.com/actions/virtual-environments
const KNOWN_VISUAL_STUDIO_INSTALLATIONS = [ const KNOWN_VISUAL_STUDIO_INSTALLATIONS = [
@ -11,9 +11,7 @@ const KNOWN_VISUAL_STUDIO_INSTALLATIONS = [
] ]
if (process.env['VSINSTALLDIR']) { if (process.env['VSINSTALLDIR']) {
// if VSINSTALLDIR is set, make it the first known installation // if VSINSTALLDIR is set, make it the first known installation
KNOWN_VISUAL_STUDIO_INSTALLATIONS.unshift( KNOWN_VISUAL_STUDIO_INSTALLATIONS.unshift(process.env['VSINSTALLDIR'].replace(/\\$/, ''))
process.env['VSINSTALLDIR'].replace(/\\$/, '')
)
} }
const VCVARSALL_SUBPATH = 'VC\\Auxiliary\\Build\\vcvarsall.bat' const VCVARSALL_SUBPATH = 'VC\\Auxiliary\\Build\\vcvarsall.bat'
@ -45,13 +43,7 @@ export function setUpWindowsEnvironment(
graalVMVersion: string, graalVMVersion: string,
isGraalVMforJDK17OrLater: boolean isGraalVMforJDK17OrLater: boolean
): void { ): void {
if ( if (!needsWindowsEnvironmentSetup(javaVersion, graalVMVersion, isGraalVMforJDK17OrLater)) {
!needsWindowsEnvironmentSetup(
javaVersion,
graalVMVersion,
isGraalVMforJDK17OrLater
)
) {
return return
} }
@ -59,10 +51,9 @@ export function setUpWindowsEnvironment(
const vcvarsallPath = findVcvarsallPath() const vcvarsallPath = findVcvarsallPath()
core.debug(`Calling "${vcvarsallPath}"...`) core.debug(`Calling "${vcvarsallPath}"...`)
const [originalEnv, vcvarsallOutput, updatedEnv] = execSync( const [originalEnv, vcvarsallOutput, updatedEnv] = execSync(`set && cls && "${vcvarsallPath}" x64 && cls && set`, {
`set && cls && "${vcvarsallPath}" x64 && cls && set`, shell: 'cmd'
{shell: 'cmd'} })
)
.toString() .toString()
.split('\f') // form feed page break (printed by `cls`) .split('\f') // form feed page break (printed by `cls`)
core.debug(vcvarsallOutput) core.debug(vcvarsallOutput)

View File

@ -5,12 +5,12 @@ import * as httpClient from '@actions/http-client'
import * as semver from 'semver' import * as semver from 'semver'
import * as tc from '@actions/tool-cache' import * as tc from '@actions/tool-cache'
import * as fs from 'fs' import * as fs from 'fs'
import {ExecOptions, exec as e} from '@actions/exec' import { ExecOptions, exec as e } from '@actions/exec'
import {readFileSync, readdirSync} from 'fs' import { readFileSync, readdirSync } from 'fs'
import {Octokit} from '@octokit/core' import { Octokit } from '@octokit/core'
import {createHash} from 'crypto' import { createHash } from 'crypto'
import {join} from 'path' import { join } from 'path'
import {tmpdir} from 'os' import { tmpdir } from 'os'
// Set up Octokit for github.com only and in the same way as @actions/github (see https://git.io/Jy9YP) // Set up Octokit for github.com only and in the same way as @actions/github (see https://git.io/Jy9YP)
const baseUrl = 'https://api.github.com' const baseUrl = 'https://api.github.com'
@ -21,26 +21,16 @@ const GitHubDotCom = Octokit.defaults({
} }
}) })
export async function exec( export async function exec(commandLine: string, args?: string[], options?: ExecOptions | undefined): Promise<void> {
commandLine: string,
args?: string[],
options?: ExecOptions | undefined
): Promise<void> {
const exitCode = await e(commandLine, args, options) const exitCode = await e(commandLine, args, options)
if (exitCode !== 0) { if (exitCode !== 0) {
throw new Error( throw new Error(`'${[commandLine].concat(args || []).join(' ')}' exited with a non-zero code: ${exitCode}`)
`'${[commandLine]
.concat(args || [])
.join(' ')}' exited with a non-zero code: ${exitCode}`
)
} }
} }
export async function getLatestRelease( export async function getLatestRelease(repo: string): Promise<c.LatestReleaseResponse['data']> {
repo: string
): Promise<c.LatestReleaseResponse['data']> {
const githubToken = getGitHubToken() const githubToken = getGitHubToken()
const options = githubToken.length > 0 ? {auth: githubToken} : {} const options = githubToken.length > 0 ? { auth: githubToken } : {}
const octokit = new GitHubDotCom(options) const octokit = new GitHubDotCom(options)
return ( return (
await octokit.request('GET /repos/{owner}/{repo}/releases/latest', { await octokit.request('GET /repos/{owner}/{repo}/releases/latest', {
@ -50,12 +40,9 @@ export async function getLatestRelease(
).data ).data
} }
export async function getContents( export async function getContents(repo: string, path: string): Promise<c.ContentsResponse['data']> {
repo: string,
path: string
): Promise<c.ContentsResponse['data']> {
const githubToken = getGitHubToken() const githubToken = getGitHubToken()
const options = githubToken.length > 0 ? {auth: githubToken} : {} const options = githubToken.length > 0 ? { auth: githubToken } : {}
const octokit = new GitHubDotCom(options) const octokit = new GitHubDotCom(options)
return ( return (
await octokit.request('GET /repos/{owner}/{repo}/contents/{path}', { await octokit.request('GET /repos/{owner}/{repo}/contents/{path}', {
@ -72,7 +59,7 @@ export async function getTaggedRelease(
tag: string tag: string
): Promise<c.LatestReleaseResponse['data']> { ): Promise<c.LatestReleaseResponse['data']> {
const githubToken = getGitHubToken() const githubToken = getGitHubToken()
const options = githubToken.length > 0 ? {auth: githubToken} : {} const options = githubToken.length > 0 ? { auth: githubToken } : {}
const octokit = new GitHubDotCom(options) const octokit = new GitHubDotCom(options)
return ( return (
await octokit.request('GET /repos/{owner}/{repo}/releases/tags/{tag}', { await octokit.request('GET /repos/{owner}/{repo}/releases/tags/{tag}', {
@ -89,26 +76,19 @@ export async function getMatchingTags(
tagPrefix: string tagPrefix: string
): Promise<c.MatchingRefsResponse['data']> { ): Promise<c.MatchingRefsResponse['data']> {
const githubToken = getGitHubToken() const githubToken = getGitHubToken()
const options = githubToken.length > 0 ? {auth: githubToken} : {} const options = githubToken.length > 0 ? { auth: githubToken } : {}
const octokit = new GitHubDotCom(options) const octokit = new GitHubDotCom(options)
return ( return (
await octokit.request( await octokit.request('GET /repos/{owner}/{repo}/git/matching-refs/tags/{tagPrefix}', {
'GET /repos/{owner}/{repo}/git/matching-refs/tags/{tagPrefix}', owner,
{ repo,
owner, tagPrefix
repo, })
tagPrefix
}
)
).data ).data
} }
export async function downloadAndExtractJDK( export async function downloadAndExtractJDK(downloadUrl: string): Promise<string> {
downloadUrl: string return findJavaHomeInSubfolder(await extract(await tc.downloadTool(downloadUrl)))
): Promise<string> {
return findJavaHomeInSubfolder(
await extract(await tc.downloadTool(downloadUrl))
)
} }
export async function downloadExtractAndCacheJDK( export async function downloadExtractAndCacheJDK(
@ -140,9 +120,7 @@ async function extract(downloadPath: string): Promise<string> {
} else if (c.GRAALVM_FILE_EXTENSION === '.zip') { } else if (c.GRAALVM_FILE_EXTENSION === '.zip') {
return await tc.extractZip(downloadPath) return await tc.extractZip(downloadPath)
} else { } else {
throw new Error( throw new Error(`Unexpected filetype downloaded: ${c.GRAALVM_FILE_EXTENSION}`)
`Unexpected filetype downloaded: ${c.GRAALVM_FILE_EXTENSION}`
)
} }
} }
@ -151,9 +129,7 @@ function findJavaHomeInSubfolder(searchPath: string): string {
if (baseContents.length === 1) { if (baseContents.length === 1) {
return join(searchPath, baseContents[0], c.JDK_HOME_SUFFIX) return join(searchPath, baseContents[0], c.JDK_HOME_SUFFIX)
} else { } else {
throw new Error( throw new Error(`Unexpected amount of directory items found: ${baseContents.length}`)
`Unexpected amount of directory items found: ${baseContents.length}`
)
} }
} }
@ -171,9 +147,7 @@ export function toSemVer(version: string): string {
const suffix = versionParts.length === 2 ? '-' + versionParts[1] : '' const suffix = versionParts.length === 2 ? '-' + versionParts[1] : ''
const validVersion = semver.valid(semver.coerce(versionParts[0]) + suffix) const validVersion = semver.valid(semver.coerce(versionParts[0]) + suffix)
if (!validVersion) { if (!validVersion) {
throw new Error( throw new Error(`Unable to convert '${version}' to semantic version. ${c.ERROR_HINT}`)
`Unable to convert '${version}' to semantic version. ${c.ERROR_HINT}`
)
} }
return validVersion return validVersion
} }
@ -186,9 +160,7 @@ function getGitHubToken(): string {
return core.getInput(c.INPUT_GITHUB_TOKEN) return core.getInput(c.INPUT_GITHUB_TOKEN)
} }
export async function findExistingPRCommentId( export async function findExistingPRCommentId(bodyStartsWith: string): Promise<number | undefined> {
bodyStartsWith: string
): Promise<number | undefined> {
if (!isPREvent()) { if (!isPREvent()) {
throw new Error('Not a PR event.') throw new Error('Not a PR event.')
} }
@ -200,7 +172,7 @@ export async function findExistingPRCommentId(
...context.repo, ...context.repo,
issue_number: context.payload.pull_request?.number as number issue_number: context.payload.pull_request?.number as number
}) })
const matchingComment = comments.reverse().find(comment => { const matchingComment = comments.reverse().find((comment) => {
return comment.body && comment.body.startsWith(bodyStartsWith) return comment.body && comment.body.startsWith(bodyStartsWith)
}) })
return matchingComment ? matchingComment.id : undefined return matchingComment ? matchingComment.id : undefined
@ -211,10 +183,7 @@ export async function findExistingPRCommentId(
} }
} }
export async function updatePRComment( export async function updatePRComment(content: string, commentId: number): Promise<void> {
content: string,
commentId: number
): Promise<void> {
if (!isPREvent()) { if (!isPREvent()) {
throw new Error('Not a PR event.') throw new Error('Not a PR event.')
} }
@ -254,14 +223,10 @@ export function tmpfile(fileName: string) {
return join(tmpdir(), fileName) return join(tmpdir(), fileName)
} }
export function setNativeImageOption( export function setNativeImageOption(javaVersionOrDev: string, optionValue: string): void {
javaVersionOrDev: string,
optionValue: string
): void {
const coercedJavaVersionOrDev = semver.coerce(javaVersionOrDev) const coercedJavaVersionOrDev = semver.coerce(javaVersionOrDev)
if ( if (
(coercedJavaVersionOrDev && (coercedJavaVersionOrDev && semver.gte(coercedJavaVersionOrDev, '22.0.0')) ||
semver.gte(coercedJavaVersionOrDev, '22.0.0')) ||
javaVersionOrDev === c.VERSION_DEV || javaVersionOrDev === c.VERSION_DEV ||
javaVersionOrDev.endsWith('-ea') javaVersionOrDev.endsWith('-ea')
) { ) {