Skip to content

Commit 5112dc2

Browse files
Aiqiao YanAiqiao Yan
authored andcommitted
Only use zstd on windows when gnu tar is installed, otherwise use gzip due to bug actions#301
1 parent 77761a4 commit 5112dc2

File tree

3 files changed

+22
-12
lines changed

3 files changed

+22
-12
lines changed

packages/cache/__tests__/tar.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ test('gzip extract GNU tar on windows', async () => {
9595
jest.spyOn(fs, 'existsSync').mockReturnValueOnce(false)
9696

9797
const isGnuMock = jest
98-
.spyOn(utils, 'useGnuTar')
98+
.spyOn(utils, 'isGnuTarInstalled')
9999
.mockReturnValue(Promise.resolve(true))
100100
const execMock = jest.spyOn(exec, 'exec')
101101
const archivePath = `${process.env['windir']}\\fakepath\\cache.tar`

packages/cache/src/internal/cacheUtils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ async function getVersion(app: string): Promise<string> {
8383

8484
// Use zstandard if possible to maximize cache performance
8585
export async function getCompressionMethod(): Promise<CompressionMethod> {
86-
if (process.platform === 'win32') {
87-
// Disable zstd on windows due to bug https://github.com/actions/cache/issues/301
86+
if (process.platform === 'win32' && !isGnuTarInstalled()) {
87+
// Disable zstd due to bug https://github.com/actions/cache/issues/301
8888
return CompressionMethod.Gzip
8989
} else {
9090
const versionOutput = await getVersion('zstd')
@@ -103,7 +103,7 @@ export function getCacheFileName(compressionMethod: CompressionMethod): string {
103103
: CacheFilename.Zstd
104104
}
105105

106-
export async function useGnuTar(): Promise<boolean> {
106+
export async function isGnuTarInstalled(): Promise<boolean> {
107107
const versionOutput = await getVersion('tar')
108108
return versionOutput.toLowerCase().includes('gnu tar')
109109
}

packages/cache/src/internal/tar.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,33 @@ import * as path from 'path'
55
import * as utils from './cacheUtils'
66
import {CompressionMethod} from './constants'
77

8-
async function getTarPath(args: string[]): Promise<string> {
9-
// Explicitly use BSD Tar on Windows
8+
async function getTarPath(
9+
args: string[],
10+
compressionMethod: CompressionMethod
11+
): Promise<string> {
1012
const IS_WINDOWS = process.platform === 'win32'
1113
if (IS_WINDOWS) {
1214
const systemTar = `${process.env['windir']}\\System32\\tar.exe`
13-
if (existsSync(systemTar)) {
15+
if (compressionMethod !== CompressionMethod.Gzip) {
16+
// We only use zstandard compression on windows when gnu tar is installed due to
17+
// a bug with compressing large files with bsdtar + zstd
18+
args.push('--force-local')
19+
} else if (existsSync(systemTar)) {
1420
return systemTar
15-
} else if (await utils.useGnuTar()) {
21+
} else if (await utils.isGnuTarInstalled()) {
1622
args.push('--force-local')
1723
}
1824
}
1925
return await io.which('tar', true)
2026
}
2127

22-
async function execTar(args: string[], cwd?: string): Promise<void> {
28+
async function execTar(
29+
args: string[],
30+
compressionMethod: CompressionMethod,
31+
cwd?: string
32+
): Promise<void> {
2333
try {
24-
await exec(`"${await getTarPath(args)}"`, args, {cwd})
34+
await exec(`"${await getTarPath(args, compressionMethod)}"`, args, {cwd})
2535
} catch (error) {
2636
throw new Error(`Tar failed with error: ${error?.message}`)
2737
}
@@ -59,7 +69,7 @@ export async function extractTar(
5969
'-C',
6070
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
6171
]
62-
await execTar(args)
72+
await execTar(args, compressionMethod)
6373
}
6474

6575
export async function createTar(
@@ -100,5 +110,5 @@ export async function createTar(
100110
'--files-from',
101111
manifestFilename
102112
]
103-
await execTar(args, archiveFolder)
113+
await execTar(args, compressionMethod, archiveFolder)
104114
}

0 commit comments

Comments
 (0)