mirror of
				https://gitea.com/actions/cache.git
				synced 2025-10-31 17:18:10 +07:00 
			
		
		
		
	Fallback to GNU tar if BSD tar is unavailable
This commit is contained in:
		
							parent
							
								
									70655ec832
								
							
						
					
					
						commit
						84e606dfac
					
				| @ -1,5 +1,7 @@ | |||||||
| import * as exec from "@actions/exec"; | import * as exec from "@actions/exec"; | ||||||
| import * as io from "@actions/io"; | import * as io from "@actions/io"; | ||||||
|  | import * as fs from "fs"; | ||||||
|  | import * as path from "path"; | ||||||
| import * as tar from "../src/tar"; | import * as tar from "../src/tar"; | ||||||
| 
 | 
 | ||||||
| jest.mock("@actions/exec"); | jest.mock("@actions/exec"); | ||||||
| @ -11,17 +13,19 @@ beforeAll(() => { | |||||||
|     }); |     }); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| test("extract tar", async () => { | test("extract BSD tar", async () => { | ||||||
|     const mkdirMock = jest.spyOn(io, "mkdirP"); |     const mkdirMock = jest.spyOn(io, "mkdirP"); | ||||||
|     const execMock = jest.spyOn(exec, "exec"); |     const execMock = jest.spyOn(exec, "exec"); | ||||||
| 
 | 
 | ||||||
|     const archivePath = "cache.tar"; |     const IS_WINDOWS = process.platform === "win32"; | ||||||
|  |     const archivePath = IS_WINDOWS | ||||||
|  |         ? `${process.env["windir"]}\\fakepath\\cache.tar` | ||||||
|  |         : "cache.tar"; | ||||||
|     const targetDirectory = "~/.npm/cache"; |     const targetDirectory = "~/.npm/cache"; | ||||||
|     await tar.extractTar(archivePath, targetDirectory); |     await tar.extractTar(archivePath, targetDirectory); | ||||||
| 
 | 
 | ||||||
|     expect(mkdirMock).toHaveBeenCalledWith(targetDirectory); |     expect(mkdirMock).toHaveBeenCalledWith(targetDirectory); | ||||||
| 
 | 
 | ||||||
|     const IS_WINDOWS = process.platform === "win32"; |  | ||||||
|     const tarPath = IS_WINDOWS |     const tarPath = IS_WINDOWS | ||||||
|         ? `${process.env["windir"]}\\System32\\tar.exe` |         ? `${process.env["windir"]}\\System32\\tar.exe` | ||||||
|         : "tar"; |         : "tar"; | ||||||
| @ -29,13 +33,48 @@ test("extract tar", async () => { | |||||||
|     expect(execMock).toHaveBeenCalledWith(`"${tarPath}"`, [ |     expect(execMock).toHaveBeenCalledWith(`"${tarPath}"`, [ | ||||||
|         "-xz", |         "-xz", | ||||||
|         "-f", |         "-f", | ||||||
|         archivePath, |         archivePath?.replace(/\\/g, "/"), | ||||||
|         "-C", |         "-C", | ||||||
|         targetDirectory |         targetDirectory?.replace(/\\/g, "/"), | ||||||
|     ]); |     ]); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| test("create tar", async () => { | test("extract GNU tar", async () => { | ||||||
|  |     const IS_WINDOWS = process.platform === "win32"; | ||||||
|  |     if (IS_WINDOWS) { | ||||||
|  |         jest.mock("fs"); | ||||||
|  | 
 | ||||||
|  |         const execMock = jest.spyOn(exec, "exec"); | ||||||
|  |         const existsSyncMock = jest | ||||||
|  |             .spyOn(fs, "existsSync") | ||||||
|  |             .mockReturnValue(false); | ||||||
|  |         const isGnuTarMock = jest | ||||||
|  |             .spyOn(tar, "isGnuTar") | ||||||
|  |             .mockReturnValue(Promise.resolve(true)); | ||||||
|  |         const archivePath = `${process.env["windir"]}\\fakepath\\cache.tar`; | ||||||
|  |         const targetDirectory = "~/.npm/cache"; | ||||||
|  | 
 | ||||||
|  |         await tar.extractTar(archivePath, targetDirectory); | ||||||
|  | 
 | ||||||
|  |         expect(existsSyncMock).toHaveBeenCalledTimes(1); | ||||||
|  |         expect(isGnuTarMock).toHaveBeenCalledTimes(1); | ||||||
|  |         expect(execMock).toHaveBeenCalledTimes(2); | ||||||
|  |         expect(execMock).toHaveBeenLastCalledWith( | ||||||
|  |             "tar", | ||||||
|  |             [ | ||||||
|  |                 "-xz", | ||||||
|  |                 "-f", | ||||||
|  |                 archivePath?.replace(/\\/g, "/"), | ||||||
|  |                 "-C", | ||||||
|  |                 targetDirectory?.replace(/\\/g, "/"), | ||||||
|  |                 "--force-local" | ||||||
|  |             ], | ||||||
|  |             { cwd: undefined } | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("create BSD tar", async () => { | ||||||
|     const execMock = jest.spyOn(exec, "exec"); |     const execMock = jest.spyOn(exec, "exec"); | ||||||
| 
 | 
 | ||||||
|     const archivePath = "cache.tar"; |     const archivePath = "cache.tar"; | ||||||
| @ -50,9 +89,9 @@ test("create tar", async () => { | |||||||
|     expect(execMock).toHaveBeenCalledWith(`"${tarPath}"`, [ |     expect(execMock).toHaveBeenCalledWith(`"${tarPath}"`, [ | ||||||
|         "-cz", |         "-cz", | ||||||
|         "-f", |         "-f", | ||||||
|         archivePath, |         archivePath?.replace(/\\/g, "/"), | ||||||
|         "-C", |         "-C", | ||||||
|         sourceDirectory, |         sourceDirectory?.replace(/\\/g, "/"), | ||||||
|         "." |         "." | ||||||
|     ]); |     ]); | ||||||
| }); | }); | ||||||
|  | |||||||
							
								
								
									
										87
									
								
								dist/restore/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										87
									
								
								dist/restore/index.js
									
									
									
									
										vendored
									
									
								
							| @ -2928,10 +2928,34 @@ var __importStar = (this && this.__importStar) || function (mod) { | |||||||
|     return result; |     return result; | ||||||
| }; | }; | ||||||
| Object.defineProperty(exports, "__esModule", { value: true }); | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
|  | const core = __importStar(__webpack_require__(470)); | ||||||
| const exec_1 = __webpack_require__(986); | const exec_1 = __webpack_require__(986); | ||||||
| const io = __importStar(__webpack_require__(1)); | const io = __importStar(__webpack_require__(1)); | ||||||
| const fs_1 = __webpack_require__(747); | const fs_1 = __webpack_require__(747); | ||||||
|  | <<<<<<< HEAD | ||||||
| function getTarPath() { | function getTarPath() { | ||||||
|  | ======= | ||||||
|  | const path = __importStar(__webpack_require__(622)); | ||||||
|  | const constants_1 = __webpack_require__(694); | ||||||
|  | function isGnuTar() { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         core.debug("Checking tar --version"); | ||||||
|  |         let versionOutput = ""; | ||||||
|  |         yield exec_1.exec("tar --version", [], { | ||||||
|  |             ignoreReturnCode: true, | ||||||
|  |             silent: true, | ||||||
|  |             listeners: { | ||||||
|  |                 stdout: (data) => (versionOutput += data.toString()), | ||||||
|  |                 stderr: (data) => (versionOutput += data.toString()) | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |         core.debug(versionOutput.trim()); | ||||||
|  |         return versionOutput.toUpperCase().includes("GNU TAR"); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | exports.isGnuTar = isGnuTar; | ||||||
|  | function getTarPath(args) { | ||||||
|  | >>>>>>> 4fa017f... Fallback to GNU tar if BSD tar is unavailable | ||||||
|     return __awaiter(this, void 0, void 0, function* () { |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|         // Explicitly use BSD Tar on Windows
 |         // Explicitly use BSD Tar on Windows
 | ||||||
|         const IS_WINDOWS = process.platform === "win32"; |         const IS_WINDOWS = process.platform === "win32"; | ||||||
| @ -2940,38 +2964,91 @@ function getTarPath() { | |||||||
|             if (fs_1.existsSync(systemTar)) { |             if (fs_1.existsSync(systemTar)) { | ||||||
|                 return systemTar; |                 return systemTar; | ||||||
|             } |             } | ||||||
|  |             else if (isGnuTar()) { | ||||||
|  |                 args.push("--force-local"); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         return yield io.which("tar", true); |         return yield io.which("tar", true); | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  | <<<<<<< HEAD | ||||||
| function execTar(args) { | function execTar(args) { | ||||||
|     var _a, _b; |     var _a, _b; | ||||||
|     return __awaiter(this, void 0, void 0, function* () { |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|         try { |         try { | ||||||
|             yield exec_1.exec(`"${yield getTarPath()}"`, args); |             yield exec_1.exec(`"${yield getTarPath()}"`, args); | ||||||
|  | ======= | ||||||
|  | function execTar(args, cwd) { | ||||||
|  |     var _a; | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         try { | ||||||
|  |             yield exec_1.exec(`"${yield getTarPath(args)}"`, args, { cwd: cwd }); | ||||||
|  | >>>>>>> 4fa017f... Fallback to GNU tar if BSD tar is unavailable | ||||||
|         } |         } | ||||||
|         catch (error) { |         catch (error) { | ||||||
|             const IS_WINDOWS = process.platform === "win32"; |             throw new Error(`Tar failed with error: ${(_a = error) === null || _a === void 0 ? void 0 : _a.message}`); | ||||||
|             if (IS_WINDOWS) { |  | ||||||
|                 throw new Error(`Tar failed with error: ${(_a = error) === null || _a === void 0 ? void 0 : _a.message}. Ensure BSD tar is installed and on the PATH.`); |  | ||||||
|             } |  | ||||||
|             throw new Error(`Tar failed with error: ${(_b = error) === null || _b === void 0 ? void 0 : _b.message}`); |  | ||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  | <<<<<<< HEAD | ||||||
| function extractTar(archivePath, targetDirectory) { | function extractTar(archivePath, targetDirectory) { | ||||||
|     return __awaiter(this, void 0, void 0, function* () { |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|         // Create directory to extract tar into
 |         // Create directory to extract tar into
 | ||||||
|         yield io.mkdirP(targetDirectory); |         yield io.mkdirP(targetDirectory); | ||||||
|         const args = ["-xz", "-f", archivePath, "-C", targetDirectory]; |         const args = ["-xz", "-f", archivePath, "-C", targetDirectory]; | ||||||
|  | ======= | ||||||
|  | function getWorkingDirectory() { | ||||||
|  |     var _a; | ||||||
|  |     return _a = process.env["GITHUB_WORKSPACE"], (_a !== null && _a !== void 0 ? _a : process.cwd()); | ||||||
|  | } | ||||||
|  | function extractTar(archivePath) { | ||||||
|  |     var _a, _b; | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         // Create directory to extract tar into
 | ||||||
|  |         const workingDirectory = getWorkingDirectory(); | ||||||
|  |         yield io.mkdirP(workingDirectory); | ||||||
|  |         const args = [ | ||||||
|  |             "-xz", | ||||||
|  |             "-f", | ||||||
|  |             (_a = archivePath) === null || _a === void 0 ? void 0 : _a.replace(/\\/g, "/"), | ||||||
|  |             "-P", | ||||||
|  |             "-C", | ||||||
|  |             (_b = workingDirectory) === null || _b === void 0 ? void 0 : _b.replace(/\\/g, "/") | ||||||
|  |         ]; | ||||||
|  | >>>>>>> 4fa017f... Fallback to GNU tar if BSD tar is unavailable | ||||||
|         yield execTar(args); |         yield execTar(args); | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| exports.extractTar = extractTar; | exports.extractTar = extractTar; | ||||||
|  | <<<<<<< HEAD | ||||||
| function createTar(archivePath, sourceDirectory) { | function createTar(archivePath, sourceDirectory) { | ||||||
|     return __awaiter(this, void 0, void 0, function* () { |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|         const args = ["-cz", "-f", archivePath, "-C", sourceDirectory, "."]; |         const args = ["-cz", "-f", archivePath, "-C", sourceDirectory, "."]; | ||||||
|         yield execTar(args); |         yield execTar(args); | ||||||
|  | ======= | ||||||
|  | function createTar(archiveFolder, sourceDirectories) { | ||||||
|  |     var _a, _b; | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         // Write source directories to manifest.txt to avoid command length limits
 | ||||||
|  |         const manifestFilename = "manifest.txt"; | ||||||
|  |         fs_1.writeFileSync(path.join(archiveFolder, manifestFilename), sourceDirectories.join("\n")); | ||||||
|  |         const workingDirectory = getWorkingDirectory(); | ||||||
|  |         const args = [ | ||||||
|  |             "-cz", | ||||||
|  |             "-f", | ||||||
|  | <<<<<<< HEAD | ||||||
|  |             constants_1.CacheFilename, | ||||||
|  |             "-P", | ||||||
|  | ======= | ||||||
|  |             (_a = constants_1.CacheFilename) === null || _a === void 0 ? void 0 : _a.replace(/\\/g, "/"), | ||||||
|  | >>>>>>> Fallback to GNU tar if BSD tar is unavailable | ||||||
|  |             "-C", | ||||||
|  |             (_b = workingDirectory) === null || _b === void 0 ? void 0 : _b.replace(/\\/g, "/"), | ||||||
|  |             "--files-from", | ||||||
|  |             manifestFilename | ||||||
|  |         ]; | ||||||
|  |         yield execTar(args, archiveFolder); | ||||||
|  | >>>>>>> 4fa017f... Fallback to GNU tar if BSD tar is unavailable | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| exports.createTar = createTar; | exports.createTar = createTar; | ||||||
|  | |||||||
							
								
								
									
										87
									
								
								dist/save/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										87
									
								
								dist/save/index.js
									
									
									
									
										vendored
									
									
								
							| @ -2909,10 +2909,34 @@ var __importStar = (this && this.__importStar) || function (mod) { | |||||||
|     return result; |     return result; | ||||||
| }; | }; | ||||||
| Object.defineProperty(exports, "__esModule", { value: true }); | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
|  | const core = __importStar(__webpack_require__(470)); | ||||||
| const exec_1 = __webpack_require__(986); | const exec_1 = __webpack_require__(986); | ||||||
| const io = __importStar(__webpack_require__(1)); | const io = __importStar(__webpack_require__(1)); | ||||||
| const fs_1 = __webpack_require__(747); | const fs_1 = __webpack_require__(747); | ||||||
|  | <<<<<<< HEAD | ||||||
| function getTarPath() { | function getTarPath() { | ||||||
|  | ======= | ||||||
|  | const path = __importStar(__webpack_require__(622)); | ||||||
|  | const constants_1 = __webpack_require__(694); | ||||||
|  | function isGnuTar() { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         core.debug("Checking tar --version"); | ||||||
|  |         let versionOutput = ""; | ||||||
|  |         yield exec_1.exec("tar --version", [], { | ||||||
|  |             ignoreReturnCode: true, | ||||||
|  |             silent: true, | ||||||
|  |             listeners: { | ||||||
|  |                 stdout: (data) => (versionOutput += data.toString()), | ||||||
|  |                 stderr: (data) => (versionOutput += data.toString()) | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |         core.debug(versionOutput.trim()); | ||||||
|  |         return versionOutput.toUpperCase().includes("GNU TAR"); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | exports.isGnuTar = isGnuTar; | ||||||
|  | function getTarPath(args) { | ||||||
|  | >>>>>>> 4fa017f... Fallback to GNU tar if BSD tar is unavailable | ||||||
|     return __awaiter(this, void 0, void 0, function* () { |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|         // Explicitly use BSD Tar on Windows
 |         // Explicitly use BSD Tar on Windows
 | ||||||
|         const IS_WINDOWS = process.platform === "win32"; |         const IS_WINDOWS = process.platform === "win32"; | ||||||
| @ -2921,38 +2945,91 @@ function getTarPath() { | |||||||
|             if (fs_1.existsSync(systemTar)) { |             if (fs_1.existsSync(systemTar)) { | ||||||
|                 return systemTar; |                 return systemTar; | ||||||
|             } |             } | ||||||
|  |             else if (isGnuTar()) { | ||||||
|  |                 args.push("--force-local"); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         return yield io.which("tar", true); |         return yield io.which("tar", true); | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  | <<<<<<< HEAD | ||||||
| function execTar(args) { | function execTar(args) { | ||||||
|     var _a, _b; |     var _a, _b; | ||||||
|     return __awaiter(this, void 0, void 0, function* () { |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|         try { |         try { | ||||||
|             yield exec_1.exec(`"${yield getTarPath()}"`, args); |             yield exec_1.exec(`"${yield getTarPath()}"`, args); | ||||||
|  | ======= | ||||||
|  | function execTar(args, cwd) { | ||||||
|  |     var _a; | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         try { | ||||||
|  |             yield exec_1.exec(`"${yield getTarPath(args)}"`, args, { cwd: cwd }); | ||||||
|  | >>>>>>> 4fa017f... Fallback to GNU tar if BSD tar is unavailable | ||||||
|         } |         } | ||||||
|         catch (error) { |         catch (error) { | ||||||
|             const IS_WINDOWS = process.platform === "win32"; |             throw new Error(`Tar failed with error: ${(_a = error) === null || _a === void 0 ? void 0 : _a.message}`); | ||||||
|             if (IS_WINDOWS) { |  | ||||||
|                 throw new Error(`Tar failed with error: ${(_a = error) === null || _a === void 0 ? void 0 : _a.message}. Ensure BSD tar is installed and on the PATH.`); |  | ||||||
|             } |  | ||||||
|             throw new Error(`Tar failed with error: ${(_b = error) === null || _b === void 0 ? void 0 : _b.message}`); |  | ||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  | <<<<<<< HEAD | ||||||
| function extractTar(archivePath, targetDirectory) { | function extractTar(archivePath, targetDirectory) { | ||||||
|     return __awaiter(this, void 0, void 0, function* () { |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|         // Create directory to extract tar into
 |         // Create directory to extract tar into
 | ||||||
|         yield io.mkdirP(targetDirectory); |         yield io.mkdirP(targetDirectory); | ||||||
|         const args = ["-xz", "-f", archivePath, "-C", targetDirectory]; |         const args = ["-xz", "-f", archivePath, "-C", targetDirectory]; | ||||||
|  | ======= | ||||||
|  | function getWorkingDirectory() { | ||||||
|  |     var _a; | ||||||
|  |     return _a = process.env["GITHUB_WORKSPACE"], (_a !== null && _a !== void 0 ? _a : process.cwd()); | ||||||
|  | } | ||||||
|  | function extractTar(archivePath) { | ||||||
|  |     var _a, _b; | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         // Create directory to extract tar into
 | ||||||
|  |         const workingDirectory = getWorkingDirectory(); | ||||||
|  |         yield io.mkdirP(workingDirectory); | ||||||
|  |         const args = [ | ||||||
|  |             "-xz", | ||||||
|  |             "-f", | ||||||
|  |             (_a = archivePath) === null || _a === void 0 ? void 0 : _a.replace(/\\/g, "/"), | ||||||
|  |             "-P", | ||||||
|  |             "-C", | ||||||
|  |             (_b = workingDirectory) === null || _b === void 0 ? void 0 : _b.replace(/\\/g, "/") | ||||||
|  |         ]; | ||||||
|  | >>>>>>> 4fa017f... Fallback to GNU tar if BSD tar is unavailable | ||||||
|         yield execTar(args); |         yield execTar(args); | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| exports.extractTar = extractTar; | exports.extractTar = extractTar; | ||||||
|  | <<<<<<< HEAD | ||||||
| function createTar(archivePath, sourceDirectory) { | function createTar(archivePath, sourceDirectory) { | ||||||
|     return __awaiter(this, void 0, void 0, function* () { |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|         const args = ["-cz", "-f", archivePath, "-C", sourceDirectory, "."]; |         const args = ["-cz", "-f", archivePath, "-C", sourceDirectory, "."]; | ||||||
|         yield execTar(args); |         yield execTar(args); | ||||||
|  | ======= | ||||||
|  | function createTar(archiveFolder, sourceDirectories) { | ||||||
|  |     var _a, _b; | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         // Write source directories to manifest.txt to avoid command length limits
 | ||||||
|  |         const manifestFilename = "manifest.txt"; | ||||||
|  |         fs_1.writeFileSync(path.join(archiveFolder, manifestFilename), sourceDirectories.join("\n")); | ||||||
|  |         const workingDirectory = getWorkingDirectory(); | ||||||
|  |         const args = [ | ||||||
|  |             "-cz", | ||||||
|  |             "-f", | ||||||
|  | <<<<<<< HEAD | ||||||
|  |             constants_1.CacheFilename, | ||||||
|  |             "-P", | ||||||
|  | ======= | ||||||
|  |             (_a = constants_1.CacheFilename) === null || _a === void 0 ? void 0 : _a.replace(/\\/g, "/"), | ||||||
|  | >>>>>>> Fallback to GNU tar if BSD tar is unavailable | ||||||
|  |             "-C", | ||||||
|  |             (_b = workingDirectory) === null || _b === void 0 ? void 0 : _b.replace(/\\/g, "/"), | ||||||
|  |             "--files-from", | ||||||
|  |             manifestFilename | ||||||
|  |         ]; | ||||||
|  |         yield execTar(args, archiveFolder); | ||||||
|  | >>>>>>> 4fa017f... Fallback to GNU tar if BSD tar is unavailable | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| exports.createTar = createTar; | exports.createTar = createTar; | ||||||
|  | |||||||
							
								
								
									
										48
									
								
								src/tar.ts
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								src/tar.ts
									
									
									
									
									
								
							| @ -1,14 +1,35 @@ | |||||||
|  | import * as core from "@actions/core"; | ||||||
| import { exec } from "@actions/exec"; | import { exec } from "@actions/exec"; | ||||||
| import * as io from "@actions/io"; | import * as io from "@actions/io"; | ||||||
| import { existsSync } from "fs"; | import { existsSync } from "fs"; | ||||||
|  | import * as path from "path"; | ||||||
| 
 | 
 | ||||||
| async function getTarPath(): Promise<string> { | export async function isGnuTar(): Promise<boolean> { | ||||||
|  |     core.debug("Checking tar --version"); | ||||||
|  |     let versionOutput = ""; | ||||||
|  |     await exec("tar --version", [], { | ||||||
|  |         ignoreReturnCode: true, | ||||||
|  |         silent: true, | ||||||
|  |         listeners: { | ||||||
|  |             stdout: (data: Buffer): string => | ||||||
|  |                 (versionOutput += data.toString()), | ||||||
|  |             stderr: (data: Buffer): string => (versionOutput += data.toString()) | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     core.debug(versionOutput.trim()); | ||||||
|  |     return versionOutput.toUpperCase().includes("GNU TAR"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function getTarPath(args: string[]): Promise<string> { | ||||||
|     // Explicitly use BSD Tar on Windows
 |     // Explicitly use BSD Tar on Windows
 | ||||||
|     const IS_WINDOWS = process.platform === "win32"; |     const IS_WINDOWS = process.platform === "win32"; | ||||||
|     if (IS_WINDOWS) { |     if (IS_WINDOWS) { | ||||||
|         const systemTar = `${process.env["windir"]}\\System32\\tar.exe`; |         const systemTar = `${process.env["windir"]}\\System32\\tar.exe`; | ||||||
|         if (existsSync(systemTar)) { |         if (existsSync(systemTar)) { | ||||||
|             return systemTar; |             return systemTar; | ||||||
|  |         } else if (isGnuTar()) { | ||||||
|  |             args.push("--force-local"); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return await io.which("tar", true); |     return await io.which("tar", true); | ||||||
| @ -16,14 +37,8 @@ async function getTarPath(): Promise<string> { | |||||||
| 
 | 
 | ||||||
| async function execTar(args: string[]): Promise<void> { | async function execTar(args: string[]): Promise<void> { | ||||||
|     try { |     try { | ||||||
|         await exec(`"${await getTarPath()}"`, args); |         await exec(`"${await getTarPath(args)}"`, args); | ||||||
|     } catch (error) { |     } catch (error) { | ||||||
|         const IS_WINDOWS = process.platform === "win32"; |  | ||||||
|         if (IS_WINDOWS) { |  | ||||||
|             throw new Error( |  | ||||||
|                 `Tar failed with error: ${error?.message}. Ensure BSD tar is installed and on the PATH.` |  | ||||||
|             ); |  | ||||||
|         } |  | ||||||
|         throw new Error(`Tar failed with error: ${error?.message}`); |         throw new Error(`Tar failed with error: ${error?.message}`); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -34,7 +49,13 @@ export async function extractTar( | |||||||
| ): Promise<void> { | ): Promise<void> { | ||||||
|     // Create directory to extract tar into
 |     // Create directory to extract tar into
 | ||||||
|     await io.mkdirP(targetDirectory); |     await io.mkdirP(targetDirectory); | ||||||
|     const args = ["-xz", "-f", archivePath, "-C", targetDirectory]; |     const args = [ | ||||||
|  |         "-xz", | ||||||
|  |         "-f", | ||||||
|  |         archivePath?.replace(/\\/g, "/"), | ||||||
|  |         "-C", | ||||||
|  |         targetDirectory?.replace(/\\/g, "/") | ||||||
|  |     ]; | ||||||
|     await execTar(args); |     await execTar(args); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -42,6 +63,13 @@ export async function createTar( | |||||||
|     archivePath: string, |     archivePath: string, | ||||||
|     sourceDirectory: string |     sourceDirectory: string | ||||||
| ): Promise<void> { | ): Promise<void> { | ||||||
|     const args = ["-cz", "-f", archivePath, "-C", sourceDirectory, "."]; |     const args = [ | ||||||
|  |         "-cz", | ||||||
|  |         "-f", | ||||||
|  |         archivePath?.replace(/\\/g, "/"), | ||||||
|  |         "-C", | ||||||
|  |         sourceDirectory?.replace(/\\/g, "/"), | ||||||
|  |         "." | ||||||
|  |     ]; | ||||||
|     await execTar(args); |     await execTar(args); | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user