Compare commits

...

13 Commits

Author SHA1 Message Date
Fabio Niephaus
174eff573d Bump version to 1.0.5. 2022-04-20 11:45:33 +02:00
Fabio Niephaus
e343c9a746 Enable support for GraalVM Enterprise Edition.
Fixes #5.
2022-04-20 11:41:11 +02:00
Fabio Niephaus
8cce0a82bf Document GraalVM Enterprise Edition support.
Closes #7.

[ci skip]
2022-04-20 11:41:11 +02:00
Fabio Niephaus
60c5807781 Simplify GraalVM Native Image example.
[ci skip]
2022-03-30 18:48:08 +02:00
Fabio Niephaus
8085574f90 Improve title. [ci skip] 2022-03-30 14:41:52 +02:00
Fabio Niephaus
cf025f1a74 Simplify complex Native Image template. 2022-03-29 15:23:04 +02:00
Fabio Niephaus
5a3116eab6 Add test-native-image-msvc. 2022-03-29 15:02:26 +02:00
Fabio Niephaus
0c5c948baa Update zlib-1.2.11 download link.
Fixes https://github.com/oracle/graal/issues/4439
2022-03-28 18:16:44 +02:00
Fabio Niephaus
bbe485154c Regenerate dist/ files. 2022-03-11 13:37:06 +01:00
Fabio Niephaus
b3777a3c57 Fail builds on non-zero exit codes. 2022-03-11 13:37:06 +01:00
Fabio Niephaus
77fd73038b Extend Mandrel testing. 2022-03-11 13:37:06 +01:00
Fabio Niephaus
2240cb3432 Add support for GraalVM Enterprise Edition.
Fixes #5.
2022-03-11 13:37:06 +01:00
Fabio Niephaus
1a4a7ccb68 Bump version to 1.0.4. 2022-03-11 13:37:06 +01:00
18 changed files with 851 additions and 130 deletions

View File

