Refactor configuration errors (#2105)

Refactor the existing classes of configuration errors into their own file; consolidate the place we check for configuration errors into `codeql.ts`, where the actual command invocations happen.

Also, rename the `UserError` type to `ConfigurationError` to standardize on a single term.
This commit is contained in:
Angela P Wen
2024-02-08 09:20:03 -08:00
committed by GitHub
parent fc9f9e5ef9
commit 1515e2bb20
54 changed files with 654 additions and 502 deletions

4
lib/actions-util.js generated
View File

@@ -41,7 +41,7 @@ const pkg = require("../package.json");
const getRequiredInput = function (name) { const getRequiredInput = function (name) {
const value = core.getInput(name); const value = core.getInput(name);
if (!value) { if (!value) {
throw new util_1.UserError(`Input required and not supplied: ${name}`); throw new util_1.ConfigurationError(`Input required and not supplied: ${name}`);
} }
return value; return value;
}; };
@@ -177,7 +177,7 @@ async function getRef() {
const hasShaInput = !!shaInput; const hasShaInput = !!shaInput;
// If one of 'ref' or 'sha' are provided, both are required // If one of 'ref' or 'sha' are provided, both are required
if ((hasRefInput || hasShaInput) && !(hasRefInput && hasShaInput)) { if ((hasRefInput || hasShaInput) && !(hasRefInput && hasShaInput)) {
throw new util_1.UserError("Both 'ref' and 'sha' are required if one of them is provided."); throw new util_1.ConfigurationError("Both 'ref' and 'sha' are required if one of them is provided.");
} }
const ref = refInput || getRefFromEnv(); const ref = refInput || getRefFromEnv();
const sha = shaInput || (0, util_1.getRequiredEnvParam)("GITHUB_SHA"); const sha = shaInput || (0, util_1.getRequiredEnvParam)("GITHUB_SHA");

File diff suppressed because one or more lines are too long

4
lib/analyze-action.js generated
View File

@@ -153,7 +153,7 @@ async function run() {
throw new Error("Config file could not be found at expected location. Has the 'init' action been called?"); throw new Error("Config file could not be found at expected location. Has the 'init' action been called?");
} }
if (hasBadExpectErrorInput()) { if (hasBadExpectErrorInput()) {
throw new util.UserError("`expect-error` input parameter is for internal use only. It should only be set by codeql-action or a fork."); throw new util.ConfigurationError("`expect-error` input parameter is for internal use only. It should only be set by codeql-action or a fork.");
} }
const apiDetails = (0, api_client_1.getApiDetails)(); const apiDetails = (0, api_client_1.getApiDetails)();
const outputDir = actionsUtil.getRequiredInput("output"); const outputDir = actionsUtil.getRequiredInput("output");
@@ -180,7 +180,7 @@ async function run() {
core.setOutput("sarif-output", path_1.default.resolve(outputDir)); core.setOutput("sarif-output", path_1.default.resolve(outputDir));
const uploadInput = actionsUtil.getOptionalInput("upload"); const uploadInput = actionsUtil.getOptionalInput("upload");
if (runStats && actionsUtil.getUploadValue(uploadInput) === "always") { if (runStats && actionsUtil.getUploadValue(uploadInput) === "always") {
uploadResult = await uploadLib.uploadFromActions(outputDir, actionsUtil.getRequiredInput("checkout_path"), actionsUtil.getOptionalInput("category"), logger, { considerInvalidRequestUserError: false }); uploadResult = await uploadLib.uploadFromActions(outputDir, actionsUtil.getRequiredInput("checkout_path"), actionsUtil.getOptionalInput("category"), logger, { considerInvalidRequestConfigError: false });
core.setOutput("sarif-id", uploadResult.sarifID); core.setOutput("sarif-id", uploadResult.sarifID);
} }
else { else {

File diff suppressed because one or more lines are too long

179
lib/cli-errors.js generated Normal file
View File

@@ -0,0 +1,179 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.wrapCliConfigurationError = exports.getCliConfigCategoryIfExists = exports.cliErrorsConfig = exports.CliConfigErrorCategory = exports.CommandInvocationError = void 0;
const util_1 = require("./util");
/**
* A class of Error that we can classify as an error stemming from a CLI
* invocation, with associated exit code, stderr,etc.
*/
class CommandInvocationError extends Error {
constructor(cmd, args, exitCode, stderr, stdout) {
const prettyCommand = [cmd, ...args]
.map((x) => (x.includes(" ") ? `'${x}'` : x))
.join(" ");
const fatalErrors = extractFatalErrors(stderr);
const lastLine = stderr.trim().split("\n").pop()?.trim();
let error = fatalErrors
? ` and error was: ${fatalErrors.trim()}`
: lastLine
? ` and last log line was: ${lastLine}`
: "";
if (error[error.length - 1] !== ".") {
error += ".";
}
super(`Encountered a fatal error while running "${prettyCommand}". ` +
`Exit code was ${exitCode}${error} See the logs for more details.`);
this.exitCode = exitCode;
this.stderr = stderr;
this.stdout = stdout;
}
}
exports.CommandInvocationError = CommandInvocationError;
/**
* Provide a better error message from the stderr of a CLI invocation that failed with a fatal
* error.
*
* - If the CLI invocation failed with a fatal error, this returns that fatal error, followed by
* any fatal errors that occurred in plumbing commands.
* - If the CLI invocation did not fail with a fatal error, this returns `undefined`.
*
* ### Example
*
* ```
* Running TRAP import for CodeQL database at /home/runner/work/_temp/codeql_databases/javascript...
* A fatal error occurred: Evaluator heap must be at least 384.00 MiB
* A fatal error occurred: Dataset import for
* /home/runner/work/_temp/codeql_databases/javascript/db-javascript failed with code 2
* ```
*
* becomes
*
* ```
* Encountered a fatal error while running "codeql-for-testing database finalize --finalize-dataset
* --threads=2 --ram=2048 db". Exit code was 32 and error was: A fatal error occurred: Dataset
* import for /home/runner/work/_temp/codeql_databases/javascript/db-javascript failed with code 2.
* Context: A fatal error occurred: Evaluator heap must be at least 384.00 MiB.
* ```
*
* Where possible, this tries to summarize the error into a single line, as this displays better in
* the Actions UI.
*/
function extractFatalErrors(error) {
const fatalErrorRegex = /.*fatal error occurred:/gi;
let fatalErrors = [];
let lastFatalErrorIndex;
let match;
while ((match = fatalErrorRegex.exec(error)) !== null) {
if (lastFatalErrorIndex !== undefined) {
fatalErrors.push(error.slice(lastFatalErrorIndex, match.index).trim());
}
lastFatalErrorIndex = match.index;
}
if (lastFatalErrorIndex !== undefined) {
const lastError = error.slice(lastFatalErrorIndex).trim();
if (fatalErrors.length === 0) {
// No other errors
return lastError;
}
const isOneLiner = !fatalErrors.some((e) => e.includes("\n"));
if (isOneLiner) {
fatalErrors = fatalErrors.map(ensureEndsInPeriod);
}
return [
ensureEndsInPeriod(lastError),
"Context:",
...fatalErrors.reverse(),
].join(isOneLiner ? " " : "\n");
}
return undefined;
}
function ensureEndsInPeriod(text) {
return text[text.length - 1] === "." ? text : `${text}.`;
}
/** Error messages from the CLI that we consider configuration errors and handle specially. */
var CliConfigErrorCategory;
(function (CliConfigErrorCategory) {
CliConfigErrorCategory["IncompatibleWithActionVersion"] = "IncompatibleWithActionVersion";
CliConfigErrorCategory["InitCalledTwice"] = "InitCalledTwice";
CliConfigErrorCategory["InvalidSourceRoot"] = "InvalidSourceRoot";
CliConfigErrorCategory["NoJavaScriptTypeScriptCodeFound"] = "NoJavaScriptTypeScriptCodeFound";
})(CliConfigErrorCategory || (exports.CliConfigErrorCategory = CliConfigErrorCategory = {}));
/**
* All of our caught CLI error messages that we handle specially: ie. if we
* would like to categorize an error as a configuration error or not.
*/
exports.cliErrorsConfig = {
// Version of CodeQL CLI is incompatible with this version of the CodeQL Action
[CliConfigErrorCategory.IncompatibleWithActionVersion]: {
cliErrorMessageSnippets: ["is not compatible with this CodeQL CLI"],
},
[CliConfigErrorCategory.InitCalledTwice]: {
cliErrorMessageSnippets: [
"Refusing to create databases",
"exists and is not an empty directory",
],
additionalErrorMessageToPrepend: `Is the "init" action called twice in the same job?`,
},
// Expected source location for database creation does not exist
[CliConfigErrorCategory.InvalidSourceRoot]: {
cliErrorMessageSnippets: ["Invalid source root"],
},
/**
* Earlier versions of the JavaScript extractor (pre-CodeQL 2.12.0) extract externs even if no
* source code was found. This means that we don't get the no code found error from
* `codeql database finalize`. To ensure users get a good error message, we detect this manually
* here, and upon detection override the error message.
*
* This can be removed once support for CodeQL 2.11.6 is removed.
*/
[CliConfigErrorCategory.NoJavaScriptTypeScriptCodeFound]: {
exitCode: 32,
cliErrorMessageSnippets: ["No JavaScript or TypeScript code found."],
additionalErrorMessageToPrepend: "No code found during the build. Please see: " +
"https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build.",
},
};
// Check if the given CLI error or exit code, if applicable, apply to any known
// CLI errors in the configuration record. If either the CLI error message matches all of
// the error messages in the config record, or the exit codes match, return the error category;
// if not, return undefined.
function getCliConfigCategoryIfExists(cliError) {
for (const [category, configuration] of Object.entries(exports.cliErrorsConfig)) {
if (cliError.exitCode !== undefined &&
configuration.exitCode !== undefined &&
cliError.exitCode === configuration.exitCode) {
return category;
}
let allMessageSnippetsFound = true;
for (const e of configuration.cliErrorMessageSnippets) {
if (!cliError.message.includes(e) && !cliError.stderr.includes(e)) {
allMessageSnippetsFound = false;
}
}
if (allMessageSnippetsFound === true) {
return category;
}
}
return undefined;
}
exports.getCliConfigCategoryIfExists = getCliConfigCategoryIfExists;
/**
* Changes an error received from the CLI to a ConfigurationError with optionally an extra
* error message prepended, if it exists in a known set of configuration errors. Otherwise,
* simply returns the original error.
*/
function wrapCliConfigurationError(cliError) {
if (!(cliError instanceof CommandInvocationError)) {
return cliError;
}
const cliConfigErrorCategory = getCliConfigCategoryIfExists(cliError);
if (cliConfigErrorCategory === undefined) {
return cliError;
}
const errorMessageWrapperIfExists = exports.cliErrorsConfig[cliConfigErrorCategory].additionalErrorMessageToPrepend;
return errorMessageWrapperIfExists
? new util_1.ConfigurationError(`${errorMessageWrapperIfExists} ${cliError.message}`)
: new util_1.ConfigurationError(cliError.message);
}
exports.wrapCliConfigurationError = wrapCliConfigurationError;
//# sourceMappingURL=cli-errors.js.map

1
lib/cli-errors.js.map Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"cli-errors.js","sourceRoot":"","sources":["../src/cli-errors.ts"],"names":[],"mappings":"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"}

141
lib/codeql.js generated
View File

@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result; return result;
}; };
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.getGeneratedCodeScanningConfigPath = exports.getTrapCachingExtractorConfigArgsForLang = exports.getTrapCachingExtractorConfigArgs = exports.getExtraOptions = exports.getCodeQLForCmd = exports.getCodeQLForTesting = exports.getCachedCodeQL = exports.setCodeQL = exports.getCodeQL = exports.setupCodeQL = exports.CODEQL_VERSION_SUBLANGUAGE_FILE_COVERAGE = exports.CODEQL_VERSION_ANALYSIS_SUMMARY_V2 = exports.CODEQL_VERSION_LANGUAGE_ALIASING = exports.CODEQL_VERSION_LANGUAGE_BASELINE_CONFIG = exports.CODEQL_VERSION_RESOLVE_ENVIRONMENT = exports.CODEQL_VERSION_DIAGNOSTICS_EXPORT_FIXED = exports.CODEQL_VERSION_BETTER_NO_CODE_ERROR_MESSAGE = exports.CODEQL_VERSION_INIT_WITH_QLCONFIG = exports.CODEQL_VERSION_EXPORT_CODE_SCANNING_CONFIG = exports.CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE = exports.CommandInvocationError = void 0; exports.getGeneratedCodeScanningConfigPath = exports.getTrapCachingExtractorConfigArgsForLang = exports.getTrapCachingExtractorConfigArgs = exports.getExtraOptions = exports.getCodeQLForCmd = exports.getCodeQLForTesting = exports.getCachedCodeQL = exports.setCodeQL = exports.getCodeQL = exports.setupCodeQL = exports.CODEQL_VERSION_SUBLANGUAGE_FILE_COVERAGE = exports.CODEQL_VERSION_ANALYSIS_SUMMARY_V2 = exports.CODEQL_VERSION_LANGUAGE_ALIASING = exports.CODEQL_VERSION_LANGUAGE_BASELINE_CONFIG = exports.CODEQL_VERSION_RESOLVE_ENVIRONMENT = exports.CODEQL_VERSION_DIAGNOSTICS_EXPORT_FIXED = exports.CODEQL_VERSION_BETTER_NO_CODE_ERROR_MESSAGE = exports.CODEQL_VERSION_INIT_WITH_QLCONFIG = exports.CODEQL_VERSION_EXPORT_CODE_SCANNING_CONFIG = exports.CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE = void 0;
const fs = __importStar(require("fs")); const fs = __importStar(require("fs"));
const path = __importStar(require("path")); const path = __importStar(require("path"));
const core = __importStar(require("@actions/core")); const core = __importStar(require("@actions/core"));
@@ -31,6 +31,7 @@ const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
const yaml = __importStar(require("js-yaml")); const yaml = __importStar(require("js-yaml"));
const semver = __importStar(require("semver")); const semver = __importStar(require("semver"));
const actions_util_1 = require("./actions-util"); const actions_util_1 = require("./actions-util");
const cli_errors_1 = require("./cli-errors");
const environment_1 = require("./environment"); const environment_1 = require("./environment");
const feature_flags_1 = require("./feature-flags"); const feature_flags_1 = require("./feature-flags");
const languages_1 = require("./languages"); const languages_1 = require("./languages");
@@ -38,29 +39,6 @@ const setupCodeql = __importStar(require("./setup-codeql"));
const tools_features_1 = require("./tools-features"); const tools_features_1 = require("./tools-features");
const util = __importStar(require("./util")); const util = __importStar(require("./util"));
const util_1 = require("./util"); const util_1 = require("./util");
class CommandInvocationError extends Error {
constructor(cmd, args, exitCode, stderr, stdout) {
const prettyCommand = [cmd, ...args]
.map((x) => (x.includes(" ") ? `'${x}'` : x))
.join(" ");
const fatalErrors = extractFatalErrors(stderr);
const lastLine = stderr.trim().split("\n").pop()?.trim();
let error = fatalErrors
? ` and error was: ${fatalErrors.trim()}`
: lastLine
? ` and last log line was: ${lastLine}`
: "";
if (error[error.length - 1] !== ".") {
error += ".";
}
super(`Encountered a fatal error while running "${prettyCommand}". ` +
`Exit code was ${exitCode}${error} See the logs for more details.`);
this.exitCode = exitCode;
this.stderr = stderr;
this.stdout = stdout;
}
}
exports.CommandInvocationError = CommandInvocationError;
/** /**
* Stores the CodeQL object, and is populated by `setupCodeQL` or `getCodeQL`. * Stores the CodeQL object, and is populated by `setupCodeQL` or `getCodeQL`.
* Can be overridden in tests using `setCodeQL`. * Can be overridden in tests using `setCodeQL`.
@@ -156,7 +134,7 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV
codeqlCmd += ".exe"; codeqlCmd += ".exe";
} }
else if (process.platform !== "linux" && process.platform !== "darwin") { else if (process.platform !== "linux" && process.platform !== "darwin") {
throw new util.UserError(`Unsupported platform: ${process.platform}`); throw new util.ConfigurationError(`Unsupported platform: ${process.platform}`);
} }
cachedCodeQL = await getCodeQLForCmd(codeqlCmd, checkVersion); cachedCodeQL = await getCodeQLForCmd(codeqlCmd, checkVersion);
return { return {
@@ -316,16 +294,24 @@ async function getCodeQLForCmd(cmd, checkVersion) {
else if (await util.codeQlVersionAbove(this, exports.CODEQL_VERSION_SUBLANGUAGE_FILE_COVERAGE)) { else if (await util.codeQlVersionAbove(this, exports.CODEQL_VERSION_SUBLANGUAGE_FILE_COVERAGE)) {
extraArgs.push("--no-sublanguage-file-coverage"); extraArgs.push("--no-sublanguage-file-coverage");
} }
await runTool(cmd, [ try {
"database", await runTool(cmd, [
"init", "database",
"--db-cluster", "init",
config.dbLocation, "--db-cluster",
`--source-root=${sourceRoot}`, config.dbLocation,
...(await getLanguageAliasingArguments(this)), `--source-root=${sourceRoot}`,
...extraArgs, ...(await getLanguageAliasingArguments(this)),
...getExtraOptionsFromEnv(["database", "init"]), ...extraArgs,
], { stdin: externalRepositoryToken }); ...getExtraOptionsFromEnv(["database", "init"]),
], { stdin: externalRepositoryToken });
}
catch (e) {
if (e instanceof Error) {
throw (0, cli_errors_1.wrapCliConfigurationError)(e);
}
throw e;
}
}, },
async runAutobuild(language) { async runAutobuild(language) {
const autobuildCmd = path.join(await this.resolveExtractor(language), "tools", process.platform === "win32" ? "autobuild.cmd" : "autobuild.sh"); const autobuildCmd = path.join(await this.resolveExtractor(language), "tools", process.platform === "win32" ? "autobuild.cmd" : "autobuild.sh");
@@ -389,11 +375,9 @@ async function getCodeQLForCmd(cmd, checkVersion) {
await runTool(cmd, args); await runTool(cmd, args);
} }
catch (e) { catch (e) {
if (e instanceof CommandInvocationError && if (e instanceof Error &&
!(await util.codeQlVersionAbove(this, exports.CODEQL_VERSION_BETTER_NO_CODE_ERROR_MESSAGE)) && !(await util.codeQlVersionAbove(this, exports.CODEQL_VERSION_BETTER_NO_CODE_ERROR_MESSAGE))) {
isNoCodeFoundError(e)) { throw (0, cli_errors_1.wrapCliConfigurationError)(e);
throw new util.UserError("No code found during the build. Please see: " +
"https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build");
} }
throw e; throw e;
} }
@@ -700,7 +684,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
// CodeQL object is created. // CodeQL object is created.
if (checkVersion && if (checkVersion &&
!(await util.codeQlVersionAbove(codeql, CODEQL_MINIMUM_VERSION))) { !(await util.codeQlVersionAbove(codeql, CODEQL_MINIMUM_VERSION))) {
throw new util.UserError(`Expected a CodeQL CLI with version at least ${CODEQL_MINIMUM_VERSION} but got version ${(await codeql.getVersion()).version}`); throw new util.ConfigurationError(`Expected a CodeQL CLI with version at least ${CODEQL_MINIMUM_VERSION} but got version ${(await codeql.getVersion()).version}`);
} }
else if (checkVersion && else if (checkVersion &&
process.env[environment_1.EnvVar.SUPPRESS_DEPRECATED_SOON_WARNING] !== "true" && process.env[environment_1.EnvVar.SUPPRESS_DEPRECATED_SOON_WARNING] !== "true" &&
@@ -805,71 +789,10 @@ async function runTool(cmd, args = [], opts = {}) {
...(opts.stdin ? { input: Buffer.from(opts.stdin || "") } : {}), ...(opts.stdin ? { input: Buffer.from(opts.stdin || "") } : {}),
}).exec(); }).exec();
if (exitCode !== 0) { if (exitCode !== 0) {
throw new CommandInvocationError(cmd, args, exitCode, error, output); throw new cli_errors_1.CommandInvocationError(cmd, args, exitCode, error, output);
} }
return output; return output;
} }
/**
* Provide a better error message from the stderr of a CLI invocation that failed with a fatal
* error.
*
* - If the CLI invocation failed with a fatal error, this returns that fatal error, followed by
* any fatal errors that occurred in plumbing commands.
* - If the CLI invocation did not fail with a fatal error, this returns `undefined`.
*
* ### Example
*
* ```
* Running TRAP import for CodeQL database at /home/runner/work/_temp/codeql_databases/javascript...
* A fatal error occurred: Evaluator heap must be at least 384.00 MiB
* A fatal error occurred: Dataset import for
* /home/runner/work/_temp/codeql_databases/javascript/db-javascript failed with code 2
* ```
*
* becomes
*
* ```
* Encountered a fatal error while running "codeql-for-testing database finalize --finalize-dataset
* --threads=2 --ram=2048 db". Exit code was 32 and error was: A fatal error occurred: Dataset
* import for /home/runner/work/_temp/codeql_databases/javascript/db-javascript failed with code 2.
* Context: A fatal error occurred: Evaluator heap must be at least 384.00 MiB.
* ```
*
* Where possible, this tries to summarize the error into a single line, as this displays better in
* the Actions UI.
*/
function extractFatalErrors(error) {
const fatalErrorRegex = /.*fatal error occurred:/gi;
let fatalErrors = [];
let lastFatalErrorIndex;
let match;
while ((match = fatalErrorRegex.exec(error)) !== null) {
if (lastFatalErrorIndex !== undefined) {
fatalErrors.push(error.slice(lastFatalErrorIndex, match.index).trim());
}
lastFatalErrorIndex = match.index;
}
if (lastFatalErrorIndex !== undefined) {
const lastError = error.slice(lastFatalErrorIndex).trim();
if (fatalErrors.length === 0) {
// No other errors
return lastError;
}
const isOneLiner = !fatalErrors.some((e) => e.includes("\n"));
if (isOneLiner) {
fatalErrors = fatalErrors.map(ensureEndsInPeriod);
}
return [
ensureEndsInPeriod(lastError),
"Context:",
...fatalErrors.reverse(),
].join(isOneLiner ? " " : "\n");
}
return undefined;
}
function ensureEndsInPeriod(text) {
return text[text.length - 1] === "." ? text : `${text}.`;
}
/** /**
* Generates a code scanning configuration that is to be used for a scan. * Generates a code scanning configuration that is to be used for a scan.
* *
@@ -971,18 +894,6 @@ function getGeneratedCodeScanningConfigPath(config) {
return path.resolve(config.tempDir, "user-config.yaml"); return path.resolve(config.tempDir, "user-config.yaml");
} }
exports.getGeneratedCodeScanningConfigPath = getGeneratedCodeScanningConfigPath; exports.getGeneratedCodeScanningConfigPath = getGeneratedCodeScanningConfigPath;
function isNoCodeFoundError(e) {
/**
* Earlier versions of the JavaScript extractor (pre-CodeQL 2.12.0) extract externs even if no
* source code was found. This means that we don't get the no code found error from
* `codeql database finalize`. To ensure users get a good error message, we detect this manually
* here, and upon detection override the error message.
*
* This can be removed once support for CodeQL 2.11.6 is removed.
*/
const javascriptNoCodeFoundWarning = "No JavaScript or TypeScript code found.";
return e.exitCode === 32 || e.stderr.includes(javascriptNoCodeFoundWarning);
}
async function isDiagnosticsExportInvalidSarifFixed(codeql) { async function isDiagnosticsExportInvalidSarifFixed(codeql) {
return await util.codeQlVersionAbove(codeql, exports.CODEQL_VERSION_DIAGNOSTICS_EXPORT_FIXED); return await util.codeQlVersionAbove(codeql, exports.CODEQL_VERSION_DIAGNOSTICS_EXPORT_FIXED);
} }

