From 0911ed2ca5459db55cb07fa7cd034a5a2f8679f7 Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Wed, 12 May 2021 16:02:14 -0400 Subject: [PATCH 01/16] Add new powershell commands for windows unzip --- packages/tool-cache/src/tool-cache.ts | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/tool-cache/src/tool-cache.ts b/packages/tool-cache/src/tool-cache.ts index e9696f4eaf..a272058e50 100644 --- a/packages/tool-cache/src/tool-cache.ts +++ b/packages/tool-cache/src/tool-cache.ts @@ -344,7 +344,27 @@ async function extractZipWin(file: string, dest: string): Promise { // build the powershell command const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, '') // double-up single quotes, remove double quotes and newlines const escapedDest = dest.replace(/'/g, "''").replace(/"|\n|\r/g, '') - const command = `$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')` + const pwshPath = await io.which('pwsh', false) + + let command = '' + if (pwshPath) { + //overwrite=true + command = [ + `$ErrorActionPreference = 'Stop' ;`, + `try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`, + `try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}', $true) }`, + `catch { if ($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException'){ Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest} -Force } } ;` + ].join(' ') + } else { + command = [ + `$ErrorActionPreference = 'Stop' ;`, + `try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ;`, + `[System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')` + ].join(' ') + } + + //TODO: remove this + command = `$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')` // run powershell const powershellPath = await io.which('powershell', true) From ce084098b5fc9d5b62bf78f4feb9955627c7604d Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Wed, 12 May 2021 16:20:01 -0400 Subject: [PATCH 02/16] Test fails to overwrite file --- packages/tool-cache/__tests__/tool-cache.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/tool-cache/__tests__/tool-cache.test.ts b/packages/tool-cache/__tests__/tool-cache.test.ts index d929c1b86c..fc9341b7dc 100644 --- a/packages/tool-cache/__tests__/tool-cache.test.ts +++ b/packages/tool-cache/__tests__/tool-cache.test.ts @@ -597,7 +597,7 @@ describe('@actions/tool-cache', function() { // folder/nested-file.txt const stagingDir = path.join(tempDir, 'zip-staging') await io.mkdirP(path.join(stagingDir, 'folder')) - fs.writeFileSync(path.join(stagingDir, 'file.txt'), '') + fs.writeFileSync(path.join(stagingDir, 'file.txt'), 'originalText') fs.writeFileSync(path.join(stagingDir, 'folder', 'nested-file.txt'), '') // create the zip @@ -629,12 +629,14 @@ describe('@actions/tool-cache', function() { await io.rmRF(destDir) await io.mkdirP(destDir) try { + fs.writeFileSync(path.join(destDir, 'file.txt'), 'overwriteMe') const extPath: string = await tc.extractZip(zipFile, destDir) await tc.cacheDir(extPath, 'foo', '1.1.0') const toolPath: string = tc.find('foo', '1.1.0') expect(fs.existsSync(toolPath)).toBeTruthy() expect(fs.existsSync(`${toolPath}.complete`)).toBeTruthy() expect(fs.existsSync(path.join(toolPath, 'file.txt'))).toBeTruthy() + expect(fs.readFileSync(path.join(toolPath, 'file.txt'), 'utf8')).toBe('originalText') expect( fs.existsSync(path.join(toolPath, 'folder', 'nested-file.txt')) ).toBeTruthy() From 008211edadf3ce4cb37fabbf80b945ddfd6a7fb4 Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Wed, 12 May 2021 16:28:24 -0400 Subject: [PATCH 03/16] Add new windows commands for unzip --- __MACOSX/test-win/._test.txt | Bin 0 -> 384 bytes .../tool-cache/__tests__/tool-cache.test.ts | 116 ++++++++++-------- packages/tool-cache/src/tool-cache.ts | 60 +++++---- 3 files changed, 105 insertions(+), 71 deletions(-) create mode 100644 __MACOSX/test-win/._test.txt diff --git a/__MACOSX/test-win/._test.txt b/__MACOSX/test-win/._test.txt new file mode 100644 index 0000000000000000000000000000000000000000..17087ac241beba69017efe1971b971391f0c7fba GIT binary patch literal 384 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFfjT7X&|4m0Z0=89795aAj&{G7&(CK z3N&rZP;q_+2Jz(lT)o7Cf}B*nkkpD2*SzHXl+3(zum(nPASJ-SAcatqlUQ6*TAZ4a zl30?e91sjKmr)%^M=~&&Bh=-lmLvkzBwA(ry7(j}rRKz^q-9kkRi&F|m6lfI78qw& z=4Tg|q-UlVrvf#XmZa%gSQ{Ff7#W&dTA0l6n417H+R^wMh+_CuZ_vHaVE@U3GKse~ zDBu6O#mnvX#Ls)QTDeWnHqKdcy83f6Yuz!s8U5e+s=I8SgikGua_YPA#C8pPz0*VC h0~Hgik+MwLx4;jTLcied71OPS_Wy$~m literal 0 HcmV?d00001 diff --git a/packages/tool-cache/__tests__/tool-cache.test.ts b/packages/tool-cache/__tests__/tool-cache.test.ts index fc9341b7dc..fbc4ed12f9 100644 --- a/packages/tool-cache/__tests__/tool-cache.test.ts +++ b/packages/tool-cache/__tests__/tool-cache.test.ts @@ -534,58 +534,76 @@ describe('@actions/tool-cache', function() { ).toBe('foo/hello: world') }) - it('installs a zip and finds it', async () => { - const tempDir = path.join(__dirname, 'test-install-zip') - try { - await io.mkdirP(tempDir) + it.each(['pwsh', 'powershell'])( + 'installs a zip and finds it (%s)', + async powershellTool => { + const tempDir = path.join(__dirname, 'test-install-zip') + const originalPath = process.env['PATH'] + try { + await io.mkdirP(tempDir) - // stage the layout for a zip file: - // file.txt - // folder/nested-file.txt - const stagingDir = path.join(tempDir, 'zip-staging') - await io.mkdirP(path.join(stagingDir, 'folder')) - fs.writeFileSync(path.join(stagingDir, 'file.txt'), '') - fs.writeFileSync(path.join(stagingDir, 'folder', 'nested-file.txt'), '') + // stage the layout for a zip file: + // file.txt + // folder/nested-file.txt + const stagingDir = path.join(tempDir, 'zip-staging') + await io.mkdirP(path.join(stagingDir, 'folder')) + fs.writeFileSync(path.join(stagingDir, 'file.txt'), '') + fs.writeFileSync(path.join(stagingDir, 'folder', 'nested-file.txt'), '') + + // create the zip + const zipFile = path.join(tempDir, 'test.zip') + await io.rmRF(zipFile) + if (IS_WINDOWS) { + const escapedStagingPath = stagingDir.replace(/'/g, "''") // double-up single quotes + const escapedZipFile = zipFile.replace(/'/g, "''") + const powershellPath = + (await io.which('pwsh', false)) || + (await io.which('powershell', true)) + const args = [ + '-NoLogo', + '-Sta', + '-NoProfile', + '-NonInteractive', + '-ExecutionPolicy', + 'Unrestricted', + '-Command', + `$ErrorActionPreference = 'Stop' ; Add-Type -AssemblyName System.IO.Compression.FileSystem ; [System.IO.Compression.ZipFile]::CreateFromDirectory('${escapedStagingPath}', '${escapedZipFile}')` + ] + await exec.exec(`"${powershellPath}"`, args) + } else { + const zipPath: string = await io.which('zip', true) + await exec.exec(`"${zipPath}`, [zipFile, '-r', '.'], { + cwd: stagingDir + }) + } - // create the zip - const zipFile = path.join(tempDir, 'test.zip') - await io.rmRF(zipFile) - if (IS_WINDOWS) { - const escapedStagingPath = stagingDir.replace(/'/g, "''") // double-up single quotes - const escapedZipFile = zipFile.replace(/'/g, "''") - const powershellPath = - (await io.which('pwsh', false)) || - (await io.which('powershell', true)) - const args = [ - '-NoLogo', - '-Sta', - '-NoProfile', - '-NonInteractive', - '-ExecutionPolicy', - 'Unrestricted', - '-Command', - `$ErrorActionPreference = 'Stop' ; Add-Type -AssemblyName System.IO.Compression.FileSystem ; [System.IO.Compression.ZipFile]::CreateFromDirectory('${escapedStagingPath}', '${escapedZipFile}')` - ] - await exec.exec(`"${powershellPath}"`, args) - } else { - const zipPath: string = await io.which('zip', true) - await exec.exec(`"${zipPath}`, [zipFile, '-r', '.'], {cwd: stagingDir}) - } + if (powershellTool === 'powershell' && IS_WINDOWS) { + //remove pwsh from PATH temporarily to test fallback case + const newPath = originalPath + ?.split(';') + .filter(segment => { + return !segment.startsWith(`C:\\Program Files\\PowerShell`) + }) + .join(';') + process.env['PATH'] = newPath + } - const extPath: string = await tc.extractZip(zipFile) - await tc.cacheDir(extPath, 'foo', '1.1.0') - const toolPath: string = tc.find('foo', '1.1.0') + const extPath: string = await tc.extractZip(zipFile) + await tc.cacheDir(extPath, 'foo', '1.1.0') + const toolPath: string = tc.find('foo', '1.1.0') - expect(fs.existsSync(toolPath)).toBeTruthy() - expect(fs.existsSync(`${toolPath}.complete`)).toBeTruthy() - expect(fs.existsSync(path.join(toolPath, 'file.txt'))).toBeTruthy() - expect( - fs.existsSync(path.join(toolPath, 'folder', 'nested-file.txt')) - ).toBeTruthy() - } finally { - await io.rmRF(tempDir) + expect(fs.existsSync(toolPath)).toBeTruthy() + expect(fs.existsSync(`${toolPath}.complete`)).toBeTruthy() + expect(fs.existsSync(path.join(toolPath, 'file.txt'))).toBeTruthy() + expect( + fs.existsSync(path.join(toolPath, 'folder', 'nested-file.txt')) + ).toBeTruthy() + } finally { + await io.rmRF(tempDir) + process.env['PATH'] = originalPath + } } - }) + ) it('installs a zip and extracts it to specified directory', async function() { const tempDir = path.join(__dirname, 'test-install-zip') @@ -636,7 +654,9 @@ describe('@actions/tool-cache', function() { expect(fs.existsSync(toolPath)).toBeTruthy() expect(fs.existsSync(`${toolPath}.complete`)).toBeTruthy() expect(fs.existsSync(path.join(toolPath, 'file.txt'))).toBeTruthy() - expect(fs.readFileSync(path.join(toolPath, 'file.txt'), 'utf8')).toBe('originalText') + expect(fs.readFileSync(path.join(toolPath, 'file.txt'), 'utf8')).toBe( + 'originalText' + ) expect( fs.existsSync(path.join(toolPath, 'folder', 'nested-file.txt')) ).toBeTruthy() diff --git a/packages/tool-cache/src/tool-cache.ts b/packages/tool-cache/src/tool-cache.ts index a272058e50..cb34fce86d 100644 --- a/packages/tool-cache/src/tool-cache.ts +++ b/packages/tool-cache/src/tool-cache.ts @@ -346,39 +346,52 @@ async function extractZipWin(file: string, dest: string): Promise { const escapedDest = dest.replace(/'/g, "''").replace(/"|\n|\r/g, '') const pwshPath = await io.which('pwsh', false) - let command = '' + //To match the file overwrite behavior on nix systems, we use the overwrite = true flag for ExtractToDirectory + //and the -Force flag for Expand-Archive as a fallback if (pwshPath) { - //overwrite=true - command = [ + //attempt to use pwsh with ExtractToDirectory, if this fails attempt Expand-Archive + const pwshCommand = [ `$ErrorActionPreference = 'Stop' ;`, `try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`, `try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}', $true) }`, - `catch { if ($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException'){ Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest} -Force } } ;` + `catch { if ($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException'){ Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest}' -Force } else { $_ } } ;` ].join(' ') + + const args = [ + '-NoLogo', + '-NoProfile', + '-NonInteractive', + '-ExecutionPolicy', + 'Unrestricted', + '-Command', + pwshCommand + ] + + core.debug(`Using pwsh at path: ${pwshPath}`) + await exec(`"${pwshPath}"`, args) } else { - command = [ + const powershellCommand = [ `$ErrorActionPreference = 'Stop' ;`, `try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ;`, - `[System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')` + `Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest}' -Force` ].join(' ') - } - //TODO: remove this - command = `$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')` - - // run powershell - const powershellPath = await io.which('powershell', true) - const args = [ - '-NoLogo', - '-Sta', - '-NoProfile', - '-NonInteractive', - '-ExecutionPolicy', - 'Unrestricted', - '-Command', - command - ] - await exec(`"${powershellPath}"`, args) + const args = [ + '-NoLogo', + '-Sta', + '-NoProfile', + '-NonInteractive', + '-ExecutionPolicy', + 'Unrestricted', + '-Command', + powershellCommand + ] + + const powershellPath = await io.which('powershell', true) + core.debug(`Using powershell at path: ${powershellPath}`) + + await exec(`"${powershellPath}"`, args) + } } async function extractZipNix(file: string, dest: string): Promise { @@ -387,6 +400,7 @@ async function extractZipNix(file: string, dest: string): Promise { if (!core.isDebug()) { args.unshift('-q') } + args.unshift('-o') //overwrite with -o, otherwise a prompt is shown which freezes the run await exec(`"${unzipPath}"`, args, {cwd: dest}) } From 495c529f84515cd04a844496542564b9ca9785f7 Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Thu, 13 May 2021 17:45:45 -0400 Subject: [PATCH 04/16] Add Test for failing case for both pwsh and powershell --- .../tool-cache/__tests__/tool-cache.test.ts | 33 ++++++++++++++---- source.zip | Bin 0 -> 164 bytes 2 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 source.zip diff --git a/packages/tool-cache/__tests__/tool-cache.test.ts b/packages/tool-cache/__tests__/tool-cache.test.ts index fbc4ed12f9..290700b9bb 100644 --- a/packages/tool-cache/__tests__/tool-cache.test.ts +++ b/packages/tool-cache/__tests__/tool-cache.test.ts @@ -347,6 +347,22 @@ describe('@actions/tool-cache', function() { await io.rmRF(tempDir) } }) + it.each(['pwsh', 'powershell'])( + 'unzip properly fails with bad path (%s)', + async powershellTool => { + const originalPath = process.env['PATH'] + try { + if (powershellTool === 'powershell' && IS_WINDOWS) { + //remove pwsh from PATH temporarily to test fallback case + process.env['PATH'] = removePWSHFromPath(process.env['PATH']) + } + + await expect(tc.extractZip('badPath')).rejects.toThrow() + } finally { + process.env['PATH'] = originalPath + } + } + ) } else if (IS_MAC) { it('extract .xar', async () => { const tempDir = path.join(tempPath, 'test-install.xar') @@ -579,13 +595,7 @@ describe('@actions/tool-cache', function() { if (powershellTool === 'powershell' && IS_WINDOWS) { //remove pwsh from PATH temporarily to test fallback case - const newPath = originalPath - ?.split(';') - .filter(segment => { - return !segment.startsWith(`C:\\Program Files\\PowerShell`) - }) - .join(';') - process.env['PATH'] = newPath + process.env['PATH'] = removePWSHFromPath(process.env['PATH']) } const extPath: string = await tc.extractZip(zipFile) @@ -865,3 +875,12 @@ function setGlobal(key: string, value: T | undefined): void { g[key] = value } } + +function removePWSHFromPath(path: string | undefined): string { + return (path || '') + .split(';') + .filter(segment => { + return !segment.startsWith(`C:\\Program Files\\PowerShell`) + }) + .join(';') +} diff --git a/source.zip b/source.zip new file mode 100644 index 0000000000000000000000000000000000000000..5e4697c64a88a8708afc02807acfe68c704d6e71 GIT binary patch literal 164 zcmWIWW@h1H0D)WGYlFZHD8bGk!%&=GT9lls9~#2Rz}z!yZUP9GR&X;gvV3J^U|vWRhdXWrPIOFad_Qjvyx7Kvsx>7>2R3fs`=tO%@PA?i+ literal 0 HcmV?d00001 From b31bbe5d67464d22a141868d2098893a0cd3471c Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Fri, 14 May 2021 12:53:39 -0400 Subject: [PATCH 05/16] Modify test to confirm overwrite behavior for xar --- .../tool-cache/__tests__/tool-cache.test.ts | 20 +++++++++++++++--- packages/tool-cache/src/tool-cache.ts | 2 +- source.zip | Bin 164 -> 0 bytes 3 files changed, 18 insertions(+), 4 deletions(-) delete mode 100644 source.zip diff --git a/packages/tool-cache/__tests__/tool-cache.test.ts b/packages/tool-cache/__tests__/tool-cache.test.ts index 290700b9bb..63cf51290c 100644 --- a/packages/tool-cache/__tests__/tool-cache.test.ts +++ b/packages/tool-cache/__tests__/tool-cache.test.ts @@ -243,6 +243,10 @@ describe('@actions/tool-cache', function() { const _7zFile: string = path.join(tempDir, 'test.7z') await io.cp(path.join(__dirname, 'data', 'test.7z'), _7zFile) + const destDir = path.join(tempDir, 'destination') + await io.mkdirP(destDir) + fs.writeFileSync(path.join(destDir, 'file.txt'), 'overwriteMe') + // extract/cache const extPath: string = await tc.extract7z(_7zFile) await tc.cacheDir(extPath, 'my-7z-contents', '1.1.0') @@ -251,6 +255,9 @@ describe('@actions/tool-cache', function() { expect(fs.existsSync(toolPath)).toBeTruthy() expect(fs.existsSync(`${toolPath}.complete`)).toBeTruthy() expect(fs.existsSync(path.join(toolPath, 'file.txt'))).toBeTruthy() + expect(fs.readFileSync(path.join(toolPath, 'file.txt'), 'utf8')).toBe( + 'file.txt contents' + ) expect( fs.existsSync(path.join(toolPath, 'file-with-ç-character.txt')) ).toBeTruthy() @@ -376,14 +383,21 @@ describe('@actions/tool-cache', function() { cwd: sourcePath }) + const destDir = path.join(tempDir, 'destination') + await io.mkdirP(destDir) + fs.writeFileSync(path.join(destDir, 'file.txt'), 'overwriteMe') + // extract/cache - const extPath: string = await tc.extractXar(targetPath, undefined, '-x') + const extPath: string = await tc.extractXar(targetPath, destDir, ['-x']) await tc.cacheDir(extPath, 'my-xar-contents', '1.1.0') const toolPath: string = tc.find('my-xar-contents', '1.1.0') expect(fs.existsSync(toolPath)).toBeTruthy() expect(fs.existsSync(`${toolPath}.complete`)).toBeTruthy() expect(fs.existsSync(path.join(toolPath, 'file.txt'))).toBeTruthy() + expect(fs.readFileSync(path.join(toolPath, 'file.txt'), 'utf8')).toBe( + 'file.txt contents' + ) expect( fs.existsSync(path.join(toolPath, 'file-with-ç-character.txt')) ).toBeTruthy() @@ -876,8 +890,8 @@ function setGlobal(key: string, value: T | undefined): void { } } -function removePWSHFromPath(path: string | undefined): string { - return (path || '') +function removePWSHFromPath(pathEnv: string | undefined): string { + return (pathEnv || '') .split(';') .filter(segment => { return !segment.startsWith(`C:\\Program Files\\PowerShell`) diff --git a/packages/tool-cache/src/tool-cache.ts b/packages/tool-cache/src/tool-cache.ts index cb34fce86d..50d05c3015 100644 --- a/packages/tool-cache/src/tool-cache.ts +++ b/packages/tool-cache/src/tool-cache.ts @@ -354,7 +354,7 @@ async function extractZipWin(file: string, dest: string): Promise { `$ErrorActionPreference = 'Stop' ;`, `try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`, `try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}', $true) }`, - `catch { if ($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException'){ Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest}' -Force } else { $_ } } ;` + `catch { if ($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException'){ Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest}' -Force } else { throw $_ } } ;` ].join(' ') const args = [ diff --git a/source.zip b/source.zip deleted file mode 100644 index 5e4697c64a88a8708afc02807acfe68c704d6e71..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 164 zcmWIWW@h1H0D)WGYlFZHD8bGk!%&=GT9lls9~#2Rz}z!yZUP9GR&X;gvV3J^U|vWRhdXWrPIOFad_Qjvyx7Kvsx>7>2R3fs`=tO%@PA?i+ From 8684339c787fc8c807300c973a08a55a770c3e00 Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Fri, 14 May 2021 14:18:45 -0400 Subject: [PATCH 06/16] Delete ._test.txt --- __MACOSX/test-win/._test.txt | Bin 384 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 __MACOSX/test-win/._test.txt diff --git a/__MACOSX/test-win/._test.txt b/__MACOSX/test-win/._test.txt deleted file mode 100644 index 17087ac241beba69017efe1971b971391f0c7fba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 384 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFfjT7X&|4m0Z0=89795aAj&{G7&(CK z3N&rZP;q_+2Jz(lT)o7Cf}B*nkkpD2*SzHXl+3(zum(nPASJ-SAcatqlUQ6*TAZ4a zl30?e91sjKmr)%^M=~&&Bh=-lmLvkzBwA(ry7(j}rRKz^q-9kkRi&F|m6lfI78qw& z=4Tg|q-UlVrvf#XmZa%gSQ{Ff7#W&dTA0l6n417H+R^wMh+_CuZ_vHaVE@U3GKse~ zDBu6O#mnvX#Ls)QTDeWnHqKdcy83f6Yuz!s8U5e+s=I8SgikGua_YPA#C8pPz0*VC h0~Hgik+MwLx4;jTLcied71OPS_Wy$~m From 62eb9f86e4dbf2aba8843fd73c30e1f7aa06dd74 Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Tue, 18 May 2021 09:39:42 -0400 Subject: [PATCH 07/16] Add fallback case for older windows systems --- packages/tool-cache/src/tool-cache.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/tool-cache/src/tool-cache.ts b/packages/tool-cache/src/tool-cache.ts index 50d05c3015..0e558eb417 100644 --- a/packages/tool-cache/src/tool-cache.ts +++ b/packages/tool-cache/src/tool-cache.ts @@ -373,7 +373,8 @@ async function extractZipWin(file: string, dest: string): Promise { const powershellCommand = [ `$ErrorActionPreference = 'Stop' ;`, `try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ;`, - `Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest}' -Force` + `if ((Get-Command -Name Expand-Archive -Module Microsoft.PowerShell.Archive -ErrorAction Ignore)) { Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest}' -Force }`, + `else { try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ; try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}', $true) } }` ].join(' ') const args = [ From 72970bf9f1742ef8f16e1854fb39287e9eb683eb Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Tue, 18 May 2021 09:52:55 -0400 Subject: [PATCH 08/16] Remove try --- packages/tool-cache/src/tool-cache.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tool-cache/src/tool-cache.ts b/packages/tool-cache/src/tool-cache.ts index 0e558eb417..d21093ad0e 100644 --- a/packages/tool-cache/src/tool-cache.ts +++ b/packages/tool-cache/src/tool-cache.ts @@ -374,7 +374,7 @@ async function extractZipWin(file: string, dest: string): Promise { `$ErrorActionPreference = 'Stop' ;`, `try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ;`, `if ((Get-Command -Name Expand-Archive -Module Microsoft.PowerShell.Archive -ErrorAction Ignore)) { Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest}' -Force }`, - `else { try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ; try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}', $true) } }` + `else { try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}', $true) }` ].join(' ') const args = [ From e5db96a79c6ce55885adad50edd7c2af3e403be0 Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Wed, 19 May 2021 11:37:56 -0400 Subject: [PATCH 09/16] Run Tests on windows-2016 --- .github/workflows/unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index f5bcb340ea..29b2a026eb 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: - runs-on: [ubuntu-latest, macos-latest, windows-latest] + runs-on: [ubuntu-latest, macos-latest, windows-latest, windows-2016] fail-fast: false runs-on: ${{ matrix.runs-on }} From 0195ec2f6832e674e0fa5aa5dab1daf49824c548 Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Wed, 19 May 2021 13:46:50 -0400 Subject: [PATCH 10/16] Update tar tests to handle existing files --- .github/workflows/unit-tests.yml | 2 +- packages/tool-cache/__tests__/tool-cache.test.ts | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 29b2a026eb..f5bcb340ea 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: - runs-on: [ubuntu-latest, macos-latest, windows-latest, windows-2016] + runs-on: [ubuntu-latest, macos-latest, windows-latest] fail-fast: false runs-on: ${{ matrix.runs-on }} diff --git a/packages/tool-cache/__tests__/tool-cache.test.ts b/packages/tool-cache/__tests__/tool-cache.test.ts index 63cf51290c..9feb810eb9 100644 --- a/packages/tool-cache/__tests__/tool-cache.test.ts +++ b/packages/tool-cache/__tests__/tool-cache.test.ts @@ -497,9 +497,14 @@ describe('@actions/tool-cache', function() { await tc.cacheDir(extPath, 'my-tgz-contents', '1.1.0') const toolPath: string = tc.find('my-tgz-contents', '1.1.0') + fs.writeFileSync(path.join(tempDir, 'file.txt'), 'overwriteMe') + expect(fs.existsSync(toolPath)).toBeTruthy() expect(fs.existsSync(`${toolPath}.complete`)).toBeTruthy() expect(fs.existsSync(path.join(toolPath, 'file.txt'))).toBeTruthy() + expect(fs.readFileSync(path.join(toolPath, 'file.txt'), 'utf8')).toBe( + 'file.txt contents' + ) expect( fs.existsSync(path.join(toolPath, 'file-with-ç-character.txt')) ).toBeTruthy() @@ -520,6 +525,8 @@ describe('@actions/tool-cache', function() { // copy the .tar.gz file to the test dir const _tgzFile: string = path.join(tempDir, 'test.tar.gz') await io.cp(path.join(__dirname, 'data', 'test.tar.gz'), _tgzFile) + fs.writeFileSync(path.join(tempDir, 'file.txt'), 'overwriteMe') + // extract/cache const extPath: string = await tc.extractTar(_tgzFile, destDir) @@ -530,6 +537,9 @@ describe('@actions/tool-cache', function() { expect(fs.existsSync(toolPath)).toBeTruthy() expect(fs.existsSync(`${toolPath}.complete`)).toBeTruthy() expect(fs.existsSync(path.join(toolPath, 'file.txt'))).toBeTruthy() + expect(fs.readFileSync(path.join(toolPath, 'file.txt'), 'utf8')).toBe( + 'file.txt contents' + ) expect( fs.existsSync(path.join(toolPath, 'file-with-ç-character.txt')) ).toBeTruthy() From 533ca19bd510ff409b1beb8020816b9c88b61801 Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Wed, 19 May 2021 13:50:08 -0400 Subject: [PATCH 11/16] Lint --- packages/tool-cache/__tests__/tool-cache.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/tool-cache/__tests__/tool-cache.test.ts b/packages/tool-cache/__tests__/tool-cache.test.ts index 9feb810eb9..42ef432346 100644 --- a/packages/tool-cache/__tests__/tool-cache.test.ts +++ b/packages/tool-cache/__tests__/tool-cache.test.ts @@ -527,7 +527,6 @@ describe('@actions/tool-cache', function() { await io.cp(path.join(__dirname, 'data', 'test.tar.gz'), _tgzFile) fs.writeFileSync(path.join(tempDir, 'file.txt'), 'overwriteMe') - // extract/cache const extPath: string = await tc.extractTar(_tgzFile, destDir) await tc.cacheDir(extPath, 'my-tgz-contents', '1.1.0') From a00d1ad97a3a98ac4e2ba859751cb9023a668211 Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Wed, 19 May 2021 14:04:57 -0400 Subject: [PATCH 12/16] Update tool-cache.test.ts --- .../tool-cache/__tests__/tool-cache.test.ts | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/tool-cache/__tests__/tool-cache.test.ts b/packages/tool-cache/__tests__/tool-cache.test.ts index 42ef432346..510a4800e1 100644 --- a/packages/tool-cache/__tests__/tool-cache.test.ts +++ b/packages/tool-cache/__tests__/tool-cache.test.ts @@ -492,12 +492,19 @@ describe('@actions/tool-cache', function() { const _tgzFile: string = path.join(tempDir, 'test.tar.gz') await io.cp(path.join(__dirname, 'data', 'test.tar.gz'), _tgzFile) + + //Create file to overwrite + const destDir = path.join(__dirname, 'extract-dest') + await io.rmRF(destDir) + await io.mkdirP(destDir) + fs.writeFileSync(path.join(destDir, 'file.txt'), 'overwriteMe') + + // extract/cache - const extPath: string = await tc.extractTar(_tgzFile) + const extPath: string = await tc.extractTar(_tgzFile, destDir) await tc.cacheDir(extPath, 'my-tgz-contents', '1.1.0') const toolPath: string = tc.find('my-tgz-contents', '1.1.0') - fs.writeFileSync(path.join(tempDir, 'file.txt'), 'overwriteMe') expect(fs.existsSync(toolPath)).toBeTruthy() expect(fs.existsSync(`${toolPath}.complete`)).toBeTruthy() @@ -525,7 +532,7 @@ describe('@actions/tool-cache', function() { // copy the .tar.gz file to the test dir const _tgzFile: string = path.join(tempDir, 'test.tar.gz') await io.cp(path.join(__dirname, 'data', 'test.tar.gz'), _tgzFile) - fs.writeFileSync(path.join(tempDir, 'file.txt'), 'overwriteMe') + fs.writeFileSync(path.join(destDir, 'file.txt'), 'overwriteMe') // extract/cache const extPath: string = await tc.extractTar(_tgzFile, destDir) @@ -559,8 +566,14 @@ describe('@actions/tool-cache', function() { const _txzFile: string = path.join(tempDir, 'test.tar.xz') await io.cp(path.join(__dirname, 'data', 'test.tar.xz'), _txzFile) + //Create file to overwrite + const destDir = path.join(__dirname, 'extract-dest') + await io.rmRF(destDir) + await io.mkdirP(destDir) + fs.writeFileSync(path.join(destDir, 'file.txt'), 'overwriteMe') + // extract/cache - const extPath: string = await tc.extractTar(_txzFile, undefined, 'x') + const extPath: string = await tc.extractTar(_txzFile, destDir, 'x') await tc.cacheDir(extPath, 'my-txz-contents', '1.1.0') const toolPath: string = tc.find('my-txz-contents', '1.1.0') From 3b564776656e21a9e28f0c4537eeb5ffbc017614 Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Wed, 19 May 2021 14:08:08 -0400 Subject: [PATCH 13/16] Update tool-cache.test.ts --- packages/tool-cache/__tests__/tool-cache.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/tool-cache/__tests__/tool-cache.test.ts b/packages/tool-cache/__tests__/tool-cache.test.ts index 510a4800e1..609bb05641 100644 --- a/packages/tool-cache/__tests__/tool-cache.test.ts +++ b/packages/tool-cache/__tests__/tool-cache.test.ts @@ -532,7 +532,6 @@ describe('@actions/tool-cache', function() { // copy the .tar.gz file to the test dir const _tgzFile: string = path.join(tempDir, 'test.tar.gz') await io.cp(path.join(__dirname, 'data', 'test.tar.gz'), _tgzFile) - fs.writeFileSync(path.join(destDir, 'file.txt'), 'overwriteMe') // extract/cache const extPath: string = await tc.extractTar(_tgzFile, destDir) From 58ac2ac7b4684580d0994d2f9bfb7d43c06591c0 Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Wed, 19 May 2021 14:12:28 -0400 Subject: [PATCH 14/16] Update tool-cache.test.ts --- packages/tool-cache/__tests__/tool-cache.test.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/tool-cache/__tests__/tool-cache.test.ts b/packages/tool-cache/__tests__/tool-cache.test.ts index 609bb05641..b6a85e288f 100644 --- a/packages/tool-cache/__tests__/tool-cache.test.ts +++ b/packages/tool-cache/__tests__/tool-cache.test.ts @@ -492,20 +492,17 @@ describe('@actions/tool-cache', function() { const _tgzFile: string = path.join(tempDir, 'test.tar.gz') await io.cp(path.join(__dirname, 'data', 'test.tar.gz'), _tgzFile) - //Create file to overwrite const destDir = path.join(__dirname, 'extract-dest') await io.rmRF(destDir) await io.mkdirP(destDir) fs.writeFileSync(path.join(destDir, 'file.txt'), 'overwriteMe') - // extract/cache const extPath: string = await tc.extractTar(_tgzFile, destDir) await tc.cacheDir(extPath, 'my-tgz-contents', '1.1.0') const toolPath: string = tc.find('my-tgz-contents', '1.1.0') - expect(fs.existsSync(toolPath)).toBeTruthy() expect(fs.existsSync(`${toolPath}.complete`)).toBeTruthy() expect(fs.existsSync(path.join(toolPath, 'file.txt'))).toBeTruthy() From b88c5cf94fa13bb6d4f3dd4a73bac5911730359d Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Wed, 19 May 2021 14:28:12 -0400 Subject: [PATCH 15/16] Update tool-cache.test.ts --- packages/tool-cache/__tests__/tool-cache.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/tool-cache/__tests__/tool-cache.test.ts b/packages/tool-cache/__tests__/tool-cache.test.ts index b6a85e288f..47cba0278c 100644 --- a/packages/tool-cache/__tests__/tool-cache.test.ts +++ b/packages/tool-cache/__tests__/tool-cache.test.ts @@ -493,7 +493,7 @@ describe('@actions/tool-cache', function() { await io.cp(path.join(__dirname, 'data', 'test.tar.gz'), _tgzFile) //Create file to overwrite - const destDir = path.join(__dirname, 'extract-dest') + const destDir = path.join(tempDir, 'extract-dest') await io.rmRF(destDir) await io.mkdirP(destDir) fs.writeFileSync(path.join(destDir, 'file.txt'), 'overwriteMe') @@ -563,7 +563,7 @@ describe('@actions/tool-cache', function() { await io.cp(path.join(__dirname, 'data', 'test.tar.xz'), _txzFile) //Create file to overwrite - const destDir = path.join(__dirname, 'extract-dest') + const destDir = path.join(tempDir, 'extract-dest') await io.rmRF(destDir) await io.mkdirP(destDir) fs.writeFileSync(path.join(destDir, 'file.txt'), 'overwriteMe') From aebc03ccbbd6b80e87c3e78c9efefbf198b29f40 Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Fri, 21 May 2021 16:40:02 -0400 Subject: [PATCH 16/16] Update from PR feedback --- packages/tool-cache/src/tool-cache.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/tool-cache/src/tool-cache.ts b/packages/tool-cache/src/tool-cache.ts index d21093ad0e..92fd519afa 100644 --- a/packages/tool-cache/src/tool-cache.ts +++ b/packages/tool-cache/src/tool-cache.ts @@ -272,6 +272,7 @@ export async function extractTar( if (isGnuTar) { // Suppress warnings when using GNU tar to extract archives created by BSD tar args.push('--warning=no-unknown-keyword') + args.push('--overwrite') } args.push('-C', destArg, '-f', fileArg) @@ -354,7 +355,7 @@ async function extractZipWin(file: string, dest: string): Promise { `$ErrorActionPreference = 'Stop' ;`, `try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`, `try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}', $true) }`, - `catch { if ($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException'){ Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest}' -Force } else { throw $_ } } ;` + `catch { if (($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException') -or ($_.Exception.GetType().FullName -eq 'System.Management.Automation.RuntimeException') ){ Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest}' -Force } else { throw $_ } } ;` ].join(' ') const args = [ @@ -374,7 +375,7 @@ async function extractZipWin(file: string, dest: string): Promise { `$ErrorActionPreference = 'Stop' ;`, `try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ;`, `if ((Get-Command -Name Expand-Archive -Module Microsoft.PowerShell.Archive -ErrorAction Ignore)) { Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest}' -Force }`, - `else { try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}', $true) }` + `else {[System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}', $true) }` ].join(' ') const args = [