@@ -18,8 +18,8 @@ jobs:
npm install
- run: |
npm run all
test: # make sure the action works on a clean machine without building
name: ${{ matrix.version }} + JDK${{ matrix.java-version }} on ${{ matrix.os }}
test-ce: # make sure the action works on a clean machine without building
name: CE ${{ matrix.version }} + JDK${{ matrix.java-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -40,14 +40,6 @@ jobs:
java-version: '17'
components: 'native-image'
os: windows-2022
- version: 'mandrel-latest'
java-version: '11'
components: ''
os: ubuntu-latest
- version: 'mandrel-21.3.0.0-Final'
java-version: '17'
components: ''
os: windows-latest
steps:
- uses: actions/checkout@v2
- name: Run setup-graalvm action
@@ -60,6 +52,79 @@ jobs:
- name: Check environment
run: |
echo "GRAALVM_HOME: $GRAALVM_HOME"
if [[ "${{ matrix.version }}" == "dev" ]]; then
[[ "$GRAALVM_HOME" == *"$RUNNER_TEMP"* ]] || exit 12
else
[[ "$GRAALVM_HOME" == *"$RUNNER_TOOL_CACHE"* ]] || exit 23
fi
echo "JAVA_HOME: $JAVA_HOME"
java --version
java --version | grep "GraalVM CE" || exit 34
native-image --version
if: runner.os != 'Windows'
- name: Check Windows environment
run: |
echo "GRAALVM_HOME: $env:GRAALVM_HOME"
echo "JAVA_HOME: $env:JAVA_HOME"
java --version
native-image --version
if: runner.os == 'Windows'
test-ee:
name: EE ${{ matrix.version }} + JDK${{ matrix.java-version }} on ${{ matrix.os }}
if: github.event_name != 'pull_request'
runs-on: ${{ matrix.os }}
strategy:
matrix:
version: ['22.1.0', 'latest']
java-version: ['11', '17']
components: ['native-image']
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- uses: actions/checkout@v2
- name: Run setup-graalvm action
uses: ./
with:
version: ${{ matrix.version }}
gds-token: ${{ secrets.GDS_TOKEN }}
java-version: ${{ matrix.java-version }}
components: ${{ matrix.components }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Check environment
run: |
echo "GRAALVM_HOME: $GRAALVM_HOME"
[[ "$GRAALVM_HOME" == *"$RUNNER_TOOL_CACHE"* ]] || exit 12
echo "JAVA_HOME: $JAVA_HOME"
java --version
java --version | grep "GraalVM EE" || exit 23
native-image --version
if: runner.os != 'Windows'
- name: Check Windows environment
run: |
echo "GRAALVM_HOME: $env:GRAALVM_HOME"
echo "JAVA_HOME: $env:JAVA_HOME"
java --version
native-image --version
if: runner.os == 'Windows'
test-mandrel:
name: ${{ matrix.version }} + JDK${{ matrix.java-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
version: ['mandrel-21.3.0.0-Final', 'mandrel-latest']
java-version: ['11', '17']
os: [windows-latest, ubuntu-latest]
steps:
- uses: actions/checkout@v2
- name: Run setup-graalvm action
uses: ./
with:
version: ${{ matrix.version }}
java-version: ${{ matrix.java-version }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Check environment
run: |
echo "GRAALVM_HOME: $GRAALVM_HOME"
[[ "$GRAALVM_HOME" == *"$RUNNER_TOOL_CACHE"* ]] || exit 12
echo "JAVA_HOME: $JAVA_HOME"
java --version
native-image --version
@@ -69,8 +134,26 @@ jobs:
echo "GRAALVM_HOME: $env:GRAALVM_HOME"
echo "JAVA_HOME: $env:JAVA_HOME"
java --version
native-image.cmd --version
native-image --version
if: runner.os == 'Windows'
test-native-image-msvc:
name: native-image on windows-latest
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- name: Run setup-graalvm action
uses: ./
with:
version: 'latest'
java-version: '17'
components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Build HelloWorld executable with GraalVM Native Image on Windows
run: |
echo 'public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } }' > HelloWorld.java
javac HelloWorld.java
native-image HelloWorld
./helloworld
test-native-image-musl:
name: native-image-musl on ubuntu-latest
runs-on: ubuntu-latest
@@ -84,13 +167,13 @@ jobs:
components: 'native-image'
native-image-musl: 'true'
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Build static HelloWorld image with Native Image and musl
- name: Build static HelloWorld executable with GraalVM Native Image and musl
run: |
echo 'public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } }' > HelloWorld.java
javac HelloWorld.java
native-image --static --libc=musl HelloWorld
./helloworld
test-additional:
test-extensive:
name: extensive tests on ubuntu-latest
runs-on: ubuntu-latest
steps:
@@ -123,7 +206,7 @@ jobs:
R --version
truffleruby --version
wasm --version
- name: Build HelloWorld.java with Native Image
- name: Build HelloWorld.java with GraalVM Native Image
run: |
echo 'public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } }' > HelloWorld.java
javac HelloWorld.java

View File

@@ -1,16 +1,16 @@
# GitHub Action for GraalVM [![build-test](https://github.com/graalvm/setup-graalvm/actions/workflows/test.yml/badge.svg)](https://github.com/graalvm/setup-graalvm/actions/workflows/test.yml)
This GitHub action sets up [GraalVM Community Edition][repo] and GraalVM components such as [Native Image][native-image] and [Truffle languages][truffle-languages].
This GitHub action sets up GraalVM [Community Edition (CE)][repo] or [Enterprise Edition (EE)][graalvm-ee] as well as GraalVM components such as [Native Image][native-image] and [Truffle languages][truffle-languages].
## Key Features
This action:
- supports GraalVM CE [releases], [dev builds][dev-builds], and [Mandrel][mandrel] (see [options](#options))
- has built-in support for GraalVM components and the [GraalVM updater][gu]
- supports GraalVM Community Edition (CE) [releases], [dev builds][dev-builds], GraalVM Enterprise Edition (EE) [releases][graalvm-ee] (set [`gds-token`](#options)) 22.1.0 and later, and [Mandrel][mandrel] (see [options](#options))
- has built-in support for GraalVM components and the [GraalVM Updater][gu]
- exports a `$GRAALVM_HOME` environment variable
- adds `$GRAALVM_HOME/bin` to the `$PATH` environment variable<br>(Truffle languages and tools can be invoked directly)
- sets `$JAVA_HOME` to `$GRAALVM_HOME` by default<br>(can be disabled via `set-java-home: 'false'`, see [options](#options))
- supports `amd64` and `aarch64` (requires a [self-hosted runner][gh-self-hosted-runners])
- supports `amd64` and `aarch64` (requires a [self-hosted runner][gha-self-hosted-runners])
- sets up Windows environments with build tools using [vcvarsall.bat][vcvarsall]
@@ -29,7 +29,7 @@ jobs:
- uses: graalvm/setup-graalvm@v1
with:
version: 'latest'
java-version: '11'
java-version: '17'
components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Example step
@@ -41,56 +41,79 @@ jobs:
native-image --version
```
### Complex Native Image Template
### Building a HelloWorld with GraalVM Native Image on Different Platforms
```yml
name: GraalVM Native Image build
on: [push, pull_request]
jobs:
build:
name: ${{ matrix.version }} on ${{ matrix.os }}
name: HelloWorld on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
version: [latest, dev, '22.0.0.2']
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: graalvm/setup-graalvm@v1
with:
version: ${{ matrix.version }}
version: '22.0.0.2'
java-version: '11'
components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Build and run HelloWorld.java
run: |
echo 'public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } }' > HelloWorld.java
javac HelloWorld.java
native-image HelloWorld
./helloworld
if: runner.os != 'Windows'
- name: Build and run HelloWorld.java on Windows
run: |
javac.exe HelloWorld.java
native-image.cmd HelloWorld
./helloworld.exe
if: runner.os == 'Windows'
- name: Upload binary
uses: actions/upload-artifact@v2
with:
name: helloworld-${{ matrix.os }}-${{ matrix.version }}
name: helloworld-${{ matrix.os }}
path: helloworld*
```
### Basic GraalVM Enterprise Edition Template
#### Prerequisites
1. Download the version of [GraalVM Enterprise Edition (EE)][graalvm-ee] you want to run on GitHub Actions.
2. Use the [GraalVM Updater][gu] to install the GraalVM components you need on GitHub Actions and accept the corresponding licenses.
3. Run `$GRAALVM_HOME/bin/gu --show-ee-token` to display your token for the GraalVM Download Service.
4. Store this token as a [GitHub Action secret][gha-secrets]. For this template, we use the name `GDS_TOKEN`.
```yml
name: GraalVM build
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: graalvm/setup-graalvm@v1
with:
version: '22.1.0'
gds-token: ${{ secrets.GDS_TOKEN }}
java-version: '11'
components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Example step
run: |
java --version
native-image --version
```
## Options
| Name | Default | Description |
|-----------------|:--------:|-------------|
| `version`<br>*(required)* | n/a | `X.Y.Z` (e.g., `21.3.0`) for a specific [GraalVM release][releases]<br>`latest` for [latest stable release][stable],<br>`dev` for [latest dev build][dev-build],<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]. |
| `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](#basic-graalvm-enterprise-edition-template)). |
| `java-version`<br>*(required)* | n/a | `'11'` or `'17'` for a specific Java version.<br>(`'8'` and `'16'` are supported for GraalVM 21.2 and earlier.) |
| `components` | `''` | Comma-spearated list of GraalVM components (e.g., `native-image` or `ruby,nodejs`) that will be installed by the [GraalVM Updater][gu]. |
| `github-token` | `''` | Token for communication with the GitHub API. Please set to `${{ secrets.GITHUB_TOKEN }}` (see [templates](#templates)) to allow the action to authenticate with the GitHub API, which helps to reduce rate limiting issues. |
@@ -107,8 +130,10 @@ Only pull requests from committers that can be verified as having signed the OCA
[dev-build]: https://github.com/graalvm/graalvm-ce-dev-builds/releases/latest
[dev-builds]: https://github.com/graalvm/graalvm-ce-dev-builds
[gh-self-hosted-runners]: https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners
[gha-secrets]: https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository
[gha-self-hosted-runners]: https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners
[gu]: https://www.graalvm.org/reference-manual/graalvm-updater/
[graalvm-ee]: https://www.oracle.com/downloads/graalvm-downloads.html
[mandrel]: https://github.com/graalvm/mandrel
[mandrel-releases]: https://github.com/graalvm/mandrel/releases
[mandrel-stable]: https://github.com/graalvm/mandrel/releases/latest

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

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

View File

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

View File

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

365
dist/index.js generated vendored
View File

@@ -7,7 +7,7 @@ require('./sourcemap-register.js');/******/ (() => { // webpackBootstrap
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MANDREL_NAMESPACE = exports.JDK_HOME_SUFFIX = exports.GRAALVM_PLATFORM = exports.GRAALVM_GH_USER = exports.GRAALVM_FILE_EXTENSION = exports.GRAALVM_ARCH = exports.VERSION_LATEST = exports.VERSION_DEV = exports.IS_WINDOWS = exports.IS_MACOS = exports.IS_LINUX = void 0;
exports.GDS_GRAALVM_PRODUCT_ID = exports.GDS_BASE = exports.MANDREL_NAMESPACE = exports.JDK_HOME_SUFFIX = exports.GRAALVM_PLATFORM = exports.GRAALVM_GH_USER = exports.GRAALVM_FILE_EXTENSION = exports.GRAALVM_ARCH = exports.VERSION_LATEST = exports.VERSION_DEV = exports.IS_WINDOWS = exports.IS_MACOS = exports.IS_LINUX = void 0;
exports.IS_LINUX = process.platform === 'linux';
exports.IS_MACOS = process.platform === 'darwin';
exports.IS_WINDOWS = process.platform === 'win32';
@@ -19,6 +19,8 @@ exports.GRAALVM_GH_USER = 'graalvm';
exports.GRAALVM_PLATFORM = exports.IS_WINDOWS ? 'windows' : process.platform;
exports.JDK_HOME_SUFFIX = exports.IS_MACOS ? '/Contents/Home' : '';
exports.MANDREL_NAMESPACE = 'mandrel-';
exports.GDS_BASE = 'https://gds.oracle.com/api/20220101';
exports.GDS_GRAALVM_PRODUCT_ID = 'D53FAE8052773FFAE0530F15000AA6C6';
function determineGraalVMArchitecture() {
switch (process.arch) {
case 'x64': {
@@ -73,7 +75,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.setUpDependencies = void 0;
const core = __importStar(__nccwpck_require__(2186));
const constants_1 = __nccwpck_require__(5105);
const exec_1 = __nccwpck_require__(1514);
const utils_1 = __nccwpck_require__(918);
const APT_GET_INSTALL_BASE = 'sudo apt-get -y --no-upgrade install';
const COMPONENT_TO_DEPS = new Map([
[
@@ -97,7 +99,7 @@ function setUpDependencies(components) {
const depCommand = platformDeps.get(component);
if (depCommand) {
core.startGroup(`Installing dependencies for ${component}...`);
yield (0, exec_1.exec)(depCommand);
yield (0, utils_1.exec)(depCommand);
core.endGroup();
}
}
@@ -147,7 +149,7 @@ exports.setUpNativeImageMusl = void 0;
const core = __importStar(__nccwpck_require__(2186));
const tc = __importStar(__nccwpck_require__(7784));
const constants_1 = __nccwpck_require__(5105);
const exec_1 = __nccwpck_require__(1514);
const utils_1 = __nccwpck_require__(918);
const path_1 = __nccwpck_require__(1017);
const MUSL_NAME = 'x86_64-linux-musl-native';
const MUSL_VERSION = '10.2.1';
@@ -167,16 +169,16 @@ function setUpNativeImageMusl() {
const muslExtractPath = yield tc.extractTar(muslDownloadPath);
const muslPath = (0, path_1.join)(muslExtractPath, MUSL_NAME);
const zlibVersion = '1.2.11';
const zlibDownloadPath = yield tc.downloadTool(`https://zlib.net/zlib-${zlibVersion}.tar.gz`);
const zlibDownloadPath = yield tc.downloadTool(`https://zlib.net/fossils/zlib-${zlibVersion}.tar.gz`);
const zlibExtractPath = yield tc.extractTar(zlibDownloadPath);
const zlibPath = (0, path_1.join)(zlibExtractPath, `zlib-${zlibVersion}`);
const zlibBuildOptions = {
cwd: zlibPath,
env: Object.assign(Object.assign({}, process.env), { CC: (0, path_1.join)(muslPath, 'bin', 'gcc') })
};
yield (0, exec_1.exec)('./configure', [`--prefix=${muslPath}`, '--static'], zlibBuildOptions);
yield (0, exec_1.exec)('make', [], zlibBuildOptions);
yield (0, exec_1.exec)('make', ['install'], { cwd: zlibPath });
yield (0, utils_1.exec)('./configure', [`--prefix=${muslPath}`, '--static'], zlibBuildOptions);
yield (0, utils_1.exec)('make', [], zlibBuildOptions);
yield (0, utils_1.exec)('make', ['install'], { cwd: zlibPath });
core.info(`Adding ${MUSL_NAME} ${MUSL_VERSION} to tool-cache ...`);
toolPath = yield tc.cacheDir(muslPath, MUSL_NAME, MUSL_VERSION);
core.endGroup();
@@ -187,6 +189,200 @@ function setUpNativeImageMusl() {
exports.setUpNativeImageMusl = setUpNativeImageMusl;
/***/ }),
/***/ 253:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.fetchArtifact = exports.downloadGraalVMEE = void 0;
const c = __importStar(__nccwpck_require__(5105));
const core = __importStar(__nccwpck_require__(2186));
const fs = __importStar(__nccwpck_require__(7147));
const httpClient = __importStar(__nccwpck_require__(9925));
const io = __importStar(__nccwpck_require__(7436));
const path = __importStar(__nccwpck_require__(1017));
const stream = __importStar(__nccwpck_require__(2781));
const util = __importStar(__nccwpck_require__(3837));
const retry_helper_1 = __nccwpck_require__(8279);
const utils_1 = __nccwpck_require__(918);
const assert_1 = __nccwpck_require__(9491);
const v4_1 = __importDefault(__nccwpck_require__(824));
function downloadGraalVMEE(gdsToken, version, javaVersion) {
return __awaiter(this, void 0, void 0, function* () {
const userAgent = `GraalVMGitHubAction/1.0.5 (arch:${c.GRAALVM_ARCH}; os:${c.GRAALVM_PLATFORM}; java:${javaVersion})`;
const baseArtifact = yield fetchArtifact(userAgent, 'isBase:True', version, javaVersion);
return downloadArtifact(gdsToken, userAgent, baseArtifact);
});
}
exports.downloadGraalVMEE = downloadGraalVMEE;
function fetchArtifact(userAgent, metadata, version, javaVersion) {
return __awaiter(this, void 0, void 0, function* () {
const http = new httpClient.HttpClient(userAgent);
let filter;
if (version === c.VERSION_LATEST) {
filter = `sortBy=displayName&sortOrder=DESC&limit=1`; // latest and only one item
}
else {
filter = `metadata=version:${version}`;
}
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`;
core.debug(`Requesting ${requestUrl}`);
const response = yield http.get(requestUrl, { accept: 'application/json' });
if (response.message.statusCode !== 200) {
throw new Error(`Unable to find JDK${javaVersion}-based GraalVM EE ${version}`);
}
const artifactResponse = JSON.parse(yield response.readBody());
if (artifactResponse.items.length !== 1) {
throw new Error(`Found more than one GDS artifact`);
}
return artifactResponse.items[0];
});
}
exports.fetchArtifact = fetchArtifact;
function downloadArtifact(gdsToken, userAgent, artifact) {
return __awaiter(this, void 0, void 0, function* () {
let downloadPath;
try {
downloadPath = yield downloadTool(`${c.GDS_BASE}/artifacts/${artifact.id}/content`, userAgent, {
accept: 'application/x-yaml',
'x-download-token': gdsToken
});
}
catch (err) {
if (err instanceof HTTPError && err.httpStatusCode) {
if (err.httpStatusCode === 401) {
throw new Error(`The provided "gds-token" was rejected (reason: "${err.gdsError.message}", opc-request-id: ${err.headers['opc-request-id']})`);
}
}
throw err;
}
const sha256 = (0, utils_1.calculateSHA256)(downloadPath);
if (sha256.toLowerCase() !== artifact.checksum.toLowerCase()) {
throw new Error(`Checksum does not match (expected: "${artifact.checksum}", got: "${sha256}")`);
}
return downloadPath;
});
}
/**
* Simplified fork of tool-cache's downloadTool [1] with the ability to set a custom user agent.
* [1] https://github.com/actions/toolkit/blob/2f164000dcd42fb08287824a3bc3030dbed33687/packages/tool-cache/src/tool-cache.ts
*/
class HTTPError extends Error {
constructor(httpStatusCode, gdsError, headers) {
super(`Unexpected HTTP response: ${httpStatusCode}`);
this.httpStatusCode = httpStatusCode;
this.gdsError = gdsError;
this.headers = headers;
Object.setPrototypeOf(this, new.target.prototype);
}
}
function downloadTool(url, userAgent, headers) {
return __awaiter(this, void 0, void 0, function* () {
const dest = path.join(getTempDirectory(), (0, v4_1.default)());
yield io.mkdirP(path.dirname(dest));
core.debug(`Downloading ${url}`);
core.debug(`Destination ${dest}`);
const maxAttempts = 3;
const minSeconds = 10;
const maxSeconds = 20;
const retryHelper = new retry_helper_1.RetryHelper(maxAttempts, minSeconds, maxSeconds);
return yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () {
return yield downloadToolAttempt(url, userAgent, dest || '', headers);
}), (err) => {
if (err instanceof HTTPError && err.httpStatusCode) {
// Don't retry anything less than 500, except 408 Request Timeout and 429 Too Many Requests
if (err.httpStatusCode < 500 &&
err.httpStatusCode !== 408 &&
err.httpStatusCode !== 429) {
return false;
}
}
// Otherwise retry
return true;
});
});
}
function downloadToolAttempt(url, userAgent, dest, headers) {
return __awaiter(this, void 0, void 0, function* () {
if (fs.existsSync(dest)) {
throw new Error(`Destination file path ${dest} already exists`);
}
// Get the response headers
const http = new httpClient.HttpClient(userAgent, [], {
allowRetries: false
});
const response = yield http.get(url, headers);
if (response.message.statusCode !== 200) {
const errorResponse = JSON.parse(yield response.readBody());
const err = new HTTPError(response.message.statusCode, errorResponse, response.message.headers);
core.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`);
throw err;
}
// Download the response body
const pipeline = util.promisify(stream.pipeline);
let succeeded = false;
try {
yield pipeline(response.message, fs.createWriteStream(dest));
core.debug('Download complete');
succeeded = true;
return dest;
}
finally {
// Error, delete dest before retry
if (!succeeded) {
core.debug('Download failed');
try {
yield io.rmRF(dest);
}
catch (err) {
core.debug(`Failed to delete '${dest}'. ${err}`);
}
}
}
});
}
function getTempDirectory() {
const tempDirectory = process.env['RUNNER_TEMP'] || '';
(0, assert_1.ok)(tempDirectory, 'Expected RUNNER_TEMP to be defined');
return tempDirectory;
}
/***/ }),
/***/ 1763:
@@ -226,26 +422,34 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.setUpGraalVMRelease = exports.setUpGraalVMDevBuild = exports.setUpGraalVMLatest = void 0;
const c = __importStar(__nccwpck_require__(5105));
const utils_1 = __nccwpck_require__(918);
const gds_1 = __nccwpck_require__(253);
const tool_cache_1 = __nccwpck_require__(7784);
const GRAALVM_CE_DL_BASE = 'https://github.com/graalvm/graalvm-ce-builds/releases/download';
const GRAALVM_REPO_DEV_BUILDS = 'graalvm-ce-dev-builds';
const GRAALVM_REPO_RELEASES = 'graalvm-ce-builds';
const GRAALVM_TAG_PREFIX = 'vm-';
function setUpGraalVMLatest(javaVersion) {
function setUpGraalVMLatest(gdsToken, javaVersion) {
return __awaiter(this, void 0, void 0, function* () {
if (gdsToken.length > 0) {
return setUpGraalVMRelease(gdsToken, c.VERSION_LATEST, javaVersion);
}
const latestRelease = yield (0, utils_1.getLatestRelease)(GRAALVM_REPO_RELEASES);
const tag_name = latestRelease.tag_name;
if (tag_name.startsWith(GRAALVM_TAG_PREFIX)) {
const latestVersion = tag_name.substring(GRAALVM_TAG_PREFIX.length, tag_name.length);
return setUpGraalVMRelease(latestVersion, javaVersion);
return setUpGraalVMRelease(gdsToken, latestVersion, javaVersion);
}
throw new Error(`Could not find latest GraalVM release: ${tag_name}`);
});
}
exports.setUpGraalVMLatest = setUpGraalVMLatest;
function setUpGraalVMDevBuild(javaVersion) {
function setUpGraalVMDevBuild(gdsToken, javaVersion) {
return __awaiter(this, void 0, void 0, function* () {
if (gdsToken.length > 0) {
throw new Error('Downloading GraalVM EE dev builds is not supported');
}
const latestDevBuild = yield (0, utils_1.getLatestRelease)(GRAALVM_REPO_DEV_BUILDS);
const graalVMIdentifier = determineGraalVMIdentifier('dev', javaVersion);
const graalVMIdentifier = determineGraalVMIdentifier(false, 'dev', javaVersion);
const expectedFileName = `${graalVMIdentifier}${c.GRAALVM_FILE_EXTENSION}`;
for (const asset of latestDevBuild.assets) {
if (asset.name === expectedFileName) {
@@ -256,20 +460,28 @@ function setUpGraalVMDevBuild(javaVersion) {
});
}
exports.setUpGraalVMDevBuild = setUpGraalVMDevBuild;
function setUpGraalVMRelease(version, javaVersion) {
function setUpGraalVMRelease(gdsToken, version, javaVersion) {
return __awaiter(this, void 0, void 0, function* () {
const graalVMIdentifier = determineGraalVMIdentifier(version, javaVersion);
const downloadUrl = `${GRAALVM_CE_DL_BASE}/${GRAALVM_TAG_PREFIX}${version}/${graalVMIdentifier}${c.GRAALVM_FILE_EXTENSION}`;
const toolName = determineToolName(javaVersion);
return (0, utils_1.downloadExtractAndCacheJDK)(downloadUrl, toolName, version);
const isEE = gdsToken.length > 0;
const graalVMIdentifier = determineGraalVMIdentifier(isEE, version, javaVersion);
const toolName = determineToolName(isEE, javaVersion);
let downloader;
if (isEE) {
downloader = () => __awaiter(this, void 0, void 0, function* () { return (0, gds_1.downloadGraalVMEE)(gdsToken, version, javaVersion); });
}
else {
const downloadUrl = `${GRAALVM_CE_DL_BASE}/${GRAALVM_TAG_PREFIX}${version}/${graalVMIdentifier}${c.GRAALVM_FILE_EXTENSION}`;
downloader = () => __awaiter(this, void 0, void 0, function* () { return (0, tool_cache_1.downloadTool)(downloadUrl); });
}
return (0, utils_1.downloadExtractAndCacheJDK)(downloader, toolName, version);
});
}
exports.setUpGraalVMRelease = setUpGraalVMRelease;
function determineGraalVMIdentifier(version, javaVersion) {
return `graalvm-ce-java${javaVersion}-${c.GRAALVM_PLATFORM}-${c.GRAALVM_ARCH}-${version}`;
function determineGraalVMIdentifier(isEE, version, javaVersion) {
return `graalvm-${isEE ? 'ee' : 'ce'}-java${javaVersion}-${c.GRAALVM_PLATFORM}-${c.GRAALVM_ARCH}-${version}`;
}
function determineToolName(javaVersion) {
return `graalvm-ce-java${javaVersion}-${c.GRAALVM_PLATFORM}`;
function determineToolName(isEE, javaVersion) {
return `graalvm-${isEE ? 'ee' : 'ce'}-java${javaVersion}-${c.GRAALVM_PLATFORM}`;
}
@@ -292,8 +504,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.setUpGUComponents = void 0;
const constants_1 = __nccwpck_require__(5105);
const exec_1 = __nccwpck_require__(1514);
const utils_1 = __nccwpck_require__(918);
const path_1 = __nccwpck_require__(1017);
const BASE_FLAGS = ['--non-interactive', 'install', '--no-progress'];
const COMPONENT_TO_POST_INSTALL_HOOK = new Map([
[
'linux',
@@ -311,15 +524,17 @@ const COMPONENT_TO_POST_INSTALL_HOOK = new Map([
]
// No post install hooks for Windows (yet)
]);
function setUpGUComponents(graalVMHome, components) {
function setUpGUComponents(gdsToken, graalVMHome, components) {
return __awaiter(this, void 0, void 0, function* () {
yield (0, exec_1.exec)('gu', ['install', '--no-progress'].concat(components));
yield (0, utils_1.exec)('gu', BASE_FLAGS.concat(components), {
env: Object.assign(Object.assign({}, process.env), { GRAAL_EE_DOWNLOAD_TOKEN: gdsToken })
});
const platformHooks = COMPONENT_TO_POST_INSTALL_HOOK.get(constants_1.GRAALVM_PLATFORM);
if (platformHooks) {
for (const component of components) {
const postInstallHook = platformHooks.get(component);
if (postInstallHook) {
yield (0, exec_1.exec)(`"${(0, path_1.join)(graalVMHome, postInstallHook)}"`);
yield (0, utils_1.exec)(`"${(0, path_1.join)(graalVMHome, postInstallHook)}"`);
}
}
}
@@ -377,6 +592,7 @@ function run() {
return __awaiter(this, void 0, void 0, function* () {
try {
const graalvmVersion = core.getInput('version', { required: true });
const gdsToken = core.getInput('gds-token');
const javaVersion = core.getInput('java-version', { required: true });
const componentsString = core.getInput('components');
const components = componentsString.length > 0 ? componentsString.split(',') : [];
@@ -393,17 +609,17 @@ function run() {
let graalVMHome;
switch (graalvmVersion) {
case c.VERSION_LATEST:
graalVMHome = yield graalvm.setUpGraalVMLatest(javaVersion);
graalVMHome = yield graalvm.setUpGraalVMLatest(gdsToken, javaVersion);
break;
case c.VERSION_DEV:
graalVMHome = yield graalvm.setUpGraalVMDevBuild(javaVersion);
graalVMHome = yield graalvm.setUpGraalVMDevBuild(gdsToken, javaVersion);
break;
default:
if (graalvmVersion.startsWith(c.MANDREL_NAMESPACE)) {
graalVMHome = yield (0, mandrel_1.setUpMandrel)(graalvmVersion, javaVersion);
}
else {
graalVMHome = yield graalvm.setUpGraalVMRelease(graalvmVersion, javaVersion);
graalVMHome = yield graalvm.setUpGraalVMRelease(gdsToken, graalvmVersion, javaVersion);
}
break;
}
@@ -420,7 +636,7 @@ function run() {
core.warning(`Mandrel does not support GraalVM components: ${componentsString}`);
}
else {
yield (0, gu_1.setUpGUComponents)(graalVMHome, components);
yield (0, gu_1.setUpGUComponents)(gdsToken, graalVMHome, components);
}
}
}
@@ -472,6 +688,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.setUpMandrel = void 0;
const c = __importStar(__nccwpck_require__(5105));
const utils_1 = __nccwpck_require__(918);
const tool_cache_1 = __nccwpck_require__(7784);
const MANDREL_REPO = 'mandrel';
const MANDREL_TAG_PREFIX = c.MANDREL_NAMESPACE;
const MANDREL_DL_BASE = 'https://github.com/graalvm/mandrel/releases/download';
@@ -507,7 +724,7 @@ function setUpMandrelRelease(version, javaVersion) {
const identifier = determineMandrelIdentifier(version, javaVersion);
const downloadUrl = `${MANDREL_DL_BASE}/${MANDREL_TAG_PREFIX}${version}/${identifier}${c.GRAALVM_FILE_EXTENSION}`;
const toolName = determineToolName(javaVersion);
return (0, utils_1.downloadExtractAndCacheJDK)(downloadUrl, toolName, version);
return (0, utils_1.downloadExtractAndCacheJDK)(() => __awaiter(this, void 0, void 0, function* () { return (0, tool_cache_1.downloadTool)(downloadUrl); }), toolName, version);
});
}
function determineMandrelIdentifier(version, javaVersion) {
@@ -637,14 +854,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.downloadExtractAndCacheJDK = exports.downloadAndExtractJDK = exports.getLatestRelease = void 0;
exports.calculateSHA256 = exports.downloadExtractAndCacheJDK = exports.downloadAndExtractJDK = exports.getLatestRelease = exports.exec = void 0;
const c = __importStar(__nccwpck_require__(5105));
const core = __importStar(__nccwpck_require__(2186));
const httpClient = __importStar(__nccwpck_require__(9925));
const tc = __importStar(__nccwpck_require__(7784));
const core_1 = __nccwpck_require__(6762);
const path_1 = __nccwpck_require__(1017);
const exec_1 = __nccwpck_require__(1514);
const fs_1 = __nccwpck_require__(7147);
const core_1 = __nccwpck_require__(6762);
const crypto_1 = __nccwpck_require__(6113);
const path_1 = __nccwpck_require__(1017);
// Set up Octokit in the same way as @actions/github (see https://git.io/Jy9YP)
const baseUrl = process.env['GITHUB_API_URL'] || 'https://api.github.com';
const GitHub = core_1.Octokit.defaults({
@@ -653,6 +872,17 @@ const GitHub = core_1.Octokit.defaults({
agent: new httpClient.HttpClient().getAgent(baseUrl)
}
});
function exec(commandLine, args, options) {
return __awaiter(this, void 0, void 0, function* () {
const exitCode = yield (0, exec_1.exec)(commandLine, args, options);
if (exitCode !== 0) {
throw new Error(`'${[commandLine]
.concat(args || [])
.join(' ')}' exited with a non-zero code: ${exitCode}`);
}
});
}
exports.exec = exec;
function getLatestRelease(repo) {
return __awaiter(this, void 0, void 0, function* () {
const githubToken = core.getInput('github-token');
@@ -667,11 +897,11 @@ function getLatestRelease(repo) {
exports.getLatestRelease = getLatestRelease;
function downloadAndExtractJDK(downloadUrl) {
return __awaiter(this, void 0, void 0, function* () {
return findJavaHomeInSubfolder(yield downloadAndExtract(downloadUrl));
return findJavaHomeInSubfolder(yield extract(yield tc.downloadTool(downloadUrl)));
});
}
exports.downloadAndExtractJDK = downloadAndExtractJDK;
function downloadExtractAndCacheJDK(downloadUrl, toolName, version) {
function downloadExtractAndCacheJDK(downloader, toolName, version) {
return __awaiter(this, void 0, void 0, function* () {
const semVersion = toSemVer(version);
let toolPath = tc.find(toolName, semVersion);
@@ -679,7 +909,7 @@ function downloadExtractAndCacheJDK(downloadUrl, toolName, version) {
core.info(`Found ${toolName} ${version} in tool-cache @ ${toolPath}`);
}
else {
const extractDir = yield downloadAndExtract(downloadUrl);
const extractDir = yield extract(yield downloader());
core.info(`Adding ${toolName} ${version} to tool-cache ...`);
toolPath = yield tc.cacheDir(extractDir, toolName, semVersion);
}
@@ -687,17 +917,22 @@ function downloadExtractAndCacheJDK(downloadUrl, toolName, version) {
});
}
exports.downloadExtractAndCacheJDK = downloadExtractAndCacheJDK;
function downloadAndExtract(downloadUrl) {
function calculateSHA256(filePath) {
const hashSum = (0, crypto_1.createHash)('sha256');
hashSum.update((0, fs_1.readFileSync)(filePath));
return hashSum.digest('hex');
}
exports.calculateSHA256 = calculateSHA256;
function extract(downloadPath) {
return __awaiter(this, void 0, void 0, function* () {
const downloadPath = yield tc.downloadTool(downloadUrl);
if (downloadUrl.endsWith('.tar.gz')) {
if (c.GRAALVM_FILE_EXTENSION === '.tar.gz') {
return yield tc.extractTar(downloadPath);
}
else if (downloadUrl.endsWith('.zip')) {
else if (c.GRAALVM_FILE_EXTENSION === '.zip') {
return yield tc.extractZip(downloadPath);
}
else {
throw new Error(`Unexpected filetype downloaded: ${downloadUrl}`);
throw new Error(`Unexpected filetype downloaded: ${c.GRAALVM_FILE_EXTENSION}`);
}
});
}
@@ -6864,9 +7099,17 @@ AbortError.prototype = Object.create(Error.prototype);
AbortError.prototype.constructor = AbortError;
AbortError.prototype.name = 'AbortError';
const URL$1 = Url.URL || whatwgUrl.URL;
// fix an issue where "PassThrough", "resolve" aren't a named export for node <10
const PassThrough$1 = Stream.PassThrough;
const resolve_url = Url.resolve;
const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) {
const orig = new URL$1(original).hostname;
const dest = new URL$1(destination).hostname;
return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest);
};
/**
* Fetch function
@@ -6954,7 +7197,19 @@ function fetch(url, opts) {
const location = headers.get('Location');
// HTTP fetch step 5.3
const locationURL = location === null ? null : resolve_url(request.url, location);
let locationURL = null;
try {
locationURL = location === null ? null : new URL$1(location, request.url).toString();
} catch (err) {
// error here can only be invalid URL in Location: header
// do not throw when options.redirect == manual
// let the user extract the errorneous redirect URL
if (request.redirect !== 'manual') {
reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect'));
finalize();
return;
}
}
// HTTP fetch step 5.5
switch (request.redirect) {
@@ -7002,6 +7257,12 @@ function fetch(url, opts) {
size: request.size
};
if (!isDomainOrSubdomain(request.url, locationURL)) {
for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) {
requestOpts.headers.delete(name);
}
}
// HTTP-redirect fetch step 9
if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) {
reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect'));
@@ -11268,16 +11529,14 @@ function bytesToUuid(buf, offset) {
var i = offset || 0;
var bth = byteToHex;
// join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
return ([
bth[buf[i++]], bth[buf[i++]],
bth[buf[i++]], bth[buf[i++]], '-',
bth[buf[i++]], bth[buf[i++]], '-',
bth[buf[i++]], bth[buf[i++]], '-',
bth[buf[i++]], bth[buf[i++]], '-',
bth[buf[i++]], bth[buf[i++]],
bth[buf[i++]], bth[buf[i++]],
bth[buf[i++]], bth[buf[i++]]
]).join('');
return ([bth[buf[i++]], bth[buf[i++]],
bth[buf[i++]], bth[buf[i++]], '-',
bth[buf[i++]], bth[buf[i++]], '-',
bth[buf[i++]], bth[buf[i++]], '-',
bth[buf[i++]], bth[buf[i++]], '-',
bth[buf[i++]], bth[buf[i++]],
bth[buf[i++]], bth[buf[i++]],
bth[buf[i++]], bth[buf[i++]]]).join('');
}
module.exports = bytesToUuid;

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

28
package-lock.json generated
View File

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

View File

@@ -1,6 +1,6 @@
{
"name": "setup-graalvm",
"version": "1.0.3",
"version": "1.0.5",
"private": true,
"description": "GitHub Action for GraalVM",
"main": "lib/main.js",
@@ -32,10 +32,12 @@
"@actions/io": "^1.1.1",
"@actions/tool-cache": "^1.7.1",
"@octokit/core": "^3.5.1",
"@octokit/types": "^6.34.0"
"@octokit/types": "^6.34.0",
"uuid": "^3.3.2"
},
"devDependencies": {
"@types/node": "^17.0.6",
"@types/uuid": "^3.4.10",
"@typescript-eslint/parser": "^5.8.1",
"@vercel/ncc": "^0.33.1",
"eslint": "^8.6.0",

View File

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

View File

@@ -1,6 +1,6 @@
import * as core from '@actions/core'
import {GRAALVM_PLATFORM} from './constants'
import {exec} from '@actions/exec'
import {exec} from './utils'
const APT_GET_INSTALL_BASE = 'sudo apt-get -y --no-upgrade install'
const COMPONENT_TO_DEPS = new Map<string, Map<string, string>>([

View File

@@ -1,7 +1,7 @@
import * as core from '@actions/core'
import * as tc from '@actions/tool-cache'
import {IS_LINUX} from './constants'
import {exec} from '@actions/exec'
import {exec} from './utils'
import {join} from 'path'
const MUSL_NAME = 'x86_64-linux-musl-native'
@@ -25,7 +25,7 @@ export async function setUpNativeImageMusl(): Promise<void> {
const zlibVersion = '1.2.11'
const zlibDownloadPath = await tc.downloadTool(
`https://zlib.net/zlib-${zlibVersion}.tar.gz`
`https://zlib.net/fossils/zlib-${zlibVersion}.tar.gz`
)
const zlibExtractPath = await tc.extractTar(zlibDownloadPath)
const zlibPath = join(zlibExtractPath, `zlib-${zlibVersion}`)

220
src/gds.ts Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,9 +2,11 @@ import * as c from './constants'
import * as core from '@actions/core'
import * as httpClient from '@actions/http-client'
import * as tc from '@actions/tool-cache'
import {ExecOptions, exec as e} from '@actions/exec'
import {readFileSync, readdirSync} from 'fs'
import {Octokit} from '@octokit/core'
import {createHash} from 'crypto'
import {join} from 'path'
import {readdirSync} from 'fs'
// Set up Octokit in the same way as @actions/github (see https://git.io/Jy9YP)
const baseUrl = process.env['GITHUB_API_URL'] || 'https://api.github.com'
@@ -15,6 +17,21 @@ const GitHub = Octokit.defaults({
}
})
export async function exec(
commandLine: string,
args?: string[],
options?: ExecOptions | undefined
): Promise<void> {
const exitCode = await e(commandLine, args, options)
if (exitCode !== 0) {
throw new Error(
`'${[commandLine]
.concat(args || [])
.join(' ')}' exited with a non-zero code: ${exitCode}`
)
}
}
export async function getLatestRelease(
repo: string
): Promise<c.LatestReleaseResponse['data']> {
@@ -32,11 +49,13 @@ export async function getLatestRelease(
export async function downloadAndExtractJDK(
downloadUrl: string
): Promise<string> {
return findJavaHomeInSubfolder(await downloadAndExtract(downloadUrl))
return findJavaHomeInSubfolder(
await extract(await tc.downloadTool(downloadUrl))
)
}
export async function downloadExtractAndCacheJDK(
downloadUrl: string,
downloader: () => Promise<string>,
toolName: string,
version: string
): Promise<string> {
@@ -45,21 +64,28 @@ export async function downloadExtractAndCacheJDK(
if (toolPath) {
core.info(`Found ${toolName} ${version} in tool-cache @ ${toolPath}`)
} else {
const extractDir = await downloadAndExtract(downloadUrl)
const extractDir = await extract(await downloader())
core.info(`Adding ${toolName} ${version} to tool-cache ...`)
toolPath = await tc.cacheDir(extractDir, toolName, semVersion)
}
return findJavaHomeInSubfolder(toolPath)
}
async function downloadAndExtract(downloadUrl: string): Promise<string> {
const downloadPath = await tc.downloadTool(downloadUrl)
if (downloadUrl.endsWith('.tar.gz')) {
export function calculateSHA256(filePath: string): string {
const hashSum = createHash('sha256')
hashSum.update(readFileSync(filePath))
return hashSum.digest('hex')
}
async function extract(downloadPath: string): Promise<string> {
if (c.GRAALVM_FILE_EXTENSION === '.tar.gz') {
return await tc.extractTar(downloadPath)
} else if (downloadUrl.endsWith('.zip')) {
} else if (c.GRAALVM_FILE_EXTENSION === '.zip') {
return await tc.extractZip(downloadPath)
} else {
throw new Error(`Unexpected filetype downloaded: ${downloadUrl}`)
throw new Error(
`Unexpected filetype downloaded: ${c.GRAALVM_FILE_EXTENSION}`
)
}
}