Compare commits

..

14 Commits

Author SHA1 Message Date
Fabio Niephaus
d72e3dbf5f Bump version to 1.1.7. 2024-02-13 17:28:29 +01:00
Fabio Niephaus
22551b2bec Minor edit. 2024-02-13 17:16:15 +01:00
Fabio Niephaus
bf3e45bce6 Use toSemVer() for tool name. 2024-02-13 15:44:22 +01:00
Fabio Niephaus
1588b03f82 Use semver in toSemVer(). 2024-02-13 15:44:08 +01:00
Fabio Niephaus
6df9f698c6 Avoid deprecated methods in tests. 2024-02-13 15:43:34 +01:00
Fabio Niephaus
2408275e34 Add initial support for early access (EA) builds. 2024-02-13 13:37:00 +01:00
Fabio Niephaus
a638430bc0 Move migration notice further down. 2024-02-08 12:05:32 +01:00
Fabio Niephaus
3bd233e767 Test on macos-14 (macOS on Apple Silicon).
For context: https://github.blog/changelog/2024-01-30-github-actions-introducing-the-new-m1-macos-runner-available-to-open-source/
2024-01-31 14:27:15 +01:00
Fabio Niephaus
c99915cc1a Upgrade actions/setup-node to v4. 2024-01-31 14:27:03 +01:00
Jongwoo Han
a0f131ece5 Upgrade node-version to v20. 2024-01-31 14:35:58 +09:00
Fabio Niephaus
a1b47fdf04 Bump version to 1.1.6. 2024-01-30 15:36:39 +01:00
Fabio Niephaus
129a551a10 Upgrade Node to v20. 2024-01-30 15:26:44 +01:00
Foivos Zakkak
b8dc5fccfb Get latest mandrel release if version not specified
Update doc.
2023-11-03 13:30:38 +01:00
Foivos Zakkak
1c219f5b27 Remove user-agent from HttpClient 2023-11-03 13:30:38 +01:00
17 changed files with 59415 additions and 16054 deletions

View File

@@ -26,10 +26,10 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Set Node.js 16.x
uses: actions/setup-node@v3
- name: Set Node.js 20.x
uses: actions/setup-node@v4
with:
node-version: 16.x
node-version: 20.x
cache: npm
- name: Install dependencies

View File

@@ -27,9 +27,17 @@ jobs:
matrix:
java-version: ['21', '17', '20', 'dev']
distribution: ['graalvm', 'graalvm-community']
os: [macos-latest, windows-latest, ubuntu-latest]
os: [
ubuntu-latest,
macos-14, # macOS on Apple silicon
macos-12, # macOS on Intel
windows-latest
]
components: ['']
include:
- java-version: '22-ea'
distribution: 'graalvm'
os: ubuntu-latest
- java-version: '21'
distribution: ''
os: ubuntu-latest
@@ -199,6 +207,10 @@ jobs:
java-version: '17'
distribution: '' # test empty distribution for backward compatibility
os: ubuntu-latest
- version: '' # test with no version
java-version: '21'
distribution: 'mandrel'
os: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run setup-graalvm action

View File

