Compare commits

..

7 Commits

Author SHA1 Message Date
Sascha Mann
20e957a751 Add benchmark 2021-01-13 11:24:02 +01: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
Sascha Mann
6c3c1efae0 Bump version 2021-01-08 11:12:56 +01:00
Sascha Mann
531b2e0973 Support release nightlies (#63)
* Support release nightlies

See #62

* Replace == nightly with endsWith nightly

* Use majorMinorMatch, not full match

* Replace more (in-)equality checks

* Reduce number of duplicate CI builds

* Add example to docs

* Tidy up nightly conditions
2021-01-07 23:09:50 -05:00
Sascha Mann
66addd1b2f Don't print version twice if show-versioninfo is enabled 2021-01-03 13:42:52 +01:00
Sascha Mann
3ff0592a25 Use --compile=min -O0 flags for versioninfo
Co-authored-by: Mosè Giordano <giordano@users.noreply.github.com>
2021-01-03 13:42:52 +01:00
10 changed files with 253 additions and 65 deletions

View File

@@ -2,6 +2,7 @@ name: Example builds (nightly)
on: on:
push: push:
branches: ['main', 'master', 'releases/*']
pull_request: pull_request:
schedule: schedule:
- cron: '37 17 * * *' - cron: '37 17 * * *'
@@ -12,6 +13,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
julia-version: [nightly, 1.6-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
@@ -28,10 +30,10 @@ jobs:
npm run build npm run build
npm run pack npm run pack
- name: "Set up Julia (nightly)" - name: "Set up Julia (${{ matrix.julia-version }})"
uses: ./ uses: ./
with: with:
version: nightly version: ${{ matrix.julia-version }}
arch: ${{ matrix.julia-arch }} arch: ${{ matrix.julia-arch }}
show-versioninfo: 'true'
- run: julia --version - run: julia --version
- run: julia --compile=min -O0 -e 'import InteractiveUtils; InteractiveUtils.versioninfo()'

View File

@@ -1,6 +1,9 @@
name: Example builds name: Example builds
on: [push, pull_request] on:
push:
branches: ['main', 'master', 'releases/*']
pull_request:
jobs: jobs:
test: test:
@@ -31,9 +34,5 @@ jobs:
with: with:
version: ${{ matrix.julia-version }} version: ${{ matrix.julia-version }}
arch: ${{ matrix.julia-arch }} arch: ${{ matrix.julia-arch }}
show-versioninfo: 'true'
- run: julia --version - run: julia --version
- run: time julia --compile=min -O0 -e 'using InteractiveUtils; versioninfo()' - run: julia --compile=min -O0 -e 'import InteractiveUtils; InteractiveUtils.versioninfo()'
shell: bash
- run: time julia -e 'using InteractiveUtils; versioninfo()'
shell: bash

44
.github/workflows/windows-tests.yml vendored Normal file
View File

@@ -0,0 +1,44 @@
name: Windows Benchmark
on: [push]
jobs:
installer:
name: Installer
runs-on: windows-latest
steps:
- name: Download
run: curl -O https://julialang-s3.julialang.org/bin/winnt/x64/1.5/julia-1.5.3-win64.exe
shell: bash
- name: Install
run: |
Start-Process -FilePath julia-1.5.3-win64.exe -ArgumentList "/SILENT /dir=C:\Julia" -NoNewWindow -Wait
- name: Add to path
run: |
echo "C:\Julia\bin" >> $GITHUB_PATH
shell: bash
- run: julia --version
archive:
name: Archive
runs-on: windows-latest
steps:
- name: Download
run: curl -O https://julialang-s3.julialang.org/bin/winnt/x64/1.5/julia-1.5.3-win64.zip
shell: bash
- name: Install
run: |
[System.IO.Compression.ZipFile]::ExtractToDirectory('julia-1.5.3-win64.zip', 'C:\Julia')
- name: Add to path
run: |
echo "C:\Julia\julia-1.5.3\bin" >> $GITHUB_PATH
shell: bash
- run: julia --version

View File

@@ -43,8 +43,18 @@ This action sets up a Julia environment for use in actions by downloading a spec
# Default: x64 # Default: x64
arch: '' arch: ''
# If true, display the output of InteractiveUtils.versioninfo() after installing. # Set the display setting for printing InteractiveUtils.versioninfo() after installing.
# See "versioninfo" below for example usage. #
# 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 # Default: false
show-versioninfo: '' show-versioninfo: ''
@@ -93,6 +103,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 **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`. - `~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. - `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.
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). 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).
@@ -178,18 +189,13 @@ jobs:
### versioninfo ### versioninfo
By default, only a brief version identifier is printed in the run log. You can display the full `versioninfo` by adding `show-versioninfo`. By default, only the output of `julia --version` is printed as verification that Julia has been installed for stable versions of Julia.
Here's an example that prints this information just for `nightly`: `InteractiveUtils.versioninfo()` is run by default for nightly builds.
```yaml 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.
- uses: julia-actions/setup-julia@v1 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.
with:
version: ${{ matrix.version }} 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.
arch: ${{ matrix.arch }}
show-versioninfo: ${{ matrix.version == 'nightly' }}
```
You use `'true'` if you want it printed for all Julia versions.
## Versioning ## Versioning

81
lib/installer.js generated
View File

@@ -22,6 +22,7 @@ const crypto = __importStar(require("crypto"));
const fs = __importStar(require("fs")); const fs = __importStar(require("fs"));
const os = __importStar(require("os")); const os = __importStar(require("os"));
const path = __importStar(require("path")); const path = __importStar(require("path"));
const retry = require("async-retry");
const semver = __importStar(require("semver")); const semver = __importStar(require("semver"));
// Translations between actions input and Julia arch names // Translations between actions input and Julia arch names
const osMap = { const osMap = {
@@ -59,7 +60,15 @@ function calculateChecksum(file) {
*/ */
function getJuliaVersionInfo() { function getJuliaVersionInfo() {
return __awaiter(this, void 0, void 0, function* () { 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()); return JSON.parse(fs.readFileSync(versionsFile).toString());
}); });
} }
@@ -78,14 +87,10 @@ function getJuliaVersions(versionInfo) {
} }
exports.getJuliaVersions = getJuliaVersions; exports.getJuliaVersions = getJuliaVersions;
function getJuliaVersion(availableReleases, versionInput) { function getJuliaVersion(availableReleases, versionInput) {
if (semver.valid(versionInput) == versionInput) { if (semver.valid(versionInput) == versionInput || versionInput.endsWith('nightly')) {
// versionInput is a valid version, use it directly // versionInput is a valid version or a nightly version, use it directly
return versionInput; return versionInput;
} }
// nightlies
if (versionInput == 'nightly') {
return 'nightly';
}
// Use the highest available version that matches versionInput // Use the highest available version that matches versionInput
let version = semver.maxSatisfying(availableReleases, versionInput); let version = semver.maxSatisfying(availableReleases, versionInput);
if (version == null) { if (version == null) {
@@ -119,7 +124,7 @@ function getNightlyFileName(arch) {
return `julia-latest${versionExt}.${ext}`; return `julia-latest${versionExt}.${ext}`;
} }
function getFileInfo(versionInfo, version, arch) { function getFileInfo(versionInfo, version, arch) {
if (version == 'nightly') { if (version.endsWith('nightly')) {
return null; return null;
} }
for (let file of versionInfo[version].files) { for (let file of versionInfo[version].files) {
@@ -131,10 +136,15 @@ function getFileInfo(versionInfo, version, arch) {
} }
exports.getFileInfo = getFileInfo; exports.getFileInfo = getFileInfo;
function getDownloadURL(fileInfo, version, arch) { function getDownloadURL(fileInfo, version, arch) {
const baseURL = `https://julialangnightlies-s3.julialang.org/bin/${osMap[osPlat]}/${arch}`;
// release branch nightlies, e.g. 1.6-nightlies should return .../bin/linux/x64/1.6/julia-latest-linux64.tar.gz
const majorMinorMatches = /^(\d*.\d*)-nightly/.exec(version);
if (majorMinorMatches) {
return `${baseURL}/${majorMinorMatches[1]}/${getNightlyFileName(arch)}`;
}
// nightlies // nightlies
if (version == 'nightly') { if (version == 'nightly') {
const baseURL = 'https://julialangnightlies-s3.julialang.org/bin'; return `${baseURL}/${getNightlyFileName(arch)}`;
return `${baseURL}/${osMap[osPlat]}/${arch}/${getNightlyFileName(arch)}`;
} }
return fileInfo.url; return fileInfo.url;
} }
@@ -145,9 +155,17 @@ function installJulia(versionInfo, version, arch) {
const fileInfo = getFileInfo(versionInfo, version, arch); const fileInfo = getFileInfo(versionInfo, version, arch);
const downloadURL = getDownloadURL(fileInfo, version, arch); const downloadURL = getDownloadURL(fileInfo, version, arch);
core.debug(`downloading Julia from ${downloadURL}`); 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 // Verify checksum
if (version != 'nightly') { if (!version.endsWith('nightly')) {
const checkSum = yield calculateChecksum(juliaDownloadPath); const checkSum = yield calculateChecksum(juliaDownloadPath);
if (fileInfo.sha256 != checkSum) { if (fileInfo.sha256 != checkSum) {
throw new Error(`Checksum of downloaded file does not match the expected checksum from versions.json.\nExpected: ${fileInfo.sha256}\nGot: ${checkSum}`); throw new Error(`Checksum of downloaded file does not match the expected checksum from versions.json.\nExpected: ${fileInfo.sha256}\nGot: ${checkSum}`);
@@ -165,7 +183,7 @@ function installJulia(versionInfo, version, arch) {
yield exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', tempInstallDir]); yield exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', tempInstallDir]);
return tempInstallDir; return tempInstallDir;
case 'win32': case 'win32':
if (version == 'nightly' || semver.gtr(version, '1.3', { includePrerelease: true })) { if (version.endsWith('nightly') || semver.gtr(version, '1.3', { includePrerelease: true })) {
// The installer changed in 1.4: https://github.com/JuliaLang/julia/blob/ef0c9108b12f3ae177c51037934351ffa703b0b5/NEWS.md#build-system-changes // The installer changed in 1.4: https://github.com/JuliaLang/julia/blob/ef0c9108b12f3ae177c51037934351ffa703b0b5/NEWS.md#build-system-changes
yield exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/SILENT /dir=${path.join(process.cwd(), tempInstallDir)}" -NoNewWindow -Wait`]); yield exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/SILENT /dir=${path.join(process.cwd(), tempInstallDir)}" -NoNewWindow -Wait`]);
} }
@@ -183,3 +201,40 @@ function installJulia(versionInfo, version, arch) {
}); });
} }
exports.installJulia = installJulia; 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;

10
lib/setup-julia.js generated
View File

@@ -16,7 +16,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
}; };
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core")); const core = __importStar(require("@actions/core"));
const exec = __importStar(require("@actions/exec"));
const tc = __importStar(require("@actions/tool-cache")); const tc = __importStar(require("@actions/tool-cache"));
const fs = __importStar(require("fs")); const fs = __importStar(require("fs"));
const https = __importStar(require("https")); const https = __importStar(require("https"));
@@ -78,12 +77,9 @@ function run() {
core.addPath(path.join(juliaPath, 'bin')); core.addPath(path.join(juliaPath, 'bin'));
// Set output // Set output
core.setOutput('julia-bindir', path.join(juliaPath, 'bin')); core.setOutput('julia-bindir', path.join(juliaPath, 'bin'));
// Test if Julia has been installed // Test if Julia has been installed and print the version
exec.exec('julia', ['--version']); const showVersionInfoInput = core.getInput('show-versioninfo');
// If enabled, also show the full version info yield installer.showVersionInfo(showVersionInfoInput, version);
if (core.getInput('show-versioninfo') == 'true') {
exec.exec('julia', ['-e', 'using InteractiveUtils; versioninfo()']);
}
} }
catch (error) { catch (error) {
core.setFailed(error.message); core.setFailed(error.message);

30
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{ {
"name": "setup-julia", "name": "setup-julia",
"version": "1.5.0", "version": "1.6.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@@ -1384,6 +1384,15 @@
"@types/yargs": "^12.0.9" "@types/yargs": "^12.0.9"
} }
}, },
"@types/async-retry": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/@types/async-retry/-/async-retry-1.4.2.tgz",
"integrity": "sha512-GUDuJURF0YiJZ+CBjNQA0+vbP/VHlJbB0sFqkzsV7EcOPRfurVonXpXKAt3w8qIjM1TEzpz6hc6POocPvHOS3w==",
"dev": true,
"requires": {
"@types/retry": "*"
}
},
"@types/babel__core": { "@types/babel__core": {
"version": "7.1.6", "version": "7.1.6",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.6.tgz", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.6.tgz",
@@ -1471,6 +1480,12 @@
"integrity": "sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==", "integrity": "sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==",
"dev": true "dev": true
}, },
"@types/retry": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
"dev": true
},
"@types/semver": { "@types/semver": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-6.0.1.tgz", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-6.0.1.tgz",
@@ -1643,6 +1658,14 @@
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
"dev": true "dev": true
}, },
"async-retry": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.1.tgz",
"integrity": "sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA==",
"requires": {
"retry": "0.12.0"
}
},
"asynckit": { "asynckit": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -6046,6 +6069,11 @@
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
"dev": true "dev": true
}, },
"retry": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs="
},
"rimraf": { "rimraf": {
"version": "2.7.1", "version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",

View File

@@ -1,6 +1,6 @@
{ {
"name": "setup-julia", "name": "setup-julia",
"version": "1.5.0", "version": "1.6.0",
"private": true, "private": true,
"description": "setup Julia action", "description": "setup Julia action",
"main": "lib/setup-julia.js", "main": "lib/setup-julia.js",
@@ -25,9 +25,11 @@
"@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",
"async-retry": "^1.3.1",
"semver": "^6.3.0" "semver": "^6.3.0"
}, },
"devDependencies": { "devDependencies": {
"@types/async-retry": "^1.4.2",
"@types/jest": "^24.0.13", "@types/jest": "^24.0.13",
"@types/node": "^12.12.7", "@types/node": "^12.12.7",
"@types/semver": "^6.0.0", "@types/semver": "^6.0.0",

View File

@@ -6,6 +6,7 @@ import * as crypto from 'crypto'
import * as fs from 'fs' import * as fs from 'fs'
import * as os from 'os' import * as os from 'os'
import * as path from 'path' import * as path from 'path'
import retry = require('async-retry')
import * as semver from 'semver' import * as semver from 'semver'
@@ -47,7 +48,15 @@ async function calculateChecksum(file: string): Promise<string> {
* @returns The content of the downloaded versions.json file as object. * @returns The content of the downloaded versions.json file as object.
*/ */
export async function getJuliaVersionInfo(): Promise<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()) return JSON.parse(fs.readFileSync(versionsFile).toString())
} }
@@ -66,16 +75,11 @@ export async function getJuliaVersions(versionInfo): Promise<string[]> {
} }
export function getJuliaVersion(availableReleases: string[], versionInput: string): string { export function getJuliaVersion(availableReleases: string[], versionInput: string): string {
if (semver.valid(versionInput) == versionInput) { if (semver.valid(versionInput) == versionInput || versionInput.endsWith('nightly')) {
// versionInput is a valid version, use it directly // versionInput is a valid version or a nightly version, use it directly
return versionInput return versionInput
} }
// nightlies
if (versionInput == 'nightly') {
return 'nightly'
}
// Use the highest available version that matches versionInput // Use the highest available version that matches versionInput
let version = semver.maxSatisfying(availableReleases, versionInput) let version = semver.maxSatisfying(availableReleases, versionInput)
if (version == null) { if (version == null) {
@@ -111,7 +115,7 @@ function getNightlyFileName(arch: string): string {
} }
export function getFileInfo(versionInfo, version: string, arch: string) { export function getFileInfo(versionInfo, version: string, arch: string) {
if (version == 'nightly') { if (version.endsWith('nightly')) {
return null return null
} }
@@ -125,10 +129,17 @@ export function getFileInfo(versionInfo, version: string, arch: string) {
} }
export function getDownloadURL(fileInfo, version: string, arch: string): string { export function getDownloadURL(fileInfo, version: string, arch: string): string {
const baseURL = `https://julialangnightlies-s3.julialang.org/bin/${osMap[osPlat]}/${arch}`
// release branch nightlies, e.g. 1.6-nightlies should return .../bin/linux/x64/1.6/julia-latest-linux64.tar.gz
const majorMinorMatches = /^(\d*.\d*)-nightly/.exec(version)
if (majorMinorMatches) {
return `${baseURL}/${majorMinorMatches[1]}/${getNightlyFileName(arch)}`
}
// nightlies // nightlies
if (version == 'nightly') { if (version == 'nightly') {
const baseURL = 'https://julialangnightlies-s3.julialang.org/bin' return `${baseURL}/${getNightlyFileName(arch)}`
return `${baseURL}/${osMap[osPlat]}/${arch}/${getNightlyFileName(arch)}`
} }
return fileInfo.url return fileInfo.url
@@ -139,10 +150,20 @@ export async function installJulia(versionInfo, version: string, arch: string):
const fileInfo = getFileInfo(versionInfo, version, arch) const fileInfo = getFileInfo(versionInfo, version, arch)
const downloadURL = getDownloadURL(fileInfo, version, arch) const downloadURL = getDownloadURL(fileInfo, version, arch)
core.debug(`downloading Julia from ${downloadURL}`) 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 // Verify checksum
if (version != 'nightly') { if (!version.endsWith('nightly')) {
const checkSum = await calculateChecksum(juliaDownloadPath) const checkSum = await calculateChecksum(juliaDownloadPath)
if (fileInfo.sha256 != checkSum) { if (fileInfo.sha256 != checkSum) {
throw new Error(`Checksum of downloaded file does not match the expected checksum from versions.json.\nExpected: ${fileInfo.sha256}\nGot: ${checkSum}`) throw new Error(`Checksum of downloaded file does not match the expected checksum from versions.json.\nExpected: ${fileInfo.sha256}\nGot: ${checkSum}`)
@@ -161,7 +182,7 @@ export async function installJulia(versionInfo, version: string, arch: string):
await exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', tempInstallDir]) await exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', tempInstallDir])
return tempInstallDir return tempInstallDir
case 'win32': case 'win32':
if (version == 'nightly' || semver.gtr(version, '1.3', {includePrerelease: true})) { if (version.endsWith('nightly') || semver.gtr(version, '1.3', {includePrerelease: true})) {
// The installer changed in 1.4: https://github.com/JuliaLang/julia/blob/ef0c9108b12f3ae177c51037934351ffa703b0b5/NEWS.md#build-system-changes // The installer changed in 1.4: https://github.com/JuliaLang/julia/blob/ef0c9108b12f3ae177c51037934351ffa703b0b5/NEWS.md#build-system-changes
await exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/SILENT /dir=${path.join(process.cwd(), tempInstallDir)}" -NoNewWindow -Wait`]) await exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/SILENT /dir=${path.join(process.cwd(), tempInstallDir)}" -NoNewWindow -Wait`])
} else { } else {
@@ -176,3 +197,42 @@ export async function installJulia(versionInfo, version: string, arch: string):
throw new Error(`Platform ${osPlat} is not supported`) 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

@@ -73,14 +73,10 @@ async function run() {
// Set output // Set output
core.setOutput('julia-bindir', path.join(juliaPath, 'bin')) core.setOutput('julia-bindir', path.join(juliaPath, 'bin'))
// Test if Julia has been installed
exec.exec('julia', ['--version'])
// If enabled, also show the full version info // Test if Julia has been installed and print the version
if (core.getInput('show-versioninfo') == 'true') { const showVersionInfoInput = core.getInput('show-versioninfo')
exec.exec('julia', ['-e', 'using InteractiveUtils; versioninfo()']) await installer.showVersionInfo(showVersionInfoInput, version)
}
} catch (error) { } catch (error) {
core.setFailed(error.message) core.setFailed(error.message)
} }