Skip to content

Commit dcf5c88

Browse files
authored
Merge pull request actions#469 from actions/users/aiyan/zstd-fixes
Fix two issues related to using zstd compression
2 parents a67b91e + 0dea61a commit dcf5c88

File tree

8 files changed

+184
-125
lines changed

8 files changed

+184
-125
lines changed

packages/cache/RELEASES.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@
22

33
### 0.1.0
44

5-
- Initial release
5+
- Initial release
6+
7+
### 0.2.0
8+
- Fixes two issues around using zstd compression algorithm

packages/cache/__tests__/tar.test.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,11 @@ test('zstd extract tar', async () => {
3838
? `${process.env['windir']}\\fakepath\\cache.tar`
3939
: 'cache.tar'
4040
const workspace = process.env['GITHUB_WORKSPACE']
41+
const tarPath = 'tar'
4142

4243
await tar.extractTar(archivePath, CompressionMethod.Zstd)
4344

4445
expect(mkdirMock).toHaveBeenCalledWith(workspace)
45-
const tarPath = IS_WINDOWS
46-
? `${process.env['windir']}\\System32\\tar.exe`
47-
: 'tar'
4846
expect(execMock).toHaveBeenCalledTimes(1)
4947
expect(execMock).toHaveBeenCalledWith(
5048
`"${tarPath}"`,
@@ -56,7 +54,7 @@ test('zstd extract tar', async () => {
5654
'-P',
5755
'-C',
5856
IS_WINDOWS ? workspace?.replace(/\\/g, '/') : workspace
59-
],
57+
].concat(IS_WINDOWS ? ['--force-local'] : []),
6058
{cwd: undefined}
6159
)
6260
})
@@ -95,7 +93,7 @@ test('gzip extract GNU tar on windows', async () => {
9593
jest.spyOn(fs, 'existsSync').mockReturnValueOnce(false)
9694

9795
const isGnuMock = jest
98-
.spyOn(utils, 'useGnuTar')
96+
.spyOn(utils, 'isGnuTarInstalled')
9997
.mockReturnValue(Promise.resolve(true))
10098
const execMock = jest.spyOn(exec, 'exec')
10199
const archivePath = `${process.env['windir']}\\fakepath\\cache.tar`
@@ -127,15 +125,12 @@ test('zstd create tar', async () => {
127125
const archiveFolder = getTempDir()
128126
const workspace = process.env['GITHUB_WORKSPACE']
129127
const sourceDirectories = ['~/.npm/cache', `${workspace}/dist`]
128+
const tarPath = 'tar'
130129

131130
await fs.promises.mkdir(archiveFolder, {recursive: true})
132131

133132
await tar.createTar(archiveFolder, sourceDirectories, CompressionMethod.Zstd)
134133

135-
const tarPath = IS_WINDOWS
136-
? `${process.env['windir']}\\System32\\tar.exe`
137-
: 'tar'
138-
139134
expect(execMock).toHaveBeenCalledTimes(1)
140135
expect(execMock).toHaveBeenCalledWith(
141136
`"${tarPath}"`,
@@ -149,7 +144,7 @@ test('zstd create tar', async () => {
149144
IS_WINDOWS ? workspace?.replace(/\\/g, '/') : workspace,
150145
'--files-from',
151146
'manifest.txt'
152-
],
147+
].concat(IS_WINDOWS ? ['--force-local'] : []),
153148
{
154149
cwd: archiveFolder
155150
}

packages/cache/package-lock.json

Lines changed: 101 additions & 90 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/cache/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@actions/cache",
3-
"version": "0.1.0",
3+
"version": "0.2.0",
44
"preview": true,
55
"description": "Actions cache lib",
66
"keywords": [
@@ -41,10 +41,12 @@
4141
"@actions/glob": "^0.1.0",
4242
"@actions/http-client": "^1.0.8",
4343
"@actions/io": "^1.0.1",
44+
"semver": "^6.1.0",
4445
"uuid": "^3.3.3"
4546
},
4647
"devDependencies": {
4748
"typescript": "^3.8.3",
49+
"@types/semver": "^6.0.0",
4850
"@types/uuid": "^3.4.5"
4951
}
5052
}

packages/cache/src/internal/cacheHttpClient.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ export function getCacheVersion(
9696
compressionMethod?: CompressionMethod
9797
): string {
9898
const components = paths.concat(
99-
compressionMethod === CompressionMethod.Zstd ? [compressionMethod] : []
99+
!compressionMethod || compressionMethod === CompressionMethod.Gzip
100+
? []
101+
: [compressionMethod]
100102
)
101103

102104
// Add salt to cache version to support breaking changes in cache entry

packages/cache/src/internal/cacheUtils.ts

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as glob from '@actions/glob'
44
import * as io from '@actions/io'
55
import * as fs from 'fs'
66
import * as path from 'path'
7+
import * as semver from 'semver'
78
import * as util from 'util'
89
import {v4 as uuidV4} from 'uuid'
910
import {CacheFilename, CompressionMethod} from './constants'
@@ -82,19 +83,33 @@ async function getVersion(app: string): Promise<string> {
8283

8384
// Use zstandard if possible to maximize cache performance
8485
export async function getCompressionMethod(): Promise<CompressionMethod> {
86+
if (process.platform === 'win32' && !isGnuTarInstalled()) {
87+
// Disable zstd due to bug https://github.com/actions/cache/issues/301
88+
return CompressionMethod.Gzip
89+
}
90+
8591
const versionOutput = await getVersion('zstd')
86-
return versionOutput.toLowerCase().includes('zstd command line interface')
87-
? CompressionMethod.Zstd
88-
: CompressionMethod.Gzip
92+
const version = semver.clean(versionOutput)
93+
94+
if (!versionOutput.toLowerCase().includes('zstd command line interface')) {
95+
// zstd is not installed
96+
return CompressionMethod.Gzip
97+
} else if (!version || semver.lt(version, 'v1.3.2')) {
98+
// zstd is installed but using a version earlier than v1.3.2
99+
// v1.3.2 is required to use the `--long` options in zstd
100+
return CompressionMethod.ZstdWithoutLong
101+
} else {
102+
return CompressionMethod.Zstd
103+
}
89104
}
90105

91106
export function getCacheFileName(compressionMethod: CompressionMethod): string {
92-
return compressionMethod === CompressionMethod.Zstd
93-
? CacheFilename.Zstd
94-
: CacheFilename.Gzip
107+
return compressionMethod === CompressionMethod.Gzip
108+
? CacheFilename.Gzip
109+
: CacheFilename.Zstd
95110
}
96111

97-
export async function useGnuTar(): Promise<boolean> {
112+
export async function isGnuTarInstalled(): Promise<boolean> {
98113
const versionOutput = await getVersion('tar')
99114
return versionOutput.toLowerCase().includes('gnu tar')
100115
}

packages/cache/src/internal/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ export enum CacheFilename {
55

66
export enum CompressionMethod {
77
Gzip = 'gzip',
8+
// Long range mode was added to zstd in v1.3.2.
9+
// This enum is for earlier version of zstd that does not have --long support
10+
ZstdWithoutLong = 'zstd-without-long',
811
Zstd = 'zstd'
912
}
1013

0 commit comments

Comments
 (0)