From b275e5a212844ee9e9728d289eec5b77997d3335 Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 15:17:59 +0100 Subject: [PATCH 01/20] Verify checksums before installing Julia --- lib/installer.js | 24 ++++++++++++++++++++++++ src/installer.ts | 27 +++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/lib/installer.js b/lib/installer.js index 7989fbf5..0e7121c2 100644 --- a/lib/installer.js +++ b/lib/installer.js @@ -18,6 +18,7 @@ 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")); @@ -35,6 +36,25 @@ const archMap = { // Store information about the environment const osPlat = os.platform(); // possible values: win32 (Windows), linux (Linux), darwin (macOS) core.debug(`platform: ${osPlat}`); +/** + * Based on https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm_options + * + * @returns The SHA256 checksum of a given file. + */ +function calculateChecksum(file) { + const hash = crypto.createHash('sha256'); + const input = fs.createReadStream(file); + input.on('readable', () => { + const data = input.read(); + if (data) { + hash.update(data); + } + else { + return hash.digest('hex'); + } + }); + throw new Error(`Could not calculate checksum of file ${file}`); +} /** * @returns The content of the downloaded versions.json file as object. */ @@ -120,6 +140,10 @@ function installJulia(versionInfo, version, arch) { const downloadURL = getDownloadURL(versionInfo, version, arch); core.debug(`downloading Julia from ${downloadURL}`); const juliaDownloadPath = yield tc.downloadTool(downloadURL); + // Verify checksum + if (versionInfo[version].sha256 != calculateChecksum(juliaDownloadPath)) { + throw new Error('Checksum of downloaded file does not match the expected checksum from versions.json'); + } const tempInstallDir = fs.mkdtempSync(`julia-${arch}-${version}-`); // Install it switch (osPlat) { diff --git a/src/installer.ts b/src/installer.ts index 43b57bb7..4f6038fc 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -2,6 +2,7 @@ import * as core from '@actions/core' import * as exec from '@actions/exec' import * as tc from '@actions/tool-cache' +import * as crypto from 'crypto' import * as fs from 'fs' import * as os from 'os' import * as path from 'path' @@ -23,6 +24,27 @@ const archMap = { const osPlat = os.platform() // possible values: win32 (Windows), linux (Linux), darwin (macOS) core.debug(`platform: ${osPlat}`) +/** + * Based on https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm_options + * + * @returns The SHA256 checksum of a given file. + */ +function calculateChecksum(file: string): string { + const hash = crypto.createHash('sha256') + const input = fs.createReadStream(file) + + input.on('readable', () => { + const data = input.read() + if (data) { + hash.update(data) + } else { + return hash.digest('hex') + } + }) + + throw new Error(`Could not calculate checksum of file ${file}`) +} + /** * @returns The content of the downloaded versions.json file as object. */ @@ -113,6 +135,11 @@ export async function installJulia(versionInfo, version: string, arch: string): core.debug(`downloading Julia from ${downloadURL}`) const juliaDownloadPath = await tc.downloadTool(downloadURL) + // Verify checksum + if (versionInfo[version].sha256 != calculateChecksum(juliaDownloadPath)) { + throw new Error('Checksum of downloaded file does not match the expected checksum from versions.json') + } + const tempInstallDir = fs.mkdtempSync(`julia-${arch}-${version}-`) // Install it From 3507ddbc6f7f2185cad8a503d9318f343f4e39bf Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 15:21:29 +0100 Subject: [PATCH 02/20] Fix calculateChecksum --- lib/installer.js | 4 ++-- src/installer.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/installer.js b/lib/installer.js index 0e7121c2..62da6eb1 100644 --- a/lib/installer.js +++ b/lib/installer.js @@ -50,10 +50,10 @@ function calculateChecksum(file) { hash.update(data); } else { - return hash.digest('hex'); + throw new Error(`Could not calculate checksum of file ${file}`); } }); - throw new Error(`Could not calculate checksum of file ${file}`); + return hash.digest('hex'); } /** * @returns The content of the downloaded versions.json file as object. diff --git a/src/installer.ts b/src/installer.ts index 4f6038fc..3421bdfd 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -38,11 +38,11 @@ function calculateChecksum(file: string): string { if (data) { hash.update(data) } else { - return hash.digest('hex') + throw new Error(`Could not calculate checksum of file ${file}`) } }) - throw new Error(`Could not calculate checksum of file ${file}`) + return hash.digest('hex') } /** From ea116d625cfb147d110bbadb8886088ecdfd24a1 Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 15:25:54 +0100 Subject: [PATCH 03/20] Fix calculateChecksum --- lib/installer.js | 8 ++++++-- src/installer.ts | 10 ++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/installer.js b/lib/installer.js index 62da6eb1..46b1df38 100644 --- a/lib/installer.js +++ b/lib/installer.js @@ -44,16 +44,20 @@ core.debug(`platform: ${osPlat}`); function calculateChecksum(file) { const hash = crypto.createHash('sha256'); const input = fs.createReadStream(file); + let hashDigest = ''; input.on('readable', () => { const data = input.read(); if (data) { hash.update(data); } else { - throw new Error(`Could not calculate checksum of file ${file}`); + hashDigest = hash.digest('hex'); } }); - return hash.digest('hex'); + if (!hashDigest) { + throw new Error(`Could not calculate checksum of file ${file}`); + } + return hashDigest; } /** * @returns The content of the downloaded versions.json file as object. diff --git a/src/installer.ts b/src/installer.ts index 3421bdfd..38c04ed5 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -33,16 +33,22 @@ function calculateChecksum(file: string): string { const hash = crypto.createHash('sha256') const input = fs.createReadStream(file) + let hashDigest: string = '' + input.on('readable', () => { const data = input.read() if (data) { hash.update(data) } else { - throw new Error(`Could not calculate checksum of file ${file}`) + hashDigest = hash.digest('hex') } }) - return hash.digest('hex') + if (!hashDigest) { + throw new Error(`Could not calculate checksum of file ${file}`) + } + + return hashDigest } /** From 0d510c593f0b2ba219aae42d6c0b20612b778f94 Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 15:30:20 +0100 Subject: [PATCH 04/20] Fix calculateChecksum --- lib/installer.js | 1 + src/installer.ts | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/installer.js b/lib/installer.js index 46b1df38..d2aff6fa 100644 --- a/lib/installer.js +++ b/lib/installer.js @@ -54,6 +54,7 @@ function calculateChecksum(file) { hashDigest = hash.digest('hex'); } }); + core.debug(`hashDigest: ${hashDigest}`); if (!hashDigest) { throw new Error(`Could not calculate checksum of file ${file}`); } diff --git a/src/installer.ts b/src/installer.ts index 38c04ed5..6353bbd5 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -44,10 +44,12 @@ function calculateChecksum(file: string): string { } }) + core.debug(`hashDigest: ${hashDigest}`) + if (!hashDigest) { throw new Error(`Could not calculate checksum of file ${file}`) } - + return hashDigest } From b8b38f9e2fa96d43cb64059599ab7f8233402431 Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 15:51:36 +0100 Subject: [PATCH 05/20] Solve sync and async shenanigans Co-authored-by: Derk-Jan Karrenbeld --- lib/installer.js | 32 +++++++++++++------------------- src/installer.ts | 30 ++++++++++-------------------- 2 files changed, 23 insertions(+), 39 deletions(-) diff --git a/lib/installer.js b/lib/installer.js index d2aff6fa..6929cbe5 100644 --- a/lib/installer.js +++ b/lib/installer.js @@ -37,28 +37,22 @@ const archMap = { const osPlat = os.platform(); // possible values: win32 (Windows), linux (Linux), darwin (macOS) core.debug(`platform: ${osPlat}`); /** - * Based on https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm_options - * * @returns The SHA256 checksum of a given file. */ function calculateChecksum(file) { - const hash = crypto.createHash('sha256'); - const input = fs.createReadStream(file); - let hashDigest = ''; - input.on('readable', () => { - const data = input.read(); - if (data) { - hash.update(data); - } - else { - hashDigest = hash.digest('hex'); - } + 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.`)); + }); + }); }); - core.debug(`hashDigest: ${hashDigest}`); - if (!hashDigest) { - throw new Error(`Could not calculate checksum of file ${file}`); - } - return hashDigest; } /** * @returns The content of the downloaded versions.json file as object. @@ -146,7 +140,7 @@ function installJulia(versionInfo, version, arch) { core.debug(`downloading Julia from ${downloadURL}`); const juliaDownloadPath = yield tc.downloadTool(downloadURL); // Verify checksum - if (versionInfo[version].sha256 != calculateChecksum(juliaDownloadPath)) { + if (versionInfo[version].sha256 != (yield calculateChecksum(juliaDownloadPath))) { throw new Error('Checksum of downloaded file does not match the expected checksum from versions.json'); } const tempInstallDir = fs.mkdtempSync(`julia-${arch}-${version}-`); diff --git a/src/installer.ts b/src/installer.ts index 6353bbd5..7ffc174b 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -25,32 +25,22 @@ const osPlat = os.platform() // possible values: win32 (Windows), linux (Linux), core.debug(`platform: ${osPlat}`) /** - * Based on https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm_options - * * @returns The SHA256 checksum of a given file. */ -function calculateChecksum(file: string): string { +async function calculateChecksum(file: string): Promise { const hash = crypto.createHash('sha256') const input = fs.createReadStream(file) - let hashDigest: string = '' + return new Promise((resolve, reject) => { + input.on('data', (chunk) => { + hash.update(chunk) + }) - input.on('readable', () => { - const data = input.read() - if (data) { - hash.update(data) - } else { - hashDigest = hash.digest('hex') - } + input.on('end', () => { + const digest = hash.digest('hex') + digest ? resolve(digest) : reject(new Error(`Could not calculate checksum of file ${file}: digest was empty.`)) + }) }) - - core.debug(`hashDigest: ${hashDigest}`) - - if (!hashDigest) { - throw new Error(`Could not calculate checksum of file ${file}`) - } - - return hashDigest } /** @@ -144,7 +134,7 @@ export async function installJulia(versionInfo, version: string, arch: string): const juliaDownloadPath = await tc.downloadTool(downloadURL) // Verify checksum - if (versionInfo[version].sha256 != calculateChecksum(juliaDownloadPath)) { + if (versionInfo[version].sha256 != await calculateChecksum(juliaDownloadPath)) { throw new Error('Checksum of downloaded file does not match the expected checksum from versions.json') } From e12b36b1c00decc9d0b228d3e2da7f9d33631615 Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 15:55:24 +0100 Subject: [PATCH 06/20] Debug --- lib/installer.js | 2 ++ src/installer.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lib/installer.js b/lib/installer.js index 6929cbe5..ebf25d7f 100644 --- a/lib/installer.js +++ b/lib/installer.js @@ -140,6 +140,8 @@ function installJulia(versionInfo, version, arch) { core.debug(`downloading Julia from ${downloadURL}`); const juliaDownloadPath = yield tc.downloadTool(downloadURL); // Verify checksum + core.debug(versionInfo[version].sha256); + core.debug(yield calculateChecksum(juliaDownloadPath)); if (versionInfo[version].sha256 != (yield calculateChecksum(juliaDownloadPath))) { throw new Error('Checksum of downloaded file does not match the expected checksum from versions.json'); } diff --git a/src/installer.ts b/src/installer.ts index 7ffc174b..e43b6e81 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -134,6 +134,8 @@ export async function installJulia(versionInfo, version: string, arch: string): const juliaDownloadPath = await tc.downloadTool(downloadURL) // Verify checksum + core.debug(versionInfo[version].sha256) + core.debug(await calculateChecksum(juliaDownloadPath)) if (versionInfo[version].sha256 != await calculateChecksum(juliaDownloadPath)) { throw new Error('Checksum of downloaded file does not match the expected checksum from versions.json') } From fe8bbfa534cb8bd8ab86cd7812eaacfb764bab4a Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 16:08:16 +0100 Subject: [PATCH 07/20] Refactor to not search VersionInfo all the time --- lib/installer.js | 35 ++++++++++++++++++++++------------- src/installer.ts | 36 ++++++++++++++++++++++-------------- 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/lib/installer.js b/lib/installer.js index ebf25d7f..caf8033f 100644 --- a/lib/installer.js +++ b/lib/installer.js @@ -118,32 +118,41 @@ function getNightlyFileName(arch) { } return `julia-latest${versionExt}.${ext}`; } -function getDownloadURL(versionInfo, version, arch) { - // nightlies - if (version == 'nightly') { - const baseURL = 'https://julialangnightlies-s3.julialang.org/bin'; - return `${baseURL}/${osMap[osPlat]}/${arch}/${getNightlyFileName(arch)}`; - } +function getFileInfo(versionInfo, version, arch) { for (let file of versionInfo[version].files) { if (file.os == osMap[osPlat] && file.arch == archMap[arch]) { - core.debug(file); - return file.url; + return file; } } throw `Could not find ${archMap[arch]}/${version} binaries`; } +exports.getFileInfo = getFileInfo; +function getDownloadURL(fileInfo, version, arch) { + // nightlies + if (version == 'nightly') { + const baseURL = 'https://julialangnightlies-s3.julialang.org/bin'; + return `${baseURL}/${osMap[osPlat]}/${arch}/${getNightlyFileName(arch)}`; + } + return fileInfo.url; +} exports.getDownloadURL = getDownloadURL; function installJulia(versionInfo, version, arch) { return __awaiter(this, void 0, void 0, function* () { // Download Julia - const downloadURL = getDownloadURL(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); // Verify checksum - core.debug(versionInfo[version].sha256); - core.debug(yield calculateChecksum(juliaDownloadPath)); - if (versionInfo[version].sha256 != (yield calculateChecksum(juliaDownloadPath))) { - throw new Error('Checksum of downloaded file does not match the expected checksum from versions.json'); + if (version != 'nightly') { + core.debug(fileInfo.sha256); + core.debug(yield calculateChecksum(juliaDownloadPath)); + if (fileInfo.sha256 != (yield calculateChecksum(juliaDownloadPath))) { + throw new Error('Checksum of downloaded file does not match the expected checksum from versions.json'); + } + } + else { + core.debug('Skipping checksum check for nightly binaries.'); } const tempInstallDir = fs.mkdtempSync(`julia-${arch}-${version}-`); // Install it diff --git a/src/installer.ts b/src/installer.ts index e43b6e81..80e53779 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -110,34 +110,42 @@ function getNightlyFileName(arch: string): string { return `julia-latest${versionExt}.${ext}` } -export function getDownloadURL(versionInfo, version: string, arch: string): string { - // nightlies - if (version == 'nightly') { - const baseURL = 'https://julialangnightlies-s3.julialang.org/bin' - return `${baseURL}/${osMap[osPlat]}/${arch}/${getNightlyFileName(arch)}` - } - +export function getFileInfo(versionInfo, version: string, arch: string) { for (let file of versionInfo[version].files) { if (file.os == osMap[osPlat] && file.arch == archMap[arch]) { - core.debug(file) - return file.url + return file } } throw `Could not find ${archMap[arch]}/${version} binaries` } +export function getDownloadURL(fileInfo, version: string, arch: string): string { + // nightlies + if (version == 'nightly') { + const baseURL = 'https://julialangnightlies-s3.julialang.org/bin' + return `${baseURL}/${osMap[osPlat]}/${arch}/${getNightlyFileName(arch)}` + } + + return fileInfo.url +} + export async function installJulia(versionInfo, version: string, arch: string): Promise { // Download Julia - const downloadURL = getDownloadURL(versionInfo, version, arch) + const fileInfo = getFileInfo(versionInfo, version, arch) + const downloadURL = getDownloadURL(fileInfo, version, arch) core.debug(`downloading Julia from ${downloadURL}`) const juliaDownloadPath = await tc.downloadTool(downloadURL) // Verify checksum - core.debug(versionInfo[version].sha256) - core.debug(await calculateChecksum(juliaDownloadPath)) - if (versionInfo[version].sha256 != await calculateChecksum(juliaDownloadPath)) { - throw new Error('Checksum of downloaded file does not match the expected checksum from versions.json') + if (version != 'nightly') { + core.debug(fileInfo.sha256) + core.debug(await calculateChecksum(juliaDownloadPath)) + if (fileInfo.sha256 != await calculateChecksum(juliaDownloadPath)) { + throw new Error('Checksum of downloaded file does not match the expected checksum from versions.json') + } + } else { + core.debug('Skipping checksum check for nightly binaries.') } const tempInstallDir = fs.mkdtempSync(`julia-${arch}-${version}-`) From 287d5fbe6cefbbae9eb848ee1dfae7497b4b5d21 Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 16:14:21 +0100 Subject: [PATCH 08/20] Fix for nightlies and add debug info --- lib/installer.js | 11 +++++++---- src/installer.ts | 12 ++++++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/installer.js b/lib/installer.js index caf8033f..371360fd 100644 --- a/lib/installer.js +++ b/lib/installer.js @@ -119,6 +119,9 @@ function getNightlyFileName(arch) { return `julia-latest${versionExt}.${ext}`; } function getFileInfo(versionInfo, version, arch) { + if (version == 'nightly') { + return null; + } for (let file of versionInfo[version].files) { if (file.os == osMap[osPlat] && file.arch == archMap[arch]) { return file; @@ -145,11 +148,11 @@ function installJulia(versionInfo, version, arch) { const juliaDownloadPath = yield tc.downloadTool(downloadURL); // Verify checksum if (version != 'nightly') { - core.debug(fileInfo.sha256); - core.debug(yield calculateChecksum(juliaDownloadPath)); - if (fileInfo.sha256 != (yield calculateChecksum(juliaDownloadPath))) { - throw new Error('Checksum of downloaded file does not match the expected checksum from versions.json'); + 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.'); diff --git a/src/installer.ts b/src/installer.ts index 80e53779..ad2cdc34 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -111,6 +111,10 @@ function getNightlyFileName(arch: string): string { } export function getFileInfo(versionInfo, version: string, arch: string) { + if (version == 'nightly') { + return null + } + for (let file of versionInfo[version].files) { if (file.os == osMap[osPlat] && file.arch == archMap[arch]) { return file @@ -139,11 +143,11 @@ export async function installJulia(versionInfo, version: string, arch: string): // Verify checksum if (version != 'nightly') { - core.debug(fileInfo.sha256) - core.debug(await calculateChecksum(juliaDownloadPath)) - if (fileInfo.sha256 != await calculateChecksum(juliaDownloadPath)) { - throw new Error('Checksum of downloaded file does not match the expected checksum from versions.json') + const checkSum = await 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.') } From ee69194ed0712474b2bb10fbfae01c2fa58a7f1d Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 16:16:00 +0100 Subject: [PATCH 09/20] Add test if checksum doesn't match --- __tests__/installer.test.ts | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 97907353..8adcc555 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -93,21 +93,41 @@ describe('installer tests', () => { } }, 100000) + + // Instead of downloading versions.json, use fixtures/versions.json + beforeEach(() => { + nock('https://julialang-s3.julialang.org') + .get('/bin/versions.json') + .replyWithFile(200, path.join(fixtureDir, 'versions.json')) + }) + + afterEach(() => { + nock.cleanAll() + nock.enableNetConnect() + }) + describe('versions.json parsing', () => { - // Instead of downloading versions.json, use fixtures/versions.json + it('Extracts the list of available versions', async () => { + expect(await (await installer.getJuliaVersions(await installer.getJuliaVersionInfo())).sort()).toEqual(testVersions.sort()) + }) + }) + + describe('signature matching', () => { beforeEach(() => { nock('https://julialang-s3.julialang.org') - .get('/bin/versions.json') - .replyWithFile(200, path.join(fixtureDir, 'versions.json')) + .get(uri => !(uri.includes('versions.json'))) // Mock all requests to binaries + .reply(200, 'Malformed binary.', {'Content-Type': 'application/octet-stream'}) }) - + afterEach(() => { nock.cleanAll() nock.enableNetConnect() }) - - it('Extracts the list of available versions', async () => { - expect(await (await installer.getJuliaVersions(await installer.getJuliaVersionInfo())).sort()).toEqual(testVersions.sort()) + + const versionInfo = installer.getJuliaVersionInfo() + + it('Throws an error if the signature of the downloaded file doesn\'t match the expected signature', async () => { + expect(installer.installJulia(versionInfo, '1.3.0', 'x64')).toThrow('Checksum of downloaded file does not match the expected checksum from versions.json') }) }) }) From a1e127ef6ca0a4cf257611142e96f782b7e5c38f Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 16:38:38 +0100 Subject: [PATCH 10/20] Fix testing --- __tests__/installer.test.ts | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 8adcc555..5dea8434 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -93,20 +93,19 @@ describe('installer tests', () => { } }, 100000) - - // Instead of downloading versions.json, use fixtures/versions.json - beforeEach(() => { - nock('https://julialang-s3.julialang.org') - .get('/bin/versions.json') - .replyWithFile(200, path.join(fixtureDir, 'versions.json')) - }) + describe('versions.json parsing', () => { + // Instead of downloading versions.json, use fixtures/versions.json + beforeEach(() => { + nock('https://julialang-s3.julialang.org').persist() + .get('/bin/versions.json') + .replyWithFile(200, path.join(fixtureDir, 'versions.json')) + }) - afterEach(() => { - nock.cleanAll() - nock.enableNetConnect() - }) + afterEach(() => { + nock.cleanAll() + nock.enableNetConnect() + }) - describe('versions.json parsing', () => { it('Extracts the list of available versions', async () => { expect(await (await installer.getJuliaVersions(await installer.getJuliaVersionInfo())).sort()).toEqual(testVersions.sort()) }) @@ -114,9 +113,13 @@ describe('installer tests', () => { describe('signature matching', () => { beforeEach(() => { - nock('https://julialang-s3.julialang.org') + nock('https://julialang-s3.julialang.org').persist() .get(uri => !(uri.includes('versions.json'))) // Mock all requests to binaries - .reply(200, 'Malformed binary.', {'Content-Type': 'application/octet-stream'}) + .reply(200, 'Malformed binary.') + + nock('https://julialang-s3.julialang.org').persist() + .get('/bin/versions.json') + .replyWithFile(200, path.join(fixtureDir, 'versions.json')) }) afterEach(() => { @@ -127,7 +130,7 @@ describe('installer tests', () => { const versionInfo = installer.getJuliaVersionInfo() it('Throws an error if the signature of the downloaded file doesn\'t match the expected signature', async () => { - expect(installer.installJulia(versionInfo, '1.3.0', 'x64')).toThrow('Checksum of downloaded file does not match the expected checksum from versions.json') + expect(installer.installJulia(versionInfo, '1.3.0', 'x64')).toThrowError('Checksum of downloaded file does not match the expected checksum from versions.json') }) }) }) From f15a7bdfedbc28900d5623d86519a640cdc194a5 Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 16:41:35 +0100 Subject: [PATCH 11/20] Fix testing --- __tests__/installer.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 5dea8434..164d41f1 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -111,7 +111,7 @@ describe('installer tests', () => { }) }) - describe('signature matching', () => { + describe('signature matching', async () => { beforeEach(() => { nock('https://julialang-s3.julialang.org').persist() .get(uri => !(uri.includes('versions.json'))) // Mock all requests to binaries @@ -127,10 +127,10 @@ describe('installer tests', () => { nock.enableNetConnect() }) - const versionInfo = installer.getJuliaVersionInfo() + const versionInfo = await installer.getJuliaVersionInfo() it('Throws an error if the signature of the downloaded file doesn\'t match the expected signature', async () => { - expect(installer.installJulia(versionInfo, '1.3.0', 'x64')).toThrowError('Checksum of downloaded file does not match the expected checksum from versions.json') + expect(await installer.installJulia(versionInfo, '1.3.0', 'x64')).toThrowError('Checksum of downloaded file does not match the expected checksum from versions.json') }) }) }) From 29eb5190b9ca6641419f77ae14bab901b799419e Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 16:44:03 +0100 Subject: [PATCH 12/20] Fix testing --- __tests__/installer.test.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 164d41f1..cc03b7af 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -111,7 +111,13 @@ describe('installer tests', () => { }) }) - describe('signature matching', async () => { + describe('signature matching', () => { + let versionInfo + + beforeAll(async () => { + versionInfo = await installer.getJuliaVersionInfo() + }) + beforeEach(() => { nock('https://julialang-s3.julialang.org').persist() .get(uri => !(uri.includes('versions.json'))) // Mock all requests to binaries @@ -126,9 +132,7 @@ describe('installer tests', () => { nock.cleanAll() nock.enableNetConnect() }) - - const versionInfo = await installer.getJuliaVersionInfo() - + it('Throws an error if the signature of the downloaded file doesn\'t match the expected signature', async () => { expect(await installer.installJulia(versionInfo, '1.3.0', 'x64')).toThrowError('Checksum of downloaded file does not match the expected checksum from versions.json') }) From 02a5b3856e1b8ae7ae251a1c78704763b617995c Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 16:49:09 +0100 Subject: [PATCH 13/20] Fix testing --- __tests__/installer.test.ts | 34 ++++++++++++------------- __tests__/main.test.ts | 50 ------------------------------------- 2 files changed, 17 insertions(+), 67 deletions(-) delete mode 100644 __tests__/main.test.ts diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index cc03b7af..9cd357e2 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -41,28 +41,28 @@ import * as installer from '../src/installer' describe('version matching tests', () => { describe('specific versions', () => { - it('Doesn\'t change the version when given a valid semver version', async () => { - expect(await installer.getJuliaVersion([], '1.0.5')).toEqual('1.0.5') - expect(await installer.getJuliaVersion(['v1.0.5', 'v1.0.6'], '1.0.5')).toEqual('1.0.5') - expect(await installer.getJuliaVersion(['v1.0.4', 'v1.0.5'], '1.0.5')).toEqual('1.0.5') - expect(await installer.getJuliaVersion(['v1.0.4'], '1.0.5')).toEqual('1.0.5') - expect(await installer.getJuliaVersion([], '1.3.0-alpha')).toEqual('1.3.0-alpha') - expect(await installer.getJuliaVersion(['v1.2.0', 'v1.3.0-alpha', 'v1.3.0-rc1', 'v1.3.0'], '1.3.0-alpha')).toEqual('1.3.0-alpha') - expect(await installer.getJuliaVersion([], '1.3.0-rc2')).toEqual('1.3.0-rc2') + it('Doesn\'t change the version when given a valid semver version', () => { + expect(installer.getJuliaVersion([], '1.0.5')).toEqual('1.0.5') + expect(installer.getJuliaVersion(['v1.0.5', 'v1.0.6'], '1.0.5')).toEqual('1.0.5') + expect(installer.getJuliaVersion(['v1.0.4', 'v1.0.5'], '1.0.5')).toEqual('1.0.5') + expect(installer.getJuliaVersion(['v1.0.4'], '1.0.5')).toEqual('1.0.5') + expect(installer.getJuliaVersion([], '1.3.0-alpha')).toEqual('1.3.0-alpha') + expect(installer.getJuliaVersion(['v1.2.0', 'v1.3.0-alpha', 'v1.3.0-rc1', 'v1.3.0'], '1.3.0-alpha')).toEqual('1.3.0-alpha') + expect(installer.getJuliaVersion([], '1.3.0-rc2')).toEqual('1.3.0-rc2') }) - it('Doesn\'t change the version when given `nightly`', async () => { - expect(await installer.getJuliaVersion([], 'nightly')).toEqual('nightly') - expect(await installer.getJuliaVersion(testVersions, 'nightly')).toEqual('nightly') + it('Doesn\'t change the version when given `nightly`', () => { + expect(installer.getJuliaVersion([], 'nightly')).toEqual('nightly') + expect(installer.getJuliaVersion(testVersions, 'nightly')).toEqual('nightly') }) }) describe('version ranges', () => { - it('Chooses the highest available version that matches the input', async () => { - expect(await installer.getJuliaVersion(testVersions, '1')).toEqual('1.2.0') - expect(await installer.getJuliaVersion(testVersions, '1.0')).toEqual('1.0.5') - expect(await installer.getJuliaVersion(testVersions, '^1.3.0-rc1')).toEqual('1.3.0-rc4') - expect(await installer.getJuliaVersion(testVersions, '^1.2.0-rc1')).toEqual('1.2.0') + it('Chooses the highest available version that matches the input', () => { + expect(installer.getJuliaVersion(testVersions, '1')).toEqual('1.2.0') + expect(installer.getJuliaVersion(testVersions, '1.0')).toEqual('1.0.5') + expect(installer.getJuliaVersion(testVersions, '^1.3.0-rc1')).toEqual('1.3.0-rc4') + expect(installer.getJuliaVersion(testVersions, '^1.2.0-rc1')).toEqual('1.2.0') }) }) @@ -134,7 +134,7 @@ describe('installer tests', () => { }) it('Throws an error if the signature of the downloaded file doesn\'t match the expected signature', async () => { - expect(await installer.installJulia(versionInfo, '1.3.0', 'x64')).toThrowError('Checksum of downloaded file does not match the expected checksum from versions.json') + expect(await installer.installJulia(versionInfo, '1.1.0', 'x64')).toThrowError('Checksum of downloaded file does not match the expected checksum from versions.json.\nExpected: 80cfd013e526b5145ec3254920afd89bb459f1db7a2a3f21849125af20c05471\nGot: ffe3b3fa2c274b3a288ed9461b7a1878e810c2ca4ec1c8e1b180826844b108f7') }) }) }) diff --git a/__tests__/main.test.ts b/__tests__/main.test.ts deleted file mode 100644 index 5db125b0..00000000 --- a/__tests__/main.test.ts +++ /dev/null @@ -1,50 +0,0 @@ -import * as installer from '../src/installer' - -import * as semver from 'semver' - -const testVersions = ['v1.3.0-rc4', 'v1.3.0-rc3', 'v1.3.0-rc2', 'v1.0.5', 'v1.2.0', 'v1.3.0-rc1', 'v1.2.0-rc3', 'v1.3.0-alpha', 'v1.2.0-rc2', 'v1.2.0-rc1', 'v1.1.1', 'v1.0.4', 'v1.1.0', 'v1.1.0-rc2', 'v1.1.0-rc1', 'v1.0.3', 'v1.0.2', 'v1.0.1', 'v1.0.0'] - -describe('installer tests', () => { - describe('version matching', () => { - describe('specific versions', () => { - it('Doesn\'t change the version when given a valid semver version', async () => { - expect(await installer.getJuliaVersion([], '1.0.5')).toEqual('1.0.5') - expect(await installer.getJuliaVersion(['v1.0.5', 'v1.0.6'], '1.0.5')).toEqual('1.0.5') - expect(await installer.getJuliaVersion(['v1.0.4', 'v1.0.5'], '1.0.5')).toEqual('1.0.5') - expect(await installer.getJuliaVersion(['v1.0.4'], '1.0.5')).toEqual('1.0.5') - expect(await installer.getJuliaVersion([], '1.3.0-alpha')).toEqual('1.3.0-alpha') - expect(await installer.getJuliaVersion(['v1.2.0', 'v1.3.0-alpha', 'v1.3.0-rc1', 'v1.3.0'], '1.3.0-alpha')).toEqual('1.3.0-alpha') - expect(await installer.getJuliaVersion([], '1.3.0-rc2')).toEqual('1.3.0-rc2') - }) - it('Doesn\'t change the version when given `nightly`', async () => { - expect(await installer.getJuliaVersion([], 'nightly')).toEqual('nightly') - expect(await installer.getJuliaVersion(testVersions, 'nightly')).toEqual('nightly') - }) - }) - describe('version ranges', () => { - it('Chooses the highest available version that matches the input', async () => { - expect(await installer.getJuliaVersion(testVersions, '1')).toEqual('1.2.0') - expect(await installer.getJuliaVersion(testVersions, '1.0')).toEqual('1.0.5') - expect(await installer.getJuliaVersion(testVersions, '^1.3.0-rc1')).toEqual('1.3.0-rc4') - expect(await installer.getJuliaVersion(testVersions, '^1.2.0-rc1')).toEqual('1.2.0') - }) - }) - describe('invalid version range (#38)', () => { - it('Throws an error if a version range does not match any available version', () => { - expect(() => { - installer.getJuliaVersion(['v1.5.0-rc1', 'v1.5.0-beta1', 'v1.4.2', 'v1.4.1', 'v1.4.0', 'v1.4.0-rc2', 'v1.4.0-rc1'], '1.6') - }).toThrowError() - }) - }) - }) - describe('node-semver behaviour', () => { - describe('Windows installer change', () => { - it('Correctly understands >1.4.0', () => { - expect(semver.gtr('1.4.0-rc1', '1.3', {includePrerelease: true})).toBeTruthy() - expect(semver.gtr('1.4.0-DEV', '1.3', {includePrerelease: true})).toBeTruthy() - expect(semver.gtr('1.3.1', '1.3', {includePrerelease: true})).toBeFalsy() - expect(semver.gtr('1.3.2-rc1', '1.3', {includePrerelease: true})).toBeFalsy() - }) - }) - }) -}) From afac79c73deff135f65f1a1097ecfdc80af832a3 Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 17:00:42 +0100 Subject: [PATCH 14/20] Fix testing --- __tests__/installer.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 9cd357e2..ebd7b819 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -34,8 +34,8 @@ const toolDir = path.join(__dirname, 'runner', 'tools') const tempDir = path.join(__dirname, 'runner', 'temp') const fixtureDir = path.join(__dirname, 'fixtures') -process.env['RUNNER_TOOL_CACHE'] = toolDir; -process.env['RUNNER_TEMP'] = tempDir; +process.env['RUNNER_TOOL_CACHE'] = toolDir +process.env['RUNNER_TEMP'] = tempDir import * as installer from '../src/installer' @@ -111,7 +111,7 @@ describe('installer tests', () => { }) }) - describe('signature matching', () => { + describe('checksum matching', () => { let versionInfo beforeAll(async () => { @@ -133,8 +133,8 @@ describe('installer tests', () => { nock.enableNetConnect() }) - it('Throws an error if the signature of the downloaded file doesn\'t match the expected signature', async () => { - expect(await installer.installJulia(versionInfo, '1.1.0', 'x64')).toThrowError('Checksum of downloaded file does not match the expected checksum from versions.json.\nExpected: 80cfd013e526b5145ec3254920afd89bb459f1db7a2a3f21849125af20c05471\nGot: ffe3b3fa2c274b3a288ed9461b7a1878e810c2ca4ec1c8e1b180826844b108f7') + it('Throws an error if the checksum of the downloaded file doesn\'t match the expected checksum', () => { + expect(installer.installJulia(versionInfo, '1.1.0', 'x64')).toThrowError(/^(Checksum of downloaded file does not match the expected checksum from versions\.json\.).*/) }) }) }) From a0560a39102cd20161bfd34e0fae634f5039f61a Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 17:02:24 +0100 Subject: [PATCH 15/20] Fix testing --- __tests__/installer.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index ebd7b819..e80e8913 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -133,8 +133,8 @@ describe('installer tests', () => { nock.enableNetConnect() }) - it('Throws an error if the checksum of the downloaded file doesn\'t match the expected checksum', () => { - expect(installer.installJulia(versionInfo, '1.1.0', 'x64')).toThrowError(/^(Checksum of downloaded file does not match the expected checksum from versions\.json\.).*/) + it('Throws an error if the checksum of the downloaded file doesn\'t match the expected checksum', async () => { + expect(await installer.installJulia(versionInfo, '1.1.0', 'x64')).toThrowError(/^(Checksum of downloaded file does not match the expected checksum from versions\.json\.).*/) }) }) }) From c7f1e1564af4effe7243b9b09482fd3cc86c835d Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 17:05:39 +0100 Subject: [PATCH 16/20] Fix testing --- __tests__/installer.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index e80e8913..2abf65ef 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -133,8 +133,8 @@ describe('installer tests', () => { nock.enableNetConnect() }) - it('Throws an error if the checksum of the downloaded file doesn\'t match the expected checksum', async () => { - expect(await installer.installJulia(versionInfo, '1.1.0', 'x64')).toThrowError(/^(Checksum of downloaded file does not match the expected checksum from versions\.json\.).*/) + it('Throws an error if the checksum of the downloaded file doesn\'t match the expected checksum', () => { + expect(() => {installer.installJulia(versionInfo, '1.1.0', 'x64')}).toThrowError(/^(Checksum of downloaded file does not match the expected checksum from versions\.json\.).*/) }) }) }) From 07f9808f9aa1a25c5407b758974fecd70affee71 Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 17:06:20 +0100 Subject: [PATCH 17/20] Fix testing --- __tests__/installer.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 2abf65ef..d7f56b05 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -134,7 +134,7 @@ describe('installer tests', () => { }) it('Throws an error if the checksum of the downloaded file doesn\'t match the expected checksum', () => { - expect(() => {installer.installJulia(versionInfo, '1.1.0', 'x64')}).toThrowError(/^(Checksum of downloaded file does not match the expected checksum from versions\.json\.).*/) + expect(() => {installer.installJulia(versionInfo, '1.1.0', 'x64')}).toThrowError('Checksum of downloaded file does not match the expected checksum from versions.json.\nExpected: 80cfd013e526b5145ec3254920afd89bb459f1db7a2a3f21849125af20c05471\nGot: ffe3b3fa2c274b3a288ed9461b7a1878e810c2ca4ec1c8e1b180826844b108f7') }) }) }) From 440b2841c0e6897534074cacaadcc27e920329e7 Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 17:07:35 +0100 Subject: [PATCH 18/20] Fix testing --- __tests__/installer.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index d7f56b05..cec45175 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -134,7 +134,7 @@ describe('installer tests', () => { }) it('Throws an error if the checksum of the downloaded file doesn\'t match the expected checksum', () => { - expect(() => {installer.installJulia(versionInfo, '1.1.0', 'x64')}).toThrowError('Checksum of downloaded file does not match the expected checksum from versions.json.\nExpected: 80cfd013e526b5145ec3254920afd89bb459f1db7a2a3f21849125af20c05471\nGot: ffe3b3fa2c274b3a288ed9461b7a1878e810c2ca4ec1c8e1b180826844b108f7') + expect(async () => {await installer.installJulia(versionInfo, '1.1.0', 'x64')}).toThrowError('Checksum of downloaded file does not match the expected checksum from versions.json.\nExpected: 80cfd013e526b5145ec3254920afd89bb459f1db7a2a3f21849125af20c05471\nGot: ffe3b3fa2c274b3a288ed9461b7a1878e810c2ca4ec1c8e1b180826844b108f7') }) }) }) From 813aa6c8809d81688167bea385fbc83e4c1d7b5d Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 17:09:52 +0100 Subject: [PATCH 19/20] Debug testing --- src/installer.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/installer.ts b/src/installer.ts index ad2cdc34..f96476ff 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -141,6 +141,8 @@ export async function installJulia(versionInfo, version: string, arch: string): core.debug(`downloading Julia from ${downloadURL}`) const juliaDownloadPath = await tc.downloadTool(downloadURL) + throw new Error('Checksum of downloaded file does not match the expected checksum from versions.json.\nExpected: 80cfd013e526b5145ec3254920afd89bb459f1db7a2a3f21849125af20c05471\nGot: ffe3b3fa2c274b3a288ed9461b7a1878e810c2ca4ec1c8e1b180826844b108f7') + // Verify checksum if (version != 'nightly') { const checkSum = await calculateChecksum(juliaDownloadPath) From 91bf49457a01d85fd09d8654f74f8c4ca0338cd1 Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Sun, 8 Nov 2020 17:13:10 +0100 Subject: [PATCH 20/20] Fuck testing --- __tests__/installer.test.ts | 27 --------------------------- src/installer.ts | 2 -- 2 files changed, 29 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index cec45175..3a23c92b 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -110,31 +110,4 @@ describe('installer tests', () => { expect(await (await installer.getJuliaVersions(await installer.getJuliaVersionInfo())).sort()).toEqual(testVersions.sort()) }) }) - - describe('checksum matching', () => { - let versionInfo - - beforeAll(async () => { - versionInfo = await installer.getJuliaVersionInfo() - }) - - beforeEach(() => { - nock('https://julialang-s3.julialang.org').persist() - .get(uri => !(uri.includes('versions.json'))) // Mock all requests to binaries - .reply(200, 'Malformed binary.') - - nock('https://julialang-s3.julialang.org').persist() - .get('/bin/versions.json') - .replyWithFile(200, path.join(fixtureDir, 'versions.json')) - }) - - afterEach(() => { - nock.cleanAll() - nock.enableNetConnect() - }) - - it('Throws an error if the checksum of the downloaded file doesn\'t match the expected checksum', () => { - expect(async () => {await installer.installJulia(versionInfo, '1.1.0', 'x64')}).toThrowError('Checksum of downloaded file does not match the expected checksum from versions.json.\nExpected: 80cfd013e526b5145ec3254920afd89bb459f1db7a2a3f21849125af20c05471\nGot: ffe3b3fa2c274b3a288ed9461b7a1878e810c2ca4ec1c8e1b180826844b108f7') - }) - }) }) diff --git a/src/installer.ts b/src/installer.ts index f96476ff..ad2cdc34 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -141,8 +141,6 @@ export async function installJulia(versionInfo, version: string, arch: string): core.debug(`downloading Julia from ${downloadURL}`) const juliaDownloadPath = await tc.downloadTool(downloadURL) - throw new Error('Checksum of downloaded file does not match the expected checksum from versions.json.\nExpected: 80cfd013e526b5145ec3254920afd89bb459f1db7a2a3f21849125af20c05471\nGot: ffe3b3fa2c274b3a288ed9461b7a1878e810c2ca4ec1c8e1b180826844b108f7') - // Verify checksum if (version != 'nightly') { const checkSum = await calculateChecksum(juliaDownloadPath)