diff --git a/lib/codeql.js b/lib/codeql.js index b9e5a0705..79bef36dd 100644 --- a/lib/codeql.js +++ b/lib/codeql.js @@ -21,6 +21,8 @@ const globalutil = __importStar(require("util")); const v4_1 = __importDefault(require("uuid/v4")); const api = __importStar(require("./api-client")); const defaults = __importStar(require("./defaults.json")); // Referenced from codeql-action-sync-tool! +const error_matcher_1 = require("./error-matcher"); +const toolrunner_error_catcher_1 = require("./toolrunner-error-catcher"); const util = __importStar(require("./util")); /** * Stores the CodeQL object, and is populated by `setupCodeQL` or `getCodeQL`. @@ -318,22 +320,22 @@ function getCodeQLForCmd(cmd) { const ext = process.platform === "win32" ? ".cmd" : ".sh"; const traceCommand = path.resolve(JSON.parse(extractorPath), "tools", `autobuild${ext}`); // Run trace command - await new toolrunnner.ToolRunner(cmd, [ + await toolrunner_error_catcher_1.toolrunnerErrorCatcher(cmd, [ "database", "trace-command", ...getExtraOptionsFromEnv(["database", "trace-command"]), databasePath, "--", traceCommand, - ]).exec(); + ], error_matcher_1.errorMatchers); }, async finalizeDatabase(databasePath) { - await new toolrunnner.ToolRunner(cmd, [ + await toolrunner_error_catcher_1.toolrunnerErrorCatcher(cmd, [ "database", "finalize", ...getExtraOptionsFromEnv(["database", "finalize"]), databasePath, - ]).exec(); + ], error_matcher_1.errorMatchers); }, async resolveQueries(queries, extraSearchPath) { const codeqlArgs = [ diff --git a/lib/codeql.js.map b/lib/codeql.js.map index a42fc6b81..6e38f30f3 100644 --- a/lib/codeql.js.map +++ b/lib/codeql.js.map @@ -1 +1 @@ -{"version":3,"file":"codeql.js","sourceRoot":"","sources":["../src/codeql.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"codeql.js","sourceRoot":"","sources":["../src/codeql.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/lib/error-matcher.js b/lib/error-matcher.js new file mode 100644 index 000000000..5d13441d1 --- /dev/null +++ b/lib/error-matcher.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +// exported only for testing purposes +exports.namedMatchersForTesting = { + /* + In due course it may be possible to remove the regex, if/when javascript also exits with code 32. + */ + noSourceCodeFound: { + exitCode: 32, + outputRegex: new RegExp("No JavaScript or TypeScript code found\\."), + message: "No code found during the build. Please see:\n" + + "https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/troubleshooting-code-scanning#no-code-found-during-the-build", + }, +}; +// we collapse the matches into an array for use in execErrorCatcher +exports.errorMatchers = Object.values(exports.namedMatchersForTesting); +//# sourceMappingURL=error-matcher.js.map \ No newline at end of file diff --git a/lib/error-matcher.js.map b/lib/error-matcher.js.map new file mode 100644 index 000000000..48bd956af --- /dev/null +++ b/lib/error-matcher.js.map @@ -0,0 +1 @@ +{"version":3,"file":"error-matcher.js","sourceRoot":"","sources":["../src/error-matcher.ts"],"names":[],"mappings":";;AAQA,qCAAqC;AACxB,QAAA,uBAAuB,GAAoC;IACtE;;MAEE;IACF,iBAAiB,EAAE;QACjB,QAAQ,EAAE,EAAE;QACZ,WAAW,EAAE,IAAI,MAAM,CAAC,2CAA2C,CAAC;QACpE,OAAO,EACL,+CAA+C;YAC/C,yJAAyJ;KAC5J;CACF,CAAC;AAEF,oEAAoE;AACvD,QAAA,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,+BAAuB,CAAC,CAAC"} \ No newline at end of file diff --git a/lib/error-matcher.test.js b/lib/error-matcher.test.js new file mode 100644 index 000000000..c81c304bc --- /dev/null +++ b/lib/error-matcher.test.js @@ -0,0 +1,29 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const ava_1 = __importDefault(require("ava")); +const error_matcher_1 = require("./error-matcher"); +/* +NB We test the regexes for all the matchers against example log output snippets. +*/ +ava_1.default("noSourceCodeFound matches against example javascript output", async (t) => { + t.assert(testErrorMatcher("noSourceCodeFound", ` + 2020-09-07T17:39:53.9050522Z [2020-09-07 17:39:53] [build] Done extracting /opt/hostedtoolcache/CodeQL/0.0.0-20200630/x64/codeql/javascript/tools/data/externs/web/ie_vml.js (3 ms) + 2020-09-07T17:39:53.9051849Z [2020-09-07 17:39:53] [build-err] No JavaScript or TypeScript code found. + 2020-09-07T17:39:53.9052444Z [2020-09-07 17:39:53] [build-err] No JavaScript or TypeScript code found. + 2020-09-07T17:39:53.9251124Z [2020-09-07 17:39:53] [ERROR] Spawned process exited abnormally (code 255; tried to run: [/opt/hostedtoolcache/CodeQL/0.0.0-20200630/x64/codeql/javascript/tools/autobuild.sh]) + `)); +}); +function testErrorMatcher(matcherName, logSample) { + if (!(matcherName in error_matcher_1.namedMatchersForTesting)) { + throw new Error(`Unknown matcher ${matcherName}`); + } + const regex = error_matcher_1.namedMatchersForTesting[matcherName].outputRegex; + if (regex === undefined) { + throw new Error(`Cannot test matcher ${matcherName} with null regex`); + } + return regex.test(logSample); +} +//# sourceMappingURL=error-matcher.test.js.map \ No newline at end of file diff --git a/lib/error-matcher.test.js.map b/lib/error-matcher.test.js.map new file mode 100644 index 000000000..4c99de6c8 --- /dev/null +++ b/lib/error-matcher.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"error-matcher.test.js","sourceRoot":"","sources":["../src/error-matcher.test.ts"],"names":[],"mappings":";;;;;AAAA,8CAAuB;AAEvB,mDAA0D;AAE1D;;EAEE;AAEF,aAAI,CAAC,6DAA6D,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC9E,CAAC,CAAC,MAAM,CACN,gBAAgB,CACd,mBAAmB,EACnB;;;;;GAKH,CACE,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,SAAS,gBAAgB,CAAC,WAAmB,EAAE,SAAiB;IAC9D,IAAI,CAAC,CAAC,WAAW,IAAI,uCAAuB,CAAC,EAAE;QAC7C,MAAM,IAAI,KAAK,CAAC,mBAAmB,WAAW,EAAE,CAAC,CAAC;KACnD;IACD,MAAM,KAAK,GAAG,uCAAuB,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC;IAC/D,IAAI,KAAK,KAAK,SAAS,EAAE;QACvB,MAAM,IAAI,KAAK,CAAC,uBAAuB,WAAW,kBAAkB,CAAC,CAAC;KACvE;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC"} \ No newline at end of file diff --git a/lib/toolrunner-error-catcher.js b/lib/toolrunner-error-catcher.js new file mode 100644 index 000000000..73874bcc5 --- /dev/null +++ b/lib/toolrunner-error-catcher.js @@ -0,0 +1,86 @@ +"use strict"; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const toolrunnner = __importStar(require("@actions/exec/lib/toolrunner")); +/** + * Wrapper for toolrunner.Toolrunner which checks for specific return code and/or regex matches in console output. + * Output will be streamed to the live console as well as captured for subsequent processing. + * Returns promise with return code + * + * @param commandLine command to execute + * @param args optional arguments for tool. Escaping is handled by the lib. + * @param matchers defines specific codes and/or regexes that should lead to return of a custom error + * @param options optional exec options. See ExecOptions + * @returns Promise exit code + */ +async function toolrunnerErrorCatcher(commandLine, args, matchers, options) { + var _a, _b, _c; + let stdout = ""; + let stderr = ""; + const listeners = { + stdout: (data) => { + var _a, _b; + stdout += data.toString(); + if (((_b = (_a = options) === null || _a === void 0 ? void 0 : _a.listeners) === null || _b === void 0 ? void 0 : _b.stdout) !== undefined) { + options.listeners.stdout(data); + } + else { + // if no stdout listener was originally defined then we match default behavior of Toolrunner + process.stdout.write(data); + } + }, + stderr: (data) => { + var _a, _b; + stderr += data.toString(); + if (((_b = (_a = options) === null || _a === void 0 ? void 0 : _a.listeners) === null || _b === void 0 ? void 0 : _b.stderr) !== undefined) { + options.listeners.stderr(data); + } + else { + // if no stderr listener was originally defined then we match default behavior of Toolrunner + process.stderr.write(data); + } + }, + }; + // we capture the original return code or error so that if no match is found we can duplicate the behavior + let returnState; + try { + returnState = await new toolrunnner.ToolRunner(commandLine, args, { + ...options, + listeners, + ignoreReturnCode: true, + }).exec(); + } + catch (e) { + returnState = e; + } + // if there is a zero return code then we do not apply the matchers + if (returnState === 0) + return returnState; + if (matchers) { + for (const matcher of matchers) { + if (matcher.exitCode === returnState || ((_a = matcher.outputRegex) === null || _a === void 0 ? void 0 : _a.test(stderr)) || ((_b = matcher.outputRegex) === null || _b === void 0 ? void 0 : _b.test(stdout))) { + throw new Error(matcher.message); + } + } + } + if (typeof returnState === "number") { + // only if we were instructed to ignore the return code do we ever return it non-zero + if ((_c = options) === null || _c === void 0 ? void 0 : _c.ignoreReturnCode) { + return returnState; + } + else { + throw new Error(`The process \'${commandLine}\' failed with exit code ${returnState}`); + } + } + else { + throw returnState; + } +} +exports.toolrunnerErrorCatcher = toolrunnerErrorCatcher; +//# sourceMappingURL=toolrunner-error-catcher.js.map \ No newline at end of file diff --git a/lib/toolrunner-error-catcher.js.map b/lib/toolrunner-error-catcher.js.map new file mode 100644 index 000000000..b40ca2110 --- /dev/null +++ b/lib/toolrunner-error-catcher.js.map @@ -0,0 +1 @@ +{"version":3,"file":"toolrunner-error-catcher.js","sourceRoot":"","sources":["../src/toolrunner-error-catcher.ts"],"names":[],"mappings":";;;;;;;;;AACA,0EAA4D;AAI5D;;;;;;;;;;GAUG;AACI,KAAK,UAAU,sBAAsB,CAC1C,WAAmB,EACnB,IAAe,EACf,QAAyB,EACzB,OAAwB;;IAExB,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,MAAM,SAAS,GAAG;QAChB,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;;YACvB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,aAAA,OAAO,0CAAE,SAAS,0CAAE,MAAM,MAAK,SAAS,EAAE;gBAC5C,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAChC;iBAAM;gBACL,4FAA4F;gBAC5F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;aAC5B;QACH,CAAC;QACD,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;;YACvB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,aAAA,OAAO,0CAAE,SAAS,0CAAE,MAAM,MAAK,SAAS,EAAE;gBAC5C,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAChC;iBAAM;gBACL,4FAA4F;gBAC5F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;aAC5B;QACH,CAAC;KACF,CAAC;IAEF,0GAA0G;IAC1G,IAAI,WAA2B,CAAC;IAChC,IAAI;QACF,WAAW,GAAG,MAAM,IAAI,WAAW,CAAC,UAAU,CAAC,WAAW,EAAE,IAAI,EAAE;YAChE,GAAG,OAAO;YACV,SAAS;YACT,gBAAgB,EAAE,IAAI;SACvB,CAAC,CAAC,IAAI,EAAE,CAAC;KACX;IAAC,OAAO,CAAC,EAAE;QACV,WAAW,GAAG,CAAC,CAAC;KACjB;IAED,mEAAmE;IACnE,IAAI,WAAW,KAAK,CAAC;QAAE,OAAO,WAAW,CAAC;IAE1C,IAAI,QAAQ,EAAE;QACZ,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;YAC9B,IACE,OAAO,CAAC,QAAQ,KAAK,WAAW,WAChC,OAAO,CAAC,WAAW,0CAAE,IAAI,CAAC,MAAM,EAAC,WACjC,OAAO,CAAC,WAAW,0CAAE,IAAI,CAAC,MAAM,EAAC,EACjC;gBACA,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;aAClC;SACF;KACF;IAED,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE;QACnC,qFAAqF;QACrF,UAAI,OAAO,0CAAE,gBAAgB,EAAE;YAC7B,OAAO,WAAW,CAAC;SACpB;aAAM;YACL,MAAM,IAAI,KAAK,CACb,iBAAiB,WAAW,4BAA4B,WAAW,EAAE,CACtE,CAAC;SACH;KACF;SAAM;QACL,MAAM,WAAW,CAAC;KACnB;AACH,CAAC;AArED,wDAqEC"} \ No newline at end of file diff --git a/lib/toolrunner-error-catcher.test.js b/lib/toolrunner-error-catcher.test.js new file mode 100644 index 000000000..606679eb4 --- /dev/null +++ b/lib/toolrunner-error-catcher.test.js @@ -0,0 +1,145 @@ +"use strict"; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const exec = __importStar(require("@actions/exec")); +const ava_1 = __importDefault(require("ava")); +const testing_utils_1 = require("./testing-utils"); +const toolrunner_error_catcher_1 = require("./toolrunner-error-catcher"); +testing_utils_1.setupTests(ava_1.default); +ava_1.default("matchers are never applied if non-error exit", async (t) => { + const testArgs = buildDummyArgs("foo bar\\nblort qux", "foo bar\\nblort qux", "", 0); + const matchers = [ + { exitCode: 123, outputRegex: new RegExp("foo bar"), message: "error!!!" }, + ]; + t.deepEqual(await exec.exec("node", testArgs), 0); + t.deepEqual(await toolrunner_error_catcher_1.toolrunnerErrorCatcher("node", testArgs, matchers), 0); +}); +ava_1.default("regex matchers are applied to stdout for non-zero exit code", async (t) => { + const testArgs = buildDummyArgs("foo bar\\nblort qux", "", "", 1); + const matchers = [ + { exitCode: 123, outputRegex: new RegExp("foo bar"), message: "🦄" }, + ]; + await t.throwsAsync(exec.exec("node", testArgs), { + instanceOf: Error, + message: "The process 'node' failed with exit code 1", + }); + await t.throwsAsync(toolrunner_error_catcher_1.toolrunnerErrorCatcher("node", testArgs, matchers), { + instanceOf: Error, + message: "🦄", + }); +}); +ava_1.default("regex matchers are applied to stderr for non-zero exit code", async (t) => { + const testArgs = buildDummyArgs("non matching string", "foo bar\\nblort qux", "", 1); + const matchers = [ + { exitCode: 123, outputRegex: new RegExp("foo bar"), message: "🦄" }, + ]; + await t.throwsAsync(exec.exec("node", testArgs), { + instanceOf: Error, + message: "The process 'node' failed with exit code 1", + }); + await t.throwsAsync(toolrunner_error_catcher_1.toolrunnerErrorCatcher("node", testArgs, matchers), { + instanceOf: Error, + message: "🦄", + }); +}); +ava_1.default("matcher returns correct error message when multiple matchers defined", async (t) => { + const testArgs = buildDummyArgs("non matching string", "foo bar\\nblort qux", "", 1); + const matchers = [ + { exitCode: 456, outputRegex: new RegExp("lorem ipsum"), message: "😩" }, + { exitCode: 123, outputRegex: new RegExp("foo bar"), message: "🦄" }, + { exitCode: 789, outputRegex: new RegExp("blah blah"), message: "🤦‍♂️" }, + ]; + await t.throwsAsync(exec.exec("node", testArgs), { + instanceOf: Error, + message: "The process 'node' failed with exit code 1", + }); + await t.throwsAsync(toolrunner_error_catcher_1.toolrunnerErrorCatcher("node", testArgs, matchers), { + instanceOf: Error, + message: "🦄", + }); +}); +ava_1.default("matcher returns first match to regex when multiple matches", async (t) => { + const testArgs = buildDummyArgs("non matching string", "foo bar\\nblort qux", "", 1); + const matchers = [ + { exitCode: 123, outputRegex: new RegExp("foo bar"), message: "🦄" }, + { exitCode: 789, outputRegex: new RegExp("blah blah"), message: "🤦‍♂️" }, + { exitCode: 987, outputRegex: new RegExp("foo bar"), message: "🚫" }, + ]; + await t.throwsAsync(exec.exec("node", testArgs), { + instanceOf: Error, + message: "The process 'node' failed with exit code 1", + }); + await t.throwsAsync(toolrunner_error_catcher_1.toolrunnerErrorCatcher("node", testArgs, matchers), { + instanceOf: Error, + message: "🦄", + }); +}); +ava_1.default("exit code matchers are applied", async (t) => { + const testArgs = buildDummyArgs("non matching string", "foo bar\\nblort qux", "", 123); + const matchers = [ + { + exitCode: 123, + outputRegex: new RegExp("this will not match"), + message: "🦄", + }, + ]; + await t.throwsAsync(exec.exec("node", testArgs), { + instanceOf: Error, + message: "The process 'node' failed with exit code 123", + }); + await t.throwsAsync(toolrunner_error_catcher_1.toolrunnerErrorCatcher("node", testArgs, matchers), { + instanceOf: Error, + message: "🦄", + }); +}); +ava_1.default("execErrorCatcher respects the ignoreReturnValue option", async (t) => { + const testArgs = buildDummyArgs("standard output", "error output", "", 199); + await t.throwsAsync(toolrunner_error_catcher_1.toolrunnerErrorCatcher("node", testArgs, [], { ignoreReturnCode: false }), { instanceOf: Error }); + t.deepEqual(await toolrunner_error_catcher_1.toolrunnerErrorCatcher("node", testArgs, [], { + ignoreReturnCode: true, + }), 199); +}); +ava_1.default("execErrorCatcher preserves behavior of provided listeners", async (t) => { + const stdoutExpected = "standard output"; + const stderrExpected = "error output"; + let stdoutActual = ""; + let stderrActual = ""; + const listeners = { + stdout: (data) => { + stdoutActual += data.toString(); + }, + stderr: (data) => { + stderrActual += data.toString(); + }, + }; + const testArgs = buildDummyArgs(stdoutExpected, stderrExpected, "", 0); + t.deepEqual(await toolrunner_error_catcher_1.toolrunnerErrorCatcher("node", testArgs, [], { + listeners, + }), 0); + t.deepEqual(stdoutActual, `${stdoutExpected}\n`); + t.deepEqual(stderrActual, `${stderrExpected}\n`); +}); +function buildDummyArgs(stdoutContents, stderrContents, desiredErrorMessage, desiredExitCode) { + let command = ""; + if (stdoutContents) + command += `console.log("${stdoutContents}");`; + if (stderrContents) + command += `console.error("${stderrContents}");`; + if (command.length === 0) + throw new Error("Must provide contents for either stdout or stderr"); + if (desiredErrorMessage) + command += `throw new Error("${desiredErrorMessage}");`; + if (desiredExitCode) + command += `process.exitCode = ${desiredExitCode};`; + return ["-e", command]; +} +//# sourceMappingURL=toolrunner-error-catcher.test.js.map \ No newline at end of file diff --git a/lib/toolrunner-error-catcher.test.js.map b/lib/toolrunner-error-catcher.test.js.map new file mode 100644 index 000000000..aad8fddac --- /dev/null +++ b/lib/toolrunner-error-catcher.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"toolrunner-error-catcher.test.js","sourceRoot":"","sources":["../src/toolrunner-error-catcher.test.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/src/codeql.ts b/src/codeql.ts index 400e90964..cc58587fe 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -11,8 +11,10 @@ import uuidV4 from "uuid/v4"; import * as api from "./api-client"; import * as defaults from "./defaults.json"; // Referenced from codeql-action-sync-tool! +import { errorMatchers } from "./error-matcher"; import { Language } from "./languages"; import { Logger } from "./logging"; +import { toolrunnerErrorCatcher } from "./toolrunner-error-catcher"; import * as util from "./util"; type Options = Array; @@ -505,22 +507,30 @@ function getCodeQLForCmd(cmd: string): CodeQL { ); // Run trace command - await new toolrunnner.ToolRunner(cmd, [ - "database", - "trace-command", - ...getExtraOptionsFromEnv(["database", "trace-command"]), - databasePath, - "--", - traceCommand, - ]).exec(); + await toolrunnerErrorCatcher( + cmd, + [ + "database", + "trace-command", + ...getExtraOptionsFromEnv(["database", "trace-command"]), + databasePath, + "--", + traceCommand, + ], + errorMatchers + ); }, async finalizeDatabase(databasePath: string) { - await new toolrunnner.ToolRunner(cmd, [ - "database", - "finalize", - ...getExtraOptionsFromEnv(["database", "finalize"]), - databasePath, - ]).exec(); + await toolrunnerErrorCatcher( + cmd, + [ + "database", + "finalize", + ...getExtraOptionsFromEnv(["database", "finalize"]), + databasePath, + ], + errorMatchers + ); }, async resolveQueries( queries: string[], diff --git a/src/codeql.ts.orig b/src/codeql.ts.orig new file mode 100644 index 000000000..227ab7dc5 --- /dev/null +++ b/src/codeql.ts.orig @@ -0,0 +1,676 @@ +<<<<<<< HEAD +import * as toolrunnner from '@actions/exec/lib/toolrunner'; +import * as http from '@actions/http-client'; +import { IHeaders } from '@actions/http-client/interfaces'; +import * as toolcache from '@actions/tool-cache'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as semver from 'semver'; +import * as stream from 'stream'; +import * as globalutil from 'util'; +import uuidV4 from 'uuid/v4'; + +import * as api from './api-client'; +import * as defaults from './defaults.json'; // Referenced from codeql-action-sync-tool! +import { errorMatchers} from './error-matcher'; +import { Language } from './languages'; +import { Logger } from './logging'; +import { toolrunnerErrorCatcher } from './toolrunner-error-catcher'; +import * as util from './util'; + +type Options = (string|number|boolean)[]; +======= +import * as toolrunnner from "@actions/exec/lib/toolrunner"; +import * as http from "@actions/http-client"; +import { IHeaders } from "@actions/http-client/interfaces"; +import * as toolcache from "@actions/tool-cache"; +import * as fs from "fs"; +import * as path from "path"; +import * as semver from "semver"; +import * as stream from "stream"; +import * as globalutil from "util"; +import uuidV4 from "uuid/v4"; + +import * as api from "./api-client"; +import * as defaults from "./defaults.json"; // Referenced from codeql-action-sync-tool! +import { Language } from "./languages"; +import { Logger } from "./logging"; +import * as util from "./util"; + +type Options = Array; +>>>>>>> main + +/** + * Extra command line options for the codeql commands. + */ +interface ExtraOptions { + "*"?: Options; + database?: { + "*"?: Options; + init?: Options; + "trace-command"?: Options; + analyze?: Options; + finalize?: Options; + }; + resolve?: { + "*"?: Options; + extractor?: Options; + queries?: Options; + }; +} + +export interface CodeQL { + /** + * Get the path of the CodeQL executable. + */ + getPath(): string; + /** + * Print version information about CodeQL. + */ + printVersion(): Promise; + /** + * Run 'codeql database trace-command' on 'tracer-env.js' and parse + * the result to get environment variables set by CodeQL. + */ + getTracerEnv(databasePath: string): Promise<{ [key: string]: string }>; + /** + * Run 'codeql database init'. + */ + databaseInit( + databasePath: string, + language: Language, + sourceRoot: string + ): Promise; + /** + * Runs the autobuilder for the given language. + */ + runAutobuild(language: Language): Promise; + /** + * Extract code for a scanned language using 'codeql database trace-command' + * and running the language extracter. + */ + extractScannedLanguage(database: string, language: Language): Promise; + /** + * Finalize a database using 'codeql database finalize'. + */ + finalizeDatabase(databasePath: string): Promise; + /** + * Run 'codeql resolve queries'. + */ + resolveQueries( + queries: string[], + extraSearchPath: string | undefined + ): Promise; + /** + * Run 'codeql database analyze'. + */ + databaseAnalyze( + databasePath: string, + sarifFile: string, + querySuite: string, + memoryFlag: string, + addSnippetsFlag: string, + threadsFlag: string + ): Promise; +} + +export interface ResolveQueriesOutput { + byLanguage: { + [language: string]: { + [queryPath: string]: {}; + }; + }; + noDeclaredLanguage: { + [queryPath: string]: {}; + }; + multipleDeclaredLanguages: { + [queryPath: string]: {}; + }; +} + +/** + * Stores the CodeQL object, and is populated by `setupCodeQL` or `getCodeQL`. + * Can be overridden in tests using `setCodeQL`. + */ +let cachedCodeQL: CodeQL | undefined = undefined; + +const CODEQL_BUNDLE_VERSION = defaults.bundleVersion; +const CODEQL_BUNDLE_NAME = "codeql-bundle.tar.gz"; +const CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action"; + +function getCodeQLActionRepository(mode: util.Mode): string { + if (mode !== "actions") { + return CODEQL_DEFAULT_ACTION_REPOSITORY; + } + + // Actions do not know their own repository name, + // so we currently use this hack to find the name based on where our files are. + // This can be removed once the change to the runner in https://github.com/actions/runner/pull/585 is deployed. + const runnerTemp = util.getRequiredEnvParam("RUNNER_TEMP"); + const actionsDirectory = path.join(path.dirname(runnerTemp), "_actions"); + const relativeScriptPath = path.relative(actionsDirectory, __filename); + // This handles the case where the Action does not come from an Action repository, + // e.g. our integration tests which use the Action code from the current checkout. + if ( + relativeScriptPath.startsWith("..") || + path.isAbsolute(relativeScriptPath) + ) { + return CODEQL_DEFAULT_ACTION_REPOSITORY; + } + const relativeScriptPathParts = relativeScriptPath.split(path.sep); + return `${relativeScriptPathParts[0]}/${relativeScriptPathParts[1]}`; +} + +async function getCodeQLBundleDownloadURL( + githubAuth: string, + githubUrl: string, + mode: util.Mode, + logger: Logger +): Promise { + const codeQLActionRepository = getCodeQLActionRepository(mode); + const potentialDownloadSources = [ + // This GitHub instance, and this Action. + [githubUrl, codeQLActionRepository], + // This GitHub instance, and the canonical Action. + [githubUrl, CODEQL_DEFAULT_ACTION_REPOSITORY], + // GitHub.com, and the canonical Action. + [util.GITHUB_DOTCOM_URL, CODEQL_DEFAULT_ACTION_REPOSITORY], + ]; + // We now filter out any duplicates. + // Duplicates will happen either because the GitHub instance is GitHub.com, or because the Action is not a fork. + const uniqueDownloadSources = potentialDownloadSources.filter( + (url, index, self) => index === self.indexOf(url) + ); + for (const downloadSource of uniqueDownloadSources) { + const [apiURL, repository] = downloadSource; + // If we've reached the final case, short-circuit the API check since we know the bundle exists and is public. + if ( + apiURL === util.GITHUB_DOTCOM_URL && + repository === CODEQL_DEFAULT_ACTION_REPOSITORY + ) { + break; + } + const [repositoryOwner, repositoryName] = repository.split("/"); + try { + const release = await api + .getApiClient(githubAuth, githubUrl) + .repos.getReleaseByTag({ + owner: repositoryOwner, + repo: repositoryName, + tag: CODEQL_BUNDLE_VERSION, + }); + for (const asset of release.data.assets) { + if (asset.name === CODEQL_BUNDLE_NAME) { + logger.info( + `Found CodeQL bundle in ${downloadSource[1]} on ${downloadSource[0]} with URL ${asset.url}.` + ); + return asset.url; + } + } + } catch (e) { + logger.info( + `Looked for CodeQL bundle in ${downloadSource[1]} on ${downloadSource[0]} but got error ${e}.` + ); + } + } + return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${CODEQL_BUNDLE_VERSION}/${CODEQL_BUNDLE_NAME}`; +} + +// We have to download CodeQL manually because the toolcache doesn't support Accept headers. +// This can be removed once https://github.com/actions/toolkit/pull/530 is merged and released. +async function toolcacheDownloadTool( + url: string, + headers: IHeaders | undefined, + tempDir: string, + logger: Logger +): Promise { + const client = new http.HttpClient("CodeQL Action"); + const dest = path.join(tempDir, uuidV4()); + const response: http.HttpClientResponse = await client.get(url, headers); + if (response.message.statusCode !== 200) { + logger.info( + `Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})` + ); + throw new Error(`Unexpected HTTP response: ${response.message.statusCode}`); + } + const pipeline = globalutil.promisify(stream.pipeline); + fs.mkdirSync(path.dirname(dest), { recursive: true }); + await pipeline(response.message, fs.createWriteStream(dest)); + return dest; +} + +export async function setupCodeQL( + codeqlURL: string | undefined, + githubAuth: string, + githubUrl: string, + tempDir: string, + toolsDir: string, + mode: util.Mode, + logger: Logger +): Promise { + // Setting these two env vars makes the toolcache code safe to use outside, + // of actions but this is obviously not a great thing we're doing and it would + // be better to write our own implementation to use outside of actions. + process.env["RUNNER_TEMP"] = tempDir; + process.env["RUNNER_TOOL_CACHE"] = toolsDir; + + try { + const codeqlURLVersion = getCodeQLURLVersion( + codeqlURL || `/${CODEQL_BUNDLE_VERSION}/`, + logger + ); + + let codeqlFolder = toolcache.find("CodeQL", codeqlURLVersion); + if (codeqlFolder) { + logger.debug(`CodeQL found in cache ${codeqlFolder}`); + } else { + if (!codeqlURL) { + codeqlURL = await getCodeQLBundleDownloadURL( + githubAuth, + githubUrl, + mode, + logger + ); + } + + const headers: IHeaders = { accept: "application/octet-stream" }; + // We only want to provide an authorization header if we are downloading + // from the same GitHub instance the Action is running on. + // This avoids leaking Enterprise tokens to dotcom. + if (codeqlURL.startsWith(`${githubUrl}/`)) { + logger.debug("Downloading CodeQL bundle with token."); + headers.authorization = `token ${githubAuth}`; + } else { + logger.debug("Downloading CodeQL bundle without token."); + } + logger.info( + `Downloading CodeQL tools from ${codeqlURL}. This may take a while.` + ); + const codeqlPath = await toolcacheDownloadTool( + codeqlURL, + headers, + tempDir, + logger + ); + logger.debug(`CodeQL bundle download to ${codeqlPath} complete.`); + + const codeqlExtracted = await toolcache.extractTar(codeqlPath); + codeqlFolder = await toolcache.cacheDir( + codeqlExtracted, + "CodeQL", + codeqlURLVersion + ); + } + + let codeqlCmd = path.join(codeqlFolder, "codeql", "codeql"); + if (process.platform === "win32") { + codeqlCmd += ".exe"; + } else if (process.platform !== "linux" && process.platform !== "darwin") { + throw new Error(`Unsupported platform: ${process.platform}`); + } + + cachedCodeQL = getCodeQLForCmd(codeqlCmd); + return cachedCodeQL; + } catch (e) { + logger.error(e); + throw new Error("Unable to download and extract CodeQL CLI"); + } +} + +export function getCodeQLURLVersion(url: string, logger: Logger): string { + const match = url.match(/\/codeql-bundle-(.*)\//); + if (match === null || match.length < 2) { + throw new Error( + `Malformed tools url: ${url}. Version could not be inferred` + ); + } + + let version = match[1]; + + if (!semver.valid(version)) { + logger.debug( + `Bundle version ${version} is not in SemVer format. Will treat it as pre-release 0.0.0-${version}.` + ); + version = `0.0.0-${version}`; + } + + const s = semver.clean(version); + if (!s) { + throw new Error( + `Malformed tools url ${url}. Version should be in SemVer format but have ${version} instead` + ); + } + + return s; +} + +/** + * Use the CodeQL executable located at the given path. + */ +export function getCodeQL(cmd: string): CodeQL { + if (cachedCodeQL === undefined) { + cachedCodeQL = getCodeQLForCmd(cmd); + } + return cachedCodeQL; +} + +function resolveFunction( + partialCodeql: Partial, + methodName: string, + defaultImplementation?: T +): T { + if (typeof partialCodeql[methodName] !== "function") { + if (defaultImplementation !== undefined) { + return defaultImplementation; + } + const dummyMethod = () => { + throw new Error(`CodeQL ${methodName} method not correctly defined`); + }; + return dummyMethod as any; + } + return partialCodeql[methodName]; +} + +/** + * Set the functionality for CodeQL methods. Only for use in tests. + * + * Accepts a partial object and any undefined methods will be implemented + * to immediately throw an exception indicating which method is missing. + */ +export function setCodeQL(partialCodeql: Partial): CodeQL { + cachedCodeQL = { + getPath: resolveFunction(partialCodeql, "getPath", () => "/tmp/dummy-path"), + printVersion: resolveFunction(partialCodeql, "printVersion"), + getTracerEnv: resolveFunction(partialCodeql, "getTracerEnv"), + databaseInit: resolveFunction(partialCodeql, "databaseInit"), + runAutobuild: resolveFunction(partialCodeql, "runAutobuild"), + extractScannedLanguage: resolveFunction( + partialCodeql, + "extractScannedLanguage" + ), + finalizeDatabase: resolveFunction(partialCodeql, "finalizeDatabase"), + resolveQueries: resolveFunction(partialCodeql, "resolveQueries"), + databaseAnalyze: resolveFunction(partialCodeql, "databaseAnalyze"), + }; + return cachedCodeQL; +} + +/** + * Get the cached CodeQL object. Should only be used from tests. + * + * TODO: Work out a good way for tests to get this from the test context + * instead of having to have this method. + */ +export function getCachedCodeQL(): CodeQL { + if (cachedCodeQL === undefined) { + // Should never happen as setCodeQL is called by testing-utils.setupTests + throw new Error("cachedCodeQL undefined"); + } + return cachedCodeQL; +} + +function getCodeQLForCmd(cmd: string): CodeQL { + return { + getPath() { + return cmd; + }, + async printVersion() { + await new toolrunnner.ToolRunner(cmd, [ + "version", + "--format=json", + ]).exec(); + }, + async getTracerEnv(databasePath: string) { + // Write tracer-env.js to a temp location. + const tracerEnvJs = path.resolve( + databasePath, + "working", + "tracer-env.js" + ); + fs.mkdirSync(path.dirname(tracerEnvJs), { recursive: true }); + fs.writeFileSync( + tracerEnvJs, + ` + const fs = require('fs'); + const env = {}; + for (let entry of Object.entries(process.env)) { + const key = entry[0]; + const value = entry[1]; + if (typeof value !== 'undefined' && key !== '_' && !key.startsWith('JAVA_MAIN_CLASS_')) { + env[key] = value; + } + } + process.stdout.write(process.argv[2]); + fs.writeFileSync(process.argv[2], JSON.stringify(env), 'utf-8');` + ); + + const envFile = path.resolve(databasePath, "working", "env.tmp"); + await new toolrunnner.ToolRunner(cmd, [ + "database", + "trace-command", + databasePath, + ...getExtraOptionsFromEnv(["database", "trace-command"]), + process.execPath, + tracerEnvJs, + envFile, + ]).exec(); + return JSON.parse(fs.readFileSync(envFile, "utf-8")); + }, + async databaseInit( + databasePath: string, + language: Language, + sourceRoot: string + ) { + await new toolrunnner.ToolRunner(cmd, [ + "database", + "init", + databasePath, + `--language=${language}`, + `--source-root=${sourceRoot}`, + ...getExtraOptionsFromEnv(["database", "init"]), + ]).exec(); + }, + async runAutobuild(language: Language) { + const cmdName = + process.platform === "win32" ? "autobuild.cmd" : "autobuild.sh"; + const autobuildCmd = path.join( + path.dirname(cmd), + language, + "tools", + cmdName + ); + + // Update JAVA_TOOL_OPTIONS to contain '-Dhttp.keepAlive=false' + // This is because of an issue with Azure pipelines timing out connections after 4 minutes + // and Maven not properly handling closed connections + // Otherwise long build processes will timeout when pulling down Java packages + // https://developercommunity.visualstudio.com/content/problem/292284/maven-hosted-agent-connection-timeout.html + const javaToolOptions = process.env["JAVA_TOOL_OPTIONS"] || ""; + process.env["JAVA_TOOL_OPTIONS"] = [ + ...javaToolOptions.split(/\s+/), + "-Dhttp.keepAlive=false", + "-Dmaven.wagon.http.pool=false", + ].join(" "); + + await new toolrunnner.ToolRunner(autobuildCmd).exec(); + }, + async extractScannedLanguage(databasePath: string, language: Language) { + // Get extractor location + let extractorPath = ""; + await new toolrunnner.ToolRunner( + cmd, + [ + "resolve", + "extractor", + "--format=json", + `--language=${language}`, + ...getExtraOptionsFromEnv(["resolve", "extractor"]), + ], + { + silent: true, + listeners: { + stdout: (data) => { + extractorPath += data.toString(); + }, + stderr: (data) => { + process.stderr.write(data); + }, + }, + } + ).exec(); + + // Set trace command + const ext = process.platform === "win32" ? ".cmd" : ".sh"; + const traceCommand = path.resolve( + JSON.parse(extractorPath), + "tools", + `autobuild${ext}` + ); + + // Run trace command +<<<<<<< HEAD + await toolrunnerErrorCatcher( + cmd, [ + 'database', + 'trace-command', + ...getExtraOptionsFromEnv(['database', 'trace-command']), + databasePath, + '--', + traceCommand + ], + errorMatchers + ); + }, + finalizeDatabase: async function(databasePath: string) { + await toolrunnerErrorCatcher( + cmd, [ + 'database', + 'finalize', + ...getExtraOptionsFromEnv(['database', 'finalize']), + databasePath + ], + errorMatchers); +======= + await new toolrunnner.ToolRunner(cmd, [ + "database", + "trace-command", + ...getExtraOptionsFromEnv(["database", "trace-command"]), + databasePath, + "--", + traceCommand, + ]).exec(); + }, + async finalizeDatabase(databasePath: string) { + await new toolrunnner.ToolRunner(cmd, [ + "database", + "finalize", + ...getExtraOptionsFromEnv(["database", "finalize"]), + databasePath, + ]).exec(); +>>>>>>> main + }, + async resolveQueries( + queries: string[], + extraSearchPath: string | undefined + ) { + const codeqlArgs = [ + "resolve", + "queries", + ...queries, + "--format=bylanguage", + ...getExtraOptionsFromEnv(["resolve", "queries"]), + ]; + if (extraSearchPath !== undefined) { + codeqlArgs.push("--search-path", extraSearchPath); + } + let output = ""; + await new toolrunnner.ToolRunner(cmd, codeqlArgs, { + listeners: { + stdout: (data: Buffer) => { + output += data.toString(); + }, + }, + }).exec(); + + return JSON.parse(output); + }, + async databaseAnalyze( + databasePath: string, + sarifFile: string, + querySuite: string, + memoryFlag: string, + addSnippetsFlag: string, + threadsFlag: string + ) { + await new toolrunnner.ToolRunner(cmd, [ + "database", + "analyze", + memoryFlag, + threadsFlag, + databasePath, + "--format=sarif-latest", + `--output=${sarifFile}`, + addSnippetsFlag, + ...getExtraOptionsFromEnv(["database", "analyze"]), + querySuite, + ]).exec(); + }, + }; +} + +/** + * Gets the options for `path` of `options` as an array of extra option strings. + */ +function getExtraOptionsFromEnv(path: string[]) { + const options: ExtraOptions = util.getExtraOptionsEnvParam(); + return getExtraOptions(options, path, []); +} + +/** + * Gets the options for `path` of `options` as an array of extra option strings. + * + * - the special terminal step name '*' in `options` matches all path steps + * - throws an exception if this conversion is impossible. + */ +export /* exported for testing */ function getExtraOptions( + options: any, + path: string[], + pathInfo: string[] +): string[] { + /** + * Gets `options` as an array of extra option strings. + * + * - throws an exception mentioning `pathInfo` if this conversion is impossible. + */ + function asExtraOptions(options: any, pathInfo: string[]): string[] { + if (options === undefined) { + return []; + } + if (!Array.isArray(options)) { + const msg = `The extra options for '${pathInfo.join( + "." + )}' ('${JSON.stringify(options)}') are not in an array.`; + throw new Error(msg); + } + return options.map((o) => { + const t = typeof o; + if (t !== "string" && t !== "number" && t !== "boolean") { + const msg = `The extra option for '${pathInfo.join( + "." + )}' ('${JSON.stringify(o)}') is not a primitive value.`; + throw new Error(msg); + } + return `${o}`; + }); + } + const all = asExtraOptions(options?.["*"], pathInfo.concat("*")); + const specific = + path.length === 0 + ? asExtraOptions(options, pathInfo) + : getExtraOptions( + options?.[path[0]], + path?.slice(1), + pathInfo.concat(path[0]) + ); + return all.concat(specific); +} diff --git a/src/error-matcher.test.ts b/src/error-matcher.test.ts new file mode 100644 index 000000000..9d8e8a257 --- /dev/null +++ b/src/error-matcher.test.ts @@ -0,0 +1,32 @@ +import test from "ava"; + +import { namedMatchersForTesting } from "./error-matcher"; + +/* +NB We test the regexes for all the matchers against example log output snippets. +*/ + +test("noSourceCodeFound matches against example javascript output", async (t) => { + t.assert( + testErrorMatcher( + "noSourceCodeFound", + ` + 2020-09-07T17:39:53.9050522Z [2020-09-07 17:39:53] [build] Done extracting /opt/hostedtoolcache/CodeQL/0.0.0-20200630/x64/codeql/javascript/tools/data/externs/web/ie_vml.js (3 ms) + 2020-09-07T17:39:53.9051849Z [2020-09-07 17:39:53] [build-err] No JavaScript or TypeScript code found. + 2020-09-07T17:39:53.9052444Z [2020-09-07 17:39:53] [build-err] No JavaScript or TypeScript code found. + 2020-09-07T17:39:53.9251124Z [2020-09-07 17:39:53] [ERROR] Spawned process exited abnormally (code 255; tried to run: [/opt/hostedtoolcache/CodeQL/0.0.0-20200630/x64/codeql/javascript/tools/autobuild.sh]) + ` + ) + ); +}); + +function testErrorMatcher(matcherName: string, logSample: string): boolean { + if (!(matcherName in namedMatchersForTesting)) { + throw new Error(`Unknown matcher ${matcherName}`); + } + const regex = namedMatchersForTesting[matcherName].outputRegex; + if (regex === undefined) { + throw new Error(`Cannot test matcher ${matcherName} with null regex`); + } + return regex.test(logSample); +} diff --git a/src/error-matcher.ts b/src/error-matcher.ts new file mode 100644 index 000000000..ebbc5484d --- /dev/null +++ b/src/error-matcher.ts @@ -0,0 +1,24 @@ +// defines properties to match against the result of executed commands, +// and a custom error to return when a match is found +export interface ErrorMatcher { + exitCode?: number; // exit code of the run process + outputRegex?: RegExp; // pattern to match against either stdout or stderr + message: string; // the error message that will be thrown for a matching process +} + +// exported only for testing purposes +export const namedMatchersForTesting: { [key: string]: ErrorMatcher } = { + /* + In due course it may be possible to remove the regex, if/when javascript also exits with code 32. + */ + noSourceCodeFound: { + exitCode: 32, + outputRegex: new RegExp("No JavaScript or TypeScript code found\\."), + message: + "No code found during the build. Please see:\n" + + "https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/troubleshooting-code-scanning#no-code-found-during-the-build", + }, +}; + +// we collapse the matches into an array for use in execErrorCatcher +export const errorMatchers = Object.values(namedMatchersForTesting); diff --git a/src/toolrunner-error-catcher.test.ts b/src/toolrunner-error-catcher.test.ts new file mode 100644 index 000000000..700e01ecc --- /dev/null +++ b/src/toolrunner-error-catcher.test.ts @@ -0,0 +1,209 @@ +import * as exec from "@actions/exec"; +import test from "ava"; + +import { ErrorMatcher } from "./error-matcher"; +import { setupTests } from "./testing-utils"; +import { toolrunnerErrorCatcher } from "./toolrunner-error-catcher"; + +setupTests(test); + +test("matchers are never applied if non-error exit", async (t) => { + const testArgs = buildDummyArgs( + "foo bar\\nblort qux", + "foo bar\\nblort qux", + "", + 0 + ); + + const matchers: ErrorMatcher[] = [ + { exitCode: 123, outputRegex: new RegExp("foo bar"), message: "error!!!" }, + ]; + + t.deepEqual(await exec.exec("node", testArgs), 0); + + t.deepEqual(await toolrunnerErrorCatcher("node", testArgs, matchers), 0); +}); + +test("regex matchers are applied to stdout for non-zero exit code", async (t) => { + const testArgs = buildDummyArgs("foo bar\\nblort qux", "", "", 1); + + const matchers: ErrorMatcher[] = [ + { exitCode: 123, outputRegex: new RegExp("foo bar"), message: "🦄" }, + ]; + + await t.throwsAsync(exec.exec("node", testArgs), { + instanceOf: Error, + message: "The process 'node' failed with exit code 1", + }); + + await t.throwsAsync(toolrunnerErrorCatcher("node", testArgs, matchers), { + instanceOf: Error, + message: "🦄", + }); +}); + +test("regex matchers are applied to stderr for non-zero exit code", async (t) => { + const testArgs = buildDummyArgs( + "non matching string", + "foo bar\\nblort qux", + "", + 1 + ); + + const matchers: ErrorMatcher[] = [ + { exitCode: 123, outputRegex: new RegExp("foo bar"), message: "🦄" }, + ]; + + await t.throwsAsync(exec.exec("node", testArgs), { + instanceOf: Error, + message: "The process 'node' failed with exit code 1", + }); + + await t.throwsAsync(toolrunnerErrorCatcher("node", testArgs, matchers), { + instanceOf: Error, + message: "🦄", + }); +}); + +test("matcher returns correct error message when multiple matchers defined", async (t) => { + const testArgs = buildDummyArgs( + "non matching string", + "foo bar\\nblort qux", + "", + 1 + ); + + const matchers: ErrorMatcher[] = [ + { exitCode: 456, outputRegex: new RegExp("lorem ipsum"), message: "😩" }, + { exitCode: 123, outputRegex: new RegExp("foo bar"), message: "🦄" }, + { exitCode: 789, outputRegex: new RegExp("blah blah"), message: "🤦‍♂️" }, + ]; + + await t.throwsAsync(exec.exec("node", testArgs), { + instanceOf: Error, + message: "The process 'node' failed with exit code 1", + }); + + await t.throwsAsync(toolrunnerErrorCatcher("node", testArgs, matchers), { + instanceOf: Error, + message: "🦄", + }); +}); + +test("matcher returns first match to regex when multiple matches", async (t) => { + const testArgs = buildDummyArgs( + "non matching string", + "foo bar\\nblort qux", + "", + 1 + ); + + const matchers: ErrorMatcher[] = [ + { exitCode: 123, outputRegex: new RegExp("foo bar"), message: "🦄" }, + { exitCode: 789, outputRegex: new RegExp("blah blah"), message: "🤦‍♂️" }, + { exitCode: 987, outputRegex: new RegExp("foo bar"), message: "🚫" }, + ]; + + await t.throwsAsync(exec.exec("node", testArgs), { + instanceOf: Error, + message: "The process 'node' failed with exit code 1", + }); + + await t.throwsAsync(toolrunnerErrorCatcher("node", testArgs, matchers), { + instanceOf: Error, + message: "🦄", + }); +}); + +test("exit code matchers are applied", async (t) => { + const testArgs = buildDummyArgs( + "non matching string", + "foo bar\\nblort qux", + "", + 123 + ); + + const matchers: ErrorMatcher[] = [ + { + exitCode: 123, + outputRegex: new RegExp("this will not match"), + message: "🦄", + }, + ]; + + await t.throwsAsync(exec.exec("node", testArgs), { + instanceOf: Error, + message: "The process 'node' failed with exit code 123", + }); + + await t.throwsAsync(toolrunnerErrorCatcher("node", testArgs, matchers), { + instanceOf: Error, + message: "🦄", + }); +}); + +test("execErrorCatcher respects the ignoreReturnValue option", async (t) => { + const testArgs = buildDummyArgs("standard output", "error output", "", 199); + + await t.throwsAsync( + toolrunnerErrorCatcher("node", testArgs, [], { ignoreReturnCode: false }), + { instanceOf: Error } + ); + + t.deepEqual( + await toolrunnerErrorCatcher("node", testArgs, [], { + ignoreReturnCode: true, + }), + 199 + ); +}); + +test("execErrorCatcher preserves behavior of provided listeners", async (t) => { + const stdoutExpected = "standard output"; + const stderrExpected = "error output"; + + let stdoutActual = ""; + let stderrActual = ""; + + const listeners = { + stdout: (data: Buffer) => { + stdoutActual += data.toString(); + }, + stderr: (data: Buffer) => { + stderrActual += data.toString(); + }, + }; + + const testArgs = buildDummyArgs(stdoutExpected, stderrExpected, "", 0); + + t.deepEqual( + await toolrunnerErrorCatcher("node", testArgs, [], { + listeners, + }), + 0 + ); + + t.deepEqual(stdoutActual, `${stdoutExpected}\n`); + t.deepEqual(stderrActual, `${stderrExpected}\n`); +}); + +function buildDummyArgs( + stdoutContents: string, + stderrContents: string, + desiredErrorMessage?: string, + desiredExitCode?: number +): string[] { + let command = ""; + + if (stdoutContents) command += `console.log("${stdoutContents}");`; + if (stderrContents) command += `console.error("${stderrContents}");`; + + if (command.length === 0) + throw new Error("Must provide contents for either stdout or stderr"); + + if (desiredErrorMessage) + command += `throw new Error("${desiredErrorMessage}");`; + if (desiredExitCode) command += `process.exitCode = ${desiredExitCode};`; + + return ["-e", command]; +} diff --git a/src/toolrunner-error-catcher.ts b/src/toolrunner-error-catcher.ts new file mode 100644 index 000000000..baad7fa70 --- /dev/null +++ b/src/toolrunner-error-catcher.ts @@ -0,0 +1,86 @@ +import * as im from "@actions/exec/lib/interfaces"; +import * as toolrunnner from "@actions/exec/lib/toolrunner"; + +import { ErrorMatcher } from "./error-matcher"; + +/** + * Wrapper for toolrunner.Toolrunner which checks for specific return code and/or regex matches in console output. + * Output will be streamed to the live console as well as captured for subsequent processing. + * Returns promise with return code + * + * @param commandLine command to execute + * @param args optional arguments for tool. Escaping is handled by the lib. + * @param matchers defines specific codes and/or regexes that should lead to return of a custom error + * @param options optional exec options. See ExecOptions + * @returns Promise exit code + */ +export async function toolrunnerErrorCatcher( + commandLine: string, + args?: string[], + matchers?: ErrorMatcher[], + options?: im.ExecOptions +): Promise { + let stdout = ""; + let stderr = ""; + + const listeners = { + stdout: (data: Buffer) => { + stdout += data.toString(); + if (options?.listeners?.stdout !== undefined) { + options.listeners.stdout(data); + } else { + // if no stdout listener was originally defined then we match default behavior of Toolrunner + process.stdout.write(data); + } + }, + stderr: (data: Buffer) => { + stderr += data.toString(); + if (options?.listeners?.stderr !== undefined) { + options.listeners.stderr(data); + } else { + // if no stderr listener was originally defined then we match default behavior of Toolrunner + process.stderr.write(data); + } + }, + }; + + // we capture the original return code or error so that if no match is found we can duplicate the behavior + let returnState: Error | number; + try { + returnState = await new toolrunnner.ToolRunner(commandLine, args, { + ...options, // we want to override the original options, so include them first + listeners, + ignoreReturnCode: true, // so we can check for specific codes using the matchers + }).exec(); + } catch (e) { + returnState = e; + } + + // if there is a zero return code then we do not apply the matchers + if (returnState === 0) return returnState; + + if (matchers) { + for (const matcher of matchers) { + if ( + matcher.exitCode === returnState || + matcher.outputRegex?.test(stderr) || + matcher.outputRegex?.test(stdout) + ) { + throw new Error(matcher.message); + } + } + } + + if (typeof returnState === "number") { + // only if we were instructed to ignore the return code do we ever return it non-zero + if (options?.ignoreReturnCode) { + return returnState; + } else { + throw new Error( + `The process \'${commandLine}\' failed with exit code ${returnState}` + ); + } + } else { + throw returnState; + } +}