Compare commits

...

29 Commits

Author SHA1 Message Date
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
Fabio Niephaus
ce3d4ac06f Bump version to 1.0.3. 2022-03-11 10:51:57 +01:00
Fabio Niephaus
1e505b051e Document amd64 and aarch64 support. [ci skip] 2022-03-08 11:36:49 +01:00
Fabio Niephaus
a004c8ff68 Update node-fetch dependency. 2022-03-08 11:19:20 +01:00
Fabio Niephaus
0f01291c2e Use semver-conform versions for tool-cache. 2022-03-08 11:12:22 +01:00
Fabio Niephaus
b76e2627a2 Add support for aarch64 builds (#9). 2022-03-08 10:47:41 +01:00
Fabio Niephaus
a02f4df8f7 Cache musl setup in GitHub tool-cache. 2022-03-01 11:45:43 +01:00
Fabio Niephaus
66dc2bf069 Cache installations in GitHub tool-cache.
Fixes #7
2022-03-01 11:45:02 +01:00
Fabio Niephaus
61450f0977 Upgrade to 22.0.0.2. 2022-01-25 16:24:36 +01:00
Fabio Niephaus
f497c46877 Update native-image-musl-build link in docs.
[ci skip]
2022-01-24 13:57:32 +01:00
Fabio Niephaus
778131f1d6 Introduce native-image-musl feature. 2022-01-24 13:57:00 +01:00
Fabio Niephaus
b1f65935b2 Build all branches on push, ignore md changes. 2022-01-21 13:21:47 +01:00
Fabio Niephaus
6d6c7fd57c Build Ruby-FFI instead of liquid on TruffleRuby. 2022-01-21 13:16:50 +01:00
Fabio Niephaus
0141e9fea8 Enable liquid tests.
Need to use latest dev build to get the fix for GR-36108.
2022-01-21 12:43:24 +01:00
Fabio Niephaus
f786ab1178 Bump version to 1.0.2. 2022-01-20 17:49:08 +01:00
Fabio Niephaus
d0a541650c Bump version to v1.0.1. 2022-01-14 10:23:47 +01:00
Fabio Niephaus
136636a1a5 Build dev branch changes. 2022-01-14 10:23:47 +01:00
Fabio Niephaus
0584de3fce Drop support for building GraalVM from source.
Closes #3.
2022-01-14 10:20:26 +01:00
Fabio Niephaus
308aa6ad2b Update README.md. 2022-01-14 10:10:06 +01:00
Fabio Niephaus
edfd5f7c8d Tweak README.md. [ci skip] 2022-01-05 12:57:17 +01:00
20 changed files with 1104 additions and 373 deletions

View File

@@ -9,6 +9,7 @@ on:
push:
branches:
- main
- dev
paths-ignore:
- '**.md'
pull_request:

View File

@@ -1,10 +1,13 @@
name: 'build-test'
on: # rebuild any PRs and main branch changes
pull_request:
on:
push:
branches:
- main
- 'releases/*'
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
workflow_dispatch:
jobs:
build: # make sure build/ci work properly
@@ -15,36 +18,28 @@ 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:
version: [latest, dev, trunk]
version: [latest, dev]
java-version: ['11']
components: ['native-image']
os: [macos-latest, windows-latest, ubuntu-latest]
include:
- version: '21.3.0'
- version: '22.0.0.2'
java-version: '17'
components: 'native-image'
os: ubuntu-18.04
- version: '21.3.0'
- version: '22.0.0.2'
java-version: '17'
components: 'native-image'
os: macos-11
- version: '21.3.0'
- version: '22.0.0.2'
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
@@ -57,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: ['21.3.0', 'latest']
java-version: ['11', '17']
components: [''] # ['native-image'] (activate after 22.1.0 is released)
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- uses: actions/checkout@v2
- name: Run setup-graalvm action
uses: ./
with:
version: ${{ matrix.version }}
gds-token: ${{ secrets.GDS_TOKEN }}
java-version: ${{ matrix.java-version }}
components: ${{ matrix.components }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Check environment
run: |
echo "GRAALVM_HOME: $GRAALVM_HOME"
[[ "$GRAALVM_HOME" == *"$RUNNER_TOOL_CACHE"* ]] || exit 12
echo "JAVA_HOME: $JAVA_HOME"
java --version
java --version | grep "GraalVM EE" || exit 23
# native-image --version (activate after 22.1.0 is released)
if: runner.os != 'Windows'
- name: Check Windows environment
run: |
echo "GRAALVM_HOME: $env:GRAALVM_HOME"
echo "JAVA_HOME: $env:JAVA_HOME"
java --version
# native-image --version (activate after 22.1.0 is released)
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
@@ -66,10 +134,28 @@ 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-additional:
name: Extensive tests on ubuntu-latest
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
steps:
- uses: actions/checkout@v2
@@ -78,6 +164,25 @@ jobs:
with:
version: 'latest'
java-version: '17'
components: 'native-image'
native-image-musl: 'true'
github-token: ${{ secrets.GITHUB_TOKEN }}
- 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-extensive:
name: extensive tests on ubuntu-latest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run setup-graalvm action
uses: ./
with:
version: 'dev'
java-version: '17'
components: 'espresso,llvm-toolchain,native-image,nodejs,python,R,ruby,wasm'
set-java-home: 'false'
github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -101,18 +206,20 @@ 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
native-image HelloWorld
./helloworld
# [GR-36108]: Liquid does not build on TruffleRuby
# - name: Build Shopify/liquid with TruffleRuby
# run: |
# [[ $(which bundle) == *"graalvm"* ]] || exit 57
# git clone --depth 1 https://github.com/Shopify/liquid.git
# pushd liquid > /dev/null
# bundle install --jobs=3 --retry=3 --path=vendor/bundle
# bundle exec rake
# popd > /dev/null
- name: Build Ruby-FFI with TruffleRuby
run: |
[[ $(which bundle) == *"graalvm"* ]] || exit 57
git clone --depth 1 https://github.com/ffi/ffi.git
pushd ffi > /dev/null
# https://github.com/ffi/ffi/blob/447845cb3030194c79700c86fb388a12e6f81386/.github/workflows/ci.yml#L58-L62
bundle install
bundle exec rake libffi
bundle exec rake compile
bundle exec rake test
popd > /dev/null

View File

@@ -1,5 +1,5 @@
# 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 [GraalVM languages][graalvm-languages].
This GitHub action sets up [GraalVM Community Edition][repo] and GraalVM components such as [Native Image][native-image] and [Truffle languages][truffle-languages].
## Key Features
@@ -8,8 +8,9 @@ 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]
- exports a `$GRAALVM_HOME` environment variable
- adds `$GRAALVM_HOME/bin` to the `$PATH` environment variable<br>(GraalVM tools such as `gu` and GraalVM languages can be invoked directly)
- 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])
- sets up Windows environments with build tools using [vcvarsall.bat][vcvarsall]
@@ -40,47 +41,39 @@ 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, '21.3.0']
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*
```
@@ -89,11 +82,13 @@ jobs:
| Name | Default | Description |
|-----------------|:--------:|-------------|
| `version`<br>*(required)* | n/a | `X.Y.Z` (e.g., `22.0.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], or<br>`mandrel-latest` for [latest Mandrel stable release][mandrel-stable]. |
| `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]. |
| `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. |
| `set-java-home` | `'true'` | If set to `'true'`, instructs the action to set `$JAVA_HOME` to the path of the GraalVM installation. |
| `native-image-musl` | `'false'` | If set to `'true'`, sets up [musl] for building [static images][native-image-static] with GraalVM Native Image *(Linux only)*. [Example usage][native-image-musl-build] (be sure to replace `uses: ./` with `uses: graalvm/setup-graalvm@v1`). |
## Contributing
@@ -104,14 +99,18 @@ 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
[graalvm-languages]: https://www.graalvm.org/reference-manual/languages/
[gh-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/
[mandrel]: https://github.com/graalvm/mandrel
[mandrel-releases]: https://github.com/graalvm/mandrel/releases
[mandrel-stable]: https://github.com/graalvm/mandrel/releases/latest
[musl]: https://musl.libc.org/
[native-image]: https://www.graalvm.org/native-image/
[native-image-musl-build]: https://github.com/graalvm/setup-graalvm/blob/778131f1d6837ccd4b2e91382c31830896a2d56e/.github/workflows/test.yml#L74-L92
[native-image-static]: https://github.com/oracle/graal/blob/fa6f4a974dedacf4688dcc430dd100849d9882f2/docs/reference-manual/native-image/StaticImages.md
[oca]: https://oca.opensource.oracle.com
[releases]: https://github.com/graalvm/graalvm-ce-builds/releases
[repo]: https://github.com/oracle/graal
[stable]: https://github.com/graalvm/graalvm-ce-builds/releases/latest
[truffle-languages]: https://www.graalvm.org/reference-manual/languages/
[vcvarsall]: https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line

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

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

View File

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

View File

@@ -1,5 +1,5 @@
name: 'GitHub Action for GraalVM'
description: 'Set up a specific version of GraalVM Community Edition'
description: 'Set up a specific version of GraalVM Enterprise Edition (EE) or Community Edition (CE)'
author: 'GraalVM Developers'
branding:
icon: 'terminal'
@@ -7,22 +7,29 @@ branding:
inputs:
version:
required: true
description: 'GraalVM version (release, latest, dev, trunk).'
description: 'GraalVM version (release, latest, dev).'
gds-token:
required: false
description: 'Download token for the GraalVM Download Service. Set this to use GraalVM EE.'
java-version:
required: true
description: 'Java version (11 or 17, 8 or 16 for older releases).'
components:
required: false
description: 'Comma-separated list of GraalVM components to be installed'
description: 'Comma-separated list of GraalVM components to be installed.'
default: ''
github-token:
required: false
description: 'Set it to secrets.GITHUB_TOKEN to increase rate limits when accessing the GitHub API'
description: 'Set it to secrets.GITHUB_TOKEN to increase rate limits when accessing the GitHub API.'
default: ''
set-java-home:
required: false
description: 'Set $JAVA_HOME to the GraalVM installation. Default: true'
description: 'Set $JAVA_HOME to the GraalVM installation. Default: true.'
default: 'true'
native-image-musl:
required: false
description: 'Set up musl for static image building with GraalVM Native Image.'
default: 'false'
runs:
using: 'node12'
main: 'dist/index.js'

546
dist/index.js generated vendored
View File

@@ -2,25 +2,38 @@ require('./sourcemap-register.js');/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ 5105:
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
/***/ ((__unused_webpack_module, exports) => {
"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_BASE = exports.VERSION_TRUNK = exports.VERSION_LATEST = exports.VERSION_DEV = exports.IS_WINDOWS = exports.IS_MACOS = void 0;
const os_1 = __nccwpck_require__(2037);
const path_1 = __nccwpck_require__(1017);
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';
exports.VERSION_DEV = 'dev';
exports.VERSION_LATEST = 'latest';
exports.VERSION_TRUNK = 'trunk';
exports.GRAALVM_BASE = (0, path_1.join)((0, os_1.homedir)(), '.graalvm');
exports.GRAALVM_ARCH = determineGraalVMArchitecture();
exports.GRAALVM_FILE_EXTENSION = exports.IS_WINDOWS ? '.zip' : '.tar.gz';
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': {
return 'amd64';
}
case 'arm64': {
return 'aarch64';
}
default: {
throw new Error(`Unsupported architecture: ${process.arch}`);
}
}
}
/***/ }),
@@ -62,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([
[
@@ -86,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();
}
}
@@ -98,7 +111,7 @@ exports.setUpDependencies = setUpDependencies;
/***/ }),
/***/ 7538:
/***/ 5938:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@@ -132,92 +145,238 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.setUpGraalVMTrunk = void 0;
const c = __importStar(__nccwpck_require__(5105));
exports.setUpNativeImageMusl = void 0;
const core = __importStar(__nccwpck_require__(2186));
const tc = __importStar(__nccwpck_require__(7784));
const child_process_1 = __nccwpck_require__(2081);
const io_1 = __nccwpck_require__(7436);
const constants_1 = __nccwpck_require__(5105);
const utils_1 = __nccwpck_require__(918);
const path_1 = __nccwpck_require__(1017);
const GRAALVM_TRUNK_DL = 'https://github.com/oracle/graal/archive/refs/heads/master.zip';
const GRAALVM_MX_DL = 'https://github.com/graalvm/mx/archive/refs/heads/master.zip';
const DEFAULT_SUITES = '/compiler,/regex,/sdk,/tools,/truffle';
const GRAAL_REPO_DIR = (0, path_1.join)(c.GRAALVM_BASE, 'graal');
const VM_DIR = (0, path_1.join)(GRAAL_REPO_DIR, 'vm');
const MX_DIR = (0, path_1.join)(c.GRAALVM_BASE, 'mx');
const MX_EXEC = c.IS_WINDOWS ? 'mx.cmd' : 'mx';
const SPAWN_OPTIONS = {
cwd: VM_DIR,
encoding: 'utf8',
stdio: 'inherit'
};
const COMPONENTS_TO_SUITE_NAME = new Map([
['espresso', '/espresso'],
['js', '/graal-js'],
['llvm-toolchain', '/sulong'],
['native-image', '/substratevm'],
['nodejs', '/graal-nodejs'],
['python', 'graalpython'],
['R', 'fastr'],
['ruby', 'truffleruby'],
['wasm', '/wasm']
]);
function setUpGraalVMTrunk(javaVersion, components) {
const MUSL_NAME = 'x86_64-linux-musl-native';
const MUSL_VERSION = '10.2.1';
function setUpNativeImageMusl() {
return __awaiter(this, void 0, void 0, function* () {
const jdkId = `labsjdk-ce-${javaVersion}`;
core.startGroup(`Downloading GraalVM sources, mx, and ${jdkId}...`);
yield tc.extractZip(yield tc.downloadTool(GRAALVM_TRUNK_DL), c.GRAALVM_BASE);
yield (0, io_1.mv)((0, path_1.join)(c.GRAALVM_BASE, 'graal-master'), GRAAL_REPO_DIR);
yield tc.extractZip(yield tc.downloadTool(GRAALVM_MX_DL), c.GRAALVM_BASE);
yield (0, io_1.mv)((0, path_1.join)(c.GRAALVM_BASE, 'mx-master'), MX_DIR);
core.addPath(MX_DIR);
core.debug(`"${MX_DIR}" added to $PATH`);
const labsJDKDir = (0, path_1.join)(c.GRAALVM_BASE, 'labsjdk');
yield (0, io_1.mkdirP)(labsJDKDir);
(0, child_process_1.spawnSync)(MX_EXEC, ['--java-home=', 'fetch-jdk', '--jdk-id', jdkId, '--to', labsJDKDir], SPAWN_OPTIONS);
const labsJDKHome = (0, utils_1.findJavaHomeInSubfolder)(labsJDKDir);
core.exportVariable('JAVA_HOME', labsJDKHome);
core.debug(`$JAVA_HOME set to "${labsJDKHome}"`);
core.endGroup();
const dynamicImports = toSuiteNames(components).join(',');
const mxArgs = [
'--no-download-progress',
'--disable-installables=true',
'--force-bash-launchers=true',
'--disable-libpolyglot',
'--exclude-components=LibGraal',
'--dynamicimports',
dynamicImports
];
if (core.isDebug()) {
(0, child_process_1.spawnSync)(MX_EXEC, mxArgs.concat('graalvm-show'), SPAWN_OPTIONS);
if (!constants_1.IS_LINUX) {
core.warning('musl is only supported on Linux');
return;
}
const graalvmHome = (0, child_process_1.spawnSync)(MX_EXEC, mxArgs.concat(['graalvm-home']), Object.assign(Object.assign({}, SPAWN_OPTIONS), { stdio: 'pipe' }));
core.startGroup('Building GraalVM CE from source...');
(0, child_process_1.spawnSync)(MX_EXEC, mxArgs.concat(['build']), SPAWN_OPTIONS);
core.endGroup();
const graalvmHomePath = graalvmHome.stdout.trim();
if (core.isDebug()) {
const cmd = c.IS_WINDOWS ? 'dir' : 'ls';
(0, child_process_1.spawnSync)(cmd, [graalvmHomePath], { stdio: 'inherit' });
}
return graalvmHomePath;
});
}
exports.setUpGraalVMTrunk = setUpGraalVMTrunk;
function toSuiteNames(components) {
const names = [DEFAULT_SUITES];
for (const component of components) {
const suiteName = COMPONENTS_TO_SUITE_NAME.get(component);
if (suiteName) {
names.push(suiteName);
let toolPath = tc.find(MUSL_NAME, MUSL_VERSION);
if (toolPath) {
core.info(`Found ${MUSL_NAME} ${MUSL_VERSION} in tool-cache @ ${toolPath}`);
}
else {
throw new Error(`Unsupported component: ${component}`);
core.startGroup(`Setting up musl for GraalVM Native Image...`);
const muslDownloadPath = yield tc.downloadTool(`http://more.musl.cc/10/x86_64-linux-musl/${MUSL_NAME}.tgz`);
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/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, 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();
}
core.addPath((0, path_1.join)(toolPath, 'bin'));
});
}
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.4 (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=timeCreated&limit=1`; // latest and only one item
}
else {
filter = `metadata=version:${version}`;
}
const response = yield http.get(`${c.GDS_BASE}/artifacts?productId=${c.GDS_GRAALVM_PRODUCT_ID}&${filter}&metadata=java:jdk${javaVersion}&metadata=os:${c.GRAALVM_PLATFORM}&metadata=arch:${c.GRAALVM_ARCH}&metadata=${metadata}&status=PUBLISHED&responseFields=id&responseFields=checksum`, { accept: 'application/json' });
if (response.message.statusCode !== 200) {
throw new Error(`Unable to find JDK${javaVersion}-based GraalVM EE ${version}`);
}
const artifactResponse = JSON.parse(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);
}
return names;
}
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;
}
@@ -260,26 +419,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) {
@@ -290,16 +457,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}`;
return (0, utils_1.downloadAndExtractJDK)(downloadUrl);
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}-amd64-${version}`;
function determineGraalVMIdentifier(isEE, version, javaVersion) {
return `graalvm-${isEE ? 'ee' : 'ce'}-java${javaVersion}-${c.GRAALVM_PLATFORM}-${c.GRAALVM_ARCH}-${version}`;
}
function determineToolName(isEE, javaVersion) {
return `graalvm-${isEE ? 'ee' : 'ce'}-java${javaVersion}-${c.GRAALVM_PLATFORM}`;
}
@@ -322,8 +501,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',
@@ -341,15 +521,19 @@ 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));
const optionalFlags = [];
if (gdsToken.length > 0) {
optionalFlags.push('--token', gdsToken);
}
yield (0, utils_1.exec)('gu', BASE_FLAGS.concat(optionalFlags, components));
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)}"`);
}
}
}
@@ -398,44 +582,43 @@ const c = __importStar(__nccwpck_require__(5105));
const core = __importStar(__nccwpck_require__(2186));
const graalvm = __importStar(__nccwpck_require__(1763));
const path_1 = __nccwpck_require__(1017);
const io_1 = __nccwpck_require__(7436);
const dependencies_1 = __nccwpck_require__(6031);
const gu_1 = __nccwpck_require__(3466);
const graalvm_trunk_1 = __nccwpck_require__(7538);
const mandrel_1 = __nccwpck_require__(438);
const features_1 = __nccwpck_require__(5938);
const msvc_1 = __nccwpck_require__(4765);
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(',') : [];
const setJavaHome = core.getInput('set-java-home') === 'true';
const enableNativeImageMusl = core.getInput('native-image-musl') === 'true';
if (c.IS_WINDOWS) {
(0, msvc_1.setUpWindowsEnvironment)();
}
(0, dependencies_1.setUpDependencies)(components);
yield (0, io_1.mkdirP)(c.GRAALVM_BASE);
yield (0, dependencies_1.setUpDependencies)(components);
if (enableNativeImageMusl) {
yield (0, features_1.setUpNativeImageMusl)();
}
// Download or build GraalVM
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);
break;
case c.VERSION_TRUNK:
core.warning("Building GraalVM from source is deprecated and will be removed on Jan 10, 2022. Please use the latest dev build instead (version: 'dev'). For more details see https://github.com/graalvm/setup-graalvm/issues/3");
graalVMHome = yield (0, graalvm_trunk_1.setUpGraalVMTrunk)(javaVersion, components);
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;
}
@@ -448,14 +631,11 @@ function run() {
}
// Set up GraalVM components (if any)
if (components.length > 0) {
if (graalvmVersion === c.VERSION_TRUNK) {
// components built from source, nothing to do
}
else if (graalvmVersion.startsWith(c.MANDREL_NAMESPACE)) {
if (graalvmVersion.startsWith(c.MANDREL_NAMESPACE)) {
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);
}
}
}
@@ -507,6 +687,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';
@@ -541,11 +722,15 @@ function setUpMandrelRelease(version, javaVersion) {
return __awaiter(this, void 0, void 0, function* () {
const identifier = determineMandrelIdentifier(version, javaVersion);
const downloadUrl = `${MANDREL_DL_BASE}/${MANDREL_TAG_PREFIX}${version}/${identifier}${c.GRAALVM_FILE_EXTENSION}`;
return (0, utils_1.downloadAndExtractJDK)(downloadUrl);
const toolName = determineToolName(javaVersion);
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) {
return `mandrel-java${javaVersion}-${c.GRAALVM_PLATFORM}-amd64-${version}`;
return `mandrel-java${javaVersion}-${c.GRAALVM_PLATFORM}-${c.GRAALVM_ARCH}-${version}`;
}
function determineToolName(javaVersion) {
return `mandrel-java${javaVersion}-${c.GRAALVM_PLATFORM}`;
}
@@ -668,14 +853,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.findJavaHomeInSubfolder = 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({
@@ -684,6 +871,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');
@@ -698,20 +896,45 @@ function getLatestRelease(repo) {
exports.getLatestRelease = getLatestRelease;
function downloadAndExtractJDK(downloadUrl) {
return __awaiter(this, void 0, void 0, function* () {
const downloadPath = yield tc.downloadTool(downloadUrl);
if (downloadUrl.endsWith('.tar.gz')) {
yield tc.extractTar(downloadPath, c.GRAALVM_BASE);
}
else if (downloadUrl.endsWith('.zip')) {
yield tc.extractZip(downloadPath, c.GRAALVM_BASE);
}
else {
throw new Error(`Unexpected filetype downloaded: ${downloadUrl}`);
}
return findJavaHomeInSubfolder(c.GRAALVM_BASE);
return findJavaHomeInSubfolder(yield extract(yield tc.downloadTool(downloadUrl)));
});
}
exports.downloadAndExtractJDK = downloadAndExtractJDK;
function downloadExtractAndCacheJDK(downloader, toolName, version) {
return __awaiter(this, void 0, void 0, function* () {
const semVersion = toSemVer(version);
let toolPath = tc.find(toolName, semVersion);
if (toolPath) {
core.info(`Found ${toolName} ${version} in tool-cache @ ${toolPath}`);
}
else {
const extractDir = yield extract(yield downloader());
core.info(`Adding ${toolName} ${version} to tool-cache ...`);
toolPath = yield tc.cacheDir(extractDir, toolName, semVersion);
}
return findJavaHomeInSubfolder(toolPath);
});
}
exports.downloadExtractAndCacheJDK = downloadExtractAndCacheJDK;
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* () {
if (c.GRAALVM_FILE_EXTENSION === '.tar.gz') {
return yield tc.extractTar(downloadPath);
}
else if (c.GRAALVM_FILE_EXTENSION === '.zip') {
return yield tc.extractZip(downloadPath);
}
else {
throw new Error(`Unexpected filetype downloaded: ${c.GRAALVM_FILE_EXTENSION}`);
}
});
}
function findJavaHomeInSubfolder(searchPath) {
const baseContents = (0, fs_1.readdirSync)(searchPath);
if (baseContents.length === 1) {
@@ -721,7 +944,18 @@ function findJavaHomeInSubfolder(searchPath) {
throw new Error(`Unexpected amount of directory items found: ${baseContents.length}`);
}
}
exports.findJavaHomeInSubfolder = findJavaHomeInSubfolder;
/**
* 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.
*/
function toSemVer(version) {
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}`;
}
/***/ }),
@@ -6864,9 +7098,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 +7196,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 +7256,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 +11528,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

52
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "setup-graalvm",
"version": "1.0.0",
"version": "1.0.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "setup-graalvm",
"version": "1.0.0",
"version": "1.0.2",
"license": "UPL",
"dependencies": {
"@actions/core": "^1.6.0",
@@ -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",
@@ -5000,14 +5008,22 @@
"dev": true
},
"node_modules/node-fetch": {
"version": "2.6.6",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz",
"integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==",
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/node-fetch/node_modules/tr46": {
@@ -6088,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"
@@ -7381,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",
@@ -10136,9 +10158,9 @@
"dev": true
},
"node-fetch": {
"version": "2.6.6",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz",
"integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==",
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"requires": {
"whatwg-url": "^5.0.0"
},
@@ -10930,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.0",
"version": "1.0.4",
"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

@@ -1,15 +1,13 @@
import * as otypes from '@octokit/types'
import {homedir} from 'os'
import {join} from 'path'
export const IS_LINUX = process.platform === 'linux'
export const IS_MACOS = process.platform === 'darwin'
export const IS_WINDOWS = process.platform === 'win32'
export const VERSION_DEV = 'dev'
export const VERSION_LATEST = 'latest'
export const VERSION_TRUNK = 'trunk'
export const GRAALVM_BASE = join(homedir(), '.graalvm')
export const GRAALVM_ARCH = determineGraalVMArchitecture()
export const GRAALVM_FILE_EXTENSION = IS_WINDOWS ? '.zip' : '.tar.gz'
export const GRAALVM_GH_USER = 'graalvm'
export const GRAALVM_PLATFORM = IS_WINDOWS ? 'windows' : process.platform
@@ -17,5 +15,22 @@ 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']
function determineGraalVMArchitecture(): string {
switch (process.arch) {
case 'x64': {
return 'amd64'
}
case 'arm64': {
return 'aarch64'
}
default: {
throw new Error(`Unsupported architecture: ${process.arch}`)
}
}
}

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>>([

52
src/features.ts Normal file
View File

@@ -0,0 +1,52 @@
import * as core from '@actions/core'
import * as tc from '@actions/tool-cache'
import {IS_LINUX} from './constants'
import {exec} from './utils'
import {join} from 'path'
const MUSL_NAME = 'x86_64-linux-musl-native'
const MUSL_VERSION = '10.2.1'
export async function setUpNativeImageMusl(): Promise<void> {
if (!IS_LINUX) {
core.warning('musl is only supported on Linux')
return
}
let toolPath = tc.find(MUSL_NAME, MUSL_VERSION)
if (toolPath) {
core.info(`Found ${MUSL_NAME} ${MUSL_VERSION} in tool-cache @ ${toolPath}`)
} else {
core.startGroup(`Setting up musl for GraalVM Native Image...`)
const muslDownloadPath = await tc.downloadTool(
`http://more.musl.cc/10/x86_64-linux-musl/${MUSL_NAME}.tgz`
)
const muslExtractPath = await tc.extractTar(muslDownloadPath)
const muslPath = join(muslExtractPath, MUSL_NAME)
const zlibVersion = '1.2.11'
const zlibDownloadPath = await tc.downloadTool(
`https://zlib.net/fossils/zlib-${zlibVersion}.tar.gz`
)
const zlibExtractPath = await tc.extractTar(zlibDownloadPath)
const zlibPath = join(zlibExtractPath, `zlib-${zlibVersion}`)
const zlibBuildOptions = {
cwd: zlibPath,
env: {
...process.env,
CC: join(muslPath, 'bin', 'gcc')
}
}
await exec(
'./configure',
[`--prefix=${muslPath}`, '--static'],
zlibBuildOptions
)
await exec('make', [], zlibBuildOptions)
await exec('make', ['install'], {cwd: zlibPath})
core.info(`Adding ${MUSL_NAME} ${MUSL_VERSION} to tool-cache ...`)
toolPath = await tc.cacheDir(muslPath, MUSL_NAME, MUSL_VERSION)
core.endGroup()
}
core.addPath(join(toolPath, 'bin'))
}

220
src/gds.ts Normal file
View File

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

View File

@@ -1,104 +0,0 @@
import * as c from './constants'
import * as core from '@actions/core'
import * as tc from '@actions/tool-cache'
import {SpawnSyncOptionsWithStringEncoding, spawnSync} from 'child_process'
import {mkdirP, mv} from '@actions/io'
import {findJavaHomeInSubfolder} from './utils'
import {join} from 'path'
const GRAALVM_TRUNK_DL =
'https://github.com/oracle/graal/archive/refs/heads/master.zip'
const GRAALVM_MX_DL =
'https://github.com/graalvm/mx/archive/refs/heads/master.zip'
const DEFAULT_SUITES = '/compiler,/regex,/sdk,/tools,/truffle'
const GRAAL_REPO_DIR = join(c.GRAALVM_BASE, 'graal')
const VM_DIR = join(GRAAL_REPO_DIR, 'vm')
const MX_DIR = join(c.GRAALVM_BASE, 'mx')
const MX_EXEC = c.IS_WINDOWS ? 'mx.cmd' : 'mx'
const SPAWN_OPTIONS: SpawnSyncOptionsWithStringEncoding = {
cwd: VM_DIR,
encoding: 'utf8',
stdio: 'inherit'
}
const COMPONENTS_TO_SUITE_NAME = new Map<string, string>([
['espresso', '/espresso'],
['js', '/graal-js'],
['llvm-toolchain', '/sulong'],
['native-image', '/substratevm'],
['nodejs', '/graal-nodejs'],
['python', 'graalpython'],
['R', 'fastr'],
['ruby', 'truffleruby'],
['wasm', '/wasm']
])
export async function setUpGraalVMTrunk(
javaVersion: string,
components: string[]
): Promise<string> {
const jdkId = `labsjdk-ce-${javaVersion}`
core.startGroup(`Downloading GraalVM sources, mx, and ${jdkId}...`)
await tc.extractZip(await tc.downloadTool(GRAALVM_TRUNK_DL), c.GRAALVM_BASE)
await mv(join(c.GRAALVM_BASE, 'graal-master'), GRAAL_REPO_DIR)
await tc.extractZip(await tc.downloadTool(GRAALVM_MX_DL), c.GRAALVM_BASE)
await mv(join(c.GRAALVM_BASE, 'mx-master'), MX_DIR)
core.addPath(MX_DIR)
core.debug(`"${MX_DIR}" added to $PATH`)
const labsJDKDir = join(c.GRAALVM_BASE, 'labsjdk')
await mkdirP(labsJDKDir)
spawnSync(
MX_EXEC,
['--java-home=', 'fetch-jdk', '--jdk-id', jdkId, '--to', labsJDKDir],
SPAWN_OPTIONS
)
const labsJDKHome = findJavaHomeInSubfolder(labsJDKDir)
core.exportVariable('JAVA_HOME', labsJDKHome)
core.debug(`$JAVA_HOME set to "${labsJDKHome}"`)
core.endGroup()
const dynamicImports = toSuiteNames(components).join(',')
const mxArgs = [
'--no-download-progress', // avoid cluttering the build log
'--disable-installables=true', // installables not needed
'--force-bash-launchers=true', // disable native launchers
'--disable-libpolyglot', // avoid building libpolyglot to save time
'--exclude-components=LibGraal', // avoid building libgraal to save time
'--dynamicimports',
dynamicImports
]
if (core.isDebug()) {
spawnSync(MX_EXEC, mxArgs.concat('graalvm-show'), SPAWN_OPTIONS)
}
const graalvmHome = spawnSync(MX_EXEC, mxArgs.concat(['graalvm-home']), {
...SPAWN_OPTIONS,
stdio: 'pipe'
})
core.startGroup('Building GraalVM CE from source...')
spawnSync(MX_EXEC, mxArgs.concat(['build']), SPAWN_OPTIONS)
core.endGroup()
const graalvmHomePath = graalvmHome.stdout.trim()
if (core.isDebug()) {
const cmd = c.IS_WINDOWS ? 'dir' : 'ls'
spawnSync(cmd, [graalvmHomePath], {stdio: 'inherit'})
}
return graalvmHomePath
}
function toSuiteNames(components: string[]): string[] {
const names = [DEFAULT_SUITES]
for (const component of components) {
const suiteName = COMPONENTS_TO_SUITE_NAME.get(component)
if (suiteName) {
names.push(suiteName)
} else {
throw new Error(`Unsupported component: ${component}`)
}
}
return names
}

View File

@@ -1,5 +1,11 @@
import * as c from './constants'
import {downloadAndExtractJDK, getLatestRelease} from './utils'
import {
downloadAndExtractJDK,
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'
@@ -7,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)) {
@@ -15,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) {
@@ -35,17 +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}`
return downloadAndExtractJDK(downloadUrl)
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}-amd64-${version}`
return `graalvm-${isEE ? 'ee' : 'ce'}-java${javaVersion}-${
c.GRAALVM_PLATFORM
}-${c.GRAALVM_ARCH}-${version}`
}
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))
const optionalFlags = []
if (gdsToken.length > 0) {
optionalFlags.push('--token', gdsToken)
}
await exec('gu', BASE_FLAGS.concat(optionalFlags, components))
const platformHooks = COMPONENT_TO_POST_INSTALL_HOOK.get(GRAALVM_PLATFORM)
if (platformHooks) {

View File

@@ -2,49 +2,46 @@ import * as c from './constants'
import * as core from '@actions/core'
import * as graalvm from './graalvm'
import {join} from 'path'
import {mkdirP} from '@actions/io'
import {setUpDependencies} from './dependencies'
import {setUpGUComponents} from './gu'
import {setUpGraalVMTrunk} from './graalvm-trunk'
import {setUpMandrel} from './mandrel'
import {setUpNativeImageMusl} from './features'
import {setUpWindowsEnvironment} from './msvc'
async function run(): Promise<void> {
try {
const graalvmVersion: string = core.getInput('version', {required: true})
const javaVersion: string = core.getInput('java-version', {required: true})
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[] =
componentsString.length > 0 ? componentsString.split(',') : []
const setJavaHome = core.getInput('set-java-home') === 'true'
const enableNativeImageMusl = core.getInput('native-image-musl') === 'true'
if (c.IS_WINDOWS) {
setUpWindowsEnvironment()
}
setUpDependencies(components)
await mkdirP(c.GRAALVM_BASE)
await setUpDependencies(components)
if (enableNativeImageMusl) {
await setUpNativeImageMusl()
}
// Download or build GraalVM
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)
break
case c.VERSION_TRUNK:
core.warning(
"Building GraalVM from source is deprecated and will be removed on Jan 10, 2022. Please use the latest dev build instead (version: 'dev'). For more details see https://github.com/graalvm/setup-graalvm/issues/3"
)
graalVMHome = await setUpGraalVMTrunk(javaVersion, components)
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,14 +59,12 @@ async function run(): Promise<void> {
// Set up GraalVM components (if any)
if (components.length > 0) {
if (graalvmVersion === c.VERSION_TRUNK) {
// components built from source, nothing to do
} else if (graalvmVersion.startsWith(c.MANDREL_NAMESPACE)) {
if (graalvmVersion.startsWith(c.MANDREL_NAMESPACE)) {
core.warning(
`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 {downloadAndExtractJDK, getLatestRelease} from './utils'
import {downloadExtractAndCacheJDK, getLatestRelease} from './utils'
import {downloadTool} from '@actions/tool-cache'
const MANDREL_REPO = 'mandrel'
const MANDREL_TAG_PREFIX = c.MANDREL_NAMESPACE
@@ -46,12 +47,21 @@ async function setUpMandrelRelease(
): Promise<string> {
const identifier = determineMandrelIdentifier(version, javaVersion)
const downloadUrl = `${MANDREL_DL_BASE}/${MANDREL_TAG_PREFIX}${version}/${identifier}${c.GRAALVM_FILE_EXTENSION}`
return downloadAndExtractJDK(downloadUrl)
const toolName = determineToolName(javaVersion)
return downloadExtractAndCacheJDK(
async () => downloadTool(downloadUrl),
toolName,
version
)
}
function determineMandrelIdentifier(
version: string,
javaVersion: string
): string {
return `mandrel-java${javaVersion}-${c.GRAALVM_PLATFORM}-amd64-${version}`
return `mandrel-java${javaVersion}-${c.GRAALVM_PLATFORM}-${c.GRAALVM_ARCH}-${version}`
}
function determineToolName(javaVersion: string): string {
return `mandrel-java${javaVersion}-${c.GRAALVM_PLATFORM}`
}

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,18 +49,47 @@ export async function getLatestRelease(
export async function downloadAndExtractJDK(
downloadUrl: string
): Promise<string> {
const downloadPath = await tc.downloadTool(downloadUrl)
if (downloadUrl.endsWith('.tar.gz')) {
await tc.extractTar(downloadPath, c.GRAALVM_BASE)
} else if (downloadUrl.endsWith('.zip')) {
await tc.extractZip(downloadPath, c.GRAALVM_BASE)
} else {
throw new Error(`Unexpected filetype downloaded: ${downloadUrl}`)
}
return findJavaHomeInSubfolder(c.GRAALVM_BASE)
return findJavaHomeInSubfolder(
await extract(await tc.downloadTool(downloadUrl))
)
}
export function findJavaHomeInSubfolder(searchPath: string): string {
export async function downloadExtractAndCacheJDK(
downloader: () => Promise<string>,
toolName: string,
version: string
): Promise<string> {
const semVersion = toSemVer(version)
let toolPath = tc.find(toolName, semVersion)
if (toolPath) {
core.info(`Found ${toolName} ${version} in tool-cache @ ${toolPath}`)
} else {
const extractDir = await extract(await downloader())
core.info(`Adding ${toolName} ${version} to tool-cache ...`)
toolPath = await tc.cacheDir(extractDir, toolName, semVersion)
}
return findJavaHomeInSubfolder(toolPath)
}
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 (c.GRAALVM_FILE_EXTENSION === '.zip') {
return await tc.extractZip(downloadPath)
} else {
throw new Error(
`Unexpected filetype downloaded: ${c.GRAALVM_FILE_EXTENSION}`
)
}
}
function findJavaHomeInSubfolder(searchPath: string): string {
const baseContents = readdirSync(searchPath)
if (baseContents.length === 1) {
return join(searchPath, baseContents[0], c.JDK_HOME_SUFFIX)
@@ -53,3 +99,16 @@ export 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.
*/
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}`
}