@actions/cache
Advanced tools
Comparing version 3.1.0 to 3.1.1
@@ -24,3 +24,2 @@ "use strict"; | ||
const tar_1 = require("./internal/tar"); | ||
const constants_1 = require("./internal/constants"); | ||
class ValidationError extends Error { | ||
@@ -87,27 +86,12 @@ constructor(message) { | ||
} | ||
let cacheEntry; | ||
let compressionMethod = yield utils.getCompressionMethod(); | ||
const compressionMethod = yield utils.getCompressionMethod(); | ||
let archivePath = ''; | ||
try { | ||
// path are needed to compute version | ||
cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, { | ||
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, { | ||
compressionMethod | ||
}); | ||
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) { | ||
// This is to support the old cache entry created by gzip on windows. | ||
if (process.platform === 'win32' && | ||
compressionMethod !== constants_1.CompressionMethod.Gzip) { | ||
compressionMethod = constants_1.CompressionMethod.Gzip; | ||
cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, { | ||
compressionMethod | ||
}); | ||
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) { | ||
return undefined; | ||
} | ||
core.info("Couldn't find cache entry with zstd compression, falling back to gzip compression."); | ||
} | ||
else { | ||
// Cache not found | ||
return undefined; | ||
} | ||
// Cache not found | ||
return undefined; | ||
} | ||
@@ -114,0 +98,0 @@ archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); |
@@ -74,3 +74,2 @@ "use strict"; | ||
const response = yield requestUtils_1.retryTypedResponse('getCacheEntry', () => __awaiter(this, void 0, void 0, function* () { return httpClient.getJson(getCacheApiUrl(resource)); })); | ||
// Cache not found | ||
if (response.statusCode === 204) { | ||
@@ -89,3 +88,2 @@ // List cache for primary key only if cache miss occurs | ||
if (!cacheDownloadUrl) { | ||
// Cache achiveLocation not found. This should never happen, and hence bail out. | ||
throw new Error('Cache not found.'); | ||
@@ -92,0 +90,0 @@ } |
@@ -10,4 +10,4 @@ /// <reference types="node" /> | ||
export declare function getCacheFileName(compressionMethod: CompressionMethod): string; | ||
export declare function getGnuTarPathOnWindows(): Promise<string>; | ||
export declare function isGnuTarInstalled(): Promise<boolean>; | ||
export declare function assertDefined<T>(name: string, value?: T): T; | ||
export declare function isGhes(): boolean; |
@@ -135,2 +135,6 @@ "use strict"; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (process.platform === 'win32' && !(yield isGnuTarInstalled())) { | ||
// Disable zstd due to bug https://github.com/actions/cache/issues/301 | ||
return constants_1.CompressionMethod.Gzip; | ||
} | ||
const versionOutput = yield getVersion('zstd'); | ||
@@ -159,12 +163,9 @@ const version = semver.clean(versionOutput); | ||
exports.getCacheFileName = getCacheFileName; | ||
function getGnuTarPathOnWindows() { | ||
function isGnuTarInstalled() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (fs.existsSync(constants_1.GnuTarPathOnWindows)) { | ||
return constants_1.GnuTarPathOnWindows; | ||
} | ||
const versionOutput = yield getVersion('tar'); | ||
return versionOutput.toLowerCase().includes('gnu tar') ? io.which('tar') : ''; | ||
return versionOutput.toLowerCase().includes('gnu tar'); | ||
}); | ||
} | ||
exports.getGnuTarPathOnWindows = getGnuTarPathOnWindows; | ||
exports.isGnuTarInstalled = isGnuTarInstalled; | ||
function assertDefined(name, value) { | ||
@@ -171,0 +172,0 @@ if (value === undefined) { |
@@ -10,12 +10,4 @@ export declare enum CacheFilename { | ||
} | ||
export declare enum ArchiveToolType { | ||
GNU = "gnu", | ||
BSD = "bsd" | ||
} | ||
export declare const DefaultRetryAttempts = 2; | ||
export declare const DefaultRetryDelay = 5000; | ||
export declare const SocketTimeout = 5000; | ||
export declare const GnuTarPathOnWindows: string; | ||
export declare const SystemTarPathOnWindows: string; | ||
export declare const TarFilename = "cache.tar"; | ||
export declare const ManifestFilename = "manifest.txt"; |
@@ -16,7 +16,2 @@ "use strict"; | ||
})(CompressionMethod = exports.CompressionMethod || (exports.CompressionMethod = {})); | ||
var ArchiveToolType; | ||
(function (ArchiveToolType) { | ||
ArchiveToolType["GNU"] = "gnu"; | ||
ArchiveToolType["BSD"] = "bsd"; | ||
})(ArchiveToolType = exports.ArchiveToolType || (exports.ArchiveToolType = {})); | ||
// The default number of retry attempts. | ||
@@ -30,8 +25,2 @@ exports.DefaultRetryAttempts = 2; | ||
exports.SocketTimeout = 5000; | ||
// The default path of GNUtar on hosted Windows runners | ||
exports.GnuTarPathOnWindows = `${process.env['PROGRAMFILES']}\\Git\\usr\\bin\\tar.exe`; | ||
// The default path of BSDtar on hosted Windows runners | ||
exports.SystemTarPathOnWindows = `${process.env['SYSTEMDRIVE']}\\Windows\\System32\\tar.exe`; | ||
exports.TarFilename = 'cache.tar'; | ||
exports.ManifestFilename = 'manifest.txt'; | ||
//# sourceMappingURL=constants.js.map |
@@ -26,16 +26,18 @@ "use strict"; | ||
const IS_WINDOWS = process.platform === 'win32'; | ||
// Returns tar path and type: BSD or GNU | ||
function getTarPath() { | ||
function getTarPath(args, compressionMethod) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
switch (process.platform) { | ||
case 'win32': { | ||
const gnuTar = yield utils.getGnuTarPathOnWindows(); | ||
const systemTar = constants_1.SystemTarPathOnWindows; | ||
if (gnuTar) { | ||
// Use GNUtar as default on windows | ||
return { path: gnuTar, type: constants_1.ArchiveToolType.GNU }; | ||
const systemTar = `${process.env['windir']}\\System32\\tar.exe`; | ||
if (compressionMethod !== constants_1.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 (fs_1.existsSync(systemTar)) { | ||
return { path: systemTar, type: constants_1.ArchiveToolType.BSD }; | ||
return systemTar; | ||
} | ||
else if (yield utils.isGnuTarInstalled()) { | ||
args.push('--force-local'); | ||
} | ||
break; | ||
@@ -47,10 +49,6 @@ } | ||
// fix permission denied errors when extracting BSD tar archive with GNU tar - https://github.com/actions/cache/issues/527 | ||
return { path: gnuTar, type: constants_1.ArchiveToolType.GNU }; | ||
args.push('--delay-directory-restore'); | ||
return gnuTar; | ||
} | ||
else { | ||
return { | ||
path: yield io.which('tar', true), | ||
type: constants_1.ArchiveToolType.BSD | ||
}; | ||
} | ||
break; | ||
} | ||
@@ -60,78 +58,15 @@ default: | ||
} | ||
// Default assumption is GNU tar is present in path | ||
return { | ||
path: yield io.which('tar', true), | ||
type: constants_1.ArchiveToolType.GNU | ||
}; | ||
return yield io.which('tar', true); | ||
}); | ||
} | ||
// Return arguments for tar as per tarPath, compressionMethod, method type and os | ||
function getTarArgs(tarPath, compressionMethod, type, archivePath = '') { | ||
function execTar(args, compressionMethod, cwd) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const args = [`"${tarPath.path}"`]; | ||
const cacheFileName = utils.getCacheFileName(compressionMethod); | ||
const tarFile = 'cache.tar'; | ||
const workingDirectory = getWorkingDirectory(); | ||
// Speficic args for BSD tar on windows for workaround | ||
const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD && | ||
compressionMethod !== constants_1.CompressionMethod.Gzip && | ||
IS_WINDOWS; | ||
// Method specific args | ||
switch (type) { | ||
case 'create': | ||
args.push('--posix', '-cf', BSD_TAR_ZSTD | ||
? tarFile | ||
: cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '--exclude', BSD_TAR_ZSTD | ||
? tarFile | ||
: cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P', '-C', workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '--files-from', constants_1.ManifestFilename); | ||
break; | ||
case 'extract': | ||
args.push('-xf', BSD_TAR_ZSTD | ||
? tarFile | ||
: archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P', '-C', workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/')); | ||
break; | ||
case 'list': | ||
args.push('-tf', BSD_TAR_ZSTD | ||
? tarFile | ||
: archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), '-P'); | ||
break; | ||
try { | ||
yield exec_1.exec(`"${yield getTarPath(args, compressionMethod)}"`, args, { cwd }); | ||
} | ||
// Platform specific args | ||
if (tarPath.type === constants_1.ArchiveToolType.GNU) { | ||
switch (process.platform) { | ||
case 'win32': | ||
args.push('--force-local'); | ||
break; | ||
case 'darwin': | ||
args.push('--delay-directory-restore'); | ||
break; | ||
} | ||
catch (error) { | ||
throw new Error(`Tar failed with error: ${error === null || error === void 0 ? void 0 : error.message}`); | ||
} | ||
return args; | ||
}); | ||
} | ||
// Returns commands to run tar and compression program | ||
function getCommands(compressionMethod, type, archivePath = '') { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let args; | ||
const tarPath = yield getTarPath(); | ||
const tarArgs = yield getTarArgs(tarPath, compressionMethod, type, archivePath); | ||
const compressionArgs = type !== 'create' | ||
? yield getDecompressionProgram(tarPath, compressionMethod, archivePath) | ||
: yield getCompressionProgram(tarPath, compressionMethod); | ||
const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD && | ||
compressionMethod !== constants_1.CompressionMethod.Gzip && | ||
IS_WINDOWS; | ||
if (BSD_TAR_ZSTD && type !== 'create') { | ||
args = [[...compressionArgs].join(' '), [...tarArgs].join(' ')]; | ||
} | ||
else { | ||
args = [[...tarArgs].join(' '), [...compressionArgs].join(' ')]; | ||
} | ||
if (BSD_TAR_ZSTD) { | ||
return args; | ||
} | ||
return [args.join(' ')]; | ||
}); | ||
} | ||
function getWorkingDirectory() { | ||
@@ -142,95 +77,31 @@ var _a; | ||
// Common function for extractTar and listTar to get the compression method | ||
function getDecompressionProgram(tarPath, compressionMethod, archivePath) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// -d: Decompress. | ||
// unzstd is equivalent to 'zstd -d' | ||
// --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. | ||
const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD && | ||
compressionMethod !== constants_1.CompressionMethod.Gzip && | ||
IS_WINDOWS; | ||
switch (compressionMethod) { | ||
case constants_1.CompressionMethod.Zstd: | ||
return BSD_TAR_ZSTD | ||
? [ | ||
'zstd -d --long=30 --force -o', | ||
constants_1.TarFilename, | ||
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/') | ||
] | ||
: [ | ||
'--use-compress-program', | ||
IS_WINDOWS ? '"zstd -d --long=30"' : 'unzstd --long=30' | ||
]; | ||
case constants_1.CompressionMethod.ZstdWithoutLong: | ||
return BSD_TAR_ZSTD | ||
? [ | ||
'zstd -d --force -o', | ||
constants_1.TarFilename, | ||
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/') | ||
] | ||
: ['--use-compress-program', IS_WINDOWS ? '"zstd -d"' : 'unzstd']; | ||
default: | ||
return ['-z']; | ||
} | ||
}); | ||
function getCompressionProgram(compressionMethod) { | ||
// -d: Decompress. | ||
// unzstd is equivalent to 'zstd -d' | ||
// --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. | ||
switch (compressionMethod) { | ||
case constants_1.CompressionMethod.Zstd: | ||
return [ | ||
'--use-compress-program', | ||
IS_WINDOWS ? 'zstd -d --long=30' : 'unzstd --long=30' | ||
]; | ||
case constants_1.CompressionMethod.ZstdWithoutLong: | ||
return ['--use-compress-program', IS_WINDOWS ? 'zstd -d' : 'unzstd']; | ||
default: | ||
return ['-z']; | ||
} | ||
} | ||
// Used for creating the archive | ||
// -T#: Compress using # working thread. If # is 0, attempt to detect and use the number of physical CPU cores. | ||
// zstdmt is equivalent to 'zstd -T0' | ||
// --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 getCompressionProgram(tarPath, compressionMethod) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const cacheFileName = utils.getCacheFileName(compressionMethod); | ||
const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD && | ||
compressionMethod !== constants_1.CompressionMethod.Gzip && | ||
IS_WINDOWS; | ||
switch (compressionMethod) { | ||
case constants_1.CompressionMethod.Zstd: | ||
return BSD_TAR_ZSTD | ||
? [ | ||
'zstd -T0 --long=30 --force -o', | ||
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), | ||
constants_1.TarFilename | ||
] | ||
: [ | ||
'--use-compress-program', | ||
IS_WINDOWS ? '"zstd -T0 --long=30"' : 'zstdmt --long=30' | ||
]; | ||
case constants_1.CompressionMethod.ZstdWithoutLong: | ||
return BSD_TAR_ZSTD | ||
? [ | ||
'zstd -T0 --force -o', | ||
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), | ||
constants_1.TarFilename | ||
] | ||
: ['--use-compress-program', IS_WINDOWS ? '"zstd -T0"' : 'zstdmt']; | ||
default: | ||
return ['-z']; | ||
} | ||
}); | ||
} | ||
// Executes all commands as separate processes | ||
function execCommands(commands, cwd) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
for (const command of commands) { | ||
try { | ||
yield exec_1.exec(command, undefined, { cwd }); | ||
} | ||
catch (error) { | ||
throw new Error(`${command.split(' ')[0]} failed with error: ${error === null || error === void 0 ? void 0 : error.message}`); | ||
} | ||
} | ||
}); | ||
} | ||
// List the contents of a tar | ||
function listTar(archivePath, compressionMethod) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const commands = yield getCommands(compressionMethod, 'list', archivePath); | ||
yield execCommands(commands); | ||
const args = [ | ||
...getCompressionProgram(compressionMethod), | ||
'-tf', | ||
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), | ||
'-P' | ||
]; | ||
yield execTar(args, compressionMethod); | ||
}); | ||
} | ||
exports.listTar = listTar; | ||
// Extract a tar | ||
function extractTar(archivePath, compressionMethod) { | ||
@@ -241,14 +112,53 @@ return __awaiter(this, void 0, void 0, function* () { | ||
yield io.mkdirP(workingDirectory); | ||
const commands = yield getCommands(compressionMethod, 'extract', archivePath); | ||
yield execCommands(commands); | ||
const args = [ | ||
...getCompressionProgram(compressionMethod), | ||
'-xf', | ||
archivePath.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), | ||
'-P', | ||
'-C', | ||
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/') | ||
]; | ||
yield execTar(args, compressionMethod); | ||
}); | ||
} | ||
exports.extractTar = extractTar; | ||
// Create a tar | ||
function createTar(archiveFolder, sourceDirectories, compressionMethod) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// Write source directories to manifest.txt to avoid command length limits | ||
fs_1.writeFileSync(path.join(archiveFolder, constants_1.ManifestFilename), sourceDirectories.join('\n')); | ||
const commands = yield getCommands(compressionMethod, 'create'); | ||
yield execCommands(commands, archiveFolder); | ||
const manifestFilename = 'manifest.txt'; | ||
const cacheFileName = utils.getCacheFileName(compressionMethod); | ||
fs_1.writeFileSync(path.join(archiveFolder, manifestFilename), sourceDirectories.join('\n')); | ||
const workingDirectory = getWorkingDirectory(); | ||
// -T#: Compress using # working thread. If # is 0, attempt to detect and use the number of physical CPU cores. | ||
// zstdmt is equivalent to 'zstd -T0' | ||
// --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 getCompressionProgram() { | ||
switch (compressionMethod) { | ||
case constants_1.CompressionMethod.Zstd: | ||
return [ | ||
'--use-compress-program', | ||
IS_WINDOWS ? 'zstd -T0 --long=30' : 'zstdmt --long=30' | ||
]; | ||
case constants_1.CompressionMethod.ZstdWithoutLong: | ||
return ['--use-compress-program', IS_WINDOWS ? 'zstd -T0' : 'zstdmt']; | ||
default: | ||
return ['-z']; | ||
} | ||
} | ||
const args = [ | ||
'--posix', | ||
...getCompressionProgram(), | ||
'-cf', | ||
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), | ||
'--exclude', | ||
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), | ||
'-P', | ||
'-C', | ||
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), | ||
'--files-from', | ||
manifestFilename | ||
]; | ||
yield execTar(args, compressionMethod, archiveFolder); | ||
}); | ||
@@ -255,0 +165,0 @@ } |
{ | ||
"name": "@actions/cache", | ||
"version": "3.1.0", | ||
"version": "3.1.1", | ||
"preview": true, | ||
@@ -5,0 +5,0 @@ "description": "Actions cache lib", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
102014
1462
16