diff --git a/packages/cache/__tests__/tar.test.ts b/packages/cache/__tests__/tar.test.ts index cafbb543e7..3f7a1b3b91 100644 --- a/packages/cache/__tests__/tar.test.ts +++ b/packages/cache/__tests__/tar.test.ts @@ -12,6 +12,8 @@ jest.mock('@actions/io') const IS_WINDOWS = process.platform === 'win32' +const defaultTarPath = process.platform === 'darwin' ? 'gtar' : 'tar' + function getTempDir(): string { return path.join(__dirname, '_temp', 'tar') } @@ -38,14 +40,13 @@ test('zstd extract tar', async () => { ? `${process.env['windir']}\\fakepath\\cache.tar` : 'cache.tar' const workspace = process.env['GITHUB_WORKSPACE'] - const tarPath = 'tar' await tar.extractTar(archivePath, CompressionMethod.Zstd) expect(mkdirMock).toHaveBeenCalledWith(workspace) expect(execMock).toHaveBeenCalledTimes(1) expect(execMock).toHaveBeenCalledWith( - `"${tarPath}"`, + `"${defaultTarPath}"`, [ '--use-compress-program', 'zstd -d --long=30', @@ -72,7 +73,7 @@ test('gzip extract tar', async () => { expect(mkdirMock).toHaveBeenCalledWith(workspace) const tarPath = IS_WINDOWS ? `${process.env['windir']}\\System32\\tar.exe` - : 'tar' + : defaultTarPath expect(execMock).toHaveBeenCalledTimes(1) expect(execMock).toHaveBeenCalledWith( `"${tarPath}"`, @@ -125,7 +126,6 @@ test('zstd create tar', async () => { const archiveFolder = getTempDir() const workspace = process.env['GITHUB_WORKSPACE'] const sourceDirectories = ['~/.npm/cache', `${workspace}/dist`] - const tarPath = 'tar' await fs.promises.mkdir(archiveFolder, {recursive: true}) @@ -133,7 +133,7 @@ test('zstd create tar', async () => { expect(execMock).toHaveBeenCalledTimes(1) expect(execMock).toHaveBeenCalledWith( - `"${tarPath}"`, + `"${defaultTarPath}"`, [ '--posix', '--use-compress-program', @@ -165,7 +165,7 @@ test('gzip create tar', async () => { const tarPath = IS_WINDOWS ? `${process.env['windir']}\\System32\\tar.exe` - : 'tar' + : defaultTarPath expect(execMock).toHaveBeenCalledTimes(1) expect(execMock).toHaveBeenCalledWith( @@ -193,13 +193,12 @@ test('zstd list tar', async () => { const archivePath = IS_WINDOWS ? `${process.env['windir']}\\fakepath\\cache.tar` : 'cache.tar' - const tarPath = 'tar' await tar.listTar(archivePath, CompressionMethod.Zstd) expect(execMock).toHaveBeenCalledTimes(1) expect(execMock).toHaveBeenCalledWith( - `"${tarPath}"`, + `"${defaultTarPath}"`, [ '--use-compress-program', 'zstd -d --long=30', @@ -217,13 +216,12 @@ test('zstdWithoutLong list tar', async () => { const archivePath = IS_WINDOWS ? `${process.env['windir']}\\fakepath\\cache.tar` : 'cache.tar' - const tarPath = 'tar' await tar.listTar(archivePath, CompressionMethod.ZstdWithoutLong) expect(execMock).toHaveBeenCalledTimes(1) expect(execMock).toHaveBeenCalledWith( - `"${tarPath}"`, + `"${defaultTarPath}"`, [ '--use-compress-program', 'zstd -d', @@ -245,7 +243,7 @@ test('gzip list tar', async () => { const tarPath = IS_WINDOWS ? `${process.env['windir']}\\System32\\tar.exe` - : 'tar' + : defaultTarPath expect(execMock).toHaveBeenCalledTimes(1) expect(execMock).toHaveBeenCalledWith( `"${tarPath}"`, diff --git a/packages/cache/src/internal/tar.ts b/packages/cache/src/internal/tar.ts index 4c1ee6db9a..1b70dac09f 100644 --- a/packages/cache/src/internal/tar.ts +++ b/packages/cache/src/internal/tar.ts @@ -9,18 +9,29 @@ async function getTarPath( args: string[], compressionMethod: CompressionMethod ): Promise { - const IS_WINDOWS = process.platform === 'win32' - if (IS_WINDOWS) { - const systemTar = `${process.env['windir']}\\System32\\tar.exe` - 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 - } else if (await utils.isGnuTarInstalled()) { - args.push('--force-local') + switch (process.platform) { + case 'win32': { + const systemTar = `${process.env['windir']}\\System32\\tar.exe` + 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 + } else if (await utils.isGnuTarInstalled()) { + args.push('--force-local') + } + break } + case 'darwin': { + const gnuTar = await io.which('gtar', false) + if (gnuTar) { + return gnuTar + } + break + } + default: + break } return await io.which('tar', true) }