Compare commits

...

17 Commits
v1.5 ... v1.7.0

Author SHA1 Message Date
Sascha Mann
e7e85c4fe5 Add production dependencies & build 2022-05-21 21:54:14 +02:00
Sascha Mann
800ff44572 Bump version 2022-05-21 21:52:30 +02:00
Sascha Mann
6966335537 Add support for aarch64 (#102)
Setting the `arch` input to `aarch64` will install `aarch64` binaries,
intended to be used on aarch64-based self-hosted runners.

Please note that we currently don't run test builds on that
architecture, so we cannot guarantee that the input won't break
randomly, although there is no reason why it would.

In a future update, we may choose a default architecture based on the
arch of the runner.

Thanks to @giordano for providing a self-hosted runner for testing.

Co-authored-by: Mosè Giordano <mose@gnu.org>
2022-05-21 21:50:58 +02:00
Sascha Mann
f29cb961e8 Add manual trigger for example builds (#90) 2022-04-28 02:45:33 +00:00
dependabot[bot]
b69122e25a Bump ajv from 6.12.0 to 6.12.6 (#93)
Bumps [ajv](https://github.com/ajv-validator/ajv) from 6.12.0 to 6.12.6.
- [Release notes](https://github.com/ajv-validator/ajv/releases)
- [Commits](https://github.com/ajv-validator/ajv/compare/v6.12.0...v6.12.6)

---
updated-dependencies:
- dependency-name: ajv
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-13 08:52:40 +01:00
dependabot[bot]
1777cc3f15 Bump ws from 5.2.2 to 5.2.3 (#97)
Bumps [ws](https://github.com/websockets/ws) from 5.2.2 to 5.2.3.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/5.2.2...5.2.3)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-12 22:28:15 +01:00
Sascha Mann
2bb1080a55 Use 1.8-nightly in scheduled tests (#94) 2022-03-12 19:19:06 +01:00
Chris de Graaf
2d69597029 Throw an informative error for non-existent version (#86)
* Throw an informative error for non-existent version

* npm install && npm run build
2021-08-05 16:36:30 +02:00
Sascha Mann
f577b7c336 Use 1.7-nightly in scheduled test builds (#83) 2021-06-27 01:50:21 +02:00
Fons van der Plas
a12d4d2f6d Update README.md (#82) 2021-06-23 04:11:58 -04:00
dependabot[bot]
3dcf5f495f Bump hosted-git-info from 2.8.8 to 2.8.9 (#81)
Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-10 14:38:38 +02:00
dependabot[bot]
f473b6b037 Bump lodash from 4.17.19 to 4.17.21 (#80)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.19 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.19...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-10 10:02:29 +02:00
dependabot-preview[bot]
afa5e14af0 Upgrade to GitHub-native Dependabot (#79)
Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-04-29 15:05:30 -04:00
dependabot-preview[bot]
01d5d7138b [Security] Bump y18n from 4.0.0 to 4.0.1 (#78) 2021-03-29 18:51:03 +00:00
Sascha Mann
6fd5c3fbaf Only allow download URLs pointing at the official S3 URL (#71)
fixes #52
2021-01-13 05:18:46 -05:00
Sascha Mann
d57803fb22 Retry if download fails for any reason (#70)
fixes #35
2021-01-13 10:03:56 +00:00
Sascha Mann
e11d58a9c2 Change show-versioninfo to always print full info for nightlies (#68)
Co-authored-by: Derk-Jan Karrenbeld <derk-jan+github@karrenbeld.info>
2021-01-13 09:35:46 +00:00
13 changed files with 13938 additions and 80 deletions

7
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,7 @@
version: 2
updates:
- package-ecosystem: gitsubmodule
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10

View File

@@ -13,7 +13,7 @@ jobs:
strategy:
fail-fast: false
matrix:
julia-version: [nightly, 1.6-nightly]
julia-version: [nightly, 1.8-nightly]
julia-arch: [x64, x86]
os: [ubuntu-latest, macOS-latest, windows-latest]
# 32-bit Julia binaries are not available on macOS
@@ -35,5 +35,5 @@ jobs:
with:
version: ${{ matrix.julia-version }}
arch: ${{ matrix.julia-arch }}
show-versioninfo: 'true'
- run: julia --version
- run: julia --compile=min -O0 -e 'import InteractiveUtils; InteractiveUtils.versioninfo()'

View File

@@ -4,6 +4,7 @@ on:
push:
branches: ['main', 'master', 'releases/*']
pull_request:
workflow_dispatch:
jobs:
test:
@@ -34,5 +35,5 @@ jobs:
with:
version: ${{ matrix.julia-version }}
arch: ${{ matrix.julia-arch }}
show-versioninfo: 'true'
- run: julia --version
- run: julia --compile=min -O0 -e 'import InteractiveUtils; InteractiveUtils.versioninfo()'

2
.gitignore vendored
View File

@@ -1,3 +1,3 @@
node_modules/
__tests__/runner/*
dist/
!dist/

View File

@@ -38,13 +38,27 @@ This action sets up a Julia environment for use in actions by downloading a spec
# The architecture of the Julia binaries.
#
# Supported values: x64 | x86
# Please note that installing aarch64 binaries only makes sense on self-hosted aarch64 runners.
# We currently don't run test builds on that architecture, so we cannot guarantee that the input won't break randomly,
# although there is no reason why it would.
#
# Supported values: x64 | x86 | aarch64 (untested)
#
# Default: x64
arch: ''
# If true, display the output of InteractiveUtils.versioninfo() after installing.
# See "versioninfo" below for example usage.
# Set the display setting for printing InteractiveUtils.versioninfo() after installing.
#
# Starting Julia and running InteractiveUtils.versioninfo() takes a significant amount of time (1s or ~10% of the total build time in testing),
# so you may not want to run it in every build, in particular on paid runners, as this cost will add up quickly.
#
# See "versioninfo" below for example usage and further explanations.
#
# Supported values: true | false | never
#
# true: Always print versioninfo
# false: Only print versioninfo for nightly Julia
# never: Never print versioninfo
#
# Default: false
show-versioninfo: ''
@@ -93,7 +107,7 @@ You can either specify specific Julia versions or version ranges. If you specify
- `^1.3.0-0` is a **caret** version range that includes _all_ pre-releases. It matches all versions `≥ 1.3.0-` and `< 2.0.0`.
- `~1.3.0-0` is a **tilde** version range that includes _all_ pre-releases. It matches all versions `≥ 1.3.0-` and `< 1.4.0`.
- `nightly` will install the latest nightly build.
- `1.6-nightly` will install the latest nightly build for the upcoming 1.6 release. This version will only be available during certain phases of the Julia release cycle.
- `1.7-nightly` will install the latest nightly build for the upcoming 1.7 release. This version will only be available during certain phases of the Julia release cycle.
Internally the action uses node's semver package to resolve version ranges. Its [documentation](https://github.com/npm/node-semver#advanced-range-syntax) contains more details on the version range syntax. You can test what version will be selected for a given input in this JavaScript [REPL](https://repl.it/@SaschaMann/setup-julia-version-logic).
@@ -179,18 +193,13 @@ jobs:
### versioninfo
By default, only a brief version identifier is printed in the run log. You can display the full `versioninfo` by adding `show-versioninfo`.
Here's an example that prints this information just for `nightly`:
By default, only the output of `julia --version` is printed as verification that Julia has been installed for stable versions of Julia.
`InteractiveUtils.versioninfo()` is run by default for nightly builds.
```yaml
- uses: julia-actions/setup-julia@v1
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
show-versioninfo: ${{ matrix.version == 'nightly' }}
```
You use `'true'` if you want it printed for all Julia versions.
Starting Julia and printing the full versioninfo takes a significant amount of time (1s or ~10% of the total build time in testing), so you may not want to run it in every build, in particular on paid runners as this cost will add up quickly.
However, `julia --version` does not provide sufficient information to know which commit a nightly binary was built from, therefore it is useful to show the full versioninfo on nightly builds regardless.
You can override this behaviour by changing the input to `never` if you never want to run `InteractiveUtils.versioninfo()` or to `true` if you always want to run `InteractiveUtils.versioninfo()`, even on stable Julia builds.
## Versioning

5204
dist/index.js vendored Normal file

File diff suppressed because it is too large Load Diff

BIN
dist/unzip vendored Normal file

Binary file not shown.

71
lib/installer.js generated
View File

@@ -22,6 +22,7 @@ const crypto = __importStar(require("crypto"));
const fs = __importStar(require("fs"));
const os = __importStar(require("os"));
const path = __importStar(require("path"));
const retry = require("async-retry");
const semver = __importStar(require("semver"));
// Translations between actions input and Julia arch names
const osMap = {
@@ -31,7 +32,8 @@ const osMap = {
};
const archMap = {
'x86': 'i686',
'x64': 'x86_64'
'x64': 'x86_64',
'aarch64': 'aarch64'
};
// Store information about the environment
const osPlat = os.platform(); // possible values: win32 (Windows), linux (Linux), darwin (macOS)
@@ -59,7 +61,15 @@ function calculateChecksum(file) {
*/
function getJuliaVersionInfo() {
return __awaiter(this, void 0, void 0, function* () {
const versionsFile = yield tc.downloadTool('https://julialang-s3.julialang.org/bin/versions.json');
// Occasionally the connection is reset for unknown reasons
// In those cases, retry the download
const versionsFile = yield retry((bail) => __awaiter(this, void 0, void 0, function* () {
return yield tc.downloadTool('https://julialang-s3.julialang.org/bin/versions.json');
}), {
onRetry: (err) => {
core.debug(`Download of versions.json failed, trying again. Error: ${err}`);
}
});
return JSON.parse(fs.readFileSync(versionsFile).toString());
});
}
@@ -115,15 +125,19 @@ function getNightlyFileName(arch) {
return `julia-latest${versionExt}.${ext}`;
}
function getFileInfo(versionInfo, version, arch) {
const err = `Could not find ${archMap[arch]}/${version} binaries`;
if (version.endsWith('nightly')) {
return null;
}
if (!versionInfo[version]) {
throw err;
}
for (let file of versionInfo[version].files) {
if (file.os == osMap[osPlat] && file.arch == archMap[arch]) {
return file;
}
}
throw `Could not find ${archMap[arch]}/${version} binaries`;
throw err;
}
exports.getFileInfo = getFileInfo;
function getDownloadURL(fileInfo, version, arch) {
@@ -137,6 +151,10 @@ function getDownloadURL(fileInfo, version, arch) {
if (version == 'nightly') {
return `${baseURL}/${getNightlyFileName(arch)}`;
}
// Verify that fileInfo.url points at the official Julia download servers
if (!fileInfo.url.startsWith('https://julialang-s3.julialang.org/')) {
throw new Error(`versions.json points at a download location outside of Julia's download server: ${fileInfo.url}. Aborting for security reasons.`);
}
return fileInfo.url;
}
exports.getDownloadURL = getDownloadURL;
@@ -146,7 +164,15 @@ function installJulia(versionInfo, version, arch) {
const fileInfo = getFileInfo(versionInfo, version, arch);
const downloadURL = getDownloadURL(fileInfo, version, arch);
core.debug(`downloading Julia from ${downloadURL}`);
const juliaDownloadPath = yield tc.downloadTool(downloadURL);
// Occasionally the connection is reset for unknown reasons
// In those cases, retry the download
const juliaDownloadPath = yield retry((bail) => __awaiter(this, void 0, void 0, function* () {
return yield tc.downloadTool(downloadURL);
}), {
onRetry: (err) => {
core.debug(`Download of ${downloadURL} failed, trying again. Error: ${err}`);
}
});
// Verify checksum
if (!version.endsWith('nightly')) {
const checkSum = yield calculateChecksum(juliaDownloadPath);
@@ -184,3 +210,40 @@ function installJulia(versionInfo, version, arch) {
});
}
exports.installJulia = installJulia;
/**
* Test if Julia has been installed and print the version.
*
* true => always show versioninfo
* false => only show on nightlies
* never => never show it anywhere
*
* @param showVersionInfoInput
*/
function showVersionInfo(showVersionInfoInput, version) {
return __awaiter(this, void 0, void 0, function* () {
// --compile=min -O0 reduces the time from ~1.8-1.9s to ~0.8-0.9s
let exitCode;
switch (showVersionInfoInput) {
case 'true':
exitCode = yield exec.exec('julia', ['--compile=min', '-O0', '-e', 'using InteractiveUtils; versioninfo()']);
break;
case 'false':
if (version.endsWith('nightly')) {
exitCode = yield exec.exec('julia', ['--compile=min', '-O0', '-e', 'using InteractiveUtils; versioninfo()']);
}
else {
exitCode = yield exec.exec('julia', ['--version']);
}
break;
case 'never':
exitCode = yield exec.exec('julia', ['--version']);
break;
default:
throw new Error(`${showVersionInfoInput} is not a valid value for show-versioninfo. Supported values: true | false | never`);
}
if (exitCode !== 0) {
throw new Error(`Julia could not be installed properly. Exit code: ${exitCode}`);
}
});
}
exports.showVersionInfo = showVersionInfo;

12
lib/setup-julia.js generated
View File

@@ -16,7 +16,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
};
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core"));
const exec = __importStar(require("@actions/exec"));
const tc = __importStar(require("@actions/tool-cache"));
const fs = __importStar(require("fs"));
const https = __importStar(require("https"));
@@ -79,15 +78,8 @@ function run() {
// Set output
core.setOutput('julia-bindir', path.join(juliaPath, 'bin'));
// Test if Julia has been installed and print the version
if (core.getInput('show-versioninfo') == 'true') {
// If enabled, show the full version info
// --compile=min -O0 reduces the time from ~1.8-1.9s to ~0.8-0.9s
exec.exec('julia', ['--compile=min', '-O0', '-e', 'using InteractiveUtils; versioninfo()']);
}
else {
// Otherwise only print julia --version to save time
exec.exec('julia', ['--version']);
}
const showVersionInfoInput = core.getInput('show-versioninfo');
yield installer.showVersionInfo(showVersionInfoInput, version);
}
catch (error) {
core.setFailed(error.message);

8585
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "setup-julia",
"version": "1.5.2",
"version": "1.7.0",
"private": true,
"description": "setup Julia action",
"main": "lib/setup-julia.js",
@@ -25,9 +25,11 @@
"@actions/exec": "^1.0.0",
"@actions/io": "^1.0.0",
"@actions/tool-cache": "^1.0.0",
"async-retry": "^1.3.1",
"semver": "^6.3.0"
},
"devDependencies": {
"@types/async-retry": "^1.4.2",
"@types/jest": "^24.0.13",
"@types/node": "^12.12.7",
"@types/semver": "^6.0.0",

View File

@@ -6,6 +6,7 @@ import * as crypto from 'crypto'
import * as fs from 'fs'
import * as os from 'os'
import * as path from 'path'
import retry = require('async-retry')
import * as semver from 'semver'
@@ -17,7 +18,8 @@ const osMap = {
}
const archMap = {
'x86': 'i686',
'x64': 'x86_64'
'x64': 'x86_64',
'aarch64': 'aarch64'
}
// Store information about the environment
@@ -47,7 +49,15 @@ async function calculateChecksum(file: string): Promise<string> {
* @returns The content of the downloaded versions.json file as object.
*/
export async function getJuliaVersionInfo(): Promise<object> {
const versionsFile = await tc.downloadTool('https://julialang-s3.julialang.org/bin/versions.json')
// Occasionally the connection is reset for unknown reasons
// In those cases, retry the download
const versionsFile = await retry(async (bail: Function) => {
return await tc.downloadTool('https://julialang-s3.julialang.org/bin/versions.json')
}, {
onRetry: (err: Error) => {
core.debug(`Download of versions.json failed, trying again. Error: ${err}`)
}
})
return JSON.parse(fs.readFileSync(versionsFile).toString())
}
@@ -106,17 +116,23 @@ function getNightlyFileName(arch: string): string {
}
export function getFileInfo(versionInfo, version: string, arch: string) {
const err = `Could not find ${archMap[arch]}/${version} binaries`
if (version.endsWith('nightly')) {
return null
}
if (!versionInfo[version]) {
throw err
}
for (let file of versionInfo[version].files) {
if (file.os == osMap[osPlat] && file.arch == archMap[arch]) {
return file
}
}
throw `Could not find ${archMap[arch]}/${version} binaries`
throw err
}
export function getDownloadURL(fileInfo, version: string, arch: string): string {
@@ -133,6 +149,10 @@ export function getDownloadURL(fileInfo, version: string, arch: string): string
return `${baseURL}/${getNightlyFileName(arch)}`
}
// Verify that fileInfo.url points at the official Julia download servers
if (!fileInfo.url.startsWith('https://julialang-s3.julialang.org/')) {
throw new Error(`versions.json points at a download location outside of Julia's download server: ${fileInfo.url}. Aborting for security reasons.`)
}
return fileInfo.url
}
@@ -141,7 +161,17 @@ export async function installJulia(versionInfo, version: string, arch: string):
const fileInfo = getFileInfo(versionInfo, version, arch)
const downloadURL = getDownloadURL(fileInfo, version, arch)
core.debug(`downloading Julia from ${downloadURL}`)
const juliaDownloadPath = await tc.downloadTool(downloadURL)
// Occasionally the connection is reset for unknown reasons
// In those cases, retry the download
const juliaDownloadPath = await retry(async (bail: Function) => {
return await tc.downloadTool(downloadURL)
}, {
onRetry: (err: Error) => {
core.debug(`Download of ${downloadURL} failed, trying again. Error: ${err}`)
}
})
// Verify checksum
if (!version.endsWith('nightly')) {
@@ -178,3 +208,42 @@ export async function installJulia(versionInfo, version: string, arch: string):
throw new Error(`Platform ${osPlat} is not supported`)
}
}
/**
* Test if Julia has been installed and print the version.
*
* true => always show versioninfo
* false => only show on nightlies
* never => never show it anywhere
*
* @param showVersionInfoInput
*/
export async function showVersionInfo(showVersionInfoInput: string, version: string): Promise<void> {
// --compile=min -O0 reduces the time from ~1.8-1.9s to ~0.8-0.9s
let exitCode: number
switch (showVersionInfoInput) {
case 'true':
exitCode = await exec.exec('julia', ['--compile=min', '-O0', '-e', 'using InteractiveUtils; versioninfo()'])
break
case 'false':
if (version.endsWith('nightly')) {
exitCode = await exec.exec('julia', ['--compile=min', '-O0', '-e', 'using InteractiveUtils; versioninfo()'])
} else {
exitCode = await exec.exec('julia', ['--version'])
}
break
case 'never':
exitCode = await exec.exec('julia', ['--version'])
break
default:
throw new Error(`${showVersionInfoInput} is not a valid value for show-versioninfo. Supported values: true | false | never`)
}
if (exitCode !== 0) {
throw new Error(`Julia could not be installed properly. Exit code: ${exitCode}`)
}
}

View File

@@ -75,14 +75,8 @@ async function run() {
core.setOutput('julia-bindir', path.join(juliaPath, 'bin'))
// Test if Julia has been installed and print the version
if (core.getInput('show-versioninfo') == 'true') {
// If enabled, show the full version info
// --compile=min -O0 reduces the time from ~1.8-1.9s to ~0.8-0.9s
exec.exec('julia', ['--compile=min', '-O0', '-e', 'using InteractiveUtils; versioninfo()'])
} else {
// Otherwise only print julia --version to save time
exec.exec('julia', ['--version'])
}
const showVersionInfoInput = core.getInput('show-versioninfo')
await installer.showVersionInfo(showVersionInfoInput, version)
} catch (error) {
core.setFailed(error.message)
}