@ -1177,6 +1177,10 @@ function getVersion(app) {
// Use zstandard if possible to maximize cache performance
function getCompressionMethod ( ) {
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' ) ;
const version = semver . clean ( versionOutput ) ;
if ( ! versionOutput . toLowerCase ( ) . includes ( 'zstd command line interface' ) ) {
@ -1200,16 +1204,13 @@ function getCacheFileName(compressionMethod) {
: constants _1 . CacheFilename . Zstd ;
}
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 ) {
if ( value === undefined ) {
throw Error ( ` Expected ${ name } but value was undefiend ` ) ;
@ -3431,7 +3432,6 @@ function getCacheEntry(keys, paths, options) {
const version = getCacheVersion ( paths , options === null || options === void 0 ? void 0 : options . compressionMethod ) ;
const resource = ` cache?keys= ${ encodeURIComponent ( keys . join ( ',' ) ) } &version= ${ version } ` ;
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 ) {
// List cache for primary key only if cache miss occurs
if ( core . isDebug ( ) ) {
@ -3445,7 +3445,6 @@ function getCacheEntry(keys, paths, options) {
const cacheResult = response . result ;
const cacheDownloadUrl = cacheResult === null || cacheResult === void 0 ? void 0 : cacheResult . archiveLocation ;
if ( ! cacheDownloadUrl ) {
// Cache achiveLocation not found. This should never happen, and hence bail out.
throw new Error ( 'Cache not found.' ) ;
}
core . setSecret ( cacheDownloadUrl ) ;
@ -38223,19 +38222,21 @@ const path = __importStar(__webpack_require__(622));
const utils = _ _importStar ( _ _webpack _require _ _ ( 15 ) ) ;
const constants _1 = _ _webpack _require _ _ ( 931 ) ;
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 ;
}
@ -38243,92 +38244,25 @@ function getTarPath() {
const gnuTar = yield io . which ( 'gtar' , false ) ;
if ( gnuTar ) {
// 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 } ;
}
else {
return {
path : yield io . which ( 'tar' , true ) ,
type : constants _1 . ArchiveToolType . BSD
} ;
}
}
default :
break ;
}
// Default assumption is GNU tar is present in path
return {
path : yield io . which ( 'tar' , true ) ,
type : constants _1 . ArchiveToolType . GNU
} ;
} ) ;
args . push ( '--delay-directory-restore' ) ;
return gnuTar ;
}
// Return arguments for tar as per tarPath, compressionMethod, method type and os
function getTarArgs ( tarPath , compressionMethod , type , archivePath = '' ) {
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 ;
}
// 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' ) ;
default :
break ;
}
}
return args ;
return yield io . which ( 'tar' , true ) ;
} ) ;
}
// Returns commands to run tar and compression program
function getCommands ( compressionMethod , type , archivePath = '' ) {
function execTar ( args , compressionMethod , cwd ) {
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 ( ' ' ) ] ;
try {
yield exec _1 . exec ( ` " ${ yield getTarPath ( args , compressionMethod ) } " ` , args , { cwd } ) ;
}
if ( BSD _TAR _ZSTD ) {
return args ;
catch ( error ) {
throw new Error ( ` Tar failed with error: ${ error === null || error === void 0 ? void 0 : error . message } ` ) ;
}
return [ args . join ( ' ' ) ] ;
} ) ;
}
function getWorkingDirectory ( ) {
@ -38336,116 +38270,91 @@ function getWorkingDirectory() {
return ( _a = process . env [ 'GITHUB_WORKSPACE' ] ) !== null && _a !== void 0 ? _a : process . cwd ( ) ;
}
// Common function for extractTar and listTar to get the compression method
function getDecompressionProgram ( tarPath , compressionMethod , archivePath ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
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.
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' ) , '/' )
]
: [
return [
'--use-compress-program' ,
IS _WINDOWS ? ' " zstd -d --long=30" ' : 'unzstd --long=30'
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' ] ;
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 ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
// Create directory to extract tar into
const workingDirectory = getWorkingDirectory ( ) ;
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 ) ;
} ) ;
}
exports . createTar = createTar ;
@ -47195,7 +47104,6 @@ const path = __importStar(__webpack_require__(622));
const utils = _ _importStar ( _ _webpack _require _ _ ( 15 ) ) ;
const cacheHttpClient = _ _importStar ( _ _webpack _require _ _ ( 114 ) ) ;
const tar _1 = _ _webpack _require _ _ ( 434 ) ;
const constants _1 = _ _webpack _require _ _ ( 931 ) ;
class ValidationError extends Error {
constructor ( message ) {
super ( message ) ;
@ -47257,32 +47165,17 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
for ( const key of keys ) {
checkKey ( key ) ;
}
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 , {
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 , {
const 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 ;
}
}
archivePath = path . join ( yield utils . createTempDirectory ( ) , utils . getCacheFileName ( compressionMethod ) ) ;
core . debug ( ` Archive Path: ${ archivePath } ` ) ;
// Download the cache from the cache entry
@ -53362,11 +53255,6 @@ var CompressionMethod;
CompressionMethod [ "ZstdWithoutLong" ] = "zstd-without-long" ;
CompressionMethod [ "Zstd" ] = "zstd" ;
} ) ( 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.
exports . DefaultRetryAttempts = 2 ;
// The default delay in milliseconds between retry attempts.
@ -53375,12 +53263,6 @@ exports.DefaultRetryDelay = 5000;
// over the socket during this period, the socket is destroyed and the download
// is aborted.
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
/***/ } ) ,