mirror of
https://github.com/julia-actions/setup-julia.git
synced 2026-02-12 19:16:54 +08:00
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>
250 lines
10 KiB
JavaScript
Generated
250 lines
10 KiB
JavaScript
Generated
"use strict";
|
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
});
|
|
};
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
|
result["default"] = mod;
|
|
return result;
|
|
};
|
|
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 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 = {
|
|
'win32': 'winnt',
|
|
'darwin': 'mac',
|
|
'linux': 'linux'
|
|
};
|
|
const archMap = {
|
|
'x86': 'i686',
|
|
'x64': 'x86_64',
|
|
'aarch64': 'aarch64'
|
|
};
|
|
// Store information about the environment
|
|
const osPlat = os.platform(); // possible values: win32 (Windows), linux (Linux), darwin (macOS)
|
|
core.debug(`platform: ${osPlat}`);
|
|
/**
|
|
* @returns The SHA256 checksum of a given file.
|
|
*/
|
|
function calculateChecksum(file) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
const hash = crypto.createHash('sha256');
|
|
const input = fs.createReadStream(file);
|
|
return new Promise((resolve, reject) => {
|
|
input.on('data', (chunk) => {
|
|
hash.update(chunk);
|
|
});
|
|
input.on('end', () => {
|
|
const digest = hash.digest('hex');
|
|
digest ? resolve(digest) : reject(new Error(`Could not calculate checksum of file ${file}: digest was empty.`));
|
|
});
|
|
});
|
|
});
|
|
}
|
|
/**
|
|
* @returns The content of the downloaded versions.json file as object.
|
|
*/
|
|
function getJuliaVersionInfo() {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
// 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());
|
|
});
|
|
}
|
|
exports.getJuliaVersionInfo = getJuliaVersionInfo;
|
|
/**
|
|
* @returns An array of all Julia versions available for download
|
|
*/
|
|
function getJuliaVersions(versionInfo) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
let versions = [];
|
|
for (let version in versionInfo) {
|
|
versions.push(version);
|
|
}
|
|
return versions;
|
|
});
|
|
}
|
|
exports.getJuliaVersions = getJuliaVersions;
|
|
function getJuliaVersion(availableReleases, versionInput) {
|
|
if (semver.valid(versionInput) == versionInput || versionInput.endsWith('nightly')) {
|
|
// versionInput is a valid version or a nightly version, use it directly
|
|
return versionInput;
|
|
}
|
|
// Use the highest available version that matches versionInput
|
|
let version = semver.maxSatisfying(availableReleases, versionInput);
|
|
if (version == null) {
|
|
throw new Error(`Could not find a Julia version that matches ${versionInput}`);
|
|
}
|
|
// GitHub tags start with v, remove it
|
|
version = version.replace(/^v/, '');
|
|
return version;
|
|
}
|
|
exports.getJuliaVersion = getJuliaVersion;
|
|
function getNightlyFileName(arch) {
|
|
let versionExt, ext;
|
|
if (osPlat == 'win32') {
|
|
versionExt = arch == 'x64' ? '-win64' : '-win32';
|
|
ext = 'exe';
|
|
}
|
|
else if (osPlat == 'darwin') {
|
|
if (arch == 'x86') {
|
|
throw new Error('32-bit Julia is not available on macOS');
|
|
}
|
|
versionExt = '-mac64';
|
|
ext = 'dmg';
|
|
}
|
|
else if (osPlat === 'linux') {
|
|
versionExt = arch == 'x64' ? '-linux64' : '-linux32';
|
|
ext = 'tar.gz';
|
|
}
|
|
else {
|
|
throw new Error(`Platform ${osPlat} is not supported`);
|
|
}
|
|
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 err;
|
|
}
|
|
exports.getFileInfo = getFileInfo;
|
|
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
|
|
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;
|
|
function installJulia(versionInfo, version, arch) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
// Download Julia
|
|
const fileInfo = getFileInfo(versionInfo, version, arch);
|
|
const downloadURL = getDownloadURL(fileInfo, version, arch);
|
|
core.debug(`downloading Julia from ${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);
|
|
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}`);
|
|
}
|
|
core.debug(`Checksum of downloaded file matches expected checksum: ${checkSum}`);
|
|
}
|
|
else {
|
|
core.debug('Skipping checksum check for nightly binaries.');
|
|
}
|
|
const tempInstallDir = fs.mkdtempSync(`julia-${arch}-${version}-`);
|
|
// Install it
|
|
switch (osPlat) {
|
|
case 'linux':
|
|
// 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;
|
|
case 'win32':
|
|
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
|
|
yield exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/SILENT /dir=${path.join(process.cwd(), tempInstallDir)}" -NoNewWindow -Wait`]);
|
|
}
|
|
else {
|
|
yield exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/S /D=${path.join(process.cwd(), tempInstallDir)}" -NoNewWindow -Wait`]);
|
|
}
|
|
return tempInstallDir;
|
|
case 'darwin':
|
|
yield exec.exec('hdiutil', ['attach', juliaDownloadPath]);
|
|
yield exec.exec('/bin/bash', ['-c', `cp -a /Volumes/Julia-*/Julia-*.app/Contents/Resources/julia ${tempInstallDir}`]);
|
|
return path.join(tempInstallDir, 'julia');
|
|
default:
|
|
throw new Error(`Platform ${osPlat} is not supported`);
|
|
}
|
|
});
|
|
}
|
|
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;
|