1
0
Fork 0

Only use zstd on windows when gnu tar is installed, otherwise use gzip due to bug #301

pull/469/head
Aiqiao Yan 2020-05-18 16:35:13 -04:00
parent 77761a4dc9
commit 5112dc231e
3 changed files with 22 additions and 12 deletions

View File

@ -95,7 +95,7 @@ test('gzip extract GNU tar on windows', async () => {
jest.spyOn(fs, 'existsSync').mockReturnValueOnce(false) jest.spyOn(fs, 'existsSync').mockReturnValueOnce(false)
const isGnuMock = jest const isGnuMock = jest
.spyOn(utils, 'useGnuTar') .spyOn(utils, 'isGnuTarInstalled')
.mockReturnValue(Promise.resolve(true)) .mockReturnValue(Promise.resolve(true))
const execMock = jest.spyOn(exec, 'exec') const execMock = jest.spyOn(exec, 'exec')
const archivePath = `${process.env['windir']}\\fakepath\\cache.tar` const archivePath = `${process.env['windir']}\\fakepath\\cache.tar`

View File

@ -83,8 +83,8 @@ async function getVersion(app: string): Promise<string> {
// Use zstandard if possible to maximize cache performance // Use zstandard if possible to maximize cache performance
export async function getCompressionMethod(): Promise<CompressionMethod> { export async function getCompressionMethod(): Promise<CompressionMethod> {
if (process.platform === 'win32') { if (process.platform === 'win32' && !isGnuTarInstalled()) {
// Disable zstd on windows due to bug https://github.com/actions/cache/issues/301 // Disable zstd due to bug https://github.com/actions/cache/issues/301
return CompressionMethod.Gzip return CompressionMethod.Gzip
} else { } else {
const versionOutput = await getVersion('zstd') const versionOutput = await getVersion('zstd')
@ -103,7 +103,7 @@ export function getCacheFileName(compressionMethod: CompressionMethod): string {
: CacheFilename.Zstd : CacheFilename.Zstd
} }
export async function useGnuTar(): Promise<boolean> { export async function isGnuTarInstalled(): Promise<boolean> {
const versionOutput = await getVersion('tar') const versionOutput = await getVersion('tar')
return versionOutput.toLowerCase().includes('gnu tar') return versionOutput.toLowerCase().includes('gnu tar')
} }

View File

@ -5,23 +5,33 @@ import * as path from 'path'
import * as utils from './cacheUtils' import * as utils from './cacheUtils'
import {CompressionMethod} from './constants' import {CompressionMethod} from './constants'
async function getTarPath(args: string[]): Promise<string> { async function getTarPath(
// Explicitly use BSD Tar on Windows args: string[],
compressionMethod: CompressionMethod
): Promise<string> {
const IS_WINDOWS = process.platform === 'win32' const IS_WINDOWS = process.platform === 'win32'
if (IS_WINDOWS) { if (IS_WINDOWS) {
const systemTar = `${process.env['windir']}\\System32\\tar.exe` const systemTar = `${process.env['windir']}\\System32\\tar.exe`
if (existsSync(systemTar)) { if (compressionMethod !== CompressionMethod.Gzip) {
// We only use zstandard compression on windows when gnu tar is installed due to
// a bug with compressing large files with bsdtar + zstd
args.push('--force-local')
} else if (existsSync(systemTar)) {
return systemTar return systemTar
} else if (await utils.useGnuTar()) { } else if (await utils.isGnuTarInstalled()) {
args.push('--force-local') args.push('--force-local')
} }
} }
return await io.which('tar', true) return await io.which('tar', true)
} }
async function execTar(args: string[], cwd?: string): Promise<void> { async function execTar(
args: string[],
compressionMethod: CompressionMethod,
cwd?: string
): Promise<void> {
try { try {
await exec(`"${await getTarPath(args)}"`, args, {cwd}) await exec(`"${await getTarPath(args, compressionMethod)}"`, args, {cwd})
} catch (error) { } catch (error) {
throw new Error(`Tar failed with error: ${error?.message}`) throw new Error(`Tar failed with error: ${error?.message}`)
} }
@ -59,7 +69,7 @@ export async function extractTar(
'-C', '-C',
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/') workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
] ]
await execTar(args) await execTar(args, compressionMethod)
} }
export async function createTar( export async function createTar(
@ -100,5 +110,5 @@ export async function createTar(
'--files-from', '--files-from',
manifestFilename manifestFilename
] ]
await execTar(args, archiveFolder) await execTar(args, compressionMethod, archiveFolder)
} }