Compare commits

..

1 Commits
v1.8 ... v1.6

Author SHA1 Message Date
Sascha Mann
ee66464cb7 Add production dependencies & build 2021-08-05 16:38:38 +02:00
16 changed files with 103 additions and 11227 deletions

View File

@@ -9,7 +9,6 @@ on:
jobs: jobs:
backup: backup:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
timeout-minutes: 60
steps: steps:
- name: Configure cache - name: Configure cache

View File

@@ -1,21 +1,14 @@
name: "PR Checks" name: "PR Checks"
on: [pull_request, push] on: [pull_request, push]
concurrency:
# Skip intermediate builds: all builds except for builds on the `master`, `main`, or `release-*` branches
# Cancel intermediate builds: only pull request builds
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref != 'refs/heads/master' || github.ref != 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-') || github.run_number }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
jobs: jobs:
check_pr: check_pr:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 60
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- name: "npm ci" - name: "npm ci"
run: npm ci --legacy-peer-deps run: npm ci
- name: "npm run build" - name: "npm run build"
run: npm run build run: npm run build

View File

@@ -11,12 +11,6 @@
# #
name: "CodeQL" name: "CodeQL"
concurrency:
# Skip intermediate builds: all builds except for builds on the `master`, `main`, or `release-*` branches
# Cancel intermediate builds: only pull request builds
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref != 'refs/heads/master' || github.ref != 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-') || github.run_number }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
on: on:
push: push:
branches: [ master, releases/* ] branches: [ master, releases/* ]
@@ -30,7 +24,6 @@ jobs:
analyze: analyze:
name: Analyze name: Analyze
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 60
strategy: strategy:
fail-fast: false fail-fast: false

View File

@@ -1,40 +0,0 @@
name: Example builds (default arch)
concurrency:
# Skip intermediate builds: all builds except for builds on the `master`, `main`, or `release-*` branches
# Cancel intermediate builds: only pull request builds
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref != 'refs/heads/master' || github.ref != 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-') || github.run_number }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
on:
push:
branches: ['main', 'master', 'releases/*']
pull_request:
workflow_dispatch:
jobs:
test:
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
julia-version: ['1']
os: [ubuntu-latest, macOS-latest, windows-latest]
steps:
- uses: actions/checkout@v1.0.0
- name: "Install dependencies"
run: |
npm install --legacy-peer-deps
npm run build
npm run pack
- name: "Set up Julia"
id: setup-julia
uses: ./
with:
version: ${{ matrix.julia-version }}
- run: julia --version
- run: julia --compile=min -O0 -e 'import InteractiveUtils; InteractiveUtils.versioninfo()'

View File

@@ -1,38 +0,0 @@
name: Example builds (nightly, default arch)
concurrency:
# Skip intermediate builds: all builds except for builds on the `master`, `main`, or `release-*` branches
# Cancel intermediate builds: only pull request builds
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref != 'refs/heads/master' || github.ref != 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-') || github.run_number }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
on:
push:
branches: ['main', 'master', 'releases/*']
pull_request:
jobs:
test:
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
julia-version: [nightly, 1.8-nightly]
os: [ubuntu-latest, macOS-latest, windows-latest]
steps:
- uses: actions/checkout@v1.0.0
- name: "Install dependencies"
run: |
npm install --legacy-peer-deps
npm run build
npm run pack
- name: "Set up Julia (${{ matrix.julia-version }})"
uses: ./
with:
version: ${{ matrix.julia-version }}
- run: julia --version
- run: julia --compile=min -O0 -e 'import InteractiveUtils; InteractiveUtils.versioninfo()'

View File

@@ -1,11 +1,5 @@
name: Example builds (nightly) name: Example builds (nightly)
concurrency:
# Skip intermediate builds: all builds except for builds on the `master`, `main`, or `release-*` branches
# Cancel intermediate builds: only pull request builds
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref != 'refs/heads/master' || github.ref != 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-') || github.run_number }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
on: on:
push: push:
branches: ['main', 'master', 'releases/*'] branches: ['main', 'master', 'releases/*']
@@ -16,11 +10,10 @@ on:
jobs: jobs:
test: test:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
julia-version: [nightly, 1.8-nightly] julia-version: [nightly, 1.7-nightly]
julia-arch: [x64, x86] julia-arch: [x64, x86]
os: [ubuntu-latest, macOS-latest, windows-latest] os: [ubuntu-latest, macOS-latest, windows-latest]
# 32-bit Julia binaries are not available on macOS # 32-bit Julia binaries are not available on macOS
@@ -33,7 +26,7 @@ jobs:
- name: "Install dependencies" - name: "Install dependencies"
run: | run: |
npm install --legacy-peer-deps npm install
npm run build npm run build
npm run pack npm run pack

View File

@@ -1,25 +1,17 @@
name: Example builds name: Example builds
concurrency:
# Skip intermediate builds: all builds except for builds on the `master`, `main`, or `release-*` branches
# Cancel intermediate builds: only pull request builds
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref != 'refs/heads/master' || github.ref != 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-') || github.run_number }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
on: on:
push: push:
branches: ['main', 'master', 'releases/*'] branches: ['main', 'master', 'releases/*']
pull_request: pull_request:
workflow_dispatch:
jobs: jobs:
test: test:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
julia-version: ['1.0.5', '1.2', '^1.5.0-beta1', '1'] julia-version: ['1.0.5', '1', '^1.5.0-beta1']
julia-arch: [x64, x86] julia-arch: [x64, x86]
os: [ubuntu-latest, macOS-latest, windows-latest] os: [ubuntu-latest, macOS-latest, windows-latest]
# 32-bit Julia binaries are not available on macOS # 32-bit Julia binaries are not available on macOS
@@ -32,7 +24,7 @@ jobs:
- name: "Install dependencies" - name: "Install dependencies"
run: | run: |
npm install --legacy-peer-deps npm install
npm run build npm run build
npm run pack npm run pack

View File

@@ -38,15 +38,9 @@ This action sets up a Julia environment for use in actions by downloading a spec
# The architecture of the Julia binaries. # The architecture of the Julia binaries.
# #
# Please note that installing aarch64 binaries only makes sense on self-hosted aarch64 runners. # Supported values: x64 | x86
# 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
#
# Note: you can use X64, X86, and ARM64 as synonyms for x64, x86, and aarch64, respectively.
#
# Defaults to the architecture of the runner executing the job.
arch: '' arch: ''
# Set the display setting for printing InteractiveUtils.versioninfo() after installing. # Set the display setting for printing InteractiveUtils.versioninfo() after installing.

View File

@@ -6,9 +6,9 @@ inputs:
description: 'The Julia version to download (if necessary) and use. Example: 1.0.4' description: 'The Julia version to download (if necessary) and use. Example: 1.0.4'
default: '1' default: '1'
arch: arch:
description: 'Architecture of the Julia binaries. Defaults to the architecture of the runner executing the job.' description: 'Architecture of the Julia binaries. Defaults to x64.'
required: false required: false
default: '${{ runner.arch }}' default: 'x64'
show-versioninfo: show-versioninfo:
description: 'Display InteractiveUtils.versioninfo() after installing' description: 'Display InteractiveUtils.versioninfo() after installing'
required: false required: false
@@ -19,7 +19,7 @@ outputs:
julia-bindir: julia-bindir:
description: 'Path to the directory containing the Julia executable. Equivalent to JULIA_BINDIR: https://docs.julialang.org/en/v1/manual/environment-variables/#JULIA_BINDIR' description: 'Path to the directory containing the Julia executable. Equivalent to JULIA_BINDIR: https://docs.julialang.org/en/v1/manual/environment-variables/#JULIA_BINDIR'
runs: runs:
using: 'node16' using: 'node12'
main: 'dist/index.js' main: 'dist/index.js'
branding: branding:
icon: 'download' icon: 'download'

2431
dist/index.js vendored

File diff suppressed because it is too large Load Diff

68
lib/installer.js generated
View File

@@ -32,8 +32,7 @@ const osMap = {
}; };
const archMap = { const archMap = {
'x86': 'i686', 'x86': 'i686',
'x64': 'x86_64', 'x64': 'x86_64'
'aarch64': 'aarch64'
}; };
// Store information about the environment // Store information about the environment
const osPlat = os.platform(); // possible values: win32 (Windows), linux (Linux), darwin (macOS) const osPlat = os.platform(); // possible values: win32 (Windows), linux (Linux), darwin (macOS)
@@ -102,57 +101,30 @@ function getJuliaVersion(availableReleases, versionInput) {
return version; return version;
} }
exports.getJuliaVersion = getJuliaVersion; exports.getJuliaVersion = getJuliaVersion;
function getDesiredFileExts() {
let fileExt1;
let hasFileExt2;
let fileExt2;
if (osPlat == 'win32') {
fileExt1 = 'exe';
hasFileExt2 = false;
fileExt2 = '';
}
else if (osPlat == 'darwin') {
fileExt1 = 'tar.gz';
hasFileExt2 = true;
fileExt2 = 'dmg';
}
else if (osPlat === 'linux') {
fileExt1 = 'tar.gz';
hasFileExt2 = false;
fileExt2 = '';
}
else {
throw new Error(`Platform ${osPlat} is not supported`);
}
return [fileExt1, hasFileExt2, fileExt2];
}
function getNightlyFileName(arch) { function getNightlyFileName(arch) {
let versionExt; let versionExt, ext;
let fileExt1;
[fileExt1, ,] = getDesiredFileExts();
if (osPlat == 'win32') { if (osPlat == 'win32') {
versionExt = arch == 'x64' ? '-win64' : '-win32'; versionExt = arch == 'x64' ? '-win64' : '-win32';
ext = 'exe';
} }
else if (osPlat == 'darwin') { else if (osPlat == 'darwin') {
if (arch == 'x86') { if (arch == 'x86') {
throw new Error('32-bit Julia is not available on macOS'); throw new Error('32-bit Julia is not available on macOS');
} }
versionExt = '-mac64'; versionExt = '-mac64';
ext = 'dmg';
} }
else if (osPlat === 'linux') { else if (osPlat === 'linux') {
versionExt = arch == 'x64' ? '-linux64' : '-linux32'; versionExt = arch == 'x64' ? '-linux64' : '-linux32';
ext = 'tar.gz';
} }
else { else {
throw new Error(`Platform ${osPlat} is not supported`); throw new Error(`Platform ${osPlat} is not supported`);
} }
return `julia-latest${versionExt}.${fileExt1}`; return `julia-latest${versionExt}.${ext}`;
} }
function getFileInfo(versionInfo, version, arch) { function getFileInfo(versionInfo, version, arch) {
const err = `Could not find ${archMap[arch]}/${version} binaries`; const err = `Could not find ${archMap[arch]}/${version} binaries`;
let fileExt1;
let hasFileExt2;
let fileExt2;
[fileExt1, hasFileExt2, fileExt2] = getDesiredFileExts();
if (version.endsWith('nightly')) { if (version.endsWith('nightly')) {
return null; return null;
} }
@@ -161,19 +133,7 @@ function getFileInfo(versionInfo, version, arch) {
} }
for (let file of versionInfo[version].files) { for (let file of versionInfo[version].files) {
if (file.os == osMap[osPlat] && file.arch == archMap[arch]) { if (file.os == osMap[osPlat] && file.arch == archMap[arch]) {
if (file.extension == fileExt1) { return file;
return file;
}
}
}
if (hasFileExt2) {
core.debug(`Could not find ${fileExt1}; trying to find ${fileExt2} instead`);
for (let file of versionInfo[version].files) {
if (file.os == osMap[osPlat] && file.arch == archMap[arch]) {
if (file.extension == fileExt2) {
return file;
}
}
} }
} }
throw err; throw err;
@@ -240,17 +200,9 @@ function installJulia(versionInfo, version, arch) {
} }
return tempInstallDir; return tempInstallDir;
case 'darwin': case 'darwin':
if (fileInfo !== null && fileInfo.extension == 'dmg') { yield exec.exec('hdiutil', ['attach', juliaDownloadPath]);
core.debug(`Support for .dmg files is deprecated and may be removed in a future release`); yield exec.exec('/bin/bash', ['-c', `cp -a /Volumes/Julia-*/Julia-*.app/Contents/Resources/julia ${tempInstallDir}`]);
yield exec.exec('hdiutil', ['attach', juliaDownloadPath]); return path.join(tempInstallDir, 'julia');
yield exec.exec('/bin/bash', ['-c', `cp -a /Volumes/Julia-*/Julia-*.app/Contents/Resources/julia ${tempInstallDir}`]);
return path.join(tempInstallDir, 'julia');
}
else {
// tc.extractTar doesn't support stripping components, so we have to call tar manually
yield exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', tempInstallDir]);
return tempInstallDir;
}
default: default:
throw new Error(`Platform ${osPlat} is not supported`); throw new Error(`Platform ${osPlat} is not supported`);
} }

13
lib/setup-julia.js generated
View File

@@ -21,14 +21,6 @@ const fs = __importStar(require("fs"));
const https = __importStar(require("https")); const https = __importStar(require("https"));
const path = __importStar(require("path")); const path = __importStar(require("path"));
const installer = __importStar(require("./installer")); const installer = __importStar(require("./installer"));
const archSynonyms = {
'x86': 'x86',
'X86': 'x86',
'x64': 'x64',
'X64': 'x64',
'aarch64': 'aarch64',
'ARM64': 'aarch64'
};
function run() { function run() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
try { try {
@@ -49,7 +41,7 @@ function run() {
} }
// Inputs // Inputs
const versionInput = core.getInput('version'); const versionInput = core.getInput('version');
const originalArchInput = core.getInput('arch'); const arch = core.getInput('arch');
// It can easily happen that, for example, a workflow file contains an input `version: ${{ matrix.julia-version }}` // It can easily happen that, for example, a workflow file contains an input `version: ${{ matrix.julia-version }}`
// while the strategy matrix only contains a key `${{ matrix.version }}`. // while the strategy matrix only contains a key `${{ matrix.version }}`.
// In that case, we want the action to fail, rather than trying to download julia from an URL that's missing parts and 404ing. // In that case, we want the action to fail, rather than trying to download julia from an URL that's missing parts and 404ing.
@@ -58,10 +50,9 @@ function run() {
if (!versionInput) { if (!versionInput) {
throw new Error('Version input must not be null'); throw new Error('Version input must not be null');
} }
if (!originalArchInput) { if (!arch) {
throw new Error(`Arch input must not be null`); throw new Error(`Arch input must not be null`);
} }
const arch = archSynonyms[originalArchInput];
const versionInfo = yield installer.getJuliaVersionInfo(); const versionInfo = yield installer.getJuliaVersionInfo();
const availableReleases = yield installer.getJuliaVersions(versionInfo); const availableReleases = yield installer.getJuliaVersions(versionInfo);
const version = installer.getJuliaVersion(availableReleases, versionInput); const version = installer.getJuliaVersion(availableReleases, versionInput);

8583
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "setup-julia", "name": "setup-julia",
"version": "1.8.3", "version": "1.6.1",
"private": true, "private": true,
"description": "setup Julia action", "description": "setup Julia action",
"main": "lib/setup-julia.js", "main": "lib/setup-julia.js",
@@ -21,7 +21,7 @@
"author": "Sascha Mann <git@mail.saschamann.eu>", "author": "Sascha Mann <git@mail.saschamann.eu>",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/core": "^1.10.0", "@actions/core": "^1.2.6",
"@actions/exec": "^1.0.0", "@actions/exec": "^1.0.0",
"@actions/io": "^1.0.0", "@actions/io": "^1.0.0",
"@actions/tool-cache": "^1.0.0", "@actions/tool-cache": "^1.0.0",

View File

@@ -18,8 +18,7 @@ const osMap = {
} }
const archMap = { const archMap = {
'x86': 'i686', 'x86': 'i686',
'x64': 'x86_64', 'x64': 'x86_64'
'aarch64': 'aarch64'
} }
// Store information about the environment // Store information about the environment
@@ -93,59 +92,31 @@ export function getJuliaVersion(availableReleases: string[], versionInput: strin
return version return version
} }
function getDesiredFileExts(): [string, boolean, string] {
let fileExt1: string
let hasFileExt2: boolean
let fileExt2: string
if (osPlat == 'win32') {
fileExt1 = 'exe'
hasFileExt2 = false
fileExt2 = ''
} else if (osPlat == 'darwin') {
fileExt1 = 'tar.gz'
hasFileExt2 = true
fileExt2 = 'dmg'
} else if (osPlat === 'linux') {
fileExt1 = 'tar.gz'
hasFileExt2 = false
fileExt2 = ''
} else {
throw new Error(`Platform ${osPlat} is not supported`)
}
return [fileExt1, hasFileExt2, fileExt2]
}
function getNightlyFileName(arch: string): string { function getNightlyFileName(arch: string): string {
let versionExt: string let versionExt: string, ext: string
let fileExt1: string
[fileExt1, , ] = getDesiredFileExts()
if (osPlat == 'win32') { if (osPlat == 'win32') {
versionExt = arch == 'x64' ? '-win64' : '-win32' versionExt = arch == 'x64' ? '-win64' : '-win32'
ext = 'exe'
} else if (osPlat == 'darwin') { } else if (osPlat == 'darwin') {
if (arch == 'x86') { if (arch == 'x86') {
throw new Error('32-bit Julia is not available on macOS') throw new Error('32-bit Julia is not available on macOS')
} }
versionExt = '-mac64' versionExt = '-mac64'
ext = 'dmg'
} else if (osPlat === 'linux') { } else if (osPlat === 'linux') {
versionExt = arch == 'x64' ? '-linux64' : '-linux32' versionExt = arch == 'x64' ? '-linux64' : '-linux32'
ext = 'tar.gz'
} else { } else {
throw new Error(`Platform ${osPlat} is not supported`) throw new Error(`Platform ${osPlat} is not supported`)
} }
return `julia-latest${versionExt}.${fileExt1}` return `julia-latest${versionExt}.${ext}`
} }
export function getFileInfo(versionInfo, version: string, arch: string) { export function getFileInfo(versionInfo, version: string, arch: string) {
const err = `Could not find ${archMap[arch]}/${version} binaries` const err = `Could not find ${archMap[arch]}/${version} binaries`
let fileExt1: string
let hasFileExt2: boolean
let fileExt2: string
[fileExt1, hasFileExt2, fileExt2] = getDesiredFileExts()
if (version.endsWith('nightly')) { if (version.endsWith('nightly')) {
return null return null
} }
@@ -156,20 +127,7 @@ export function getFileInfo(versionInfo, version: string, arch: string) {
for (let file of versionInfo[version].files) { for (let file of versionInfo[version].files) {
if (file.os == osMap[osPlat] && file.arch == archMap[arch]) { if (file.os == osMap[osPlat] && file.arch == archMap[arch]) {
if (file.extension == fileExt1) { return file
return file
}
}
}
if (hasFileExt2) {
core.debug(`Could not find ${fileExt1}; trying to find ${fileExt2} instead`)
for (let file of versionInfo[version].files) {
if (file.os == osMap[osPlat] && file.arch == archMap[arch]) {
if (file.extension == fileExt2) {
return file
}
}
} }
} }
@@ -213,6 +171,7 @@ export async function installJulia(versionInfo, version: string, arch: string):
} }
}) })
// Verify checksum // Verify checksum
if (!version.endsWith('nightly')) { if (!version.endsWith('nightly')) {
const checkSum = await calculateChecksum(juliaDownloadPath) const checkSum = await calculateChecksum(juliaDownloadPath)
@@ -241,16 +200,9 @@ export async function installJulia(versionInfo, version: string, arch: string):
} }
return tempInstallDir return tempInstallDir
case 'darwin': case 'darwin':
if (fileInfo !== null && fileInfo.extension == 'dmg') { await exec.exec('hdiutil', ['attach', juliaDownloadPath])
core.debug(`Support for .dmg files is deprecated and may be removed in a future release`) await exec.exec('/bin/bash', ['-c', `cp -a /Volumes/Julia-*/Julia-*.app/Contents/Resources/julia ${tempInstallDir}`])
await exec.exec('hdiutil', ['attach', juliaDownloadPath]) return path.join(tempInstallDir, 'julia')
await exec.exec('/bin/bash', ['-c', `cp -a /Volumes/Julia-*/Julia-*.app/Contents/Resources/julia ${tempInstallDir}`])
return path.join(tempInstallDir, 'julia')
} else {
// tc.extractTar doesn't support stripping components, so we have to call tar manually
await exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', tempInstallDir])
return tempInstallDir
}
default: default:
throw new Error(`Platform ${osPlat} is not supported`) throw new Error(`Platform ${osPlat} is not supported`)
} }

View File

@@ -8,15 +8,6 @@ import * as path from 'path'
import * as installer from './installer' import * as installer from './installer'
const archSynonyms = {
'x86': 'x86',
'X86': 'x86',
'x64': 'x64',
'X64': 'x64',
'aarch64': 'aarch64',
'ARM64': 'aarch64'
}
async function run() { async function run() {
try { try {
// Debugging info // Debugging info
@@ -39,7 +30,7 @@ async function run() {
// Inputs // Inputs
const versionInput = core.getInput('version') const versionInput = core.getInput('version')
const originalArchInput = core.getInput('arch') const arch = core.getInput('arch')
// It can easily happen that, for example, a workflow file contains an input `version: ${{ matrix.julia-version }}` // It can easily happen that, for example, a workflow file contains an input `version: ${{ matrix.julia-version }}`
// while the strategy matrix only contains a key `${{ matrix.version }}`. // while the strategy matrix only contains a key `${{ matrix.version }}`.
@@ -49,12 +40,10 @@ async function run() {
if (!versionInput) { if (!versionInput) {
throw new Error('Version input must not be null') throw new Error('Version input must not be null')
} }
if (!originalArchInput) { if (!arch) {
throw new Error(`Arch input must not be null`) throw new Error(`Arch input must not be null`)
} }
const arch = archSynonyms[originalArchInput]
const versionInfo = await installer.getJuliaVersionInfo() const versionInfo = await installer.getJuliaVersionInfo()
const availableReleases = await installer.getJuliaVersions(versionInfo) const availableReleases = await installer.getJuliaVersions(versionInfo)
const version = installer.getJuliaVersion(availableReleases, versionInput) const version = installer.getJuliaVersion(availableReleases, versionInput)