@@ -15,34 +15,6 @@ This action:
- has built-in support for GraalVM components and the [GraalVM Updater][gu]
## Migrating from GraalVM 22.3 or Earlier to the New GraalVM for JDK 17 and Later
The [GraalVM for JDK 17 and JDK 20 release](https://medium.com/graalvm/a-new-graalvm-release-and-new-free-license-4aab483692f5) aligns the GraalVM version scheme with OpenJDK.
As a result, this action no longer requires the `version` option to select a specific GraalVM version.
At the same time, it introduces a new `distribution` option to select a specific GraalVM distribution (`graalvm`, `graalvm-community`, or `mandrel`).
Therefore, to migrate your workflow to use the latest GraalVM release, replace the `version` with the `distribution` option in the workflow `yml` config, for example:
```yml
# ...
- uses: graalvm/setup-graalvm@v1
with:
java-version: '17'
version: '22.3.2' # Old 'version' option for the GraalVM version
# ...
```
can be replaced with:
```yml
# ...
- uses: graalvm/setup-graalvm@v1
with:
java-version: '17.0.7' # for a specific JDK 17; or '17' for the latest JDK 17
distribution: 'graalvm' # New 'distribution' option
# ...
```
## Templates
### Quickstart Template
@@ -162,6 +134,35 @@ jobs:
</details>
## Migrating from GraalVM 22.3 or Earlier to the New GraalVM for JDK 17 and Later
The [GraalVM for JDK 17 and JDK 20 release](https://medium.com/graalvm/a-new-graalvm-release-and-new-free-license-4aab483692f5) aligns the GraalVM version scheme with OpenJDK.
As a result, this action no longer requires the `version` option to select a specific GraalVM version.
At the same time, it introduces a new `distribution` option to select a specific GraalVM distribution (`graalvm`, `graalvm-community`, or `mandrel`).
Therefore, to migrate your workflow to use the latest GraalVM release, replace the `version` with the `distribution` option in the workflow `yml` config, for example:
```yml
# ...
- uses: graalvm/setup-graalvm@v1
with:
java-version: '17'
version: '22.3.2' # Old 'version' option for the GraalVM version
# ...
```
can be replaced with:
```yml
# ...
- uses: graalvm/setup-graalvm@v1
with:
java-version: '17.0.7' # for a specific JDK 17; or '17' for the latest JDK 17
distribution: 'graalvm' # New 'distribution' option
# ...
```
## Options
| Name | Default | Description |
@@ -176,7 +177,7 @@ jobs:
| `native-image-job-reports` *) | `'false'` | If set to `'true'`, post a job summary containing a Native Image build report. |
| `native-image-pr-reports` *) | `'false'` | If set to `'true'`, post a comment containing a Native Image build report on pull requests. Requires `write` permissions for the [`pull-requests` scope][gha-permissions]. |
| `components` | `''` | Comma-separated list of GraalVM components (e.g., `native-image` or `ruby,nodejs`) that will be installed by the [GraalVM Updater][gu]. |
| `version` | `''` | `X.Y.Z` (e.g., `22.3.0`) for a specific [GraalVM release][releases] up to `22.3.2`<br>`mandrel-X.Y.Z` (e.g., `mandrel-21.3.0.0-Final`) for a specific [Mandrel release][mandrel-releases],<br>`mandrel-latest` for [latest Mandrel stable release][mandrel-stable]. |
| `version` | `''` | `X.Y.Z` (e.g., `22.3.0`) for a specific [GraalVM release][releases] up to `22.3.2`<br>`mandrel-X.Y.Z.W` or `X.Y.Z.W-Final` (e.g., `mandrel-21.3.0.0-Final` or `21.3.0.0-Final`) for a specific [Mandrel release][mandrel-releases],<br>`mandrel-latest` or `latest` for the latest Mandrel stable release. |
| `gds-token` | `''` | Download token for the GraalVM Download Service. If a non-empty token is provided, the action will set up GraalVM Enterprise Edition (see [GraalVM EE template](#template-for-graalvm-enterprise-edition)). |
**) Make sure that Native Image is used only once per build job. Otherwise, the report is only generated for the last Native Image build.*

View File

@@ -101,14 +101,14 @@ describe('dependency cache', () => {
})
it('throws error if unsupported package manager specified', () => {
return expect(restore('ant')).rejects.toThrowError(
return expect(restore('ant')).rejects.toThrow(
'unknown package manager specified: ant'
)
})
describe('for maven', () => {
it('throws error if no pom.xml found', async () => {
await expect(restore('maven')).rejects.toThrowError(
await expect(restore('maven')).rejects.toThrow(
`No file in ${projectRoot(
workspace
)} matched to [**/pom.xml], make sure you have checked out the target repository`
@@ -118,14 +118,14 @@ describe('dependency cache', () => {
createFile(join(workspace, 'pom.xml'))
await restore('maven')
expect(spyCacheRestore).toBeCalled()
expect(spyWarning).not.toBeCalled()
expect(spyInfo).toBeCalledWith('maven cache is not found')
expect(spyCacheRestore).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalledWith('maven cache is not found')
})
})
describe('for gradle', () => {
it('throws error if no build.gradle found', async () => {
await expect(restore('gradle')).rejects.toThrowError(
await expect(restore('gradle')).rejects.toThrow(
`No file in ${projectRoot(
workspace
)} matched to [**/*.gradle*,**/gradle-wrapper.properties,buildSrc/**/Versions.kt,buildSrc/**/Dependencies.kt], make sure you have checked out the target repository`
@@ -135,17 +135,17 @@ describe('dependency cache', () => {
createFile(join(workspace, 'build.gradle'))
await restore('gradle')
expect(spyCacheRestore).toBeCalled()
expect(spyWarning).not.toBeCalled()
expect(spyInfo).toBeCalledWith('gradle cache is not found')
expect(spyCacheRestore).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalledWith('gradle cache is not found')
})
it('downloads cache based on build.gradle.kts', async () => {
createFile(join(workspace, 'build.gradle.kts'))
await restore('gradle')
expect(spyCacheRestore).toBeCalled()
expect(spyWarning).not.toBeCalled()
expect(spyInfo).toBeCalledWith('gradle cache is not found')
expect(spyCacheRestore).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalledWith('gradle cache is not found')
})
})
it('downloads cache based on buildSrc/Versions.kt', async () => {
@@ -153,13 +153,13 @@ describe('dependency cache', () => {
createFile(join(workspace, 'buildSrc', 'Versions.kt'))
await restore('gradle')
expect(spyCacheRestore).toBeCalled()
expect(spyWarning).not.toBeCalled()
expect(spyInfo).toBeCalledWith('gradle cache is not found')
expect(spyCacheRestore).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalledWith('gradle cache is not found')
})
describe('for sbt', () => {
it('throws error if no build.sbt found', async () => {
await expect(restore('sbt')).rejects.toThrowError(
await expect(restore('sbt')).rejects.toThrow(
`No file in ${projectRoot(
workspace
)} matched to [**/*.sbt,**/project/build.properties,**/project/**.{scala,sbt}], make sure you have checked out the target repository`
@@ -169,9 +169,9 @@ describe('dependency cache', () => {
createFile(join(workspace, 'build.sbt'))
await restore('sbt')
expect(spyCacheRestore).toBeCalled()
expect(spyWarning).not.toBeCalled()
expect(spyInfo).toBeCalledWith('sbt cache is not found')
expect(spyCacheRestore).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalledWith('sbt cache is not found')
})
})
})
@@ -191,7 +191,7 @@ describe('dependency cache', () => {
})
it('throws error if unsupported package manager specified', () => {
return expect(save('ant')).rejects.toThrowError(
return expect(save('ant')).rejects.toThrow(
'unknown package manager specified: ant'
)
})
@@ -201,10 +201,10 @@ describe('dependency cache', () => {
createStateForMissingBuildFile()
await save('maven')
expect(spyCacheSave).toBeCalled()
expect(spyWarning).not.toBeCalled()
expect(spyInfo).toBeCalled()
expect(spyInfo).toBeCalledWith(
expect(spyCacheSave).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
)
})
@@ -225,24 +225,26 @@ describe('dependency cache', () => {
it('uploads cache even if no pom.xml found', async () => {
createStateForMissingBuildFile()
await save('maven')
expect(spyCacheSave).toBeCalled()
expect(spyWarning).not.toBeCalled()
expect(spyCacheSave).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled()
})
it('does not upload cache if no restore run before', async () => {
createFile(join(workspace, 'pom.xml'))
await save('maven')
expect(spyCacheSave).not.toBeCalled()
expect(spyWarning).toBeCalledWith('Error retrieving key from state.')
expect(spyCacheSave).not.toHaveBeenCalled()
expect(spyWarning).toHaveBeenCalledWith(
'Error retrieving key from state.'
)
})
it('uploads cache', async () => {
createFile(join(workspace, 'pom.xml'))
createStateForSuccessfulRestore()
await save('maven')
expect(spyCacheSave).toBeCalled()
expect(spyWarning).not.toBeCalled()
expect(spyInfo).toBeCalledWith(
expect(spyCacheSave).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
)
})
@@ -252,24 +254,26 @@ describe('dependency cache', () => {
createStateForMissingBuildFile()
await save('gradle')
expect(spyCacheSave).toBeCalled()
expect(spyWarning).not.toBeCalled()
expect(spyCacheSave).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled()
})
it('does not upload cache if no restore run before', async () => {
createFile(join(workspace, 'build.gradle'))
await save('gradle')
expect(spyCacheSave).not.toBeCalled()
expect(spyWarning).toBeCalledWith('Error retrieving key from state.')
expect(spyCacheSave).not.toHaveBeenCalled()
expect(spyWarning).toHaveBeenCalledWith(
'Error retrieving key from state.'
)
})
it('uploads cache based on build.gradle', async () => {
createFile(join(workspace, 'build.gradle'))
createStateForSuccessfulRestore()
await save('gradle')
expect(spyCacheSave).toBeCalled()
expect(spyWarning).not.toBeCalled()
expect(spyInfo).toBeCalledWith(
expect(spyCacheSave).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
)
})
@@ -278,9 +282,9 @@ describe('dependency cache', () => {
createStateForSuccessfulRestore()
await save('gradle')
expect(spyCacheSave).toBeCalled()
expect(spyWarning).not.toBeCalled()
expect(spyInfo).toBeCalledWith(
expect(spyCacheSave).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
)
})
@@ -290,9 +294,9 @@ describe('dependency cache', () => {
createStateForSuccessfulRestore()
await save('gradle')
expect(spyCacheSave).toBeCalled()
expect(spyWarning).not.toBeCalled()
expect(spyInfo).toBeCalledWith(
expect(spyCacheSave).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
)
})
@@ -301,24 +305,26 @@ describe('dependency cache', () => {
it('uploads cache even if no build.sbt found', async () => {
createStateForMissingBuildFile()
await save('sbt')
expect(spyCacheSave).toBeCalled()
expect(spyWarning).not.toBeCalled()
expect(spyCacheSave).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled()
})
it('does not upload cache if no restore run before', async () => {
createFile(join(workspace, 'build.sbt'))
await save('sbt')
expect(spyCacheSave).not.toBeCalled()
expect(spyWarning).toBeCalledWith('Error retrieving key from state.')
expect(spyCacheSave).not.toHaveBeenCalled()
expect(spyWarning).toHaveBeenCalledWith(
'Error retrieving key from state.'
)
})
it('uploads cache', async () => {
createFile(join(workspace, 'build.sbt'))
createStateForSuccessfulRestore()
await save('sbt')
expect(spyCacheSave).toBeCalled()
expect(spyWarning).not.toBeCalled()
expect(spyInfo).toBeCalledWith(
expect(spyCacheSave).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled()
expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
)
})

View File

@@ -27,7 +27,6 @@
import {run as cleanup} from '../src/cleanup'
import * as core from '@actions/core'
import * as cache from '@actions/cache'
import * as util from '../src/utils'
describe('cleanup', () => {
let spyWarning: jest.SpyInstance<void, Parameters<typeof core.warning>>
@@ -62,8 +61,8 @@ describe('cleanup', () => {
return name === 'cache' ? 'gradle' : ''
})
await cleanup()
expect(spyCacheSave).toBeCalled()
expect(spyWarning).not.toBeCalled()
expect(spyCacheSave).toHaveBeenCalled()
expect(spyWarning).not.toHaveBeenCalled()
})
it('does not fail even though the save process throws error', async () => {
@@ -74,7 +73,7 @@ describe('cleanup', () => {
return name === 'cache' ? 'gradle' : ''
})
await cleanup()
expect(spyCacheSave).toBeCalled()
expect(spyCacheSave).toHaveBeenCalled()
})
})

34
__tests__/utils.test.ts Normal file
View File

@@ -0,0 +1,34 @@
import * as path from 'path'
import {expect, test} from '@jest/globals'
import {toSemVer} from '../src/utils'
test('convert version', async () => {
for (var inputAndExpectedOutput of [
['22', '22.0.0'],
['22.0', '22.0.0'],
['22.0.0', '22.0.0'],
['22.0.0.2', '22.0.0-2'],
['22-ea', '22.0.0-ea'],
['22.0-ea', '22.0.0-ea'],
['22.0.0-ea', '22.0.0-ea']
]) {
expect(toSemVer(inputAndExpectedOutput[0])).toBe(inputAndExpectedOutput[1])
}
})
test('convert invalid version', async () => {
for (var input of ['dev', 'abc', 'a.b.c']) {
let error = new Error('unexpected')
try {
toSemVer(input)
} catch (err) {
if (!(err instanceof Error)) {
fail(`Unexpected non-Error: ${err}`)
}
error = err
}
expect(error).not.toBeUndefined()
expect(error.message).toContain('Unable to convert')
}
})

View File

@@ -54,7 +54,7 @@ outputs:
cache-hit:
description: 'A boolean value to indicate an exact match was found for the primary key'
runs:
using: 'node16'
using: 'node20'
main: 'dist/main/index.js'
post: 'dist/cleanup/index.js'
post-if: 'success()'

33096
dist/cleanup/index.js generated vendored

File diff suppressed because one or more lines are too long

32591
dist/main/index.js generated vendored

File diff suppressed because one or more lines are too long

9384
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "setup-graalvm",
"version": "1.1.5",
"version": "1.1.7",
"private": true,
"description": "GitHub Action for GraalVM",
"main": "lib/main.js",
@@ -27,33 +27,37 @@
"author": "GraalVM Community",
"license": "UPL",
"dependencies": {
"@actions/cache": "^3.0.4",
"@actions/core": "^1.10.0",
"@actions/exec": "^1.1.0",
"@actions/github": "^5.1.1",
"@actions/glob": "^0.3.0",
"@actions/http-client": "^1.0.11",
"@actions/io": "^1.1.1",
"@actions/tool-cache": "^1.7.1",
"@octokit/core": "^3.5.1",
"@octokit/types": "^6.34.0",
"semver": "^7.5.2",
"uuid": "^8.3.2"
"@actions/cache": "^3.2.3",
"@actions/core": "^1.10.1",
"@actions/exec": "^1.1.1",
"@actions/github": "^6.0.0",
"@actions/glob": "^0.4.0",
"@actions/http-client": "^2.2.0",
"@actions/io": "^1.1.3",
"@actions/tool-cache": "^2.0.1",
"@octokit/core": "^5.1.0",
"@octokit/types": "^12.0.0",
"semver": "^7.5.4",
"uuid": "^9.0.1"
},
"devDependencies": {
"@types/jest": "^27.5.2",
"@types/node": "^18.15.11",
"@types/semver": "^7.3.13",
"@types/uuid": "^8.3.4",
"@typescript-eslint/parser": "^5.8.1",
"@vercel/ncc": "^0.33.4",
"eslint": "^8.6.0",
"eslint-plugin-github": "^4.3.5",
"eslint-plugin-jest": "^25.3.4",
"jest": "^29.5.0",
"@types/jest": "^29.5.11",
"@types/node": "^20.11.10",
"@types/semver": "^7.5.6",
"@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^6.19.1",
"@typescript-eslint/parser": "^6.19.1",
"@vercel/ncc": "^0.38.1",
"eslint": "^8.56.0",
"eslint-plugin-github": "^4.10.1",
"eslint-plugin-jest": "^27.6.3",
"eslint-plugin-jsonc": "^2.13.0",
"eslint-plugin-prettier": "^5.1.3",
"jest": "^29.7.0",
"js-yaml": "^4.1.0",
"prettier": "2.5.1",
"ts-jest": "^29.1.0",
"typescript": "^5.0.4"
"prettier": "^3.2.4",
"prettier-eslint": "^16.3.0",
"ts-jest": "^29.1.2",
"typescript": "^5.3.3"
}
}

View File

@@ -49,6 +49,9 @@ export type LatestReleaseResponse =
export type MatchingRefsResponse =
otypes.Endpoints['GET /repos/{owner}/{repo}/git/matching-refs/{ref}']['response']
export type ReleasesResponse =
otypes.Endpoints['GET /repos/{owner}/{repo}/releases']['response']
function determineJDKArchitecture(): string {
switch (process.arch) {
case 'x64': {

View File

@@ -369,8 +369,8 @@ function createReport(data: BuildOutput): string {
details.total_bytes
)}</td>
<td align="left">${objectCount}${bytesToHuman(
details.image_heap.resources.bytes
)} for ${details.image_heap.resources.count.toLocaleString()} resources</td>
details.image_heap.resources.bytes
)} for ${details.image_heap.resources.count.toLocaleString()} resources</td>
</tr>${debugInfoLine}
<tr>
<td align="left"><a href="${DOCS_BASE}#glossary-other-data" target="_blank">Other data</a></td>
@@ -404,16 +404,16 @@ function createReport(data: BuildOutput): string {
<td align="left">${bytesToHuman(
resources.memory.peak_rss_bytes
)} (${toPercent(
resources.memory.peak_rss_bytes,
resources.memory.system_total
)} of ${bytesToHuman(resources.memory.system_total)} system memory)</td>
resources.memory.peak_rss_bytes,
resources.memory.system_total
)} of ${bytesToHuman(resources.memory.system_total)} system memory)</td>
</tr>
<tr>
<td align="left"><a href="${DOCS_BASE}#glossary-cpu-load" target="_blank">CPU load</a></td>
<td align="left">${resources.cpu.load.toFixed(3)} (${toPercent(
resources.cpu.load,
resources.cpu.total_cores
)} of ${resources.cpu.total_cores} CPU cores)</td>
resources.cpu.load,
resources.cpu.total_cores
)} of ${resources.cpu.total_cores} CPU cores)</td>
</tr>
</tbody>
</table>

View File

@@ -6,8 +6,7 @@ import * as io from '@actions/io'
import * as path from 'path'
import * as stream from 'stream'
import * as util from 'util'
import {IHeaders} from '@actions/http-client/interfaces'
import {IncomingHttpHeaders} from 'http'
import {IncomingHttpHeaders, OutgoingHttpHeaders} from 'http'
import {RetryHelper} from '@actions/tool-cache/lib/retry-helper'
import {calculateSHA256} from './utils'
import {ok} from 'assert'
@@ -32,7 +31,7 @@ export async function downloadGraalVMEELegacy(
version: string,
javaVersion: string
): Promise<string> {
const userAgent = `GraalVMGitHubAction/1.1.5 (arch:${c.GRAALVM_ARCH}; os:${c.GRAALVM_PLATFORM}; java:${javaVersion})`
const userAgent = `GraalVMGitHubAction/1.1.7 (arch:${c.GRAALVM_ARCH}; os:${c.GRAALVM_PLATFORM}; java:${javaVersion})`
const baseArtifact = await fetchArtifact(
userAgent,
'isBase:True',
@@ -132,7 +131,7 @@ class HTTPError extends Error {
async function downloadTool(
url: string,
userAgent: string,
headers?: IHeaders
headers?: OutgoingHttpHeaders
): Promise<string> {
const dest = path.join(getTempDirectory(), uuidv4())
await io.mkdirP(path.dirname(dest))
@@ -169,7 +168,7 @@ async function downloadToolAttempt(
url: string,
userAgent: string,
dest: string,
headers?: IHeaders
headers?: OutgoingHttpHeaders
): Promise<string> {
if (fs.existsSync(dest)) {
throw new Error(`Destination file path ${dest} already exists`)

View File

@@ -3,9 +3,11 @@ import * as semver from 'semver'
import {
downloadAndExtractJDK,
downloadExtractAndCacheJDK,
getLatestPrerelease,
getLatestRelease,
getMatchingTags,
getTaggedRelease
getTaggedRelease,
toSemVer
} from './utils'
import {downloadGraalVMEELegacy} from './gds'
import {downloadTool} from '@actions/tool-cache'
@@ -13,6 +15,7 @@ import {basename} from 'path'
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 ORACLE_GRAALVM_REPO_EA_BUILDS = 'oracle-graalvm-dev-builds'
const GRAALVM_REPO_DEV_BUILDS = 'graalvm-ce-dev-builds'
const GRAALVM_JDK_TAG_PREFIX = 'jdk-'
const GRAALVM_TAG_PREFIX = 'vm-'
@@ -26,7 +29,8 @@ export async function setUpGraalVMJDK(
return setUpGraalVMJDKDevBuild()
}
const javaVersion = javaVersionOrDev
let toolName = determineToolName(javaVersion, false)
const toolName = determineToolName(javaVersion, false)
let downloadName = toolName
let downloadUrl: string
if (javaVersion.includes('.')) {
if (semver.valid(javaVersion)) {
@@ -34,7 +38,6 @@ export async function setUpGraalVMJDK(
const minorJavaVersion = semver.minor(javaVersion)
const patchJavaVersion = semver.patch(javaVersion)
const isGARelease = minorJavaVersion === 0 && patchJavaVersion === 0
let downloadName = toolName
if (isGARelease) {
// For GA versions of JDKs, /archive/ does not use minor and patch version (see https://www.oracle.com/java/technologies/jdk-script-friendly-urls/)
downloadName = determineToolName(majorJavaVersion.toString(), false)
@@ -45,13 +48,36 @@ export async function setUpGraalVMJDK(
`java-version set to '${javaVersion}'. Please make sure the java-version is set correctly. ${c.ERROR_HINT}`
)
}
} else if (javaVersion === '22-ea') {
downloadUrl = await findLatestEABuildDownloadUrl(javaVersion)
} else {
downloadUrl = `${GRAALVM_DL_BASE}/${javaVersion}/latest/${toolName}${c.GRAALVM_FILE_EXTENSION}`
downloadUrl = `${GRAALVM_DL_BASE}/${javaVersion}/latest/${downloadName}${c.GRAALVM_FILE_EXTENSION}`
}
const downloader = async () => downloadGraalVMJDK(downloadUrl, javaVersion)
return downloadExtractAndCacheJDK(downloader, toolName, javaVersion)
}
async function findLatestEABuildDownloadUrl(
javaEaVersion: string
): Promise<string> {
const latestPrerelease = await getLatestPrerelease(
ORACLE_GRAALVM_REPO_EA_BUILDS
)
const expectedFileNamePrefix = 'graalvm-jdk-'
const expectedFileNameSuffix = `_${c.JDK_PLATFORM}-${c.JDK_ARCH}_bin${c.GRAALVM_FILE_EXTENSION}`
for (const asset of latestPrerelease.assets) {
if (
asset.name.startsWith(expectedFileNamePrefix) &&
asset.name.endsWith(expectedFileNameSuffix)
) {
return asset.browser_download_url
}
}
throw new Error(
`Could not find Oracle GraalVM build for ${javaEaVersion}. ${c.ERROR_HINT}`
)
}
export async function setUpGraalVMJDKCE(
javaVersionOrDev: string
): Promise<string> {

View File

@@ -21,6 +21,8 @@ export async function setUpMandrel(
const version = stripMandrelNamespace(mandrelVersion)
let mandrelHome
switch (version) {
case '':
// fetch latest if no version is specified
case 'latest':
mandrelHome = await setUpMandrelLatest(javaVersion)
break
@@ -59,7 +61,7 @@ export async function getLatestMandrelReleaseUrl(
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 _http = new httpClient.HttpClient('http-client-tests')
const _http = new httpClient.HttpClient()
const response = await _http.getJson<JdkData>(url)
if (response.statusCode !== 200) {
throw new Error(

View File

@@ -2,6 +2,7 @@ import * as c from './constants'
import * as core from '@actions/core'
import * as github from '@actions/github'
import * as httpClient from '@actions/http-client'
import * as semver from 'semver'
import * as tc from '@actions/tool-cache'
import {ExecOptions, exec as e} from '@actions/exec'
import {readFileSync, readdirSync} from 'fs'
@@ -33,6 +34,25 @@ export async function exec(
}
}
export async function getLatestPrerelease(
repo: string
): Promise<c.ReleasesResponse['data'][number]> {
const githubToken = getGitHubToken()
const options = githubToken.length > 0 ? {auth: githubToken} : {}
const octokit = new GitHubDotCom(options)
const releases: c.ReleasesResponse['data'] = (
await octokit.request('GET /repos/{owner}/{repo}/releases', {
owner: c.GRAALVM_GH_USER,
repo
})
).data
const firstPrerelease = releases.find(r => r.prerelease)
if (!firstPrerelease) {
throw new Error(`Unable to find latest prerelease in ${repo}`)
}
return firstPrerelease
}
export async function getLatestRelease(
repo: string
): Promise<c.LatestReleaseResponse['data']> {
@@ -135,17 +155,25 @@ function findJavaHomeInSubfolder(searchPath: string): string {
}
}
/**
* This helper turns GraalVM version numbers (e.g., `22.0.0.2`) into valid
* semver.org versions (e.g., `22.0.0-2`), which is needed because
* @actions/tool-cache uses `semver` to validate versions.
*/
export function toSemVer(version: string): string {
const parts = version.split('.')
const major = parts[0]
const minor = parts.length > 1 ? parts[1] : '0'
const patch = parts.length > 2 ? parts.slice(2).join('-') : '0'
return `${major}.${minor}.${patch}`
if (parts.length === 4) {
/**
* Turn legacy GraalVM version numbers (e.g., `22.0.0.2`) into valid
* semver.org versions (e.g., `22.0.0-2`).
*/
return `${parts[0]}.${parts[1]}.${parts.slice(2).join('-')}`
}
const versionParts = version.split('-', 2)
const suffix = versionParts.length === 2 ? '-' + versionParts[1] : ''
const validVersion = semver.valid(semver.coerce(versionParts[0]) + suffix)
if (!validVersion) {
throw new Error(
`Unable to convert '${version}' to semantic version. ${c.ERROR_HINT}`
)
}
return validVersion
}
export function isPREvent(): boolean {