extract julia directly to tool path to maintain mtimes (#196)

Co-authored-by: Dilum Aluthge <dilum@aluthge.com>
Co-authored-by: Curtis Vogt <curtis.vogt@gmail.com>
This commit is contained in:
Ian Butterworth
2024-01-05 12:49:05 -05:00
committed by GitHub
parent a46a85f797
commit d3d61d99d5
4 changed files with 45 additions and 35 deletions

23
lib/installer.js generated
View File

@@ -216,7 +216,7 @@ function getDownloadURL(fileInfo, version, arch) {
return fileInfo.url; return fileInfo.url;
} }
exports.getDownloadURL = getDownloadURL; exports.getDownloadURL = getDownloadURL;
function installJulia(versionInfo, version, arch) { function installJulia(dest, versionInfo, version, arch) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
// Download Julia // Download Julia
const fileInfo = getFileInfo(versionInfo, version, arch); const fileInfo = getFileInfo(versionInfo, version, arch);
@@ -243,39 +243,38 @@ function installJulia(versionInfo, version, arch) {
else { else {
core.debug('Skipping checksum check for nightly binaries.'); core.debug('Skipping checksum check for nightly binaries.');
} }
const tempInstallDir = fs.mkdtempSync(`julia-${arch}-${version}-`);
// Install it // Install it
switch (osPlat) { switch (osPlat) {
case 'linux': case 'linux':
// tc.extractTar doesn't support stripping components, so we have to call tar manually // 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]); yield exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', dest]);
return tempInstallDir; return dest;
case 'win32': case 'win32':
if (fileInfo !== null && fileInfo.extension == 'exe') { if (fileInfo !== null && fileInfo.extension == 'exe') {
if (version.endsWith('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(), dest)}" -NoNewWindow -Wait`]);
} }
else { else {
yield exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/S /D=${path.join(process.cwd(), tempInstallDir)}" -NoNewWindow -Wait`]); yield exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/S /D=${path.join(process.cwd(), dest)}" -NoNewWindow -Wait`]);
} }
} }
else { else {
// This is the more common path. Using .tar.gz is much faster // This is the more common path. Using .tar.gz is much faster
yield exec.exec('powershell', ['-Command', `tar xf ${juliaDownloadPath} --strip-components=1 -C ${tempInstallDir}`]); yield exec.exec('powershell', ['-Command', `tar xf ${juliaDownloadPath} --strip-components=1 -C ${dest}`]);
} }
return tempInstallDir; return dest;
case 'darwin': case 'darwin':
if (fileInfo !== null && fileInfo.extension == 'dmg') { if (fileInfo !== null && fileInfo.extension == 'dmg') {
core.debug(`Support for .dmg files is deprecated and may be removed in a future release`); core.debug(`Support for .dmg files is deprecated and may be removed in a future release`);
yield exec.exec('hdiutil', ['attach', juliaDownloadPath]); yield exec.exec('hdiutil', ['attach', juliaDownloadPath]);
yield exec.exec('/bin/bash', ['-c', `cp -a /Volumes/Julia-*/Julia-*.app/Contents/Resources/julia ${tempInstallDir}`]); yield exec.exec('/bin/bash', ['-c', `cp -a /Volumes/Julia-*/Julia-*.app/Contents/Resources/julia ${dest}`]);
return path.join(tempInstallDir, 'julia'); return path.join(dest, 'julia');
} }
else { else {
// tc.extractTar doesn't support stripping components, so we have to call tar manually // 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]); yield exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', dest]);
return tempInstallDir; return dest;
} }
default: default:
throw new Error(`Platform ${osPlat} is not supported`); throw new Error(`Platform ${osPlat} is not supported`);

16
lib/setup-julia.js generated
View File

@@ -91,12 +91,18 @@ function run() {
juliaPath = tc.find('julia', version, arch); juliaPath = tc.find('julia', version, arch);
if (!juliaPath) { if (!juliaPath) {
core.debug(`could not find Julia ${arch}/${version} in cache`); core.debug(`could not find Julia ${arch}/${version} in cache`);
const juliaInstallationPath = yield installer.installJulia(versionInfo, version, arch); // https://github.com/julia-actions/setup-julia/pull/196
// Add it to cache // we want julia to be installed with unmodified file mtimes
juliaPath = yield tc.cacheDir(juliaInstallationPath, 'julia', version, arch); // but `tc.cacheDir` uses `cp` internally which destroys mtime
// and `tc` provides no API to get the tool directory alone
// so hack it by installing a empty directory then use the path it returns
// and extract the archives directly to that location
const emptyDir = fs.mkdtempSync('empty');
juliaPath = yield tc.cacheDir(emptyDir, 'julia', version, arch);
yield installer.installJulia(juliaPath, versionInfo, version, arch);
core.debug(`added Julia to cache: ${juliaPath}`); core.debug(`added Julia to cache: ${juliaPath}`);
// Remove temporary dir // Remove empty dir
fs.rmSync(juliaInstallationPath, { recursive: true }); fs.rmdirSync(emptyDir);
} }
else { else {
core.debug(`using cached version of Julia: ${juliaPath}`); core.debug(`using cached version of Julia: ${juliaPath}`);

View File

@@ -198,7 +198,7 @@ export function getDownloadURL(fileInfo, version: string, arch: string): string
return fileInfo.url return fileInfo.url
} }
export async function installJulia(versionInfo, version: string, arch: string): Promise<string> { export async function installJulia(dest: string, versionInfo, version: string, arch: string): Promise<string> {
// Download Julia // Download Julia
const fileInfo = getFileInfo(versionInfo, version, arch) const fileInfo = getFileInfo(versionInfo, version, arch)
const downloadURL = getDownloadURL(fileInfo, version, arch) const downloadURL = getDownloadURL(fileInfo, version, arch)
@@ -226,37 +226,35 @@ export async function installJulia(versionInfo, version: string, arch: string):
core.debug('Skipping checksum check for nightly binaries.') core.debug('Skipping checksum check for nightly binaries.')
} }
const tempInstallDir = fs.mkdtempSync(`julia-${arch}-${version}-`)
// Install it // Install it
switch (osPlat) { switch (osPlat) {
case 'linux': case 'linux':
// tc.extractTar doesn't support stripping components, so we have to call tar manually // 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]) await exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', dest])
return tempInstallDir return dest
case 'win32': case 'win32':
if (fileInfo !== null && fileInfo.extension == 'exe') { if (fileInfo !== null && fileInfo.extension == 'exe') {
if (version.endsWith('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(), dest)}" -NoNewWindow -Wait`])
} else { } else {
await exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/S /D=${path.join(process.cwd(), tempInstallDir)}" -NoNewWindow -Wait`]) await exec.exec('powershell', ['-Command', `Start-Process -FilePath ${juliaDownloadPath} -ArgumentList "/S /D=${path.join(process.cwd(), dest)}" -NoNewWindow -Wait`])
} }
} else { } else {
// This is the more common path. Using .tar.gz is much faster // This is the more common path. Using .tar.gz is much faster
await exec.exec('powershell', ['-Command', `tar xf ${juliaDownloadPath} --strip-components=1 -C ${tempInstallDir}`]) await exec.exec('powershell', ['-Command', `tar xf ${juliaDownloadPath} --strip-components=1 -C ${dest}`])
} }
return tempInstallDir return dest
case 'darwin': case 'darwin':
if (fileInfo !== null && fileInfo.extension == 'dmg') { if (fileInfo !== null && fileInfo.extension == 'dmg') {
core.debug(`Support for .dmg files is deprecated and may be removed in a future release`) core.debug(`Support for .dmg files is deprecated and may be removed in a future release`)
await exec.exec('hdiutil', ['attach', juliaDownloadPath]) await exec.exec('hdiutil', ['attach', juliaDownloadPath])
await exec.exec('/bin/bash', ['-c', `cp -a /Volumes/Julia-*/Julia-*.app/Contents/Resources/julia ${tempInstallDir}`]) await exec.exec('/bin/bash', ['-c', `cp -a /Volumes/Julia-*/Julia-*.app/Contents/Resources/julia ${dest}`])
return path.join(tempInstallDir, 'julia') return path.join(dest, 'julia')
} else { } else {
// tc.extractTar doesn't support stripping components, so we have to call tar manually // 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]) await exec.exec('tar', ['xf', juliaDownloadPath, '--strip-components=1', '-C', dest])
return tempInstallDir return dest
} }
default: default:
throw new Error(`Platform ${osPlat} is not supported`) throw new Error(`Platform ${osPlat} is not supported`)

View File

@@ -69,14 +69,21 @@ async function run() {
if (!juliaPath) { if (!juliaPath) {
core.debug(`could not find Julia ${arch}/${version} in cache`) core.debug(`could not find Julia ${arch}/${version} in cache`)
const juliaInstallationPath = await installer.installJulia(versionInfo, version, arch)
// Add it to cache // https://github.com/julia-actions/setup-julia/pull/196
juliaPath = await tc.cacheDir(juliaInstallationPath, 'julia', version, arch) // we want julia to be installed with unmodified file mtimes
// but `tc.cacheDir` uses `cp` internally which destroys mtime
// and `tc` provides no API to get the tool directory alone
// so hack it by installing a empty directory then use the path it returns
// and extract the archives directly to that location
const emptyDir = fs.mkdtempSync('empty')
juliaPath = await tc.cacheDir(emptyDir, 'julia', version, arch)
await installer.installJulia(juliaPath, versionInfo, version, arch)
core.debug(`added Julia to cache: ${juliaPath}`) core.debug(`added Julia to cache: ${juliaPath}`)
// Remove temporary dir // Remove empty dir
fs.rmSync(juliaInstallationPath, {recursive: true}) fs.rmdirSync(emptyDir)
} else { } else {
core.debug(`using cached version of Julia: ${juliaPath}`) core.debug(`using cached version of Julia: ${juliaPath}`)
} }