Compare commits
7 Commits
v1.1.2
...
2a973a0f4e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a973a0f4e | ||
|
|
cbbb8b4d4f | ||
|
|
5a0add1806 | ||
|
|
9fe7ad8b07 | ||
|
|
7c7d003bbb | ||
|
|
96e5a46c57 | ||
|
|
84e606dfac |
@@ -2,6 +2,8 @@ import * as exec from "@actions/exec";
|
|||||||
import * as io from "@actions/io";
|
import * as io from "@actions/io";
|
||||||
import * as tar from "../src/tar";
|
import * as tar from "../src/tar";
|
||||||
|
|
||||||
|
import fs = require("fs");
|
||||||
|
|
||||||
jest.mock("@actions/exec");
|
jest.mock("@actions/exec");
|
||||||
jest.mock("@actions/io");
|
jest.mock("@actions/io");
|
||||||
|
|
||||||
@@ -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,37 @@ test("extract tar", async () => {
|
|||||||
expect(execMock).toHaveBeenCalledWith(`"${tarPath}"`, [
|
expect(execMock).toHaveBeenCalledWith(`"${tarPath}"`, [
|
||||||
"-xz",
|
"-xz",
|
||||||
"-f",
|
"-f",
|
||||||
archivePath,
|
IS_WINDOWS ? archivePath.replace(/\\/g, "/") : archivePath,
|
||||||
"-C",
|
"-C",
|
||||||
targetDirectory
|
IS_WINDOWS ? targetDirectory?.replace(/\\/g, "/") : targetDirectory
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("create tar", async () => {
|
test("extract GNU tar", async () => {
|
||||||
|
const IS_WINDOWS = process.platform === "win32";
|
||||||
|
if (IS_WINDOWS) {
|
||||||
|
jest.spyOn(fs, "existsSync").mockReturnValueOnce(false);
|
||||||
|
jest.spyOn(tar, "isGnuTar").mockReturnValue(Promise.resolve(true));
|
||||||
|
|
||||||
|
const execMock = jest.spyOn(exec, "exec");
|
||||||
|
const archivePath = `${process.env["windir"]}\\fakepath\\cache.tar`;
|
||||||
|
const targetDirectory = "~/.npm/cache";
|
||||||
|
|
||||||
|
await tar.extractTar(archivePath, targetDirectory);
|
||||||
|
|
||||||
|
expect(execMock).toHaveBeenCalledTimes(2);
|
||||||
|
expect(execMock).toHaveBeenLastCalledWith(`"tar"`, [
|
||||||
|
"-xz",
|
||||||
|
"-f",
|
||||||
|
archivePath.replace(/\\/g, "/"),
|
||||||
|
"-C",
|
||||||
|
targetDirectory?.replace(/\\/g, "/"),
|
||||||
|
"--force-local"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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 +78,9 @@ test("create tar", async () => {
|
|||||||
expect(execMock).toHaveBeenCalledWith(`"${tarPath}"`, [
|
expect(execMock).toHaveBeenCalledWith(`"${tarPath}"`, [
|
||||||
"-cz",
|
"-cz",
|
||||||
"-f",
|
"-f",
|
||||||
archivePath,
|
IS_WINDOWS ? archivePath.replace(/\\/g, "/") : archivePath,
|
||||||
"-C",
|
"-C",
|
||||||
sourceDirectory,
|
IS_WINDOWS ? sourceDirectory?.replace(/\\/g, "/") : sourceDirectory,
|
||||||
"."
|
"."
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|||||||
64
dist/restore/index.js
vendored
64
dist/restore/index.js
vendored
@@ -1256,6 +1256,7 @@ const fs = __importStar(__webpack_require__(747));
|
|||||||
const auth_1 = __webpack_require__(226);
|
const auth_1 = __webpack_require__(226);
|
||||||
const http_client_1 = __webpack_require__(539);
|
const http_client_1 = __webpack_require__(539);
|
||||||
const utils = __importStar(__webpack_require__(443));
|
const utils = __importStar(__webpack_require__(443));
|
||||||
|
const constants_1 = __webpack_require__(694);
|
||||||
function isSuccessStatusCode(statusCode) {
|
function isSuccessStatusCode(statusCode) {
|
||||||
if (!statusCode) {
|
if (!statusCode) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1339,7 +1340,24 @@ function downloadCache(archiveLocation, archivePath) {
|
|||||||
const stream = fs.createWriteStream(archivePath);
|
const stream = fs.createWriteStream(archivePath);
|
||||||
const httpClient = new http_client_1.HttpClient("actions/cache");
|
const httpClient = new http_client_1.HttpClient("actions/cache");
|
||||||
const downloadResponse = yield httpClient.get(archiveLocation);
|
const downloadResponse = yield httpClient.get(archiveLocation);
|
||||||
|
// Abort download if no traffic received over the socket.
|
||||||
|
downloadResponse.message.socket.setTimeout(constants_1.SocketTimeout, () => {
|
||||||
|
downloadResponse.message.destroy();
|
||||||
|
core.debug(`Aborting download, socket timed out after ${constants_1.SocketTimeout} ms`);
|
||||||
|
});
|
||||||
yield pipeResponseToStream(downloadResponse, stream);
|
yield pipeResponseToStream(downloadResponse, stream);
|
||||||
|
// Validate download size.
|
||||||
|
const contentLengthHeader = downloadResponse.message.headers["content-length"];
|
||||||
|
if (contentLengthHeader) {
|
||||||
|
const expectedLength = parseInt(contentLengthHeader);
|
||||||
|
const actualLength = utils.getArchiveFileSize(archivePath);
|
||||||
|
if (actualLength != expectedLength) {
|
||||||
|
throw new Error(`Incomplete download. Expected file size: ${expectedLength}, actual file size: ${actualLength}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
core.debug("Unable to validate download, no Content-Length header");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.downloadCache = downloadCache;
|
exports.downloadCache = downloadCache;
|
||||||
@@ -1647,6 +1665,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const core = __importStar(__webpack_require__(470));
|
const core = __importStar(__webpack_require__(470));
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
const glob = __importStar(__webpack_require__(281));
|
||||||
|
>>>>>>> 9bb13c7... Fix lint issue, build .js files
|
||||||
const io = __importStar(__webpack_require__(1));
|
const io = __importStar(__webpack_require__(1));
|
||||||
const fs = __importStar(__webpack_require__(747));
|
const fs = __importStar(__webpack_require__(747));
|
||||||
const os = __importStar(__webpack_require__(87));
|
const os = __importStar(__webpack_require__(87));
|
||||||
@@ -2022,6 +2044,12 @@ class HttpClientResponse {
|
|||||||
this.message.on('data', (chunk) => {
|
this.message.on('data', (chunk) => {
|
||||||
output = Buffer.concat([output, chunk]);
|
output = Buffer.concat([output, chunk]);
|
||||||
});
|
});
|
||||||
|
this.message.on('aborted', () => {
|
||||||
|
reject("Request was aborted or closed prematurely");
|
||||||
|
});
|
||||||
|
this.message.on('timeout', (socket) => {
|
||||||
|
reject("Request timed out");
|
||||||
|
});
|
||||||
this.message.on('end', () => {
|
this.message.on('end', () => {
|
||||||
resolve(output.toString());
|
resolve(output.toString());
|
||||||
});
|
});
|
||||||
@@ -2143,6 +2171,7 @@ class HttpClient {
|
|||||||
let response;
|
let response;
|
||||||
while (numTries < maxTries) {
|
while (numTries < maxTries) {
|
||||||
response = await this.requestRaw(info, data);
|
response = await this.requestRaw(info, data);
|
||||||
|
|
||||||
// Check if it's an authentication challenge
|
// Check if it's an authentication challenge
|
||||||
if (response && response.message && response.message.statusCode === HttpCodes.Unauthorized) {
|
if (response && response.message && response.message.statusCode === HttpCodes.Unauthorized) {
|
||||||
let authenticationHandler;
|
let authenticationHandler;
|
||||||
@@ -2721,6 +2750,10 @@ var Events;
|
|||||||
Events["Push"] = "push";
|
Events["Push"] = "push";
|
||||||
Events["PullRequest"] = "pull_request";
|
Events["PullRequest"] = "pull_request";
|
||||||
})(Events = exports.Events || (exports.Events = {}));
|
})(Events = exports.Events || (exports.Events = {}));
|
||||||
|
// Socket timeout in milliseconds during download. If no traffic is received
|
||||||
|
// over the socket during this period, the socket is destroyed and the download
|
||||||
|
// is aborted.
|
||||||
|
exports.SocketTimeout = 5000;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -2928,10 +2961,30 @@ 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);
|
||||||
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) {
|
||||||
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,6 +2993,9 @@ 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);
|
||||||
});
|
});
|
||||||
@@ -2951,11 +3007,7 @@ function execTar(args) {
|
|||||||
yield exec_1.exec(`"${yield getTarPath()}"`, args);
|
yield exec_1.exec(`"${yield getTarPath()}"`, args);
|
||||||
}
|
}
|
||||||
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}`);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
42
dist/save/index.js
vendored
42
dist/save/index.js
vendored
@@ -1339,7 +1339,24 @@ function downloadCache(archiveLocation, archivePath) {
|
|||||||
const stream = fs.createWriteStream(archivePath);
|
const stream = fs.createWriteStream(archivePath);
|
||||||
const httpClient = new http_client_1.HttpClient("actions/cache");
|
const httpClient = new http_client_1.HttpClient("actions/cache");
|
||||||
const downloadResponse = yield httpClient.get(archiveLocation);
|
const downloadResponse = yield httpClient.get(archiveLocation);
|
||||||
|
// Abort download if no traffic received over the socket.
|
||||||
|
downloadResponse.message.socket.setTimeout(constants_1.SocketTimeout, () => {
|
||||||
|
downloadResponse.message.destroy();
|
||||||
|
core.debug(`Aborting download, socket timed out after ${constants_1.SocketTimeout} ms`);
|
||||||
|
});
|
||||||
yield pipeResponseToStream(downloadResponse, stream);
|
yield pipeResponseToStream(downloadResponse, stream);
|
||||||
|
// Validate download size.
|
||||||
|
const contentLengthHeader = downloadResponse.message.headers["content-length"];
|
||||||
|
if (contentLengthHeader) {
|
||||||
|
const expectedLength = parseInt(contentLengthHeader);
|
||||||
|
const actualLength = utils.getArchiveFileSize(archivePath);
|
||||||
|
if (actualLength != expectedLength) {
|
||||||
|
throw new Error(`Incomplete download. Expected file size: ${expectedLength}, actual file size: ${actualLength}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
core.debug("Unable to validate download, no Content-Length header");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.downloadCache = downloadCache;
|
exports.downloadCache = downloadCache;
|
||||||
@@ -1647,6 +1664,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const core = __importStar(__webpack_require__(470));
|
const core = __importStar(__webpack_require__(470));
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
const glob = __importStar(__webpack_require__(281));
|
||||||
|
>>>>>>> 9bb13c7... Fix lint issue, build .js files
|
||||||
const io = __importStar(__webpack_require__(1));
|
const io = __importStar(__webpack_require__(1));
|
||||||
const fs = __importStar(__webpack_require__(747));
|
const fs = __importStar(__webpack_require__(747));
|
||||||
const os = __importStar(__webpack_require__(87));
|
const os = __importStar(__webpack_require__(87));
|
||||||
@@ -2022,6 +2043,12 @@ class HttpClientResponse {
|
|||||||
this.message.on('data', (chunk) => {
|
this.message.on('data', (chunk) => {
|
||||||
output = Buffer.concat([output, chunk]);
|
output = Buffer.concat([output, chunk]);
|
||||||
});
|
});
|
||||||
|
this.message.on('aborted', () => {
|
||||||
|
reject("Request was aborted or closed prematurely");
|
||||||
|
});
|
||||||
|
this.message.on('timeout', (socket) => {
|
||||||
|
reject("Request timed out");
|
||||||
|
});
|
||||||
this.message.on('end', () => {
|
this.message.on('end', () => {
|
||||||
resolve(output.toString());
|
resolve(output.toString());
|
||||||
});
|
});
|
||||||
@@ -2143,6 +2170,7 @@ class HttpClient {
|
|||||||
let response;
|
let response;
|
||||||
while (numTries < maxTries) {
|
while (numTries < maxTries) {
|
||||||
response = await this.requestRaw(info, data);
|
response = await this.requestRaw(info, data);
|
||||||
|
|
||||||
// Check if it's an authentication challenge
|
// Check if it's an authentication challenge
|
||||||
if (response && response.message && response.message.statusCode === HttpCodes.Unauthorized) {
|
if (response && response.message && response.message.statusCode === HttpCodes.Unauthorized) {
|
||||||
let authenticationHandler;
|
let authenticationHandler;
|
||||||
@@ -2802,6 +2830,10 @@ var Events;
|
|||||||
Events["Push"] = "push";
|
Events["Push"] = "push";
|
||||||
Events["PullRequest"] = "pull_request";
|
Events["PullRequest"] = "pull_request";
|
||||||
})(Events = exports.Events || (exports.Events = {}));
|
})(Events = exports.Events || (exports.Events = {}));
|
||||||
|
// Socket timeout in milliseconds during download. If no traffic is received
|
||||||
|
// over the socket during this period, the socket is destroyed and the download
|
||||||
|
// is aborted.
|
||||||
|
exports.SocketTimeout = 5000;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -2909,6 +2941,7 @@ 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);
|
||||||
@@ -2921,6 +2954,9 @@ 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);
|
||||||
});
|
});
|
||||||
@@ -2932,11 +2968,7 @@ function execTar(args) {
|
|||||||
yield exec_1.exec(`"${yield getTarPath()}"`, args);
|
yield exec_1.exec(`"${yield getTarPath()}"`, args);
|
||||||
}
|
}
|
||||||
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}`);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import {
|
|||||||
IRequestOptions,
|
IRequestOptions,
|
||||||
ITypedResponse
|
ITypedResponse
|
||||||
} from "@actions/http-client/interfaces";
|
} from "@actions/http-client/interfaces";
|
||||||
|
|
||||||
|
import { SocketTimeout } from "./constants";
|
||||||
import {
|
import {
|
||||||
ArtifactCacheEntry,
|
ArtifactCacheEntry,
|
||||||
CommitCacheRequest,
|
CommitCacheRequest,
|
||||||
@@ -123,7 +125,33 @@ export async function downloadCache(
|
|||||||
const stream = fs.createWriteStream(archivePath);
|
const stream = fs.createWriteStream(archivePath);
|
||||||
const httpClient = new HttpClient("actions/cache");
|
const httpClient = new HttpClient("actions/cache");
|
||||||
const downloadResponse = await httpClient.get(archiveLocation);
|
const downloadResponse = await httpClient.get(archiveLocation);
|
||||||
|
|
||||||
|
// Abort download if no traffic received over the socket.
|
||||||
|
downloadResponse.message.socket.setTimeout(SocketTimeout, () => {
|
||||||
|
downloadResponse.message.destroy();
|
||||||
|
core.debug(
|
||||||
|
`Aborting download, socket timed out after ${SocketTimeout} ms`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
await pipeResponseToStream(downloadResponse, stream);
|
await pipeResponseToStream(downloadResponse, stream);
|
||||||
|
|
||||||
|
// Validate download size.
|
||||||
|
const contentLengthHeader =
|
||||||
|
downloadResponse.message.headers["content-length"];
|
||||||
|
|
||||||
|
if (contentLengthHeader) {
|
||||||
|
const expectedLength = parseInt(contentLengthHeader);
|
||||||
|
const actualLength = utils.getArchiveFileSize(archivePath);
|
||||||
|
|
||||||
|
if (actualLength != expectedLength) {
|
||||||
|
throw new Error(
|
||||||
|
`Incomplete download. Expected file size: ${expectedLength}, actual file size: ${actualLength}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
core.debug("Unable to validate download, no Content-Length header");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reserve Cache
|
// Reserve Cache
|
||||||
|
|||||||
@@ -18,3 +18,8 @@ export enum Events {
|
|||||||
Push = "push",
|
Push = "push",
|
||||||
PullRequest = "pull_request"
|
PullRequest = "pull_request"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Socket timeout in milliseconds during download. If no traffic is received
|
||||||
|
// over the socket during this period, the socket is destroyed and the download
|
||||||
|
// is aborted.
|
||||||
|
export const SocketTimeout = 5000;
|
||||||
|
|||||||
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 (await 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(new RegExp("\\" + path.sep, "g"), "/"),
|
||||||
|
"-C",
|
||||||
|
targetDirectory.replace(new RegExp("\\" + path.sep, "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(new RegExp("\\" + path.sep, "g"), "/"),
|
||||||
|
"-C",
|
||||||
|
sourceDirectory.replace(new RegExp("\\" + path.sep, "g"), "/"),
|
||||||
|
"."
|
||||||
|
];
|
||||||
await execTar(args);
|
await execTar(args);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user