File diff suppressed because one or more lines are too long

10
lib/codeql.test.js generated
View File

@@ -554,8 +554,9 @@ for (const { codeqlVersion, flagPassed, githubVersion, negativeFlagPassed, } of
// safeWhich throws because of the test CodeQL object. // safeWhich throws because of the test CodeQL object.
sinon.stub(safeWhich, "safeWhich").resolves(""); sinon.stub(safeWhich, "safeWhich").resolves("");
await t.throwsAsync(async () => await codeqlObject.finalizeDatabase("", "", ""), { await t.throwsAsync(async () => await codeqlObject.finalizeDatabase("", "", ""), {
message: "No code found during the build. Please see: " + instanceOf: util.ConfigurationError,
"https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build", message: new RegExp("No code found during the build. Please see: " +
"https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build.+"),
}); });
}); });
(0, ava_1.default)("database finalize overrides no code found error on CodeQL 2.11.6", async (t) => { (0, ava_1.default)("database finalize overrides no code found error on CodeQL 2.11.6", async (t) => {
@@ -565,8 +566,9 @@ for (const { codeqlVersion, flagPassed, githubVersion, negativeFlagPassed, } of
// safeWhich throws because of the test CodeQL object. // safeWhich throws because of the test CodeQL object.
sinon.stub(safeWhich, "safeWhich").resolves(""); sinon.stub(safeWhich, "safeWhich").resolves("");
await t.throwsAsync(async () => await codeqlObject.finalizeDatabase("", "", ""), { await t.throwsAsync(async () => await codeqlObject.finalizeDatabase("", "", ""), {
message: "No code found during the build. Please see: " + instanceOf: util.ConfigurationError,
"https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build", message: new RegExp("No code found during the build. Please see: " +
"https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build.+"),
}); });
}); });
(0, ava_1.default)("database finalize does not override no code found error on CodeQL 2.12.4", async (t) => { (0, ava_1.default)("database finalize does not override no code found error on CodeQL 2.12.4", async (t) => {

File diff suppressed because one or more lines are too long

38
lib/config-utils.js generated
View File

@@ -154,7 +154,7 @@ async function getLanguages(codeQL, languagesInput, repository, logger) {
// If the languages parameter was not given and no languages were // If the languages parameter was not given and no languages were
// detected then fail here as this is a workflow configuration error. // detected then fail here as this is a workflow configuration error.
if (languages.length === 0) { if (languages.length === 0) {
throw new util_1.UserError(getNoLanguagesError()); throw new util_1.ConfigurationError(getNoLanguagesError());
} }
// Make sure they are supported // Make sure they are supported
const parsedLanguages = []; const parsedLanguages = [];
@@ -171,7 +171,7 @@ async function getLanguages(codeQL, languagesInput, repository, logger) {
// Any unknown languages here would have come directly from the input // Any unknown languages here would have come directly from the input
// since we filter unknown languages coming from the GitHub API. // since we filter unknown languages coming from the GitHub API.
if (unknownLanguages.length > 0) { if (unknownLanguages.length > 0) {
throw new util_1.UserError(getUnknownLanguagesError(unknownLanguages)); throw new util_1.ConfigurationError(getUnknownLanguagesError(unknownLanguages));
} }
return parsedLanguages; return parsedLanguages;
} }
@@ -321,7 +321,7 @@ function parseQueriesFromInput(rawQueriesInput, queriesInputCombines) {
? rawQueriesInput.trim().slice(1).trim() ? rawQueriesInput.trim().slice(1).trim()
: rawQueriesInput?.trim() ?? ""; : rawQueriesInput?.trim() ?? "";
if (queriesInputCombines && trimmedInput.length === 0) { if (queriesInputCombines && trimmedInput.length === 0) {
throw new util_1.UserError(getConfigFilePropertyError(undefined, "queries", "A '+' was used in the 'queries' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs.")); throw new util_1.ConfigurationError(getConfigFilePropertyError(undefined, "queries", "A '+' was used in the 'queries' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs."));
} }
return trimmedInput.split(",").map((query) => ({ uses: query.trim() })); return trimmedInput.split(",").map((query) => ({ uses: query.trim() }));
} }
@@ -341,16 +341,16 @@ function parsePacksFromInput(rawPacksInput, languages, packsInputCombines) {
return undefined; return undefined;
} }
if (languages.length > 1) { if (languages.length > 1) {
throw new util_1.UserError("Cannot specify a 'packs' input in a multi-language analysis. Use a codeql-config.yml file instead and specify packs by language."); throw new util_1.ConfigurationError("Cannot specify a 'packs' input in a multi-language analysis. Use a codeql-config.yml file instead and specify packs by language.");
} }
else if (languages.length === 0) { else if (languages.length === 0) {
throw new util_1.UserError("No languages specified. Cannot process the packs input."); throw new util_1.ConfigurationError("No languages specified. Cannot process the packs input.");
} }
rawPacksInput = rawPacksInput.trim(); rawPacksInput = rawPacksInput.trim();
if (packsInputCombines) { if (packsInputCombines) {
rawPacksInput = rawPacksInput.trim().substring(1).trim(); rawPacksInput = rawPacksInput.trim().substring(1).trim();
if (!rawPacksInput) { if (!rawPacksInput) {
throw new util_1.UserError(getConfigFilePropertyError(undefined, "packs", "A '+' was used in the 'packs' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs.")); throw new util_1.ConfigurationError(getConfigFilePropertyError(undefined, "packs", "A '+' was used in the 'packs' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs."));
} }
} }
return { return {
@@ -381,7 +381,7 @@ exports.parsePacksFromInput = parsePacksFromInput;
*/ */
function parsePacksSpecification(packStr) { function parsePacksSpecification(packStr) {
if (typeof packStr !== "string") { if (typeof packStr !== "string") {
throw new util_1.UserError(getPacksStrInvalid(packStr)); throw new util_1.ConfigurationError(getPacksStrInvalid(packStr));
} }
packStr = packStr.trim(); packStr = packStr.trim();
const atIndex = packStr.indexOf("@"); const atIndex = packStr.indexOf("@");
@@ -402,7 +402,7 @@ function parsePacksSpecification(packStr) {
? packStr.slice(pathStart, pathEnd).trim() ? packStr.slice(pathStart, pathEnd).trim()
: undefined; : undefined;
if (!PACK_IDENTIFIER_PATTERN.test(packName)) { if (!PACK_IDENTIFIER_PATTERN.test(packName)) {
throw new util_1.UserError(getPacksStrInvalid(packStr)); throw new util_1.ConfigurationError(getPacksStrInvalid(packStr));
} }
if (version) { if (version) {
try { try {
@@ -410,7 +410,7 @@ function parsePacksSpecification(packStr) {
} }
catch (e) { catch (e) {
// The range string is invalid. OK to ignore the caught error // The range string is invalid. OK to ignore the caught error
throw new util_1.UserError(getPacksStrInvalid(packStr)); throw new util_1.ConfigurationError(getPacksStrInvalid(packStr));
} }
} }
if (packPath && if (packPath &&
@@ -421,11 +421,11 @@ function parsePacksSpecification(packStr) {
// which seems more awkward. // which seems more awkward.
path.normalize(packPath).split(path.sep).join("/") !== path.normalize(packPath).split(path.sep).join("/") !==
packPath.split(path.sep).join("/"))) { packPath.split(path.sep).join("/"))) {
throw new util_1.UserError(getPacksStrInvalid(packStr)); throw new util_1.ConfigurationError(getPacksStrInvalid(packStr));
} }
if (!packPath && pathStart) { if (!packPath && pathStart) {
// 0 length path // 0 length path
throw new util_1.UserError(getPacksStrInvalid(packStr)); throw new util_1.ConfigurationError(getPacksStrInvalid(packStr));
} }
return { return {
name: packName, name: packName,
@@ -493,7 +493,7 @@ function parseRegistries(registriesInput) {
: undefined; : undefined;
} }
catch (e) { catch (e) {
throw new util_1.UserError("Invalid registries input. Must be a YAML string."); throw new util_1.ConfigurationError("Invalid registries input. Must be a YAML string.");
} }
} }
function isLocal(configPath) { function isLocal(configPath) {
@@ -506,11 +506,11 @@ function isLocal(configPath) {
function getLocalConfig(configFile, workspacePath) { function getLocalConfig(configFile, workspacePath) {
// Error if the config file is now outside of the workspace // Error if the config file is now outside of the workspace
if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) { if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) {
throw new util_1.UserError(getConfigFileOutsideWorkspaceErrorMessage(configFile)); throw new util_1.ConfigurationError(getConfigFileOutsideWorkspaceErrorMessage(configFile));
} }
// Error if the file does not exist // Error if the file does not exist
if (!fs.existsSync(configFile)) { if (!fs.existsSync(configFile)) {
throw new util_1.UserError(getConfigFileDoesNotExistErrorMessage(configFile)); throw new util_1.ConfigurationError(getConfigFileDoesNotExistErrorMessage(configFile));
} }
return yaml.load(fs.readFileSync(configFile, "utf8")); return yaml.load(fs.readFileSync(configFile, "utf8"));
} }
@@ -520,7 +520,7 @@ async function getRemoteConfig(configFile, apiDetails) {
const pieces = format.exec(configFile); const pieces = format.exec(configFile);
// 5 = 4 groups + the whole expression // 5 = 4 groups + the whole expression
if (pieces === null || pieces.groups === undefined || pieces.length < 5) { if (pieces === null || pieces.groups === undefined || pieces.length < 5) {
throw new util_1.UserError(getConfigFileRepoFormatInvalidMessage(configFile)); throw new util_1.ConfigurationError(getConfigFileRepoFormatInvalidMessage(configFile));
} }
const response = await api const response = await api
.getApiClientWithExternalAuth(apiDetails) .getApiClientWithExternalAuth(apiDetails)
@@ -535,10 +535,10 @@ async function getRemoteConfig(configFile, apiDetails) {
fileContents = response.data.content; fileContents = response.data.content;
} }
else if (Array.isArray(response.data)) { else if (Array.isArray(response.data)) {
throw new util_1.UserError(getConfigFileDirectoryGivenMessage(configFile)); throw new util_1.ConfigurationError(getConfigFileDirectoryGivenMessage(configFile));
} }
else { else {
throw new util_1.UserError(getConfigFileFormatInvalidMessage(configFile)); throw new util_1.ConfigurationError(getConfigFileFormatInvalidMessage(configFile));
} }
return yaml.load(Buffer.from(fileContents, "base64").toString("binary")); return yaml.load(Buffer.from(fileContents, "base64").toString("binary"));
} }
@@ -617,7 +617,7 @@ exports.generateRegistries = generateRegistries;
function createRegistriesBlock(registries) { function createRegistriesBlock(registries) {
if (!Array.isArray(registries) || if (!Array.isArray(registries) ||
registries.some((r) => !r.url || !r.packages)) { registries.some((r) => !r.url || !r.packages)) {
throw new util_1.UserError("Invalid 'registries' input. Must be an array of objects with 'url' and 'packages' properties."); throw new util_1.ConfigurationError("Invalid 'registries' input. Must be an array of objects with 'url' and 'packages' properties.");
} }
// be sure to remove the `token` field from the registry before writing it to disk. // be sure to remove the `token` field from the registry before writing it to disk.
const safeRegistries = registries.map((registry) => ({ const safeRegistries = registries.map((registry) => ({
@@ -669,7 +669,7 @@ function validateBuildModeInput(buildModeInput) {
return undefined; return undefined;
} }
if (!Object.values(BuildMode).includes(buildModeInput)) { if (!Object.values(BuildMode).includes(buildModeInput)) {
throw new util_1.UserError(`Invalid build mode: '${buildModeInput}'. Supported build modes are: ${Object.values(BuildMode).join(", ")}.`); throw new util_1.ConfigurationError(`Invalid build mode: '${buildModeInput}'. Supported build modes are: ${Object.values(BuildMode).join(", ")}.`);
} }
return buildModeInput; return buildModeInput;
} }

File diff suppressed because one or more lines are too long

View File

@@ -191,7 +191,7 @@ function mockListLanguages(languages) {
throw new Error("initConfig did not throw error"); throw new Error("initConfig did not throw error");
} }
catch (err) { catch (err) {
t.deepEqual(err, new util_1.UserError(configUtils.getConfigFileOutsideWorkspaceErrorMessage(path.join(tempDir, "../input")))); t.deepEqual(err, new util_1.ConfigurationError(configUtils.getConfigFileOutsideWorkspaceErrorMessage(path.join(tempDir, "../input"))));
} }
}); });
}); });
@@ -209,7 +209,7 @@ function mockListLanguages(languages) {
throw new Error("initConfig did not throw error"); throw new Error("initConfig did not throw error");
} }
catch (err) { catch (err) {
t.deepEqual(err, new util_1.UserError(configUtils.getConfigFileRepoFormatInvalidMessage("octo-org/codeql-config@main"))); t.deepEqual(err, new util_1.ConfigurationError(configUtils.getConfigFileRepoFormatInvalidMessage("octo-org/codeql-config@main")));
} }
}); });
}); });
@@ -229,7 +229,7 @@ function mockListLanguages(languages) {
throw new Error("initConfig did not throw error"); throw new Error("initConfig did not throw error");
} }
catch (err) { catch (err) {
t.deepEqual(err, new util_1.UserError(configUtils.getConfigFileDoesNotExistErrorMessage(path.join(tempDir, "input")))); t.deepEqual(err, new util_1.ConfigurationError(configUtils.getConfigFileDoesNotExistErrorMessage(path.join(tempDir, "input"))));
} }
}); });
}); });
@@ -426,7 +426,7 @@ function queriesToResolvedQueryForm(queries) {
throw new Error("initConfig did not throw error"); throw new Error("initConfig did not throw error");
} }
catch (err) { catch (err) {
t.deepEqual(err, new util_1.UserError(configUtils.getConfigFileDirectoryGivenMessage(repoReference))); t.deepEqual(err, new util_1.ConfigurationError(configUtils.getConfigFileDirectoryGivenMessage(repoReference)));
} }
}); });
}); });
@@ -447,7 +447,7 @@ function queriesToResolvedQueryForm(queries) {
throw new Error("initConfig did not throw error"); throw new Error("initConfig did not throw error");
} }
catch (err) { catch (err) {
t.deepEqual(err, new util_1.UserError(configUtils.getConfigFileFormatInvalidMessage(repoReference))); t.deepEqual(err, new util_1.ConfigurationError(configUtils.getConfigFileFormatInvalidMessage(repoReference)));
} }
}); });
}); });
@@ -471,7 +471,7 @@ function queriesToResolvedQueryForm(queries) {
throw new Error("initConfig did not throw error"); throw new Error("initConfig did not throw error");
} }
catch (err) { catch (err) {
t.deepEqual(err, new util_1.UserError(configUtils.getNoLanguagesError())); t.deepEqual(err, new util_1.ConfigurationError(configUtils.getNoLanguagesError()));
} }
}); });
}); });
@@ -488,7 +488,7 @@ function queriesToResolvedQueryForm(queries) {
throw new Error("initConfig did not throw error"); throw new Error("initConfig did not throw error");
} }
catch (err) { catch (err) {
t.deepEqual(err, new util_1.UserError(configUtils.getUnknownLanguagesError(["rubbish", "english"]))); t.deepEqual(err, new util_1.ConfigurationError(configUtils.getUnknownLanguagesError(["rubbish", "english"])));
} }
}); });
}); });

