diff --git a/packages/cache/src/internal/cacheUtils.ts b/packages/cache/src/internal/cacheUtils.ts index ed230426..53b35afa 100644 --- a/packages/cache/src/internal/cacheUtils.ts +++ b/packages/cache/src/internal/cacheUtils.ts @@ -86,14 +86,20 @@ export async function getCompressionMethod(): Promise { if (process.platform === 'win32' && !isGnuTarInstalled()) { // Disable zstd due to bug https://github.com/actions/cache/issues/301 return CompressionMethod.Gzip + } + + const versionOutput = await getVersion('zstd') + const version = semver.clean(versionOutput) + + if (!versionOutput.toLowerCase().includes('zstd command line interface')) { + // zstd is not installed + return CompressionMethod.Gzip + } else if (!version || semver.lt(version, 'v1.3.2')) { + // zstd is installed but using a version earlier than v1.3.2 + // v1.3.2 is required to use the `--long` options in zstd + return CompressionMethod.ZstdWithoutLong } else { - const versionOutput = await getVersion('zstd') - const version = semver.clean(versionOutput) - return !versionOutput.toLowerCase().includes('zstd command line interface') - ? CompressionMethod.Gzip - : !version || semver.lt(version, 'v1.3.2') - ? CompressionMethod.ZstdOld - : CompressionMethod.Zstd + return CompressionMethod.Zstd } } diff --git a/packages/cache/src/internal/constants.ts b/packages/cache/src/internal/constants.ts index ec1d4944..06c8c8f0 100644 --- a/packages/cache/src/internal/constants.ts +++ b/packages/cache/src/internal/constants.ts @@ -5,7 +5,9 @@ export enum CacheFilename { export enum CompressionMethod { Gzip = 'gzip', - ZstdOld = 'zstd-old', + // Long range mode was added to zstd in v1.3.2. + // This enum is for earlier version of zstd that does not have --long support + ZstdWithoutLong = 'zstd-without-long', Zstd = 'zstd' } diff --git a/packages/cache/src/internal/tar.ts b/packages/cache/src/internal/tar.ts index 823139c1..7f836b83 100644 --- a/packages/cache/src/internal/tar.ts +++ b/packages/cache/src/internal/tar.ts @@ -51,18 +51,18 @@ export async function extractTar( // --d: Decompress. // --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit. // Using 30 here because we also support 32-bit self-hosted runners. - function getProg(): string[] { + function getCompressionProgram(): string[] { switch (compressionMethod) { case CompressionMethod.Zstd: return ['--use-compress-program', 'zstd -d --long=30'] - case CompressionMethod.ZstdOld: + case CompressionMethod.ZstdWithoutLong: return ['--use-compress-program', 'zstd -d'] default: return ['-z'] } } const args = [ - ...getProg(), + ...getCompressionProgram(), '-xf', archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P', @@ -90,18 +90,18 @@ export async function createTar( // --long=#: Enables long distance matching with # bits. Maximum is 30 (1GB) on 32-bit OS and 31 (2GB) on 64-bit. // Using 30 here because we also support 32-bit self-hosted runners. // Long range mode is added to zstd in v1.3.2 release, so we will not use --long in older version of zstd. - function getProg(): string[] { + function getCompressionProgram(): string[] { switch (compressionMethod) { case CompressionMethod.Zstd: return ['--use-compress-program', 'zstd -T0 --long=30'] - case CompressionMethod.ZstdOld: + case CompressionMethod.ZstdWithoutLong: return ['--use-compress-program', 'zstd -T0'] default: return ['-z'] } } const args = [ - ...getProg(), + ...getCompressionProgram(), '-cf', cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P',