File diff suppressed because one or more lines are too long

View File

@@ -75,7 +75,7 @@ async function maybeUploadFailedSarif(config, repositoryNwo, features, logger) {
await codeql.databaseExportDiagnostics(databasePath, sarifFile, category, config.tempDir, logger); await codeql.databaseExportDiagnostics(databasePath, sarifFile, category, config.tempDir, logger);
} }
logger.info(`Uploading failed SARIF file ${sarifFile}`); logger.info(`Uploading failed SARIF file ${sarifFile}`);
const uploadResult = await uploadLib.uploadFromActions(sarifFile, checkoutPath, category, logger, { considerInvalidRequestUserError: false }); const uploadResult = await uploadLib.uploadFromActions(sarifFile, checkoutPath, category, logger, { considerInvalidRequestConfigError: false });
await uploadLib.waitForProcessing(repositoryNwo, uploadResult.sarifID, logger, { isUnsuccessfulExecution: true }); await uploadLib.waitForProcessing(repositoryNwo, uploadResult.sarifID, logger, { isUnsuccessfulExecution: true });
return uploadResult return uploadResult
? { ...uploadResult.statusReport, sarifID: uploadResult.sarifID } ? { ...uploadResult.statusReport, sarifID: uploadResult.sarifID }
@@ -88,7 +88,7 @@ async function tryUploadSarifIfRunFailed(config, repositoryNwo, features, logger
// means that something along the way failed in a step that is not // means that something along the way failed in a step that is not
// owned by the Action, for example a manual build step. We // owned by the Action, for example a manual build step. We
// consider this a configuration error. // consider this a configuration error.
core.exportVariable(environment_1.EnvVar.JOB_STATUS, process.env[environment_1.EnvVar.JOB_STATUS] ?? status_report_1.JobStatus.ConfigurationError); core.exportVariable(environment_1.EnvVar.JOB_STATUS, process.env[environment_1.EnvVar.JOB_STATUS] ?? status_report_1.JobStatus.ConfigErrorStatus);
try { try {
return await maybeUploadFailedSarif(config, repositoryNwo, features, logger); return await maybeUploadFailedSarif(config, repositoryNwo, features, logger);
} }
@@ -98,7 +98,7 @@ async function tryUploadSarifIfRunFailed(config, repositoryNwo, features, logger
} }
} }
else { else {
core.exportVariable(environment_1.EnvVar.JOB_STATUS, process.env[environment_1.EnvVar.JOB_STATUS] ?? status_report_1.JobStatus.Success); core.exportVariable(environment_1.EnvVar.JOB_STATUS, process.env[environment_1.EnvVar.JOB_STATUS] ?? status_report_1.JobStatus.SuccessStatus);
return { return {
upload_failed_run_skipped_because: "Analyze Action completed successfully", upload_failed_run_skipped_because: "Analyze Action completed successfully",
}; };
@@ -204,7 +204,7 @@ function getFinalJobStatus() {
const jobStatusFromEnvironment = process.env[environment_1.EnvVar.JOB_STATUS]; const jobStatusFromEnvironment = process.env[environment_1.EnvVar.JOB_STATUS];
if (!jobStatusFromEnvironment || if (!jobStatusFromEnvironment ||
!Object.values(status_report_1.JobStatus).includes(jobStatusFromEnvironment)) { !Object.values(status_report_1.JobStatus).includes(jobStatusFromEnvironment)) {
return status_report_1.JobStatus.Unknown; return status_report_1.JobStatus.UnknownStatus;
} }
return jobStatusFromEnvironment; return jobStatusFromEnvironment;
} }

File diff suppressed because one or more lines are too long

2
lib/init-action.js generated
View File

@@ -181,7 +181,7 @@ async function run() {
catch (unwrappedError) { catch (unwrappedError) {
const error = (0, util_1.wrapError)(unwrappedError); const error = (0, util_1.wrapError)(unwrappedError);
core.setFailed(error.message); core.setFailed(error.message);
await (0, status_report_1.sendStatusReport)(await (0, status_report_1.createStatusReportBase)("init", error instanceof util_1.UserError ? "user-error" : "aborted", startedAt, await (0, util_1.checkDiskUsage)(), error.message, error.stack)); await (0, status_report_1.sendStatusReport)(await (0, status_report_1.createStatusReportBase)("init", error instanceof util_1.ConfigurationError ? "user-error" : "aborted", startedAt, await (0, util_1.checkDiskUsage)(), error.message, error.stack));
return; return;
} }
try { try {

File diff suppressed because one or more lines are too long

48
lib/init.js generated
View File

@@ -32,7 +32,6 @@ const codeql_1 = require("./codeql");
const configUtils = __importStar(require("./config-utils")); const configUtils = __importStar(require("./config-utils"));
const languages_1 = require("./languages"); const languages_1 = require("./languages");
const tracer_config_1 = require("./tracer-config"); const tracer_config_1 = require("./tracer-config");
const util = __importStar(require("./util"));
async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger) { async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger) {
logger.startGroup("Setup CodeQL tools"); logger.startGroup("Setup CodeQL tools");
const { codeql, toolsDownloadDurationMs, toolsSource, toolsVersion } = await (0, codeql_1.setupCodeQL)(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger, true); const { codeql, toolsDownloadDurationMs, toolsSource, toolsVersion } = await (0, codeql_1.setupCodeQL)(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, logger, true);
@@ -52,18 +51,13 @@ async function initConfig(inputs) {
exports.initConfig = initConfig; exports.initConfig = initConfig;
async function runInit(codeql, config, sourceRoot, processName, registriesInput, apiDetails, logger) { async function runInit(codeql, config, sourceRoot, processName, registriesInput, apiDetails, logger) {
fs.mkdirSync(config.dbLocation, { recursive: true }); fs.mkdirSync(config.dbLocation, { recursive: true });
try { const { registriesAuthTokens, qlconfigFile } = await configUtils.generateRegistries(registriesInput, config.tempDir, logger);
const { registriesAuthTokens, qlconfigFile } = await configUtils.generateRegistries(registriesInput, config.tempDir, logger); await configUtils.wrapEnvironment({
await configUtils.wrapEnvironment({ GITHUB_TOKEN: apiDetails.auth,
GITHUB_TOKEN: apiDetails.auth, CODEQL_REGISTRIES_AUTH: registriesAuthTokens,
CODEQL_REGISTRIES_AUTH: registriesAuthTokens, },
}, // Init a database cluster
// Init a database cluster async () => await codeql.databaseInitCluster(config, sourceRoot, processName, qlconfigFile, logger));
async () => await codeql.databaseInitCluster(config, sourceRoot, processName, qlconfigFile, logger));
}
catch (e) {
throw processError(e);
}
return await (0, tracer_config_1.getCombinedTracerConfig)(codeql, config); return await (0, tracer_config_1.getCombinedTracerConfig)(codeql, config);
} }
exports.runInit = runInit; exports.runInit = runInit;
@@ -77,34 +71,6 @@ function printPathFiltersWarning(config, logger) {
} }
} }
exports.printPathFiltersWarning = printPathFiltersWarning; exports.printPathFiltersWarning = printPathFiltersWarning;
/**
* Possibly convert this error into a UserError in order to avoid
* counting this error towards our internal error budget.
*
* @param e The error to possibly convert to a UserError.
*
* @returns A UserError if the error is a known error that can be
* attributed to the user, otherwise the original error.
*/
function processError(e) {
if (!(e instanceof Error)) {
return e;
}
if (
// Init action called twice
e.message?.includes("Refusing to create databases") &&
e.message?.includes("exists and is not an empty directory.")) {
return new util.UserError(`Is the "init" action called twice in the same job? ${e.message}`);
}
if (
// Version of CodeQL CLI is incompatible with this version of the CodeQL Action
e.message?.includes("is not compatible with this CodeQL CLI") ||
// Expected source location for database creation does not exist
e.message?.includes("Invalid source root")) {
return new util.UserError(e.message);
}
return e;
}
/** /**
* If we are running python 3.12+ on windows, we need to switch to python 3.11. * If we are running python 3.12+ on windows, we need to switch to python 3.11.
* This check happens in a powershell script. * This check happens in a powershell script.

View File

@@ -1 +1 @@
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"} {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}

2
lib/repository.js generated
View File

@@ -5,7 +5,7 @@ const util_1 = require("./util");
function parseRepositoryNwo(input) { function parseRepositoryNwo(input) {
const parts = input.split("/"); const parts = input.split("/");
if (parts.length !== 2) { if (parts.length !== 2) {
throw new util_1.UserError(`"${input}" is not a valid repository name`); throw new util_1.ConfigurationError(`"${input}" is not a valid repository name`);
} }
return { return {
owner: parts[0], owner: parts[0],

View File

@@ -1 +1 @@
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":";;;AAAA,iCAAmC;AAQnC,SAAgB,kBAAkB,CAAC,KAAa;IAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,gBAAS,CAAC,IAAI,KAAK,kCAAkC,CAAC,CAAC;IACnE,CAAC;IACD,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QACf,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;KACf,CAAC;AACJ,CAAC;AATD,gDASC"} {"version":3,"file":"repository.js","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":";;;AAAA,iCAA4C;AAQ5C,SAAgB,kBAAkB,CAAC,KAAa;IAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,yBAAkB,CAAC,IAAI,KAAK,kCAAkC,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QACf,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;KACf,CAAC;AACJ,CAAC;AATD,gDASC"}

View File

@@ -26,7 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core")); const core = __importStar(require("@actions/core"));
const actions_util_1 = require("./actions-util"); const actions_util_1 = require("./actions-util");
const api_client_1 = require("./api-client"); const api_client_1 = require("./api-client");
const codeql_1 = require("./codeql"); const cli_errors_1 = require("./cli-errors");
const configUtils = __importStar(require("./config-utils")); const configUtils = __importStar(require("./config-utils"));
const logging_1 = require("./logging"); const logging_1 = require("./logging");
const resolve_environment_1 = require("./resolve-environment"); const resolve_environment_1 = require("./resolve-environment");
@@ -54,7 +54,7 @@ async function run() {
} }
catch (unwrappedError) { catch (unwrappedError) {
const error = (0, util_1.wrapError)(unwrappedError); const error = (0, util_1.wrapError)(unwrappedError);
if (error instanceof codeql_1.CommandInvocationError) { if (error instanceof cli_errors_1.CommandInvocationError) {
// If the CLI failed to run successfully for whatever reason, // If the CLI failed to run successfully for whatever reason,
// we just return an empty JSON object and proceed with the workflow. // we just return an empty JSON object and proceed with the workflow.
core.setOutput(ENVIRONMENT_OUTPUT_NAME, {}); core.setOutput(ENVIRONMENT_OUTPUT_NAME, {});

View File

@@ -1 +1 @@
{"version":3,"file":"resolve-environment-action.js","sourceRoot":"","sources":["../src/resolve-environment-action.ts"],"names":[],"mappings":"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"} {"version":3,"file":"resolve-environment-action.js","sourceRoot":"","sources":["../src/resolve-environment-action.ts"],"names":[],"mappings":"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"}

View File

@@ -36,7 +36,7 @@ async function runResolveBuildEnvironment(cmd, logger, workingDir, languageInput
if (!(await util.codeQlVersionAbove(codeql, codeql_1.CODEQL_VERSION_LANGUAGE_ALIASING))) { if (!(await util.codeQlVersionAbove(codeql, codeql_1.CODEQL_VERSION_LANGUAGE_ALIASING))) {
const parsedLanguage = (0, languages_1.parseLanguage)(languageInput)?.toString(); const parsedLanguage = (0, languages_1.parseLanguage)(languageInput)?.toString();
if (parsedLanguage === undefined) { if (parsedLanguage === undefined) {
throw new util.UserError(`Did not recognize the language '${languageInput}'.`); throw new util.ConfigurationError(`Did not recognize the language '${languageInput}'.`);
} }
language = parsedLanguage; language = parsedLanguage;
} }

View File

@@ -1 +1 @@
{"version":3,"file":"resolve-environment.js","sourceRoot":"","sources":["../src/resolve-environment.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAIkB;AAClB,2CAA4C;AAE5C,6CAA+B;AAExB,KAAK,UAAU,0BAA0B,CAC9C,GAAW,EACX,MAAc,EACd,UAA8B,EAC9B,aAAqB;IAErB,MAAM,CAAC,UAAU,CACf,+CAA+C,aAAa,EAAE,CAC/D,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,IAAA,kBAAS,EAAC,GAAG,CAAC,CAAC;IAEpC,IAAI,QAAQ,GAAG,aAAa,CAAC;IAC7B,6FAA6F;IAC7F,mFAAmF;IACnF,IACE,CAAC,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,yCAAgC,CAAC,CAAC,EAC1E,CAAC;QACD,MAAM,cAAc,GAAG,IAAA,yBAAa,EAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC;QAChE,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,IAAI,IAAI,CAAC,SAAS,CACtB,mCAAmC,aAAa,IAAI,CACrD,CAAC;QACJ,CAAC;QACD,QAAQ,GAAG,cAAc,CAAC;IAC5B,CAAC;IAED,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,gFAAgF;IAChF,yEAAyE;IACzE,IACE,CAAC,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,2CAAkC,CAAC,CAAC,EAC5E,CAAC;QACD,MAAM,CAAC,OAAO,CACZ,0EAA0E;YACxE,mCAAmC,CACtC,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,SAAS,UAAU,4BAA4B,CAAC,CAAC;QAC/D,CAAC;QAED,MAAM,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,CAAC,QAAQ,EAAE,CAAC;IAClB,OAAO,MAAM,CAAC;AAChB,CAAC;AAhDD,gEAgDC"} {"version":3,"file":"resolve-environment.js","sourceRoot":"","sources":["../src/resolve-environment.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAIkB;AAClB,2CAA4C;AAE5C,6CAA+B;AAExB,KAAK,UAAU,0BAA0B,CAC9C,GAAW,EACX,MAAc,EACd,UAA8B,EAC9B,aAAqB;IAErB,MAAM,CAAC,UAAU,CACf,+CAA+C,aAAa,EAAE,CAC/D,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,IAAA,kBAAS,EAAC,GAAG,CAAC,CAAC;IAEpC,IAAI,QAAQ,GAAG,aAAa,CAAC;IAC7B,6FAA6F;IAC7F,mFAAmF;IACnF,IACE,CAAC,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,yCAAgC,CAAC,CAAC,EAC1E,CAAC;QACD,MAAM,cAAc,GAAG,IAAA,yBAAa,EAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC;QAChE,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,IAAI,IAAI,CAAC,kBAAkB,CAC/B,mCAAmC,aAAa,IAAI,CACrD,CAAC;QACJ,CAAC;QACD,QAAQ,GAAG,cAAc,CAAC;IAC5B,CAAC;IAED,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,gFAAgF;IAChF,yEAAyE;IACzE,IACE,CAAC,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,2CAAkC,CAAC,CAAC,EAC5E,CAAC;QACD,MAAM,CAAC,OAAO,CACZ,0EAA0E;YACxE,mCAAmC,CACtC,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,SAAS,UAAU,4BAA4B,CAAC,CAAC;QAC/D,CAAC;QAED,MAAM,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,CAAC,QAAQ,EAAE,CAAC;IAClB,OAAO,MAAM,CAAC;AAChB,CAAC;AAhDD,gEAgDC"}

2
lib/setup-codeql.js generated
View File

@@ -441,7 +441,7 @@ exports.downloadCodeQL = downloadCodeQL;
function getCodeQLURLVersion(url) { function getCodeQLURLVersion(url) {
const match = url.match(/\/codeql-bundle-(.*)\//); const match = url.match(/\/codeql-bundle-(.*)\//);
if (match === null || match.length < 2) { if (match === null || match.length < 2) {
throw new util.UserError(`Malformed tools url: ${url}. Version could not be inferred`); throw new util.ConfigurationError(`Malformed tools url: ${url}. Version could not be inferred`);
} }
return match[1]; return match[1];
} }

File diff suppressed because one or more lines are too long

14
lib/status-report.js generated
View File

@@ -33,14 +33,14 @@ const util_1 = require("./util");
/** Overall status of the entire job. String values match the Hydro schema. */ /** Overall status of the entire job. String values match the Hydro schema. */
var JobStatus; var JobStatus;
(function (JobStatus) { (function (JobStatus) {
JobStatus["Unknown"] = "JOB_STATUS_UNKNOWN"; JobStatus["UnknownStatus"] = "JOB_STATUS_UNKNOWN";
JobStatus["Success"] = "JOB_STATUS_SUCCESS"; JobStatus["SuccessStatus"] = "JOB_STATUS_SUCCESS";
JobStatus["Failure"] = "JOB_STATUS_FAILURE"; JobStatus["FailureStatus"] = "JOB_STATUS_FAILURE";
JobStatus["ConfigurationError"] = "JOB_STATUS_CONFIGURATION_ERROR"; JobStatus["ConfigErrorStatus"] = "JOB_STATUS_CONFIGURATION_ERROR";
})(JobStatus || (exports.JobStatus = JobStatus = {})); })(JobStatus || (exports.JobStatus = JobStatus = {}));
function getActionsStatus(error, otherFailureCause) { function getActionsStatus(error, otherFailureCause) {
if (error || otherFailureCause) { if (error || otherFailureCause) {
return error instanceof util_1.UserError ? "user-error" : "failure"; return error instanceof util_1.ConfigurationError ? "user-error" : "failure";
} }
else { else {
return "success"; return "success";
@@ -54,10 +54,10 @@ exports.getActionsStatus = getActionsStatus;
*/ */
function setJobStatusIfUnsuccessful(actionStatus) { function setJobStatusIfUnsuccessful(actionStatus) {
if (actionStatus === "user-error") { if (actionStatus === "user-error") {
core.exportVariable(environment_1.EnvVar.JOB_STATUS, process.env[environment_1.EnvVar.JOB_STATUS] ?? JobStatus.ConfigurationError); core.exportVariable(environment_1.EnvVar.JOB_STATUS, process.env[environment_1.EnvVar.JOB_STATUS] ?? JobStatus.ConfigErrorStatus);
} }
else if (actionStatus === "failure" || actionStatus === "aborted") { else if (actionStatus === "failure" || actionStatus === "aborted") {
core.exportVariable(environment_1.EnvVar.JOB_STATUS, process.env[environment_1.EnvVar.JOB_STATUS] ?? JobStatus.Failure); core.exportVariable(environment_1.EnvVar.JOB_STATUS, process.env[environment_1.EnvVar.JOB_STATUS] ?? JobStatus.FailureStatus);
} }
} }
/** /**

File diff suppressed because one or more lines are too long

14
lib/upload-lib.js generated
View File

@@ -132,17 +132,17 @@ exports.findSarifFilesInDir = findSarifFilesInDir;
* Uploads a single SARIF file or a directory of SARIF files depending on what `sarifPath` refers * Uploads a single SARIF file or a directory of SARIF files depending on what `sarifPath` refers
* to. * to.
* *
* @param considerInvalidRequestUserError Whether an invalid request, for example one with a * @param considerInvalidRequestConfigError Whether an invalid request, for example one with a
* `sarifPath` that does not exist, should be considered a * `sarifPath` that does not exist, should be considered a
* user error. * user error.
*/ */
async function uploadFromActions(sarifPath, checkoutPath, category, logger, { considerInvalidRequestUserError, }) { async function uploadFromActions(sarifPath, checkoutPath, category, logger, { considerInvalidRequestConfigError: considerInvalidRequestConfigError, }) {
try { try {
return await uploadFiles(getSarifFilePaths(sarifPath), (0, repository_1.parseRepositoryNwo)(util.getRequiredEnvParam("GITHUB_REPOSITORY")), await actionsUtil.getCommitOid(checkoutPath), await actionsUtil.getRef(), await api.getAnalysisKey(), category, util.getRequiredEnvParam("GITHUB_WORKFLOW"), actionsUtil.getWorkflowRunID(), actionsUtil.getWorkflowRunAttempt(), checkoutPath, actionsUtil.getRequiredInput("matrix"), logger); return await uploadFiles(getSarifFilePaths(sarifPath), (0, repository_1.parseRepositoryNwo)(util.getRequiredEnvParam("GITHUB_REPOSITORY")), await actionsUtil.getCommitOid(checkoutPath), await actionsUtil.getRef(), await api.getAnalysisKey(), category, util.getRequiredEnvParam("GITHUB_WORKFLOW"), actionsUtil.getWorkflowRunID(), actionsUtil.getWorkflowRunAttempt(), checkoutPath, actionsUtil.getRequiredInput("matrix"), logger);
} }
catch (e) { catch (e) {
if (e instanceof InvalidRequestError && considerInvalidRequestUserError) { if (e instanceof InvalidRequestError && considerInvalidRequestConfigError) {
throw new util_1.UserError(e.message); throw new util_1.ConfigurationError(e.message);
} }
throw e; throw e;
} }
@@ -343,8 +343,8 @@ async function waitForProcessing(repositoryNwo, sarifID, logger, options = {
} }
else if (status === "failed") { else if (status === "failed") {
const message = `Code Scanning could not process the submitted SARIF file:\n${response.data.errors}`; const message = `Code Scanning could not process the submitted SARIF file:\n${response.data.errors}`;
throw shouldConsiderAsUserError(response.data.errors) throw shouldConsiderConfigurationError(response.data.errors)
? new util_1.UserError(message) ? new util_1.ConfigurationError(message)
: new InvalidRequestError(message); : new InvalidRequestError(message);
} }
else { else {
@@ -363,7 +363,7 @@ exports.waitForProcessing = waitForProcessing;
/** /**
* Returns whether the provided processing errors should be considered a user error. * Returns whether the provided processing errors should be considered a user error.
*/ */
function shouldConsiderAsUserError(processingErrors) { function shouldConsiderConfigurationError(processingErrors) {
return (processingErrors.length === 1 && return (processingErrors.length === 1 &&
processingErrors[0] === processingErrors[0] ===
"CodeQL analyses from advanced configurations cannot be processed when the default setup is enabled"); "CodeQL analyses from advanced configurations cannot be processed when the default setup is enabled");

File diff suppressed because one or more lines are too long

View File

@@ -50,7 +50,7 @@ async function run() {
return; return;
} }
try { try {
const uploadResult = await upload_lib.uploadFromActions(actionsUtil.getRequiredInput("sarif_file"), actionsUtil.getRequiredInput("checkout_path"), actionsUtil.getOptionalInput("category"), logger, { considerInvalidRequestUserError: true }); const uploadResult = await upload_lib.uploadFromActions(actionsUtil.getRequiredInput("sarif_file"), actionsUtil.getRequiredInput("checkout_path"), actionsUtil.getOptionalInput("category"), logger, { considerInvalidRequestConfigError: true });
core.setOutput("sarif-id", uploadResult.sarifID); core.setOutput("sarif-id", uploadResult.sarifID);
// We don't upload results in test mode, so don't wait for processing // We don't upload results in test mode, so don't wait for processing
if ((0, util_1.isInTestMode)()) { if ((0, util_1.isInTestMode)()) {

View File

@@ -1 +1 @@
{"version":3,"file":"upload-sarif-action.js","sourceRoot":"","sources":["../src/upload-sarif-action.ts"],"names":[],"mappings":"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"} {"version":3,"file":"upload-sarif-action.js","sourceRoot":"","sources":["../src/upload-sarif-action.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oDAAsC;AAEtC,4DAA8C;AAC9C,iDAAkD;AAClD,6CAAgD;AAChD,uCAA6C;AAC7C,6CAAkD;AAClD,mDAKyB;AACzB,yDAA2C;AAC3C,iCAOgB;AAMhB,KAAK,UAAU,uBAAuB,CACpC,SAAe,EACf,WAA0C;IAE1C,MAAM,gBAAgB,GAAG,MAAM,IAAA,sCAAsB,EACnD,cAAc,EACd,SAAS,EACT,SAAS,EACT,MAAM,IAAA,qBAAc,GAAE,CACvB,CAAC;IACF,MAAM,YAAY,GAA4B;QAC5C,GAAG,gBAAgB;QACnB,GAAG,WAAW;KACf,CAAC;IACF,MAAM,IAAA,gCAAgB,EAAC,YAAY,CAAC,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,IAAA,0BAAgB,GAAE,CAAC;IAClC,IAAA,4BAAqB,EAAC,IAAA,+BAAgB,GAAE,CAAC,CAAC;IAE1C,MAAM,aAAa,GAAG,MAAM,IAAA,6BAAgB,GAAE,CAAC;IAC/C,IAAA,yBAAkB,EAAC,IAAA,+BAAgB,GAAE,EAAE,aAAa,CAAC,CAAC;IAEtD,IACE,CAAC,CAAC,MAAM,IAAA,gCAAgB,EACtB,MAAM,IAAA,sCAAsB,EAC1B,cAAc,EACd,UAAU,EACV,SAAS,EACT,MAAM,IAAA,qBAAc,GAAE,CACvB,CACF,CAAC,EACF,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,MAAM,UAAU,CAAC,iBAAiB,CACrD,WAAW,CAAC,gBAAgB,CAAC,YAAY,CAAC,EAC1C,WAAW,CAAC,gBAAgB,CAAC,eAAe,CAAC,EAC7C,WAAW,CAAC,gBAAgB,CAAC,UAAU,CAAC,EACxC,MAAM,EACN,EAAE,iCAAiC,EAAE,IAAI,EAAE,CAC5C,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;QAEjD,qEAAqE;QACrE,IAAI,IAAA,mBAAY,GAAE,EAAE,CAAC;YACnB,IAAI,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QAClE,CAAC;aAAM,IAAI,WAAW,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,KAAK,MAAM,EAAE,CAAC;YAC1E,MAAM,UAAU,CAAC,iBAAiB,CAChC,IAAA,+BAAkB,EAAC,IAAA,0BAAmB,EAAC,mBAAmB,CAAC,CAAC,EAC5D,YAAY,CAAC,OAAO,EACpB,MAAM,CACP,CAAC;QACJ,CAAC;QACD,MAAM,uBAAuB,CAAC,SAAS,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;IACtE,CAAC;IAAC,OAAO,cAAc,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,IAAA,gBAAS,EAAC,cAAc,CAAC,CAAC;QACxC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC9B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,IAAA,gCAAgB,EACpB,MAAM,IAAA,sCAAsB,EAC1B,cAAc,EACd,IAAA,gCAAgB,EAAC,KAAK,CAAC,EACvB,SAAS,EACT,MAAM,IAAA,qBAAc,GAAE,EACtB,OAAO,EACP,KAAK,CAAC,KAAK,CACZ,CACF,CAAC;QACF,OAAO;IACT,CAAC;AACH,CAAC;AAED,KAAK,UAAU,UAAU;IACvB,IAAI,CAAC;QACH,MAAM,GAAG,EAAE,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,SAAS,CACZ,sCAAsC,IAAA,gBAAS,EAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CACjE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,EAAE,CAAC"}

16
lib/util.js generated
View File

@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod }; return (mod && mod.__esModule) ? mod : { "default": mod };
}; };
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.checkActionVersion = exports.checkDiskUsage = exports.prettyPrintPack = exports.getErrorMessage = exports.wrapError = exports.fixInvalidNotificationsInFile = exports.fixInvalidNotifications = exports.parseMatrixInput = exports.isHostedRunner = exports.checkForTimeout = exports.withTimeout = exports.tryGetFolderBytes = exports.listFolder = exports.doesDirectoryExist = exports.isInTestMode = exports.supportExpectDiscardedCache = exports.isGoodVersion = exports.delay = exports.bundleDb = exports.codeQlVersionAbove = exports.getCachedCodeQlVersion = exports.cacheCodeQlVersion = exports.isHTTPError = exports.UserError = exports.HTTPError = exports.getRequiredEnvParam = exports.initializeEnvironment = exports.assertNever = exports.apiVersionInRange = exports.DisallowedAPIVersionReason = exports.checkGitHubVersionInRange = exports.GitHubVariant = exports.parseGitHubUrl = exports.getCodeQLDatabasePath = exports.getThreadsFlag = exports.getThreadsFlagValue = exports.getAddSnippetsFlag = exports.getMemoryFlag = exports.getMemoryFlagValue = exports.getMemoryFlagValueForPlatform = exports.withTmpDir = exports.getToolNames = exports.getExtraOptionsEnvParam = exports.DEFAULT_DEBUG_DATABASE_NAME = exports.DEFAULT_DEBUG_ARTIFACT_NAME = exports.GITHUB_DOTCOM_URL = void 0; exports.checkActionVersion = exports.checkDiskUsage = exports.prettyPrintPack = exports.getErrorMessage = exports.wrapError = exports.fixInvalidNotificationsInFile = exports.fixInvalidNotifications = exports.parseMatrixInput = exports.isHostedRunner = exports.checkForTimeout = exports.withTimeout = exports.tryGetFolderBytes = exports.listFolder = exports.doesDirectoryExist = exports.isInTestMode = exports.supportExpectDiscardedCache = exports.isGoodVersion = exports.delay = exports.bundleDb = exports.codeQlVersionAbove = exports.getCachedCodeQlVersion = exports.cacheCodeQlVersion = exports.isHTTPError = exports.ConfigurationError = exports.HTTPError = exports.getRequiredEnvParam = exports.initializeEnvironment = exports.assertNever = exports.apiVersionInRange = exports.DisallowedAPIVersionReason = exports.checkGitHubVersionInRange = exports.GitHubVariant = exports.parseGitHubUrl = exports.getCodeQLDatabasePath = exports.getThreadsFlag = exports.getThreadsFlagValue = exports.getAddSnippetsFlag = exports.getMemoryFlag = exports.getMemoryFlagValue = exports.getMemoryFlagValueForPlatform = exports.withTmpDir = exports.getToolNames = exports.getExtraOptionsEnvParam = exports.DEFAULT_DEBUG_DATABASE_NAME = exports.DEFAULT_DEBUG_ARTIFACT_NAME = exports.GITHUB_DOTCOM_URL = void 0;
const fs = __importStar(require("fs")); const fs = __importStar(require("fs"));
const os = __importStar(require("os")); const os = __importStar(require("os"));
const path = __importStar(require("path")); const path = __importStar(require("path"));
@@ -78,7 +78,7 @@ function getExtraOptionsEnvParam() {
} }
catch (unwrappedError) { catch (unwrappedError) {
const error = wrapError(unwrappedError); const error = wrapError(unwrappedError);
throw new UserError(`${varName} environment variable is set, but does not contain valid JSON: ${error.message}`); throw new ConfigurationError(`${varName} environment variable is set, but does not contain valid JSON: ${error.message}`);
} }
} }
exports.getExtraOptionsEnvParam = getExtraOptionsEnvParam; exports.getExtraOptionsEnvParam = getExtraOptionsEnvParam;
@@ -142,7 +142,7 @@ function getMemoryFlagValueForPlatform(userInput, totalMemoryBytes, platform) {
if (userInput) { if (userInput) {
memoryToUseMegaBytes = Number(userInput); memoryToUseMegaBytes = Number(userInput);
if (Number.isNaN(memoryToUseMegaBytes) || memoryToUseMegaBytes <= 0) { if (Number.isNaN(memoryToUseMegaBytes) || memoryToUseMegaBytes <= 0) {
throw new UserError(`Invalid RAM setting "${userInput}", specified.`); throw new ConfigurationError(`Invalid RAM setting "${userInput}", specified.`);
} }
} }
else { else {
@@ -262,7 +262,7 @@ function getThreadsFlagValue(userInput, logger) {
if (userInput) { if (userInput) {
numThreads = Number(userInput); numThreads = Number(userInput);
if (Number.isNaN(numThreads)) { if (Number.isNaN(numThreads)) {
throw new UserError(`Invalid threads setting "${userInput}", specified.`); throw new ConfigurationError(`Invalid threads setting "${userInput}", specified.`);
} }
if (numThreads > maxThreads) { if (numThreads > maxThreads) {
logger.info(`Clamping desired number of threads (${numThreads}) to max available (${maxThreads}).`); logger.info(`Clamping desired number of threads (${numThreads}) to max available (${maxThreads}).`);
@@ -360,14 +360,14 @@ function parseGitHubUrl(inputUrl) {
inputUrl = `https://${inputUrl}`; inputUrl = `https://${inputUrl}`;
} }
if (!inputUrl.startsWith("http://") && !inputUrl.startsWith("https://")) { if (!inputUrl.startsWith("http://") && !inputUrl.startsWith("https://")) {
throw new UserError(`"${originalUrl}" is not a http or https URL`); throw new ConfigurationError(`"${originalUrl}" is not a http or https URL`);
} }
let url; let url;
try { try {
url = new URL(inputUrl); url = new URL(inputUrl);
} }
catch (e) { catch (e) {
throw new UserError(`"${originalUrl}" is not a valid URL`); throw new ConfigurationError(`"${originalUrl}" is not a valid URL`);
} }
// If we detect this is trying to be to github.com // If we detect this is trying to be to github.com
// then return with a fixed canonical URL. // then return with a fixed canonical URL.
@@ -478,12 +478,12 @@ exports.HTTPError = HTTPError;
* An Error class that indicates an error that occurred due to * An Error class that indicates an error that occurred due to
* a misconfiguration of the action or the CodeQL CLI. * a misconfiguration of the action or the CodeQL CLI.
*/ */
class UserError extends Error { class ConfigurationError extends Error {
constructor(message) { constructor(message) {
super(message); super(message);
} }
} }
exports.UserError = UserError; exports.ConfigurationError = ConfigurationError;
function isHTTPError(arg) { function isHTTPError(arg) {
return arg?.status !== undefined && Number.isInteger(arg.status); return arg?.status !== undefined && Number.isInteger(arg.status);
} }

File diff suppressed because one or more lines are too long

View File

@@ -11,7 +11,7 @@ import {
doesDirectoryExist, doesDirectoryExist,
getCodeQLDatabasePath, getCodeQLDatabasePath,
getRequiredEnvParam, getRequiredEnvParam,
UserError, ConfigurationError,
} from "./util"; } from "./util";
// eslint-disable-next-line import/no-commonjs // eslint-disable-next-line import/no-commonjs
@@ -26,7 +26,7 @@ const pkg = require("../package.json") as JSONSchemaForNPMPackageJsonFiles;
export const getRequiredInput = function (name: string): string { export const getRequiredInput = function (name: string): string {
const value = core.getInput(name); const value = core.getInput(name);
if (!value) { if (!value) {
throw new UserError(`Input required and not supplied: ${name}`); throw new ConfigurationError(`Input required and not supplied: ${name}`);
} }
return value; return value;
}; };
@@ -187,7 +187,7 @@ export async function getRef(): Promise<string> {
const hasShaInput = !!shaInput; const hasShaInput = !!shaInput;
// If one of 'ref' or 'sha' are provided, both are required // If one of 'ref' or 'sha' are provided, both are required
if ((hasRefInput || hasShaInput) && !(hasRefInput && hasShaInput)) { if ((hasRefInput || hasShaInput) && !(hasRefInput && hasShaInput)) {
throw new UserError( throw new ConfigurationError(
"Both 'ref' and 'sha' are required if one of them is provided.", "Both 'ref' and 'sha' are required if one of them is provided.",
); );
} }

View File

@@ -207,7 +207,7 @@ async function run() {
} }
if (hasBadExpectErrorInput()) { if (hasBadExpectErrorInput()) {
throw new util.UserError( throw new util.ConfigurationError(
"`expect-error` input parameter is for internal use only. It should only be set by codeql-action or a fork.", "`expect-error` input parameter is for internal use only. It should only be set by codeql-action or a fork.",
); );
} }
@@ -285,7 +285,7 @@ async function run() {
actionsUtil.getRequiredInput("checkout_path"), actionsUtil.getRequiredInput("checkout_path"),
actionsUtil.getOptionalInput("category"), actionsUtil.getOptionalInput("category"),
logger, logger,
{ considerInvalidRequestUserError: false }, { considerInvalidRequestConfigError: false },
); );
core.setOutput("sarif-id", uploadResult.sarifID); core.setOutput("sarif-id", uploadResult.sarifID);
} else { } else {

209
src/cli-errors.ts Normal file
View File

@@ -0,0 +1,209 @@
import { ConfigurationError } from "./util";
/**
* A class of Error that we can classify as an error stemming from a CLI
* invocation, with associated exit code, stderr,etc.
*/
export class CommandInvocationError extends Error {
constructor(
cmd: string,
args: string[],
public exitCode: number,
public stderr: string,
public stdout: string,
) {
const prettyCommand = [cmd, ...args]
.map((x) => (x.includes(" ") ? `'${x}'` : x))
.join(" ");
const fatalErrors = extractFatalErrors(stderr);
const lastLine = stderr.trim().split("\n").pop()?.trim();
let error = fatalErrors
? ` and error was: ${fatalErrors.trim()}`
: lastLine
? ` and last log line was: ${lastLine}`
: "";
if (error[error.length - 1] !== ".") {
error += ".";
}
super(
`Encountered a fatal error while running "${prettyCommand}". ` +
`Exit code was ${exitCode}${error} See the logs for more details.`,
);
}
}
/**
* Provide a better error message from the stderr of a CLI invocation that failed with a fatal
* error.
*
* - If the CLI invocation failed with a fatal error, this returns that fatal error, followed by
* any fatal errors that occurred in plumbing commands.
* - If the CLI invocation did not fail with a fatal error, this returns `undefined`.
*
* ### Example
*
* ```
* Running TRAP import for CodeQL database at /home/runner/work/_temp/codeql_databases/javascript...
* A fatal error occurred: Evaluator heap must be at least 384.00 MiB
* A fatal error occurred: Dataset import for
* /home/runner/work/_temp/codeql_databases/javascript/db-javascript failed with code 2
* ```
*
* becomes
*
* ```
* Encountered a fatal error while running "codeql-for-testing database finalize --finalize-dataset
* --threads=2 --ram=2048 db". Exit code was 32 and error was: A fatal error occurred: Dataset
* import for /home/runner/work/_temp/codeql_databases/javascript/db-javascript failed with code 2.
* Context: A fatal error occurred: Evaluator heap must be at least 384.00 MiB.
* ```
*
* Where possible, this tries to summarize the error into a single line, as this displays better in
* the Actions UI.
*/
function extractFatalErrors(error: string): string | undefined {
const fatalErrorRegex = /.*fatal error occurred:/gi;
let fatalErrors: string[] = [];
let lastFatalErrorIndex: number | undefined;
let match: RegExpMatchArray | null;
while ((match = fatalErrorRegex.exec(error)) !== null) {
if (lastFatalErrorIndex !== undefined) {
fatalErrors.push(error.slice(lastFatalErrorIndex, match.index).trim());
}
lastFatalErrorIndex = match.index;
}
if (lastFatalErrorIndex !== undefined) {
const lastError = error.slice(lastFatalErrorIndex).trim();
if (fatalErrors.length === 0) {
// No other errors
return lastError;
}
const isOneLiner = !fatalErrors.some((e) => e.includes("\n"));
if (isOneLiner) {
fatalErrors = fatalErrors.map(ensureEndsInPeriod);
}
return [
ensureEndsInPeriod(lastError),
"Context:",
...fatalErrors.reverse(),
].join(isOneLiner ? " " : "\n");
}
return undefined;
}
function ensureEndsInPeriod(text: string): string {
return text[text.length - 1] === "." ? text : `${text}.`;
}
/** Error messages from the CLI that we consider configuration errors and handle specially. */
export enum CliConfigErrorCategory {
IncompatibleWithActionVersion = "IncompatibleWithActionVersion",
InitCalledTwice = "InitCalledTwice",
InvalidSourceRoot = "InvalidSourceRoot",
NoJavaScriptTypeScriptCodeFound = "NoJavaScriptTypeScriptCodeFound",
}
type CliErrorConfiguration = {
cliErrorMessageSnippets: string[];
exitCode?: number;
// Error message to prepend for this type of CLI error.
// If undefined, use original CLI error message.
additionalErrorMessageToPrepend?: string;
};
/**
* All of our caught CLI error messages that we handle specially: ie. if we
* would like to categorize an error as a configuration error or not.
*/
export const cliErrorsConfig: Record<
CliConfigErrorCategory,
CliErrorConfiguration
> = {
// Version of CodeQL CLI is incompatible with this version of the CodeQL Action
[CliConfigErrorCategory.IncompatibleWithActionVersion]: {
cliErrorMessageSnippets: ["is not compatible with this CodeQL CLI"],
},
[CliConfigErrorCategory.InitCalledTwice]: {
cliErrorMessageSnippets: [
"Refusing to create databases",
"exists and is not an empty directory",
],
additionalErrorMessageToPrepend: `Is the "init" action called twice in the same job?`,
},
// Expected source location for database creation does not exist
[CliConfigErrorCategory.InvalidSourceRoot]: {
cliErrorMessageSnippets: ["Invalid source root"],
},
/**
* Earlier versions of the JavaScript extractor (pre-CodeQL 2.12.0) extract externs even if no
* source code was found. This means that we don't get the no code found error from
* `codeql database finalize`. To ensure users get a good error message, we detect this manually
* here, and upon detection override the error message.
*
* This can be removed once support for CodeQL 2.11.6 is removed.
*/
[CliConfigErrorCategory.NoJavaScriptTypeScriptCodeFound]: {
exitCode: 32,
cliErrorMessageSnippets: ["No JavaScript or TypeScript code found."],
additionalErrorMessageToPrepend:
"No code found during the build. Please see: " +
"https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build.",
},
};
// Check if the given CLI error or exit code, if applicable, apply to any known
// CLI errors in the configuration record. If either the CLI error message matches all of
// the error messages in the config record, or the exit codes match, return the error category;
// if not, return undefined.
export function getCliConfigCategoryIfExists(
cliError: CommandInvocationError,
): CliConfigErrorCategory | undefined {
for (const [category, configuration] of Object.entries(cliErrorsConfig)) {
if (
cliError.exitCode !== undefined &&
configuration.exitCode !== undefined &&
cliError.exitCode === configuration.exitCode
) {
return category as CliConfigErrorCategory;
}
let allMessageSnippetsFound: boolean = true;
for (const e of configuration.cliErrorMessageSnippets) {
if (!cliError.message.includes(e) && !cliError.stderr.includes(e)) {
allMessageSnippetsFound = false;
}
}
if (allMessageSnippetsFound === true) {
return category as CliConfigErrorCategory;
}
}
return undefined;
}
/**
* Changes an error received from the CLI to a ConfigurationError with optionally an extra
* error message prepended, if it exists in a known set of configuration errors. Otherwise,
* simply returns the original error.
*/
export function wrapCliConfigurationError(cliError: Error): Error {
if (!(cliError instanceof CommandInvocationError)) {
return cliError;
}
const cliConfigErrorCategory = getCliConfigCategoryIfExists(cliError);
if (cliConfigErrorCategory === undefined) {
return cliError;
}
const errorMessageWrapperIfExists =
cliErrorsConfig[cliConfigErrorCategory].additionalErrorMessageToPrepend;
return errorMessageWrapperIfExists
? new ConfigurationError(
`${errorMessageWrapperIfExists} ${cliError.message}`,
)
: new ConfigurationError(cliError.message);
}

View File

@@ -875,9 +875,11 @@ test("database finalize recognises JavaScript no code found error on CodeQL 2.11
await t.throwsAsync( await t.throwsAsync(
async () => await codeqlObject.finalizeDatabase("", "", ""), async () => await codeqlObject.finalizeDatabase("", "", ""),
{ {
message: instanceOf: util.ConfigurationError,
message: new RegExp(
"No code found during the build. Please see: " + "No code found during the build. Please see: " +
"https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build", "https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build.+",
),
}, },
); );
}); });
@@ -892,9 +894,11 @@ test("database finalize overrides no code found error on CodeQL 2.11.6", async (
await t.throwsAsync( await t.throwsAsync(
async () => await codeqlObject.finalizeDatabase("", "", ""), async () => await codeqlObject.finalizeDatabase("", "", ""),
{ {
message: instanceOf: util.ConfigurationError,
message: new RegExp(
"No code found during the build. Please see: " + "No code found during the build. Please see: " +
"https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build", "https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build.+",
),
}, },
); );
}); });

View File

@@ -12,6 +12,10 @@ import {
isAnalyzingDefaultBranch, isAnalyzingDefaultBranch,
} from "./actions-util"; } from "./actions-util";
import * as api from "./api-client"; import * as api from "./api-client";
import {
CommandInvocationError,
wrapCliConfigurationError,
} from "./cli-errors";
import type { Config } from "./config-utils"; import type { Config } from "./config-utils";
import { EnvVar } from "./environment"; import { EnvVar } from "./environment";
import { import {
@@ -48,36 +52,6 @@ interface ExtraOptions {
}; };
} }
export class CommandInvocationError extends Error {
constructor(
cmd: string,
args: string[],
public exitCode: number,
public stderr: string,
public stdout: string,
) {
const prettyCommand = [cmd, ...args]
.map((x) => (x.includes(" ") ? `'${x}'` : x))
.join(" ");
const fatalErrors = extractFatalErrors(stderr);
const lastLine = stderr.trim().split("\n").pop()?.trim();
let error = fatalErrors
? ` and error was: ${fatalErrors.trim()}`
: lastLine
? ` and last log line was: ${lastLine}`
: "";
if (error[error.length - 1] !== ".") {
error += ".";
}
super(
`Encountered a fatal error while running "${prettyCommand}". ` +
`Exit code was ${exitCode}${error} See the logs for more details.`,
);
}
}
export interface CodeQL { export interface CodeQL {
/** /**
* Get the path of the CodeQL executable. * Get the path of the CodeQL executable.
@@ -409,7 +383,9 @@ export async function setupCodeQL(
if (process.platform === "win32") { if (process.platform === "win32") {
codeqlCmd += ".exe"; codeqlCmd += ".exe";
} else if (process.platform !== "linux" && process.platform !== "darwin") { } else if (process.platform !== "linux" && process.platform !== "darwin") {
throw new util.UserError(`Unsupported platform: ${process.platform}`); throw new util.ConfigurationError(
`Unsupported platform: ${process.platform}`,
);
} }
cachedCodeQL = await getCodeQLForCmd(codeqlCmd, checkVersion); cachedCodeQL = await getCodeQLForCmd(codeqlCmd, checkVersion);
@@ -639,20 +615,27 @@ export async function getCodeQLForCmd(
extraArgs.push("--no-sublanguage-file-coverage"); extraArgs.push("--no-sublanguage-file-coverage");
} }
await runTool( try {
cmd, await runTool(
[ cmd,
"database", [
"init", "database",
"--db-cluster", "init",
config.dbLocation, "--db-cluster",
`--source-root=${sourceRoot}`, config.dbLocation,
...(await getLanguageAliasingArguments(this)), `--source-root=${sourceRoot}`,
...extraArgs, ...(await getLanguageAliasingArguments(this)),
...getExtraOptionsFromEnv(["database", "init"]), ...extraArgs,
], ...getExtraOptionsFromEnv(["database", "init"]),
{ stdin: externalRepositoryToken }, ],
); { stdin: externalRepositoryToken },
);
} catch (e) {
if (e instanceof Error) {
throw wrapCliConfigurationError(e);
}
throw e;
}
}, },
async runAutobuild(language: Language) { async runAutobuild(language: Language) {
const autobuildCmd = path.join( const autobuildCmd = path.join(
@@ -727,17 +710,13 @@ export async function getCodeQLForCmd(
await runTool(cmd, args); await runTool(cmd, args);
} catch (e) { } catch (e) {
if ( if (
e instanceof CommandInvocationError && e instanceof Error &&
!(await util.codeQlVersionAbove( !(await util.codeQlVersionAbove(
this, this,
CODEQL_VERSION_BETTER_NO_CODE_ERROR_MESSAGE, CODEQL_VERSION_BETTER_NO_CODE_ERROR_MESSAGE,
)) && ))
isNoCodeFoundError(e)
) { ) {
throw new util.UserError( throw wrapCliConfigurationError(e);
"No code found during the build. Please see: " +
"https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build",
);
} }
throw e; throw e;
} }
@@ -1128,7 +1107,7 @@ export async function getCodeQLForCmd(
checkVersion && checkVersion &&
!(await util.codeQlVersionAbove(codeql, CODEQL_MINIMUM_VERSION)) !(await util.codeQlVersionAbove(codeql, CODEQL_MINIMUM_VERSION))
) { ) {
throw new util.UserError( throw new util.ConfigurationError(
`Expected a CodeQL CLI with version at least ${CODEQL_MINIMUM_VERSION} but got version ${ `Expected a CodeQL CLI with version at least ${CODEQL_MINIMUM_VERSION} but got version ${
(await codeql.getVersion()).version (await codeql.getVersion()).version
}`, }`,
@@ -1265,69 +1244,6 @@ async function runTool(
return output; return output;
} }
/**
* Provide a better error message from the stderr of a CLI invocation that failed with a fatal
* error.
*
* - If the CLI invocation failed with a fatal error, this returns that fatal error, followed by
* any fatal errors that occurred in plumbing commands.
* - If the CLI invocation did not fail with a fatal error, this returns `undefined`.
*
* ### Example
*
* ```
* Running TRAP import for CodeQL database at /home/runner/work/_temp/codeql_databases/javascript...
* A fatal error occurred: Evaluator heap must be at least 384.00 MiB
* A fatal error occurred: Dataset import for
* /home/runner/work/_temp/codeql_databases/javascript/db-javascript failed with code 2
* ```
*
* becomes
*
* ```
* Encountered a fatal error while running "codeql-for-testing database finalize --finalize-dataset
* --threads=2 --ram=2048 db". Exit code was 32 and error was: A fatal error occurred: Dataset
* import for /home/runner/work/_temp/codeql_databases/javascript/db-javascript failed with code 2.
* Context: A fatal error occurred: Evaluator heap must be at least 384.00 MiB.
* ```
*
* Where possible, this tries to summarize the error into a single line, as this displays better in
* the Actions UI.
*/
function extractFatalErrors(error: string): string | undefined {
const fatalErrorRegex = /.*fatal error occurred:/gi;
let fatalErrors: string[] = [];
let lastFatalErrorIndex: number | undefined;
let match: RegExpMatchArray | null;
while ((match = fatalErrorRegex.exec(error)) !== null) {
if (lastFatalErrorIndex !== undefined) {
fatalErrors.push(error.slice(lastFatalErrorIndex, match.index).trim());
}
lastFatalErrorIndex = match.index;
}
if (lastFatalErrorIndex !== undefined) {
const lastError = error.slice(lastFatalErrorIndex).trim();
if (fatalErrors.length === 0) {
// No other errors
return lastError;
}
const isOneLiner = !fatalErrors.some((e) => e.includes("\n"));
if (isOneLiner) {
fatalErrors = fatalErrors.map(ensureEndsInPeriod);
}
return [
ensureEndsInPeriod(lastError),
"Context:",
...fatalErrors.reverse(),
].join(isOneLiner ? " " : "\n");
}
return undefined;
}
function ensureEndsInPeriod(text: string): string {
return text[text.length - 1] === "." ? text : `${text}.`;
}
/** /**
* Generates a code scanning configuration that is to be used for a scan. * Generates a code scanning configuration that is to be used for a scan.
* *
@@ -1458,20 +1374,6 @@ export function getGeneratedCodeScanningConfigPath(config: Config): string {
return path.resolve(config.tempDir, "user-config.yaml"); return path.resolve(config.tempDir, "user-config.yaml");
} }
function isNoCodeFoundError(e: CommandInvocationError): boolean {
/**
* Earlier versions of the JavaScript extractor (pre-CodeQL 2.12.0) extract externs even if no
* source code was found. This means that we don't get the no code found error from
* `codeql database finalize`. To ensure users get a good error message, we detect this manually
* here, and upon detection override the error message.
*
* This can be removed once support for CodeQL 2.11.6 is removed.
*/
const javascriptNoCodeFoundWarning =
"No JavaScript or TypeScript code found.";
return e.exitCode === 32 || e.stderr.includes(javascriptNoCodeFoundWarning);
}
async function isDiagnosticsExportInvalidSarifFixed( async function isDiagnosticsExportInvalidSarifFixed(
codeql: CodeQL, codeql: CodeQL,
): Promise<boolean> { ): Promise<boolean> {

View File

@@ -26,7 +26,7 @@ import {
GitHubVariant, GitHubVariant,
GitHubVersion, GitHubVersion,
prettyPrintPack, prettyPrintPack,
UserError, ConfigurationError,
withTmpDir, withTmpDir,
} from "./util"; } from "./util";
@@ -219,7 +219,7 @@ test("load input outside of workspace", async (t) => {
} catch (err) { } catch (err) {
t.deepEqual( t.deepEqual(
err, err,
new UserError( new ConfigurationError(
configUtils.getConfigFileOutsideWorkspaceErrorMessage( configUtils.getConfigFileOutsideWorkspaceErrorMessage(
path.join(tempDir, "../input"), path.join(tempDir, "../input"),
), ),
@@ -247,7 +247,7 @@ test("load non-local input with invalid repo syntax", async (t) => {
} catch (err) { } catch (err) {
t.deepEqual( t.deepEqual(
err, err,
new UserError( new ConfigurationError(
configUtils.getConfigFileRepoFormatInvalidMessage( configUtils.getConfigFileRepoFormatInvalidMessage(
"octo-org/codeql-config@main", "octo-org/codeql-config@main",
), ),
@@ -277,7 +277,7 @@ test("load non-existent input", async (t) => {
} catch (err) { } catch (err) {
t.deepEqual( t.deepEqual(
err, err,
new UserError( new ConfigurationError(
configUtils.getConfigFileDoesNotExistErrorMessage( configUtils.getConfigFileDoesNotExistErrorMessage(
path.join(tempDir, "input"), path.join(tempDir, "input"),
), ),
@@ -517,7 +517,7 @@ test("Remote config handles the case where a directory is provided", async (t) =
} catch (err) { } catch (err) {
t.deepEqual( t.deepEqual(
err, err,
new UserError( new ConfigurationError(
configUtils.getConfigFileDirectoryGivenMessage(repoReference), configUtils.getConfigFileDirectoryGivenMessage(repoReference),
), ),
); );
@@ -546,7 +546,7 @@ test("Invalid format of remote config handled correctly", async (t) => {
} catch (err) { } catch (err) {
t.deepEqual( t.deepEqual(
err, err,
new UserError( new ConfigurationError(
configUtils.getConfigFileFormatInvalidMessage(repoReference), configUtils.getConfigFileFormatInvalidMessage(repoReference),
), ),
); );
@@ -576,7 +576,10 @@ test("No detected languages", async (t) => {
); );
throw new Error("initConfig did not throw error"); throw new Error("initConfig did not throw error");
} catch (err) { } catch (err) {
t.deepEqual(err, new UserError(configUtils.getNoLanguagesError())); t.deepEqual(
err,
new ConfigurationError(configUtils.getNoLanguagesError()),
);
} }
}); });
}); });
@@ -598,7 +601,7 @@ test("Unknown languages", async (t) => {
} catch (err) { } catch (err) {
t.deepEqual( t.deepEqual(
err, err,
new UserError( new ConfigurationError(
configUtils.getUnknownLanguagesError(["rubbish", "english"]), configUtils.getUnknownLanguagesError(["rubbish", "english"]),
), ),
); );

View File

@@ -15,7 +15,7 @@ import {
codeQlVersionAbove, codeQlVersionAbove,
GitHubVersion, GitHubVersion,
prettyPrintPack, prettyPrintPack,
UserError, ConfigurationError,
} from "./util"; } from "./util";
// Property names from the user-supplied config file. // Property names from the user-supplied config file.
@@ -332,7 +332,7 @@ export async function getLanguages(
// If the languages parameter was not given and no languages were // If the languages parameter was not given and no languages were
// detected then fail here as this is a workflow configuration error. // detected then fail here as this is a workflow configuration error.
if (languages.length === 0) { if (languages.length === 0) {
throw new UserError(getNoLanguagesError()); throw new ConfigurationError(getNoLanguagesError());
} }
// Make sure they are supported // Make sure they are supported
@@ -350,7 +350,7 @@ export async function getLanguages(
// Any unknown languages here would have come directly from the input // Any unknown languages here would have come directly from the input
// since we filter unknown languages coming from the GitHub API. // since we filter unknown languages coming from the GitHub API.
if (unknownLanguages.length > 0) { if (unknownLanguages.length > 0) {
throw new UserError(getUnknownLanguagesError(unknownLanguages)); throw new ConfigurationError(getUnknownLanguagesError(unknownLanguages));
} }
return parsedLanguages; return parsedLanguages;
@@ -631,7 +631,7 @@ function parseQueriesFromInput(
? rawQueriesInput.trim().slice(1).trim() ? rawQueriesInput.trim().slice(1).trim()
: rawQueriesInput?.trim() ?? ""; : rawQueriesInput?.trim() ?? "";
if (queriesInputCombines && trimmedInput.length === 0) { if (queriesInputCombines && trimmedInput.length === 0) {
throw new UserError( throw new ConfigurationError(
getConfigFilePropertyError( getConfigFilePropertyError(
undefined, undefined,
"queries", "queries",
@@ -664,11 +664,11 @@ export function parsePacksFromInput(
} }
if (languages.length > 1) { if (languages.length > 1) {
throw new UserError( throw new ConfigurationError(
"Cannot specify a 'packs' input in a multi-language analysis. Use a codeql-config.yml file instead and specify packs by language.", "Cannot specify a 'packs' input in a multi-language analysis. Use a codeql-config.yml file instead and specify packs by language.",
); );
} else if (languages.length === 0) { } else if (languages.length === 0) {
throw new UserError( throw new ConfigurationError(
"No languages specified. Cannot process the packs input.", "No languages specified. Cannot process the packs input.",
); );
} }
@@ -677,7 +677,7 @@ export function parsePacksFromInput(
if (packsInputCombines) { if (packsInputCombines) {
rawPacksInput = rawPacksInput.trim().substring(1).trim(); rawPacksInput = rawPacksInput.trim().substring(1).trim();
if (!rawPacksInput) { if (!rawPacksInput) {
throw new UserError( throw new ConfigurationError(
getConfigFilePropertyError( getConfigFilePropertyError(
undefined, undefined,
"packs", "packs",
@@ -715,7 +715,7 @@ export function parsePacksFromInput(
*/ */
export function parsePacksSpecification(packStr: string): Pack { export function parsePacksSpecification(packStr: string): Pack {
if (typeof packStr !== "string") { if (typeof packStr !== "string") {
throw new UserError(getPacksStrInvalid(packStr)); throw new ConfigurationError(getPacksStrInvalid(packStr));
} }
packStr = packStr.trim(); packStr = packStr.trim();
@@ -743,14 +743,14 @@ export function parsePacksSpecification(packStr: string): Pack {
: undefined; : undefined;
if (!PACK_IDENTIFIER_PATTERN.test(packName)) { if (!PACK_IDENTIFIER_PATTERN.test(packName)) {
throw new UserError(getPacksStrInvalid(packStr)); throw new ConfigurationError(getPacksStrInvalid(packStr));
} }
if (version) { if (version) {
try { try {
new semver.Range(version); new semver.Range(version);
} catch (e) { } catch (e) {
// The range string is invalid. OK to ignore the caught error // The range string is invalid. OK to ignore the caught error
throw new UserError(getPacksStrInvalid(packStr)); throw new ConfigurationError(getPacksStrInvalid(packStr));
} }
} }
@@ -764,12 +764,12 @@ export function parsePacksSpecification(packStr: string): Pack {
path.normalize(packPath).split(path.sep).join("/") !== path.normalize(packPath).split(path.sep).join("/") !==
packPath.split(path.sep).join("/")) packPath.split(path.sep).join("/"))
) { ) {
throw new UserError(getPacksStrInvalid(packStr)); throw new ConfigurationError(getPacksStrInvalid(packStr));
} }
if (!packPath && pathStart) { if (!packPath && pathStart) {
// 0 length path // 0 length path
throw new UserError(getPacksStrInvalid(packStr)); throw new ConfigurationError(getPacksStrInvalid(packStr));
} }
return { return {
@@ -852,7 +852,9 @@ function parseRegistries(
? (yaml.load(registriesInput) as RegistryConfigWithCredentials[]) ? (yaml.load(registriesInput) as RegistryConfigWithCredentials[])
: undefined; : undefined;
} catch (e) { } catch (e) {
throw new UserError("Invalid registries input. Must be a YAML string."); throw new ConfigurationError(
"Invalid registries input. Must be a YAML string.",
);
} }
} }
@@ -868,12 +870,16 @@ function isLocal(configPath: string): boolean {
function getLocalConfig(configFile: string, workspacePath: string): UserConfig { function getLocalConfig(configFile: string, workspacePath: string): UserConfig {
// Error if the config file is now outside of the workspace // Error if the config file is now outside of the workspace
if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) { if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) {
throw new UserError(getConfigFileOutsideWorkspaceErrorMessage(configFile)); throw new ConfigurationError(
getConfigFileOutsideWorkspaceErrorMessage(configFile),
);
} }
// Error if the file does not exist // Error if the file does not exist
if (!fs.existsSync(configFile)) { if (!fs.existsSync(configFile)) {
throw new UserError(getConfigFileDoesNotExistErrorMessage(configFile)); throw new ConfigurationError(
getConfigFileDoesNotExistErrorMessage(configFile),
);
} }
return yaml.load(fs.readFileSync(configFile, "utf8")) as UserConfig; return yaml.load(fs.readFileSync(configFile, "utf8")) as UserConfig;
@@ -890,7 +896,9 @@ async function getRemoteConfig(
const pieces = format.exec(configFile); const pieces = format.exec(configFile);
// 5 = 4 groups + the whole expression // 5 = 4 groups + the whole expression
if (pieces === null || pieces.groups === undefined || pieces.length < 5) { if (pieces === null || pieces.groups === undefined || pieces.length < 5) {
throw new UserError(getConfigFileRepoFormatInvalidMessage(configFile)); throw new ConfigurationError(
getConfigFileRepoFormatInvalidMessage(configFile),
);
} }
const response = await api const response = await api
@@ -906,9 +914,11 @@ async function getRemoteConfig(
if ("content" in response.data && response.data.content !== undefined) { if ("content" in response.data && response.data.content !== undefined) {
fileContents = response.data.content; fileContents = response.data.content;
} else if (Array.isArray(response.data)) { } else if (Array.isArray(response.data)) {
throw new UserError(getConfigFileDirectoryGivenMessage(configFile)); throw new ConfigurationError(
getConfigFileDirectoryGivenMessage(configFile),
);
} else { } else {
throw new UserError(getConfigFileFormatInvalidMessage(configFile)); throw new ConfigurationError(getConfigFileFormatInvalidMessage(configFile));
} }
return yaml.load( return yaml.load(
@@ -1008,7 +1018,7 @@ function createRegistriesBlock(registries: RegistryConfigWithCredentials[]): {
!Array.isArray(registries) || !Array.isArray(registries) ||
registries.some((r) => !r.url || !r.packages) registries.some((r) => !r.url || !r.packages)
) { ) {
throw new UserError( throw new ConfigurationError(
"Invalid 'registries' input. Must be an array of objects with 'url' and 'packages' properties.", "Invalid 'registries' input. Must be an array of objects with 'url' and 'packages' properties.",
); );
} }
@@ -1071,7 +1081,7 @@ function validateBuildModeInput(
} }
if (!Object.values(BuildMode).includes(buildModeInput as BuildMode)) { if (!Object.values(BuildMode).includes(buildModeInput as BuildMode)) {
throw new UserError( throw new ConfigurationError(
`Invalid build mode: '${buildModeInput}'. Supported build modes are: ${Object.values( `Invalid build mode: '${buildModeInput}'. Supported build modes are: ${Object.values(
BuildMode, BuildMode,
).join(", ")}.`, ).join(", ")}.`,

View File

@@ -107,7 +107,7 @@ async function maybeUploadFailedSarif(
checkoutPath, checkoutPath,
category, category,
logger, logger,
{ considerInvalidRequestUserError: false }, { considerInvalidRequestConfigError: false },
); );
await uploadLib.waitForProcessing( await uploadLib.waitForProcessing(
repositoryNwo, repositoryNwo,
@@ -134,7 +134,7 @@ export async function tryUploadSarifIfRunFailed(
// consider this a configuration error. // consider this a configuration error.
core.exportVariable( core.exportVariable(
EnvVar.JOB_STATUS, EnvVar.JOB_STATUS,
process.env[EnvVar.JOB_STATUS] ?? JobStatus.ConfigurationError, process.env[EnvVar.JOB_STATUS] ?? JobStatus.ConfigErrorStatus,
); );
try { try {
return await maybeUploadFailedSarif( return await maybeUploadFailedSarif(
@@ -152,7 +152,7 @@ export async function tryUploadSarifIfRunFailed(
} else { } else {
core.exportVariable( core.exportVariable(
EnvVar.JOB_STATUS, EnvVar.JOB_STATUS,
process.env[EnvVar.JOB_STATUS] ?? JobStatus.Success, process.env[EnvVar.JOB_STATUS] ?? JobStatus.SuccessStatus,
); );
return { return {
upload_failed_run_skipped_because: upload_failed_run_skipped_because:
@@ -314,7 +314,7 @@ export function getFinalJobStatus(): JobStatus {
!jobStatusFromEnvironment || !jobStatusFromEnvironment ||
!Object.values(JobStatus).includes(jobStatusFromEnvironment as JobStatus) !Object.values(JobStatus).includes(jobStatusFromEnvironment as JobStatus)
) { ) {
return JobStatus.Unknown; return JobStatus.UnknownStatus;
} }
return jobStatusFromEnvironment as JobStatus; return jobStatusFromEnvironment as JobStatus;
} }

View File

@@ -52,7 +52,7 @@ import {
getThreadsFlagValue, getThreadsFlagValue,
initializeEnvironment, initializeEnvironment,
isHostedRunner, isHostedRunner,
UserError, ConfigurationError,
wrapError, wrapError,
checkActionVersion, checkActionVersion,
} from "./util"; } from "./util";
@@ -317,7 +317,7 @@ async function run() {
await sendStatusReport( await sendStatusReport(
await createStatusReportBase( await createStatusReportBase(
"init", "init",
error instanceof UserError ? "user-error" : "aborted", error instanceof ConfigurationError ? "user-error" : "aborted",
startedAt, startedAt,
await checkDiskUsage(), await checkDiskUsage(),
error.message, error.message,

View File

@@ -64,32 +64,29 @@ export async function runInit(
logger: Logger, logger: Logger,
): Promise<TracerConfig | undefined> { ): Promise<TracerConfig | undefined> {
fs.mkdirSync(config.dbLocation, { recursive: true }); fs.mkdirSync(config.dbLocation, { recursive: true });
try {
const { registriesAuthTokens, qlconfigFile } =
await configUtils.generateRegistries(
registriesInput,
config.tempDir,
logger,
);
await configUtils.wrapEnvironment(
{
GITHUB_TOKEN: apiDetails.auth,
CODEQL_REGISTRIES_AUTH: registriesAuthTokens,
},
// Init a database cluster const { registriesAuthTokens, qlconfigFile } =
async () => await configUtils.generateRegistries(
await codeql.databaseInitCluster( registriesInput,
config, config.tempDir,
sourceRoot, logger,
processName,
qlconfigFile,
logger,
),
); );
} catch (e) { await configUtils.wrapEnvironment(
throw processError(e); {
} GITHUB_TOKEN: apiDetails.auth,
CODEQL_REGISTRIES_AUTH: registriesAuthTokens,
},
// Init a database cluster
async () =>
await codeql.databaseInitCluster(
config,
sourceRoot,
processName,
qlconfigFile,
logger,
),
);
return await getCombinedTracerConfig(codeql, config); return await getCombinedTracerConfig(codeql, config);
} }
@@ -110,42 +107,6 @@ export function printPathFiltersWarning(
} }
} }
/**
* Possibly convert this error into a UserError in order to avoid
* counting this error towards our internal error budget.
*
* @param e The error to possibly convert to a UserError.
*
* @returns A UserError if the error is a known error that can be
* attributed to the user, otherwise the original error.
*/
function processError(e: any): Error {
if (!(e instanceof Error)) {
return e;
}
if (
// Init action called twice
e.message?.includes("Refusing to create databases") &&
e.message?.includes("exists and is not an empty directory.")
) {
return new util.UserError(
`Is the "init" action called twice in the same job? ${e.message}`,
);
}
if (
// Version of CodeQL CLI is incompatible with this version of the CodeQL Action
e.message?.includes("is not compatible with this CodeQL CLI") ||
// Expected source location for database creation does not exist
e.message?.includes("Invalid source root")
) {
return new util.UserError(e.message);
}
return e;
}
/** /**
* If we are running python 3.12+ on windows, we need to switch to python 3.11. * If we are running python 3.12+ on windows, we need to switch to python 3.11.
* This check happens in a powershell script. * This check happens in a powershell script.

View File

@@ -1,4 +1,4 @@
import { UserError } from "./util"; import { ConfigurationError } from "./util";
// A repository name with owner, parsed into its two parts // A repository name with owner, parsed into its two parts
export interface RepositoryNwo { export interface RepositoryNwo {
@@ -9,7 +9,7 @@ export interface RepositoryNwo {
export function parseRepositoryNwo(input: string): RepositoryNwo { export function parseRepositoryNwo(input: string): RepositoryNwo {
const parts = input.split("/"); const parts = input.split("/");
if (parts.length !== 2) { if (parts.length !== 2) {
throw new UserError(`"${input}" is not a valid repository name`); throw new ConfigurationError(`"${input}" is not a valid repository name`);
} }
return { return {
owner: parts[0], owner: parts[0],

View File

@@ -7,7 +7,7 @@ import {
getTemporaryDirectory, getTemporaryDirectory,
} from "./actions-util"; } from "./actions-util";
import { getGitHubVersion } from "./api-client"; import { getGitHubVersion } from "./api-client";
import { CommandInvocationError } from "./codeql"; import { CommandInvocationError } from "./cli-errors";
import * as configUtils from "./config-utils"; import * as configUtils from "./config-utils";
import { getActionsLogger } from "./logging"; import { getActionsLogger } from "./logging";
import { runResolveBuildEnvironment } from "./resolve-environment"; import { runResolveBuildEnvironment } from "./resolve-environment";

View File

@@ -27,7 +27,7 @@ export async function runResolveBuildEnvironment(
) { ) {
const parsedLanguage = parseLanguage(languageInput)?.toString(); const parsedLanguage = parseLanguage(languageInput)?.toString();
if (parsedLanguage === undefined) { if (parsedLanguage === undefined) {
throw new util.UserError( throw new util.ConfigurationError(
`Did not recognize the language '${languageInput}'.`, `Did not recognize the language '${languageInput}'.`,
); );
} }

View File

@@ -608,7 +608,7 @@ export async function downloadCodeQL(
export function getCodeQLURLVersion(url: string): string { export function getCodeQLURLVersion(url: string): string {
const match = url.match(/\/codeql-bundle-(.*)\//); const match = url.match(/\/codeql-bundle-(.*)\//);
if (match === null || match.length < 2) { if (match === null || match.length < 2) {
throw new util.UserError( throw new util.ConfigurationError(
`Malformed tools url: ${url}. Version could not be inferred`, `Malformed tools url: ${url}. Version could not be inferred`,
); );
} }

View File

@@ -14,7 +14,7 @@ import {
import { getAnalysisKey, getApiClient } from "./api-client"; import { getAnalysisKey, getApiClient } from "./api-client";
import { EnvVar } from "./environment"; import { EnvVar } from "./environment";
import { import {
UserError, ConfigurationError,
isHTTPError, isHTTPError,
getRequiredEnvParam, getRequiredEnvParam,
getCachedCodeQlVersion, getCachedCodeQlVersion,
@@ -40,10 +40,10 @@ export type ActionStatus =
/** Overall status of the entire job. String values match the Hydro schema. */ /** Overall status of the entire job. String values match the Hydro schema. */
export enum JobStatus { export enum JobStatus {
Unknown = "JOB_STATUS_UNKNOWN", UnknownStatus = "JOB_STATUS_UNKNOWN",
Success = "JOB_STATUS_SUCCESS", SuccessStatus = "JOB_STATUS_SUCCESS",
Failure = "JOB_STATUS_FAILURE", FailureStatus = "JOB_STATUS_FAILURE",
ConfigurationError = "JOB_STATUS_CONFIGURATION_ERROR", ConfigErrorStatus = "JOB_STATUS_CONFIGURATION_ERROR",
} }
export interface StatusReportBase { export interface StatusReportBase {
@@ -135,7 +135,7 @@ export function getActionsStatus(
otherFailureCause?: string, otherFailureCause?: string,
): ActionStatus { ): ActionStatus {
if (error || otherFailureCause) { if (error || otherFailureCause) {
return error instanceof UserError ? "user-error" : "failure"; return error instanceof ConfigurationError ? "user-error" : "failure";
} else { } else {
return "success"; return "success";
} }
@@ -150,12 +150,12 @@ function setJobStatusIfUnsuccessful(actionStatus: ActionStatus) {
if (actionStatus === "user-error") { if (actionStatus === "user-error") {
core.exportVariable( core.exportVariable(
EnvVar.JOB_STATUS, EnvVar.JOB_STATUS,
process.env[EnvVar.JOB_STATUS] ?? JobStatus.ConfigurationError, process.env[EnvVar.JOB_STATUS] ?? JobStatus.ConfigErrorStatus,
); );
} else if (actionStatus === "failure" || actionStatus === "aborted") { } else if (actionStatus === "failure" || actionStatus === "aborted") {
core.exportVariable( core.exportVariable(
EnvVar.JOB_STATUS, EnvVar.JOB_STATUS,
process.env[EnvVar.JOB_STATUS] ?? JobStatus.Failure, process.env[EnvVar.JOB_STATUS] ?? JobStatus.FailureStatus,
); );
} }
} }

View File

@@ -14,7 +14,7 @@ import * as fingerprints from "./fingerprints";
import { Logger } from "./logging"; import { Logger } from "./logging";
import { parseRepositoryNwo, RepositoryNwo } from "./repository"; import { parseRepositoryNwo, RepositoryNwo } from "./repository";
import * as util from "./util"; import * as util from "./util";
import { SarifFile, UserError, wrapError } from "./util"; import { SarifFile, ConfigurationError, wrapError } from "./util";
// Takes a list of paths to sarif files and combines them together, // Takes a list of paths to sarif files and combines them together,
// returning the contents of the combined sarif file. // returning the contents of the combined sarif file.
@@ -158,7 +158,7 @@ export function findSarifFilesInDir(sarifPath: string): string[] {
* Uploads a single SARIF file or a directory of SARIF files depending on what `sarifPath` refers * Uploads a single SARIF file or a directory of SARIF files depending on what `sarifPath` refers
* to. * to.
* *
* @param considerInvalidRequestUserError Whether an invalid request, for example one with a * @param considerInvalidRequestConfigError Whether an invalid request, for example one with a
* `sarifPath` that does not exist, should be considered a * `sarifPath` that does not exist, should be considered a
* user error. * user error.
*/ */
@@ -168,8 +168,8 @@ export async function uploadFromActions(
category: string | undefined, category: string | undefined,
logger: Logger, logger: Logger,
{ {
considerInvalidRequestUserError, considerInvalidRequestConfigError: considerInvalidRequestConfigError,
}: { considerInvalidRequestUserError: boolean }, }: { considerInvalidRequestConfigError: boolean },
): Promise<UploadResult> { ): Promise<UploadResult> {
try { try {
return await uploadFiles( return await uploadFiles(
@@ -187,8 +187,8 @@ export async function uploadFromActions(
logger, logger,
); );
} catch (e) { } catch (e) {
if (e instanceof InvalidRequestError && considerInvalidRequestUserError) { if (e instanceof InvalidRequestError && considerInvalidRequestConfigError) {
throw new UserError(e.message); throw new ConfigurationError(e.message);
} }
throw e; throw e;
} }
@@ -489,8 +489,8 @@ export async function waitForProcessing(
break; break;
} else if (status === "failed") { } else if (status === "failed") {
const message = `Code Scanning could not process the submitted SARIF file:\n${response.data.errors}`; const message = `Code Scanning could not process the submitted SARIF file:\n${response.data.errors}`;
throw shouldConsiderAsUserError(response.data.errors as string[]) throw shouldConsiderConfigurationError(response.data.errors as string[])
? new UserError(message) ? new ConfigurationError(message)
: new InvalidRequestError(message); : new InvalidRequestError(message);
} else { } else {
util.assertNever(status); util.assertNever(status);
@@ -508,7 +508,7 @@ export async function waitForProcessing(
/** /**
* Returns whether the provided processing errors should be considered a user error. * Returns whether the provided processing errors should be considered a user error.
*/ */
function shouldConsiderAsUserError(processingErrors: string[]): boolean { function shouldConsiderConfigurationError(processingErrors: string[]): boolean {
return ( return (
processingErrors.length === 1 && processingErrors.length === 1 &&
processingErrors[0] === processingErrors[0] ===

View File

@@ -69,7 +69,7 @@ async function run() {
actionsUtil.getRequiredInput("checkout_path"), actionsUtil.getRequiredInput("checkout_path"),
actionsUtil.getOptionalInput("category"), actionsUtil.getOptionalInput("category"),
logger, logger,
{ considerInvalidRequestUserError: true }, { considerInvalidRequestConfigError: true },
); );
core.setOutput("sarif-id", uploadResult.sarifID); core.setOutput("sarif-id", uploadResult.sarifID);

View File

@@ -120,7 +120,7 @@ export function getExtraOptionsEnvParam(): object {
return JSON.parse(raw); return JSON.parse(raw);
} catch (unwrappedError) { } catch (unwrappedError) {
const error = wrapError(unwrappedError); const error = wrapError(unwrappedError);
throw new UserError( throw new ConfigurationError(
`${varName} environment variable is set, but does not contain valid JSON: ${error.message}`, `${varName} environment variable is set, but does not contain valid JSON: ${error.message}`,
); );
} }
@@ -204,7 +204,9 @@ export function getMemoryFlagValueForPlatform(
if (userInput) { if (userInput) {
memoryToUseMegaBytes = Number(userInput); memoryToUseMegaBytes = Number(userInput);
if (Number.isNaN(memoryToUseMegaBytes) || memoryToUseMegaBytes <= 0) { if (Number.isNaN(memoryToUseMegaBytes) || memoryToUseMegaBytes <= 0) {
throw new UserError(`Invalid RAM setting "${userInput}", specified.`); throw new ConfigurationError(
`Invalid RAM setting "${userInput}", specified.`,
);
} }
} else { } else {
const totalMemoryMegaBytes = totalMemoryBytes / (1024 * 1024); const totalMemoryMegaBytes = totalMemoryBytes / (1024 * 1024);
@@ -373,7 +375,9 @@ export function getThreadsFlagValue(
if (userInput) { if (userInput) {
numThreads = Number(userInput); numThreads = Number(userInput);
if (Number.isNaN(numThreads)) { if (Number.isNaN(numThreads)) {
throw new UserError(`Invalid threads setting "${userInput}", specified.`); throw new ConfigurationError(
`Invalid threads setting "${userInput}", specified.`,
);
} }
if (numThreads > maxThreads) { if (numThreads > maxThreads) {
logger.info( logger.info(
@@ -500,14 +504,14 @@ export function parseGitHubUrl(inputUrl: string): string {
inputUrl = `https://${inputUrl}`; inputUrl = `https://${inputUrl}`;
} }
if (!inputUrl.startsWith("http://") && !inputUrl.startsWith("https://")) { if (!inputUrl.startsWith("http://") && !inputUrl.startsWith("https://")) {
throw new UserError(`"${originalUrl}" is not a http or https URL`); throw new ConfigurationError(`"${originalUrl}" is not a http or https URL`);
} }
let url: URL; let url: URL;
try { try {
url = new URL(inputUrl); url = new URL(inputUrl);
} catch (e) { } catch (e) {
throw new UserError(`"${originalUrl}" is not a valid URL`); throw new ConfigurationError(`"${originalUrl}" is not a valid URL`);
} }
// If we detect this is trying to be to github.com // If we detect this is trying to be to github.com
@@ -652,7 +656,7 @@ export class HTTPError extends Error {
* An Error class that indicates an error that occurred due to * An Error class that indicates an error that occurred due to
* a misconfiguration of the action or the CodeQL CLI. * a misconfiguration of the action or the CodeQL CLI.
*/ */
export class UserError extends Error { export class ConfigurationError extends Error {
constructor(message: string) { constructor(message: string) {
super(message); super(message);
} }