Auto-fix linting errors

This commit is contained in:
Angela P Wen
2023-07-25 10:29:00 +02:00
parent eff6331393
commit b16296be30
52 changed files with 1182 additions and 1172 deletions

File diff suppressed because one or more lines are too long

View File

@@ -93,7 +93,8 @@ async function mockHttpRequests(databaseUploadStatusCode) {
const loggedMessages = [];
await (0, database_upload_1.uploadDatabases)(testRepoName, getTestConfig(tmpDir), testApiDetails, (0, testing_utils_1.getRecordingLogger)(loggedMessages));
t.assert(loggedMessages.find((v) => v.type === "debug" &&
v.message === "Database upload disabled in workflow. Skipping upload.") !== undefined);
v.message ===
"Database upload disabled in workflow. Skipping upload.") !== undefined);
});
});
(0, ava_1.default)("Abort database upload if running against GHES", async (t) => {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -132,7 +132,7 @@ test("getRef() throws an error if only `ref` is provided as an input", async (t)
instanceOf: Error,
message:
"Both 'ref' and 'sha' are required if one of them is provided.",
}
},
);
getAdditionalInputStub.restore();
});
@@ -153,7 +153,7 @@ test("getRef() throws an error if only `sha` is provided as an input", async (t)
instanceOf: Error,
message:
"Both 'ref' and 'sha' are required if one of them is provided.",
}
},
);
getAdditionalInputStub.restore();
});
@@ -162,51 +162,51 @@ test("getRef() throws an error if only `sha` is provided as an input", async (t)
test("computeAutomationID()", async (t) => {
let actualAutomationID = computeAutomationID(
".github/workflows/codeql-analysis.yml:analyze",
'{"language": "javascript", "os": "linux"}'
'{"language": "javascript", "os": "linux"}',
);
t.deepEqual(
actualAutomationID,
".github/workflows/codeql-analysis.yml:analyze/language:javascript/os:linux/"
".github/workflows/codeql-analysis.yml:analyze/language:javascript/os:linux/",
);
// check the environment sorting
actualAutomationID = computeAutomationID(
".github/workflows/codeql-analysis.yml:analyze",
'{"os": "linux", "language": "javascript"}'
'{"os": "linux", "language": "javascript"}',
);
t.deepEqual(
actualAutomationID,
".github/workflows/codeql-analysis.yml:analyze/language:javascript/os:linux/"
".github/workflows/codeql-analysis.yml:analyze/language:javascript/os:linux/",
);
// check that an empty environment produces the right results
actualAutomationID = computeAutomationID(
".github/workflows/codeql-analysis.yml:analyze",
"{}"
"{}",
);
t.deepEqual(
actualAutomationID,
".github/workflows/codeql-analysis.yml:analyze/"
".github/workflows/codeql-analysis.yml:analyze/",
);
// check non string environment values
actualAutomationID = computeAutomationID(
".github/workflows/codeql-analysis.yml:analyze",
'{"number": 1, "object": {"language": "javascript"}}'
'{"number": 1, "object": {"language": "javascript"}}',
);
t.deepEqual(
actualAutomationID,
".github/workflows/codeql-analysis.yml:analyze/number:/object:/"
".github/workflows/codeql-analysis.yml:analyze/number:/object:/",
);
// check undefined environment
actualAutomationID = computeAutomationID(
".github/workflows/codeql-analysis.yml:analyze",
undefined
undefined,
);
t.deepEqual(
actualAutomationID,
".github/workflows/codeql-analysis.yml:analyze/"
".github/workflows/codeql-analysis.yml:analyze/",
);
});
@@ -230,7 +230,7 @@ test("isAnalyzingDefaultBranch()", async (t) => {
repository: {
default_branch: "main",
},
})
}),
);
process.env["GITHUB_EVENT_PATH"] = envFile;
@@ -248,7 +248,7 @@ test("isAnalyzingDefaultBranch()", async (t) => {
envFile,
JSON.stringify({
schedule: "0 0 * * *",
})
}),
);
process.env["GITHUB_EVENT_NAME"] = "schedule";
process.env["GITHUB_REF"] = "refs/heads/main";
@@ -288,14 +288,14 @@ test("createStatusReportBase", async (t) => {
"failure",
new Date("May 19, 2023 05:19:00"),
"failure cause",
"exception stack trace"
"exception stack trace",
);
t.assert(typeof statusReport.job_run_uuid === "string");
t.assert(statusReport.workflow_run_id === 100);
t.assert(statusReport.workflow_run_attempt === 2);
t.assert(
statusReport.workflow_name === (process.env["GITHUB_WORKFLOW"] || "")
statusReport.workflow_name === (process.env["GITHUB_WORKFLOW"] || ""),
);
t.assert(statusReport.job_name === (process.env["GITHUB_JOB"] || ""));
t.assert(statusReport.analysis_key === "analysis-key");
@@ -304,11 +304,11 @@ test("createStatusReportBase", async (t) => {
t.assert(statusReport.action_name === "init");
t.assert(statusReport.action_oid === "unknown");
t.assert(
statusReport.started_at === process.env[EnvVar.WORKFLOW_STARTED_AT]
statusReport.started_at === process.env[EnvVar.WORKFLOW_STARTED_AT],
);
t.assert(
statusReport.action_started_at ===
new Date("May 19, 2023 05:19:00").toISOString()
new Date("May 19, 2023 05:19:00").toISOString(),
);
t.assert(statusReport.status === "failure");
t.assert(statusReport.cause === "failure cause");

View File

@@ -50,7 +50,7 @@ export function getTemporaryDirectory(): string {
*/
export const getCommitOid = async function (
checkoutPath: string,
ref = "HEAD"
ref = "HEAD",
): Promise<string> {
// Try to use git to get the current commit SHA. If that fails then
// log but otherwise silently fall back to using the SHA from the environment.
@@ -75,12 +75,12 @@ export const getCommitOid = async function (
},
},
cwd: checkoutPath,
}
},
).exec();
return commitOid.trim();
} catch (e) {
core.info(
"Could not determine current commit SHA using git. Continuing with data from user input or environment."
"Could not determine current commit SHA using git. Continuing with data from user input or environment.",
);
core.debug(`Reason: ${(e as Error).message}`);
core.debug((e as Error).stack || "NO STACK");
@@ -129,7 +129,7 @@ export const determineMergeBaseCommitOid = async function (): Promise<
},
},
cwd: checkoutPath,
}
},
).exec();
// Let's confirm our assumptions: We had a merge commit and the parsed parent data looks correct
@@ -143,7 +143,7 @@ export const determineMergeBaseCommitOid = async function (): Promise<
return undefined;
} catch (e) {
core.info(
`Failed to call git to determine merge base. Continuing with data from environment: ${e}`
`Failed to call git to determine merge base. Continuing with data from environment: ${e}`,
);
core.info((e as Error).stack || "NO STACK");
return undefined;
@@ -168,7 +168,7 @@ export async function getRef(): Promise<string> {
// If one of 'ref' or 'sha' are provided, both are required
if ((hasRefInput || hasShaInput) && !(hasRefInput && hasShaInput)) {
throw new Error(
"Both 'ref' and 'sha' are required if one of them is provided."
"Both 'ref' and 'sha' are required if one of them is provided.",
);
}
@@ -201,13 +201,13 @@ export async function getRef(): Promise<string> {
sha !== head &&
(await getCommitOid(
checkoutPath,
ref.replace(/^refs\/pull\//, "refs/remotes/pull/")
ref.replace(/^refs\/pull\//, "refs/remotes/pull/"),
)) !== head;
if (hasChangedRef) {
const newRef = ref.replace(pull_ref_regex, "refs/pull/$1/head");
core.debug(
`No longer on merge commit, rewriting ref from ${ref} to ${newRef}.`
`No longer on merge commit, rewriting ref from ${ref} to ${newRef}.`,
);
return newRef;
} else {
@@ -346,7 +346,7 @@ export interface DatabaseCreationTimings {
export function getActionsStatus(
error?: unknown,
otherFailureCause?: string
otherFailureCause?: string,
): ActionStatus {
if (error || otherFailureCause) {
return error instanceof UserError ? "user-error" : "failure";
@@ -397,7 +397,7 @@ function getWorkflowEvent(): any {
return JSON.parse(fs.readFileSync(eventJsonFile, "utf-8"));
} catch (e) {
throw new Error(
`Unable to read workflow event JSON from ${eventJsonFile}: ${e}`
`Unable to read workflow event JSON from ${eventJsonFile}: ${e}`,
);
}
}
@@ -450,7 +450,7 @@ export async function printDebugLogs(config: Config) {
if (entry.isFile()) {
const absolutePath = path.resolve(dir, entry.name);
core.startGroup(
`CodeQL Debug Logs - ${language} - ${entry.name} from file at path ${absolutePath}`
`CodeQL Debug Logs - ${language} - ${entry.name} from file at path ${absolutePath}`,
);
process.stdout.write(fs.readFileSync(absolutePath));
core.endGroup();
@@ -482,7 +482,7 @@ export function getUploadValue(input: string | undefined): UploadKind {
return "never";
default:
core.warning(
`Unrecognized 'upload' input to 'analyze' Action: ${input}. Defaulting to 'always'.`
`Unrecognized 'upload' input to 'analyze' Action: ${input}. Defaulting to 'always'.`,
);
return "always";
}
@@ -496,12 +496,12 @@ export function getWorkflowRunID(): number {
const workflowRunID = parseInt(workflowRunIdString, 10);
if (Number.isNaN(workflowRunID)) {
throw new Error(
`GITHUB_RUN_ID must define a non NaN workflow run ID. Current value is ${workflowRunIdString}`
`GITHUB_RUN_ID must define a non NaN workflow run ID. Current value is ${workflowRunIdString}`,
);
}
if (workflowRunID < 0) {
throw new Error(
`GITHUB_RUN_ID must be a non-negative integer. Current value is ${workflowRunIdString}`
`GITHUB_RUN_ID must be a non-negative integer. Current value is ${workflowRunIdString}`,
);
}
return workflowRunID;
@@ -515,12 +515,12 @@ export function getWorkflowRunAttempt(): number {
const workflowRunAttempt = parseInt(workflowRunAttemptString, 10);
if (Number.isNaN(workflowRunAttempt)) {
throw new Error(
`GITHUB_RUN_ATTEMPT must define a non NaN workflow run attempt. Current value is ${workflowRunAttemptString}`
`GITHUB_RUN_ATTEMPT must define a non NaN workflow run attempt. Current value is ${workflowRunAttemptString}`,
);
}
if (workflowRunAttempt <= 0) {
throw new Error(
`GITHUB_RUN_ATTEMPT must be a positive integer. Current value is ${workflowRunAttemptString}`
`GITHUB_RUN_ATTEMPT must be a positive integer. Current value is ${workflowRunAttemptString}`,
);
}
return workflowRunAttempt;

View File

@@ -68,7 +68,7 @@ test("nonEmptyPaths", async (t) => {
t.is(process.env["LGTM_INDEX_EXCLUDE"], "path4\npath5");
t.is(
process.env["LGTM_INDEX_FILTERS"],
"include:path1\ninclude:path2\ninclude:**/path3\nexclude:path4\nexclude:path5\nexclude:path6/**"
"include:path1\ninclude:path2\ninclude:**/path3\nexclude:path4\nexclude:path5\nexclude:path6/**",
);
});
});

View File

@@ -27,7 +27,7 @@ function buildIncludeExcludeEnvVar(paths: string[]): string {
export function printPathFiltersWarning(
config: configUtils.Config,
logger: Logger
logger: Logger,
) {
// Index include/exclude/filters only work in javascript/python/ruby.
// If any other languages are detected/configured then show a warning.
@@ -36,7 +36,7 @@ export function printPathFiltersWarning(
!config.languages.every(isInterpretedLanguage)
) {
logger.warning(
'The "paths"/"paths-ignore" fields of the config only have effect for JavaScript, Python, and Ruby'
'The "paths"/"paths-ignore" fields of the config only have effect for JavaScript, Python, and Ruby',
);
}
}

View File

@@ -10,14 +10,14 @@ export async function run(uploadSarifDebugArtifact: Function) {
const config = await getConfig(actionsUtil.getTemporaryDirectory(), logger);
if (config === undefined) {
throw new Error(
"Config file could not be found at expected location. Did the 'init' action fail to start?"
"Config file could not be found at expected location. Did the 'init' action fail to start?",
);
}
// Upload Actions SARIF artifacts for debugging
if (config?.debugMode) {
core.info(
"Debug mode is on. Uploading available SARIF files as Actions debugging artifact..."
"Debug mode is on. Uploading available SARIF files as Actions debugging artifact...",
);
const outputDir = actionsUtil.getRequiredInput("output");
await uploadSarifDebugArtifact(config, outputDir);

View File

@@ -14,7 +14,7 @@ async function runWrapper() {
await analyzeActionPostHelper.run(debugArtifacts.uploadSarifDebugArtifact);
} catch (error) {
core.setFailed(
`analyze post-action step failed: ${wrapError(error).message}`
`analyze post-action step failed: ${wrapError(error).message}`,
);
}
}

View File

@@ -55,18 +55,18 @@ export async function sendStatusReport(
trapCacheUploadTime: number | undefined,
dbCreationTimings: DatabaseCreationTimings | undefined,
didUploadTrapCaches: boolean,
logger: Logger
logger: Logger,
) {
const status = actionsUtil.getActionsStatus(
error,
stats?.analyze_failure_language
stats?.analyze_failure_language,
);
const statusReportBase = await api.createStatusReportBase(
"finish",
status,
startedAt,
error?.message,
error?.stack
error?.stack,
);
const statusReport: FinishStatusReport = {
...statusReportBase,
@@ -83,7 +83,7 @@ export async function sendStatusReport(
...statusReport,
trap_cache_upload_duration_ms: Math.round(trapCacheUploadTime || 0),
trap_cache_upload_size_bytes: Math.round(
await getTotalCacheSize(config.trapCaches, logger)
await getTotalCacheSize(config.trapCaches, logger),
),
};
await api.sendStatusReport(trapCacheUploadStatusReport);
@@ -119,7 +119,7 @@ function doesGoExtractionOutputExist(config: Config): boolean {
".trap.tar.gz",
".trap.tar.br",
".trap.tar",
].some((ext) => fileName.endsWith(ext))
].some((ext) => fileName.endsWith(ext)),
)
);
}
@@ -147,20 +147,20 @@ async function runAutobuildIfLegacyGoWorkflow(config: Config, logger: Logger) {
}
if (dbIsFinalized(config, Language.go, logger)) {
logger.debug(
"Won't run Go autobuild since there is already a finalized database for Go."
"Won't run Go autobuild since there is already a finalized database for Go.",
);
return;
}
// This captures whether a user has added manual build steps for Go
if (doesGoExtractionOutputExist(config)) {
logger.debug(
"Won't run Go autobuild since at least one file of Go code has already been extracted."
"Won't run Go autobuild since at least one file of Go code has already been extracted.",
);
// If the user has run the manual build step, and has set the `CODEQL_EXTRACTOR_GO_BUILD_TRACING`
// variable, we suggest they remove it from their workflow.
if ("CODEQL_EXTRACTOR_GO_BUILD_TRACING" in process.env) {
logger.warning(
`The CODEQL_EXTRACTOR_GO_BUILD_TRACING environment variable has no effect on workflows with manual build steps, so we recommend that you remove it from your workflow.`
`The CODEQL_EXTRACTOR_GO_BUILD_TRACING environment variable has no effect on workflows with manual build steps, so we recommend that you remove it from your workflow.`,
);
}
return;
@@ -182,7 +182,7 @@ async function run() {
try {
if (
!(await api.sendStatusReport(
await api.createStatusReportBase("finish", "starting", startedAt)
await api.createStatusReportBase("finish", "starting", startedAt),
))
) {
return;
@@ -190,13 +190,13 @@ async function run() {
config = await getConfig(actionsUtil.getTemporaryDirectory(), logger);
if (config === undefined) {
throw new Error(
"Config file could not be found at expected location. Has the 'init' action been called?"
"Config file could not be found at expected location. Has the 'init' action been called?",
);
}
if (hasBadExpectErrorInput()) {
throw new Error(
"`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.",
);
}
@@ -204,11 +204,11 @@ async function run() {
const outputDir = actionsUtil.getRequiredInput("output");
const threads = util.getThreadsFlag(
actionsUtil.getOptionalInput("threads") || process.env["CODEQL_THREADS"],
logger
logger,
);
const repositoryNwo = parseRepositoryNwo(
util.getRequiredEnvParam("GITHUB_REPOSITORY")
util.getRequiredEnvParam("GITHUB_REPOSITORY"),
);
const gitHubVersion = await getGitHubVersion();
@@ -217,12 +217,12 @@ async function run() {
gitHubVersion,
repositoryNwo,
actionsUtil.getTemporaryDirectory(),
logger
logger,
);
const memory = util.getMemoryFlag(
actionsUtil.getOptionalInput("ram") || process.env["CODEQL_RAM"],
await features.getValue(Feature.ScalingReservedRamEnabled)
await features.getValue(Feature.ScalingReservedRamEnabled),
);
await runAutobuildIfLegacyGoWorkflow(config, logger);
@@ -233,7 +233,7 @@ async function run() {
memory,
config,
logger,
features
features,
);
if (actionsUtil.getRequiredInput("skip-queries") !== "true") {
@@ -245,7 +245,7 @@ async function run() {
actionsUtil.getOptionalInput("category"),
config,
logger,
features
features,
);
}
@@ -253,7 +253,7 @@ async function run() {
await runCleanup(
config,
actionsUtil.getOptionalInput("cleanup-level") || "brutal",
logger
logger,
);
}
@@ -268,7 +268,7 @@ async function run() {
outputDir,
actionsUtil.getRequiredInput("checkout_path"),
actionsUtil.getOptionalInput("category"),
logger
logger,
);
core.setOutput("sarif-id", uploadResult.sarifID);
} else {
@@ -294,13 +294,13 @@ async function run() {
await uploadLib.waitForProcessing(
parseRepositoryNwo(util.getRequiredEnvParam("GITHUB_REPOSITORY")),
uploadResult.sarifID,
getActionsLogger()
getActionsLogger(),
);
}
// If we did not throw an error yet here, but we expect one, throw it.
if (actionsUtil.getOptionalInput("expect-error") === "true") {
core.setFailed(
`expect-error input was set to true but no error was thrown.`
`expect-error input was set to true but no error was thrown.`,
);
}
core.exportVariable(EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY, "true");
@@ -323,7 +323,7 @@ async function run() {
trapCacheUploadTime,
dbCreationTimings,
didUploadTrapCaches,
logger
logger,
);
} else {
await sendStatusReport(
@@ -334,7 +334,7 @@ async function run() {
trapCacheUploadTime,
dbCreationTimings,
didUploadTrapCaches,
logger
logger,
);
}
@@ -353,7 +353,7 @@ async function run() {
trapCacheUploadTime,
dbCreationTimings,
didUploadTrapCaches,
logger
logger,
);
} else if (runStats) {
await sendStatusReport(
@@ -364,7 +364,7 @@ async function run() {
trapCacheUploadTime,
dbCreationTimings,
didUploadTrapCaches,
logger
logger,
);
} else {
await sendStatusReport(
@@ -375,7 +375,7 @@ async function run() {
trapCacheUploadTime,
dbCreationTimings,
didUploadTrapCaches,
logger
logger,
);
}
}

View File

@@ -50,14 +50,14 @@ test("status report fields and search path setting", async (t) => {
packDownload: async () => ({ packs: [] }),
databaseRunQueries: async (
_db: string,
searchPath: string | undefined
searchPath: string | undefined,
) => {
searchPathsUsed.push(searchPath);
},
databaseInterpretResults: async (
_db: string,
_queriesRun: string[],
sarifFile: string
sarifFile: string,
) => {
fs.writeFileSync(
sarifFile,
@@ -94,7 +94,7 @@ test("status report fields and search path setting", async (t) => {
},
{},
],
})
}),
);
return "";
},
@@ -142,7 +142,7 @@ test("status report fields and search path setting", async (t) => {
undefined,
config,
getRunnerLogger(true),
createFeatures([Feature.QaTelemetryEnabled])
createFeatures([Feature.QaTelemetryEnabled]),
);
const hasPacks = language in packs;
const statusReportKeys = Object.keys(builtinStatusReport).sort();
@@ -150,26 +150,26 @@ test("status report fields and search path setting", async (t) => {
t.deepEqual(statusReportKeys.length, 4, statusReportKeys.toString());
t.deepEqual(
statusReportKeys[0],
`analyze_builtin_queries_${language}_duration_ms`
`analyze_builtin_queries_${language}_duration_ms`,
);
t.deepEqual(
statusReportKeys[1],
`analyze_custom_queries_${language}_duration_ms`
`analyze_custom_queries_${language}_duration_ms`,
);
t.deepEqual(statusReportKeys[2], "event_reports");
t.deepEqual(
statusReportKeys[3],
`interpret_results_${language}_duration_ms`
`interpret_results_${language}_duration_ms`,
);
} else {
t.deepEqual(
statusReportKeys[0],
`analyze_builtin_queries_${language}_duration_ms`
`analyze_builtin_queries_${language}_duration_ms`,
);
t.deepEqual(statusReportKeys[1], "event_reports");
t.deepEqual(
statusReportKeys[2],
`interpret_results_${language}_duration_ms`
`interpret_results_${language}_duration_ms`,
);
}
if (builtinStatusReport.event_reports) {
@@ -201,11 +201,11 @@ test("status report fields and search path setting", async (t) => {
undefined,
config,
getRunnerLogger(true),
createFeatures([Feature.QaTelemetryEnabled])
createFeatures([Feature.QaTelemetryEnabled]),
);
t.deepEqual(Object.keys(customStatusReport).length, 3);
t.true(
`analyze_custom_queries_${language}_duration_ms` in customStatusReport
`analyze_custom_queries_${language}_duration_ms` in customStatusReport,
);
const expectedSearchPathsUsed = hasPacks
? [undefined, undefined, "/1", "/2", undefined]
@@ -245,12 +245,12 @@ test("status report fields and search path setting", async (t) => {
function readContents(name: string) {
const x = fs.readFileSync(
path.join(tmpDir, "codeql_databases", name),
"utf8"
"utf8",
);
console.log(x);
return yaml.load(
fs.readFileSync(path.join(tmpDir, "codeql_databases", name), "utf8")
fs.readFileSync(path.join(tmpDir, "codeql_databases", name), "utf8"),
);
}
}
@@ -294,7 +294,7 @@ function createBaseConfig(tmpDir: string): Config {
function createQueryConfig(
builtin: string[],
custom: string[]
custom: string[],
): { builtin: string[]; custom: QueriesWithSearchPath[] } {
return {
builtin,
@@ -304,7 +304,7 @@ function createQueryConfig(
async function runQueriesWithConfig(
config: Config,
features: Feature[]
features: Feature[],
): Promise<QueriesStatusReport> {
for (const language of config.languages) {
fs.mkdirSync(util.getCodeQLDatabasePath(config, language), {
@@ -319,7 +319,7 @@ async function runQueriesWithConfig(
undefined,
config,
getRunnerLogger(true),
createFeatures(features)
createFeatures(features),
);
}
@@ -338,7 +338,7 @@ test("optimizeForLastQueryRun for one language", async (t) => {
await runQueriesWithConfig(config, []);
t.deepEqual(
getDatabaseRunQueriesCalls(codeql).map((c) => c.args[4]),
[true]
[true],
);
});
});
@@ -355,7 +355,7 @@ test("optimizeForLastQueryRun for two languages", async (t) => {
await runQueriesWithConfig(config, []);
t.deepEqual(
getDatabaseRunQueriesCalls(codeql).map((c) => c.args[4]),
[true, true]
[true, true],
);
});
});
@@ -372,7 +372,7 @@ test("optimizeForLastQueryRun for two languages, with custom queries", async (t)
await runQueriesWithConfig(config, []);
t.deepEqual(
getDatabaseRunQueriesCalls(codeql).map((c) => c.args[4]),
[false, false, true, false, true]
[false, false, true, false, true],
);
});
});
@@ -390,7 +390,7 @@ test("optimizeForLastQueryRun for two languages, with custom queries and packs",
await runQueriesWithConfig(config, []);
t.deepEqual(
getDatabaseRunQueriesCalls(codeql).map((c) => c.args[4]),
[false, false, false, true, false, false, true]
[false, false, false, true, false, false, true],
);
});
});
@@ -405,7 +405,7 @@ test("optimizeForLastQueryRun for one language, CliConfigFileEnabled", async (t)
await runQueriesWithConfig(config, [Feature.CliConfigFileEnabled]);
t.deepEqual(
getDatabaseRunQueriesCalls(codeql).map((c) => c.args[4]),
[true]
[true],
);
});
});
@@ -420,7 +420,7 @@ test("optimizeForLastQueryRun for two languages, CliConfigFileEnabled", async (t
await runQueriesWithConfig(config, [Feature.CliConfigFileEnabled]);
t.deepEqual(
getDatabaseRunQueriesCalls(codeql).map((c) => c.args[4]),
[true, true]
[true, true],
);
});
});
@@ -466,14 +466,14 @@ test("validateQueryFilters", (t) => {
},
]);
},
{ message: /Query filter must have exactly one key/ }
{ message: /Query filter must have exactly one key/ },
);
t.throws(
() => {
return validateQueryFilters([{ xxx: "foo" } as any]);
},
{ message: /Only "include" or "exclude" filters are allowed/ }
{ message: /Only "include" or "exclude" filters are allowed/ },
);
t.throws(
@@ -484,7 +484,7 @@ test("validateQueryFilters", (t) => {
{
message:
/Query filters must be an array of "include" or "exclude" entries/,
}
},
);
});
@@ -581,7 +581,7 @@ test("createQuerySuiteContents", (t) => {
{
include: { "problem.severity": "recommendation" },
},
]
],
);
const expected = `- query: query1.ql
- query: query2.ql

View File

@@ -91,7 +91,7 @@ export interface QueriesStatusReport {
async function setupPythonExtractor(
logger: Logger,
features: FeatureEnablement,
codeql: CodeQL
codeql: CodeQL,
) {
const codeqlPython = process.env["CODEQL_PYTHON"];
if (codeqlPython === undefined || codeqlPython.length === 0) {
@@ -102,12 +102,12 @@ async function setupPythonExtractor(
if (
await features.getValue(
Feature.DisablePythonDependencyInstallationEnabled,
codeql
codeql,
)
) {
logger.warning(
"We recommend that you remove the CODEQL_PYTHON environment variable from your workflow. This environment variable was originally used to specify a Python executable that included the dependencies of your Python code, however Python analysis no longer uses these dependencies." +
"\nIf you used CODEQL_PYTHON to force the version of Python to analyze as, please use CODEQL_EXTRACTOR_PYTHON_ANALYSIS_VERSION instead, such as 'CODEQL_EXTRACTOR_PYTHON_ANALYSIS_VERSION=2.7' or 'CODEQL_EXTRACTOR_PYTHON_ANALYSIS_VERSION=3.11'."
"\nIf you used CODEQL_PYTHON to force the version of Python to analyze as, please use CODEQL_EXTRACTOR_PYTHON_ANALYSIS_VERSION instead, such as 'CODEQL_EXTRACTOR_PYTHON_ANALYSIS_VERSION=2.7' or 'CODEQL_EXTRACTOR_PYTHON_ANALYSIS_VERSION=3.11'.",
);
return;
}
@@ -126,7 +126,7 @@ async function setupPythonExtractor(
await new toolrunner.ToolRunner(
codeqlPython,
[path.join(scriptsFolder, "find_site_packages.py")],
options
options,
).exec();
logger.info(`Setting LGTM_INDEX_IMPORT_PATH=${output}`);
process.env["LGTM_INDEX_IMPORT_PATH"] = output;
@@ -135,7 +135,7 @@ async function setupPythonExtractor(
await new toolrunner.ToolRunner(
codeqlPython,
["-c", "import sys; print(sys.version_info[0])"],
options
options,
).exec();
logger.info(`Setting LGTM_PYTHON_SETUP_VERSION=${output}`);
process.env["LGTM_PYTHON_SETUP_VERSION"] = output;
@@ -145,7 +145,7 @@ export async function createdDBForScannedLanguages(
codeql: CodeQL,
config: configUtils.Config,
logger: Logger,
features: FeatureEnablement
features: FeatureEnablement,
) {
// Insert the LGTM_INDEX_X env vars at this point so they are set when
// we extract any scanned languages.
@@ -171,17 +171,17 @@ export async function createdDBForScannedLanguages(
export function dbIsFinalized(
config: configUtils.Config,
language: Language,
logger: Logger
logger: Logger,
) {
const dbPath = util.getCodeQLDatabasePath(config, language);
try {
const dbInfo = yaml.load(
fs.readFileSync(path.resolve(dbPath, "codeql-database.yml"), "utf8")
fs.readFileSync(path.resolve(dbPath, "codeql-database.yml"), "utf8"),
) as { inProgress?: boolean };
return !("inProgress" in dbInfo);
} catch (e) {
logger.warning(
`Could not check whether database for ${language} was finalized. Assuming it is not.`
`Could not check whether database for ${language} was finalized. Assuming it is not.`,
);
return false;
}
@@ -192,7 +192,7 @@ async function finalizeDatabaseCreation(
threadsFlag: string,
memoryFlag: string,
logger: Logger,
features: FeatureEnablement
features: FeatureEnablement,
): Promise<DatabaseCreationTimings> {
const codeql = await getCodeQL(config.codeQLCmd);
@@ -204,14 +204,14 @@ async function finalizeDatabaseCreation(
for (const language of config.languages) {
if (dbIsFinalized(config, language, logger)) {
logger.info(
`There is already a finalized database for ${language} at the location where the CodeQL Action places databases, so we did not create one.`
`There is already a finalized database for ${language} at the location where the CodeQL Action places databases, so we did not create one.`,
);
} else {
logger.startGroup(`Finalizing ${language}`);
await codeql.finalizeDatabase(
util.getCodeQLDatabasePath(config, language),
threadsFlag,
memoryFlag
memoryFlag,
);
logger.endGroup();
}
@@ -233,7 +233,7 @@ export async function runQueries(
automationDetailsId: string | undefined,
config: configUtils.Config,
logger: Logger,
features: FeatureEnablement
features: FeatureEnablement,
): Promise<QueriesStatusReport> {
const statusReport: QueriesStatusReport = {};
@@ -245,7 +245,7 @@ export async function runQueries(
for (const language of config.languages) {
const queries = config.queries[language];
const queryFilters = validateQueryFilters(
config.originalUserInput["query-filters"]
config.originalUserInput["query-filters"],
);
const packsWithVersion = config.packs[language] || [];
@@ -273,7 +273,7 @@ export async function runQueries(
language,
undefined,
sarifFile,
config.debugMode
config.debugMode,
);
endTimeInterpretResults = new Date();
statusReport[`interpret_results_${language}_duration_ms`] =
@@ -294,7 +294,7 @@ export async function runQueries(
!hasPackWithCustomQueries
) {
throw new Error(
`Unable to analyze ${language} as no queries were selected for this language`
`Unable to analyze ${language} as no queries were selected for this language`,
);
}
@@ -315,8 +315,8 @@ export async function runQueries(
"builtin",
createQuerySuiteContents(queries.builtin, queryFilters),
undefined,
customQueryIndices.length === 0 && packsWithVersion.length === 0
)) as string
customQueryIndices.length === 0 && packsWithVersion.length === 0,
)) as string,
);
statusReport[`analyze_builtin_queries_${language}_duration_ms`] =
new Date().getTime() - startTimeBuiltIn;
@@ -331,8 +331,8 @@ export async function runQueries(
createQuerySuiteContents(queries.custom[i].queries, queryFilters),
queries.custom[i].searchPath,
i === customQueryIndices[customQueryIndices.length - 1] &&
packsWithVersion.length === 0
)) as string
packsWithVersion.length === 0,
)) as string,
);
ranCustom = true;
}
@@ -343,8 +343,8 @@ export async function runQueries(
"packs",
packsWithVersion,
queryFilters,
true
)
true,
),
);
ranCustom = true;
}
@@ -359,7 +359,7 @@ export async function runQueries(
language,
querySuitePaths,
sarifFile,
config.debugMode
config.debugMode,
);
endTimeInterpretResults = new Date();
statusReport[`interpret_results_${language}_duration_ms`] =
@@ -397,7 +397,7 @@ export async function runQueries(
statusReport.analyze_failure_language = language;
throw new CodeQLAnalysisError(
statusReport,
`Error running analysis for ${language}: ${e}`
`Error running analysis for ${language}: ${e}`,
);
}
}
@@ -408,7 +408,7 @@ export async function runQueries(
language: Language,
queries: string[] | undefined,
sarifFile: string,
enableDebugLogging: boolean
enableDebugLogging: boolean,
): Promise<string> {
const databasePath = util.getCodeQLDatabasePath(config, language);
return await codeql.databaseInterpretResults(
@@ -421,18 +421,18 @@ export async function runQueries(
automationDetailsId,
config,
features,
logger
logger,
);
}
/** Get an object with all queries and their counts parsed from a SARIF file path. */
function getPerQueryAlertCounts(
sarifPath: string,
log: Logger
log: Logger,
): Record<string, number> {
validateSarifFileSchema(sarifPath, log);
const sarifObject = JSON.parse(
fs.readFileSync(sarifPath, "utf8")
fs.readFileSync(sarifPath, "utf8"),
) as util.SarifFile;
// We do not need to compute fingerprints because we are not sending data based off of locations.
@@ -463,7 +463,7 @@ export async function runQueries(
type: string,
querySuiteContents: string | undefined,
searchPath: string | undefined,
optimizeForLastQueryRun: boolean
optimizeForLastQueryRun: boolean,
): Promise<string | undefined> {
const databasePath = util.getCodeQLDatabasePath(config, language);
// Pass the queries to codeql using a file instead of using the command
@@ -474,7 +474,7 @@ export async function runQueries(
if (querySuiteContents && querySuitePath) {
fs.writeFileSync(querySuitePath, querySuiteContents);
logger.debug(
`Query suite file for ${language}-${type}...\n${querySuiteContents}`
`Query suite file for ${language}-${type}...\n${querySuiteContents}`,
);
}
await codeql.databaseRunQueries(
@@ -482,7 +482,7 @@ export async function runQueries(
searchPath,
querySuitePath,
queryFlags,
optimizeForLastQueryRun
optimizeForLastQueryRun,
);
logger.debug(`BQRS results produced for ${language} (queries: ${type})"`);
@@ -493,7 +493,7 @@ export async function runQueries(
type: string,
packs: string[],
queryFilters: configUtils.QueryFilter[],
optimizeForLastQueryRun: boolean
optimizeForLastQueryRun: boolean,
): Promise<string> {
const databasePath = util.getCodeQLDatabasePath(config, language);
@@ -516,7 +516,7 @@ export async function runQueries(
undefined,
querySuitePath,
queryFlags,
optimizeForLastQueryRun
optimizeForLastQueryRun,
);
return querySuitePath;
@@ -524,7 +524,7 @@ export async function runQueries(
}
export function convertPackToQuerySuiteEntry(
packStr: string
packStr: string,
): configUtils.QuerySuitePackEntry {
const pack = configUtils.parsePacksSpecification(packStr);
return {
@@ -542,10 +542,10 @@ export function convertPackToQuerySuiteEntry(
export function createQuerySuiteContents(
queries: string[],
queryFilters: configUtils.QueryFilter[]
queryFilters: configUtils.QueryFilter[],
) {
return yaml.dump(
queries.map((q: string) => ({ query: q })).concat(queryFilters as any[])
queries.map((q: string) => ({ query: q })).concat(queryFilters as any[]),
);
}
@@ -555,7 +555,7 @@ export async function runFinalize(
memoryFlag: string,
config: configUtils.Config,
logger: Logger,
features: FeatureEnablement
features: FeatureEnablement,
): Promise<DatabaseCreationTimings> {
try {
await del(outputDir, { force: true });
@@ -571,7 +571,7 @@ export async function runFinalize(
threadsFlag,
memoryFlag,
logger,
features
features,
);
// WARNING: This does not _really_ end tracing, as the tracer will restore its
@@ -587,7 +587,7 @@ export async function runFinalize(
export async function runCleanup(
config: configUtils.Config,
cleanupLevel: string,
logger: Logger
logger: Logger,
): Promise<void> {
logger.startGroup("Cleaning up databases");
for (const language of config.languages) {
@@ -606,7 +606,7 @@ export function validateQueryFilters(queryFilters?: configUtils.QueryFilter[]) {
if (!Array.isArray(queryFilters)) {
throw new Error(
`Query filters must be an array of "include" or "exclude" entries. Found ${typeof queryFilters}`
`Query filters must be an array of "include" or "exclude" entries. Found ${typeof queryFilters}`,
);
}
@@ -615,14 +615,14 @@ export function validateQueryFilters(queryFilters?: configUtils.QueryFilter[]) {
const keys = Object.keys(qf);
if (keys.length !== 1) {
errors.push(
`Query filter must have exactly one key: ${JSON.stringify(qf)}`
`Query filter must have exactly one key: ${JSON.stringify(qf)}`,
);
}
if (!["exclude", "include"].includes(keys[0])) {
errors.push(
`Only "include" or "exclude" filters are allowed:\n${JSON.stringify(
qf
)}`
qf,
)}`,
);
}
}

View File

@@ -36,12 +36,12 @@ test("getApiClient", async (t) => {
baseUrl: "http://api.github.localhost",
log: sinon.match.any,
userAgent: `CodeQL-Action/${actionsUtil.getActionVersion()}`,
})
}),
);
});
function mockGetMetaVersionHeader(
versionHeader: string | undefined
versionHeader: string | undefined,
): sinon.SinonStub<any, any> {
// Passing an auth token is required, so we just use a dummy value
const client = github.getOctokit("123");
@@ -67,7 +67,7 @@ test("getGitHubVersion for Dotcom", async (t) => {
sinon.stub(api, "getApiDetails").returns(apiDetails);
const v = await api.getGitHubVersionFromApi(
github.getOctokit("123"),
apiDetails
apiDetails,
);
t.deepEqual(util.GitHubVariant.DOTCOM, v.type);
});
@@ -81,7 +81,7 @@ test("getGitHubVersion for GHES", async (t) => {
});
t.deepEqual(
{ type: util.GitHubVariant.GHES, version: "2.0" } as util.GitHubVersion,
v2
v2,
);
});

View File

@@ -54,7 +54,7 @@ export interface GitHubApiExternalRepoDetails {
function createApiClientWithDetails(
apiDetails: GitHubApiCombinedDetails,
{ allowExternal = false } = {}
{ allowExternal = false } = {},
) {
const auth =
(allowExternal && apiDetails.externalRepoAuth) || apiDetails.auth;
@@ -64,7 +64,7 @@ function createApiClientWithDetails(
baseUrl: apiDetails.apiURL,
userAgent: `CodeQL-Action/${getActionVersion()}`,
log: consoleLogLevel({ level: "debug" }),
})
}),
);
}
@@ -81,7 +81,7 @@ export function getApiClient() {
}
export function getApiClientWithExternalAuth(
apiDetails: GitHubApiCombinedDetails
apiDetails: GitHubApiCombinedDetails,
) {
return createApiClientWithDetails(apiDetails, { allowExternal: true });
}
@@ -90,7 +90,7 @@ let cachedGitHubVersion: GitHubVersion | undefined = undefined;
export async function getGitHubVersionFromApi(
apiClient: any,
apiDetails: GitHubApiDetails
apiDetails: GitHubApiDetails,
): Promise<GitHubVersion> {
// We can avoid making an API request in the standard dotcom case
if (parseGitHubUrl(apiDetails.url) === GITHUB_DOTCOM_URL) {
@@ -130,7 +130,7 @@ export async function getGitHubVersion(): Promise<GitHubVersion> {
if (cachedGitHubVersion === undefined) {
cachedGitHubVersion = await getGitHubVersionFromApi(
getApiClient(),
getApiDetails()
getApiDetails(),
);
}
return cachedGitHubVersion;
@@ -150,7 +150,7 @@ export async function createStatusReportBase(
status: ActionStatus,
actionStartedAt: Date,
cause?: string,
exception?: string
exception?: string,
): Promise<StatusReportBase> {
const commitOid = getOptionalInput("sha") || process.env["GITHUB_SHA"] || "";
const ref = await getRef();
@@ -248,7 +248,7 @@ const INCOMPATIBLE_MSG =
* Returns whether sending the status report was successful of not.
*/
export async function sendStatusReport<S extends StatusReportBase>(
statusReport: S
statusReport: S,
): Promise<boolean> {
const statusReportJSON = JSON.stringify(statusReport);
core.debug(`Sending status report: ${statusReportJSON}`);
@@ -269,7 +269,7 @@ export async function sendStatusReport<S extends StatusReportBase>(
owner,
repo,
data: statusReportJSON,
}
},
);
return true;
@@ -286,7 +286,7 @@ export async function sendStatusReport<S extends StatusReportBase>(
'Workflows triggered by Dependabot on the "push" event run with read-only access. ' +
"Uploading Code Scanning results requires write access. " +
'To use Code Scanning with Dependabot, please ensure you are using the "pull_request" event for this workflow and avoid triggering on the "push" event for Dependabot branches. ' +
"See https://docs.github.com/en/code-security/secure-coding/configuring-code-scanning#scanning-on-push for more information on how to configure these events."
"See https://docs.github.com/en/code-security/secure-coding/configuring-code-scanning#scanning-on-push for more information on how to configure these events.",
);
} else {
core.setFailed(e.message || GENERIC_403_MSG);
@@ -311,7 +311,7 @@ export async function sendStatusReport<S extends StatusReportBase>(
// something else has gone wrong and the request/response will be logged by octokit
// it's possible this is a transient error and we should continue scanning
core.error(
"An unexpected error occurred when sending code scanning status report."
"An unexpected error occurred when sending code scanning status report.",
);
return true;
}
@@ -333,7 +333,7 @@ export async function getWorkflowRelativePath(): Promise<string> {
owner,
repo,
run_id,
}
},
);
const workflowUrl = runsResponse.data.workflow_url;
@@ -374,7 +374,7 @@ export async function getAutomationID(): Promise<string> {
export function computeAutomationID(
analysis_key: string,
environment: string | undefined
environment: string | undefined,
): string {
let automationID = `${analysis_key}/`;

View File

@@ -34,7 +34,7 @@ async function sendCompletedStatusReport(
startedAt: Date,
allLanguages: string[],
failingLanguage?: string,
cause?: Error
cause?: Error,
) {
initializeEnvironment(getActionVersion());
@@ -44,7 +44,7 @@ async function sendCompletedStatusReport(
status,
startedAt,
cause?.message,
cause?.stack
cause?.stack,
);
const statusReport: AutobuildStatusReport = {
...statusReportBase,
@@ -62,7 +62,7 @@ async function run() {
try {
if (
!(await sendStatusReport(
await createStatusReportBase("autobuild", "starting", startedAt)
await createStatusReportBase("autobuild", "starting", startedAt),
))
) {
return;
@@ -74,7 +74,7 @@ async function run() {
const config = await configUtils.getConfig(getTemporaryDirectory(), logger);
if (config === undefined) {
throw new Error(
"Config file could not be found at expected location. Has the 'init' action been called?"
"Config file could not be found at expected location. Has the 'init' action been called?",
);
}
@@ -83,7 +83,7 @@ async function run() {
const workingDirectory = getOptionalInput("working-directory");
if (workingDirectory) {
logger.info(
`Changing autobuilder working directory to ${workingDirectory}`
`Changing autobuilder working directory to ${workingDirectory}`,
);
process.chdir(workingDirectory);
}
@@ -98,13 +98,13 @@ async function run() {
} catch (unwrappedError) {
const error = wrapError(unwrappedError);
core.setFailed(
`We were unable to automatically build your code. Please replace the call to the autobuild action with your custom build steps. ${error.message}`
`We were unable to automatically build your code. Please replace the call to the autobuild action with your custom build steps. ${error.message}`,
);
await sendCompletedStatusReport(
startedAt,
languages ?? [],
currentLanguage,
error
error,
);
return;
}

View File

@@ -5,19 +5,19 @@ import { Logger } from "./logging";
export async function determineAutobuildLanguages(
config: configUtils.Config,
logger: Logger
logger: Logger,
): Promise<Language[] | undefined> {
// Attempt to find a language to autobuild
// We want pick the dominant language in the repo from the ones we're able to build
// The languages are sorted in order specified by user or by lines of code if we got
// them from the GitHub API, so try to build the first language on the list.
const autobuildLanguages = config.languages.filter((l) =>
isTracedLanguage(l)
isTracedLanguage(l),
);
if (!autobuildLanguages) {
logger.info(
"None of the languages in this project require extra build steps"
"None of the languages in this project require extra build steps",
);
return undefined;
}
@@ -50,7 +50,7 @@ export async function determineAutobuildLanguages(
* version of the CodeQL Action.
*/
const autobuildLanguagesWithoutGo = autobuildLanguages.filter(
(l) => l !== Language.go
(l) => l !== Language.go,
);
const languages: Language[] = [];
@@ -77,14 +77,14 @@ export async function determineAutobuildLanguages(
if (autobuildLanguagesWithoutGo.length > 1) {
logger.warning(
`We will only automatically build ${languages.join(
" and "
" and ",
)} code. If you wish to scan ${autobuildLanguagesWithoutGo
.slice(1)
.join(
" and "
" and ",
)}, you must replace the autobuild step of your workflow with custom build steps. ` +
"For more information, see " +
"https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language"
"https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language",
);
}
@@ -94,7 +94,7 @@ export async function determineAutobuildLanguages(
export async function runAutobuild(
language: Language,
config: configUtils.Config,
logger: Logger
logger: Logger,
) {
logger.startGroup(`Attempting to automatically build ${language} code`);
const codeQL = await getCodeQL(config.codeQLCmd);

View File

@@ -93,7 +93,7 @@ async function installIntoToolcache({
? { cliVersion, tagName }
: SAMPLE_DEFAULT_CLI_VERSION,
getRunnerLogger(true),
false
false,
);
}
@@ -152,7 +152,7 @@ test("downloads and caches explicitly requested bundles that aren't in the toolc
util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION,
getRunnerLogger(true),
false
false,
);
t.assert(toolcache.find("CodeQL", `0.0.0-${version}`));
@@ -185,7 +185,7 @@ test("downloads an explicitly requested bundle even if a different version is ca
util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION,
getRunnerLogger(true),
false
false,
);
t.assert(toolcache.find("CodeQL", "0.0.0-20200610"));
t.deepEqual(result.toolsVersion, "0.0.0-20200610");
@@ -235,7 +235,7 @@ for (const {
util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION,
getRunnerLogger(true),
false
false,
);
t.assert(releaseApiMock.isDone(), "Releases API should have been called");
t.assert(toolcache.find("CodeQL", expectedToolcacheVersion));
@@ -272,13 +272,13 @@ for (const toolcacheVersion of [
util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION,
getRunnerLogger(true),
false
false,
);
t.is(result.toolsVersion, SAMPLE_DEFAULT_CLI_VERSION.cliVersion);
t.is(result.toolsSource, ToolsSource.Toolcache);
t.is(result.toolsDownloadDurationMs, undefined);
});
}
},
);
}
@@ -303,7 +303,7 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
tagName: defaults.bundleVersion,
},
getRunnerLogger(true),
false
false,
);
t.deepEqual(result.toolsVersion, "0.0.0-20200601");
t.is(result.toolsSource, ToolsSource.Toolcache);
@@ -337,7 +337,7 @@ for (const variant of [util.GitHubVariant.GHAE, util.GitHubVariant.GHES]) {
tagName: defaults.bundleVersion,
},
getRunnerLogger(true),
false
false,
);
t.deepEqual(result.toolsVersion, defaults.cliVersion);
t.is(result.toolsSource, ToolsSource.Download);
@@ -369,7 +369,7 @@ test('downloads bundle if "latest" tools specified but not cached', async (t) =>
util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION,
getRunnerLogger(true),
false
false,
);
t.deepEqual(result.toolsVersion, defaults.cliVersion);
t.is(result.toolsSource, ToolsSource.Download);
@@ -404,7 +404,7 @@ for (const isBundleVersionInUrl of [true, false]) {
nock("https://example.githubenterprise.com")
.get(
`/api/v3/enterprise/code-scanning/codeql-bundle/find/${defaults.bundleVersion}`
`/api/v3/enterprise/code-scanning/codeql-bundle/find/${defaults.bundleVersion}`,
)
.reply(200, {
assets: { [codeQLBundleName]: bundleAssetID },
@@ -412,7 +412,7 @@ for (const isBundleVersionInUrl of [true, false]) {
nock("https://example.githubenterprise.com")
.get(
`/api/v3/enterprise/code-scanning/codeql-bundle/download/${bundleAssetID}`
`/api/v3/enterprise/code-scanning/codeql-bundle/download/${bundleAssetID}`,
)
.reply(200, {
url: eventualDownloadUrl,
@@ -422,12 +422,12 @@ for (const isBundleVersionInUrl of [true, false]) {
.get(
eventualDownloadUrl.replace(
"https://example.githubenterprise.com",
""
)
"",
),
)
.replyWithFile(
200,
path.join(__dirname, `/../src/testdata/codeql-bundle-pinned.tar.gz`)
path.join(__dirname, `/../src/testdata/codeql-bundle-pinned.tar.gz`),
);
mockApiDetails(sampleGHAEApiDetails);
@@ -444,7 +444,7 @@ for (const isBundleVersionInUrl of [true, false]) {
tagName: defaults.bundleVersion,
},
getRunnerLogger(true),
false
false,
);
t.is(result.toolsSource, ToolsSource.Download);
@@ -479,7 +479,7 @@ test("bundle URL from another repo is cached as 0.0.0-bundleVersion", async (t)
util.GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION,
getRunnerLogger(true),
false
false,
);
t.is(result.toolsVersion, "0.0.0-20230203");
@@ -501,7 +501,7 @@ test("getExtraOptions works for explicit paths", (t) => {
t.deepEqual(
codeql.getExtraOptions({ foo: { bar: [42] } }, ["foo", "bar"], []),
["42"]
["42"],
);
});
@@ -530,8 +530,8 @@ test("getExtraOptions throws for bad content", (t) => {
codeql.getExtraOptions(
{ "*": [42], foo: { "*": 87, bar: [99] } },
["foo", "bar"],
[]
)
[],
),
);
});
@@ -559,13 +559,13 @@ test("databaseInitCluster() without injected codescanning config", async (t) =>
undefined,
createFeatures([]),
"/path/to/qlconfig.yml",
getRunnerLogger(true)
getRunnerLogger(true),
);
const args = runnerConstructorStub.firstCall.args[1];
// should NOT have used an config file
const configArg = args.find((arg: string) =>
arg.startsWith("--codescanning-config=")
arg.startsWith("--codescanning-config="),
);
t.falsy(configArg, "Should NOT have injected a codescanning config");
});
@@ -577,7 +577,7 @@ const injectedConfigMacro = test.macro({
t: ExecutionContext<unknown>,
augmentationProperties: AugmentationProperties,
configOverride: Partial<Config>,
expectedConfig: any
expectedConfig: any,
) => {
await util.withTmpDir(async (tempDir) => {
const runnerConstructorStub = stubToolRunnerConstructor();
@@ -599,13 +599,13 @@ const injectedConfigMacro = test.macro({
undefined,
createFeatures([Feature.CliConfigFileEnabled]),
undefined,
getRunnerLogger(true)
getRunnerLogger(true),
);
const args = runnerConstructorStub.firstCall.args[1] as string[];
// should have used an config file
const configArg = args.find((arg: string) =>
arg.startsWith("--codescanning-config=")
arg.startsWith("--codescanning-config="),
);
t.truthy(configArg, "Should have injected a codescanning config");
const configFile = configArg!.split("=")[1];
@@ -629,7 +629,7 @@ test(
packsInputCombines: false,
},
{},
{}
{},
);
test(
@@ -643,7 +643,7 @@ test(
{},
{
packs: ["codeql/javascript-experimental-atm-queries@~0.4.0"],
}
},
);
test(
@@ -666,7 +666,7 @@ test(
"codeql/javascript-experimental-atm-queries@~0.4.0",
],
},
}
},
);
test(
@@ -687,7 +687,7 @@ test(
cpp: ["codeql/something-else"],
javascript: ["codeql/javascript-experimental-atm-queries@~0.4.0"],
},
}
},
);
test(
@@ -702,7 +702,7 @@ test(
{},
{
packs: ["xxx", "yyy"],
}
},
);
test(
@@ -725,7 +725,7 @@ test(
packs: {
cpp: ["codeql/something-else", "xxx", "yyy"],
},
}
},
);
test(
@@ -746,7 +746,7 @@ test(
},
{
packs: ["xxx", "yyy"],
}
},
);
test(
@@ -767,7 +767,7 @@ test(
},
{
packs: ["xxx", "yyy", "codeql/javascript-experimental-atm-queries@~0.4.0"],
}
},
);
// similar, but with queries
@@ -790,7 +790,7 @@ test(
uses: "yyy",
},
],
}
},
);
test(
@@ -816,7 +816,7 @@ test(
uses: "yyy",
},
],
}
},
);
test(
@@ -845,7 +845,7 @@ test(
uses: "yyy",
},
],
}
},
);
test(
@@ -867,7 +867,7 @@ test(
uses: "yyy",
},
],
}
},
);
test(
@@ -886,7 +886,7 @@ test(
queries: [],
},
},
{}
{},
);
test("does not pass a code scanning config or qlconfig file to the CLI when CLI config passing is disabled", async (t: ExecutionContext<unknown>) => {
@@ -902,19 +902,19 @@ test("does not pass a code scanning config or qlconfig file to the CLI when CLI
undefined,
createFeatures([]),
"/path/to/qlconfig.yml",
getRunnerLogger(true)
getRunnerLogger(true),
);
const args = runnerConstructorStub.firstCall.args[1];
// should not have used a config file
const hasConfigArg = args.some((arg: string) =>
arg.startsWith("--codescanning-config=")
arg.startsWith("--codescanning-config="),
);
t.false(hasConfigArg, "Should NOT have injected a codescanning config");
// should not have passed a qlconfig file
const hasQlconfigArg = args.some((arg: string) =>
arg.startsWith("--qlconfig-file=")
arg.startsWith("--qlconfig-file="),
);
t.false(hasQlconfigArg, "Should NOT have passed a qlconfig file");
});
@@ -934,19 +934,19 @@ test("passes a code scanning config AND qlconfig to the CLI when CLI config pass
undefined,
createFeatures([Feature.CliConfigFileEnabled]),
"/path/to/qlconfig.yml",
getRunnerLogger(true)
getRunnerLogger(true),
);
const args = runnerConstructorStub.firstCall.args[1];
// should have used a config file
const hasCodeScanningConfigArg = args.some((arg: string) =>
arg.startsWith("--codescanning-config=")
arg.startsWith("--codescanning-config="),
);
t.true(hasCodeScanningConfigArg, "Should have injected a qlconfig");
// should have passed a qlconfig file
const hasQlconfigArg = args.some((arg: string) =>
arg.startsWith("--qlconfig-file=")
arg.startsWith("--qlconfig-file="),
);
t.truthy(hasQlconfigArg, "Should have injected a codescanning config");
});
@@ -964,22 +964,22 @@ test("passes a code scanning config BUT NOT a qlconfig to the CLI when CLI confi
undefined,
createFeatures([Feature.CliConfigFileEnabled]),
"/path/to/qlconfig.yml",
getRunnerLogger(true)
getRunnerLogger(true),
);
const args = runnerConstructorStub.firstCall.args[1] as any[];
// should have used a config file
const hasCodeScanningConfigArg = args.some((arg: string) =>
arg.startsWith("--codescanning-config=")
arg.startsWith("--codescanning-config="),
);
t.true(
hasCodeScanningConfigArg,
"Should have injected a codescanning config"
"Should have injected a codescanning config",
);
// should not have passed a qlconfig file
const hasQlconfigArg = args.some((arg: string) =>
arg.startsWith("--qlconfig-file=")
arg.startsWith("--qlconfig-file="),
);
t.false(hasQlconfigArg, "should NOT have injected a qlconfig");
});
@@ -999,12 +999,12 @@ test("does not pass a qlconfig to the CLI when it is undefined", async (t: Execu
undefined,
createFeatures([Feature.CliConfigFileEnabled]),
undefined, // undefined qlconfigFile
getRunnerLogger(true)
getRunnerLogger(true),
);
const args = runnerConstructorStub.firstCall.args[1] as any[];
const hasQlconfigArg = args.some((arg: string) =>
arg.startsWith("--qlconfig-file=")
arg.startsWith("--qlconfig-file="),
);
t.false(hasQlconfigArg, "should NOT have injected a qlconfig");
});
@@ -1026,13 +1026,13 @@ test("databaseInterpretResults() sets --sarif-add-baseline-file-info for 2.11.3"
"",
stubConfig,
createFeatures([]),
getRunnerLogger(true)
getRunnerLogger(true),
);
t.true(
runnerConstructorStub.firstCall.args[1].includes(
"--sarif-add-baseline-file-info"
"--sarif-add-baseline-file-info",
),
"--sarif-add-baseline-file-info should be present, but it is absent"
"--sarif-add-baseline-file-info should be present, but it is absent",
);
});
@@ -1052,13 +1052,13 @@ test("databaseInterpretResults() does not set --sarif-add-baseline-file-info for
"",
stubConfig,
createFeatures([]),
getRunnerLogger(true)
getRunnerLogger(true),
);
t.false(
runnerConstructorStub.firstCall.args[1].includes(
"--sarif-add-baseline-file-info"
"--sarif-add-baseline-file-info",
),
"--sarif-add-baseline-file-info must be absent, but it is present"
"--sarif-add-baseline-file-info must be absent, but it is present",
);
});
@@ -1113,23 +1113,23 @@ for (const {
"",
stubConfig,
createFeatures(featureEnabled ? [Feature.NewAnalysisSummaryEnabled] : []),
getRunnerLogger(true)
getRunnerLogger(true),
);
t.is(
runnerConstructorStub.firstCall.args[1].includes(
"--new-analysis-summary"
"--new-analysis-summary",
),
flagPassed,
`--new-analysis-summary should${flagPassed ? "" : "n't"} be passed`
`--new-analysis-summary should${flagPassed ? "" : "n't"} be passed`,
);
t.is(
runnerConstructorStub.firstCall.args[1].includes(
"--no-new-analysis-summary"
"--no-new-analysis-summary",
),
negativeFlagPassed,
`--no-new-analysis-summary should${
negativeFlagPassed ? "" : "n't"
} be passed`
} be passed`,
);
});
}
@@ -1140,7 +1140,7 @@ test("database finalize recognises JavaScript no code found error on CodeQL 2.11
`2020-09-07T17:39:53.9050522Z [2020-09-07 17:39:53] [build] Done extracting /opt/hostedtoolcache/CodeQL/0.0.0-20200630/x64/codeql/javascript/tools/data/externs/web/ie_vml.js (3 ms)
2020-09-07T17:39:53.9051849Z [2020-09-07 17:39:53] [build-err] No JavaScript or TypeScript code found.
2020-09-07T17:39:53.9052444Z [2020-09-07 17:39:53] [build-err] No JavaScript or TypeScript code found.
2020-09-07T17:39:53.9251124Z [2020-09-07 17:39:53] [ERROR] Spawned process exited abnormally (code 255; tried to run: [/opt/hostedtoolcache/CodeQL/0.0.0-20200630/x64/codeql/javascript/tools/autobuild.sh])`
2020-09-07T17:39:53.9251124Z [2020-09-07 17:39:53] [ERROR] Spawned process exited abnormally (code 255; tried to run: [/opt/hostedtoolcache/CodeQL/0.0.0-20200630/x64/codeql/javascript/tools/autobuild.sh])`,
);
const codeqlObject = await codeql.getCodeQLForTesting();
sinon.stub(codeqlObject, "getVersion").resolves("2.11.6");
@@ -1153,7 +1153,7 @@ test("database finalize recognises JavaScript no code found error on CodeQL 2.11
message:
"No code found during the build. Please see: " +
"https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build",
}
},
);
});
@@ -1170,7 +1170,7 @@ test("database finalize overrides no code found error on CodeQL 2.11.6", async (
message:
"No code found during the build. Please see: " +
"https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build",
}
},
);
});
@@ -1191,7 +1191,7 @@ test("database finalize does not override no code found error on CodeQL 2.12.4",
message:
'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: ${cliMessage}`,
}
},
);
});
@@ -1216,13 +1216,13 @@ test("runTool summarizes several fatal errors", async (t) => {
message:
'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: ${datasetImportError}. Context: ${heapError}.`,
}
},
);
});
export function stubToolRunnerConstructor(
exitCode: number = 0,
stderr?: string
stderr?: string,
): sinon.SinonStub<any[], toolrunner.ToolRunner> {
const runnerObjectStub = sinon.createStubInstance(toolrunner.ToolRunner);
const runnerConstructorStub = sinon.stub(toolrunner, "ToolRunner");

View File

@@ -49,14 +49,14 @@ export class CommandInvocationError extends Error {
args: string[],
public exitCode: number,
public error: string,
public output: string
public output: string,
) {
const prettyCommand = [cmd, ...args]
.map((x) => (x.includes(" ") ? `'${x}'` : x))
.join(" ");
super(
`Encountered a fatal error while running "${prettyCommand}". ` +
`Exit code was ${exitCode} and error was: ${error.trim()}`
`Exit code was ${exitCode} and error was: ${error.trim()}`,
);
}
}
@@ -83,7 +83,7 @@ export interface CodeQL {
processName: string | undefined,
features: FeatureEnablement,
qlconfigFile: string | undefined,
logger: Logger
logger: Logger,
): Promise<void>;
/**
* Runs the autobuilder for the given language.
@@ -100,7 +100,7 @@ export interface CodeQL {
finalizeDatabase(
databasePath: string,
threadsFlag: string,
memoryFlag: string
memoryFlag: string,
): Promise<void>;
/**
* Run 'codeql resolve languages'.
@@ -115,14 +115,14 @@ export interface CodeQL {
*/
resolveQueries(
queries: string[],
extraSearchPath: string | undefined
extraSearchPath: string | undefined,
): Promise<ResolveQueriesOutput>;
/**
* Run 'codeql resolve build-environment'
*/
resolveBuildEnvironment(
workingDir: string | undefined,
language: Language
language: Language,
): Promise<ResolveBuildEnvironmentOutput>;
/**
@@ -130,7 +130,7 @@ export interface CodeQL {
*/
packDownload(
packs: string[],
qlconfigFile: string | undefined
qlconfigFile: string | undefined,
): Promise<PackDownloadOutput>;
/**
@@ -143,7 +143,7 @@ export interface CodeQL {
databaseBundle(
databasePath: string,
outputFilePath: string,
dbName: string
dbName: string,
): Promise<void>;
/**
* Run 'codeql database run-queries'.
@@ -159,7 +159,7 @@ export interface CodeQL {
extraSearchPath: string | undefined,
querySuitePath: string | undefined,
flags: string[],
optimizeForLastQueryRun: boolean
optimizeForLastQueryRun: boolean,
): Promise<void>;
/**
* Run 'codeql database interpret-results'.
@@ -174,7 +174,7 @@ export interface CodeQL {
automationDetailsId: string | undefined,
config: Config,
features: FeatureEnablement,
logger: Logger
logger: Logger,
): Promise<string>;
/**
* Run 'codeql database print-baseline'.
@@ -191,7 +191,7 @@ export interface CodeQL {
sarifFile: string,
automationDetailsId: string | undefined,
tempDir: string,
logger: Logger
logger: Logger,
): Promise<void>;
/**
* Run 'codeql diagnostics export'.
@@ -199,7 +199,7 @@ export interface CodeQL {
diagnosticsExport(
sarifFile: string,
automationDetailsId: string | undefined,
config: Config
config: Config,
): Promise<void>;
/** Get the location of an extractor for the specified language. */
resolveExtractor(language: Language): Promise<string>;
@@ -215,7 +215,7 @@ export interface BetterResolveLanguagesOutput {
{
extractor_root: string;
extractor_options?: any;
}
},
];
};
}
@@ -338,7 +338,7 @@ export async function setupCodeQL(
variant: util.GitHubVariant,
defaultCliVersion: CodeQLDefaultVersionInfo,
logger: Logger,
checkVersion: boolean
checkVersion: boolean,
): Promise<{
codeql: CodeQL;
toolsDownloadDurationMs?: number;
@@ -353,7 +353,7 @@ export async function setupCodeQL(
tempDir,
variant,
defaultCliVersion,
logger
logger,
);
let codeqlCmd = path.join(codeqlFolder, "codeql", "codeql");
if (process.platform === "win32") {
@@ -371,7 +371,7 @@ export async function setupCodeQL(
};
} catch (e) {
throw new Error(
`Unable to download and extract CodeQL CLI: ${wrapError(e).message}`
`Unable to download and extract CodeQL CLI: ${wrapError(e).message}`,
);
}
}
@@ -389,7 +389,7 @@ export async function getCodeQL(cmd: string): Promise<CodeQL> {
function resolveFunction<T>(
partialCodeql: Partial<CodeQL>,
methodName: string,
defaultImplementation?: T
defaultImplementation?: T,
): T {
if (typeof partialCodeql[methodName] !== "function") {
if (defaultImplementation !== undefined) {
@@ -415,25 +415,25 @@ export function setCodeQL(partialCodeql: Partial<CodeQL>): CodeQL {
getVersion: resolveFunction(
partialCodeql,
"getVersion",
() => new Promise((resolve) => resolve("1.0.0"))
() => new Promise((resolve) => resolve("1.0.0")),
),
printVersion: resolveFunction(partialCodeql, "printVersion"),
databaseInitCluster: resolveFunction(partialCodeql, "databaseInitCluster"),
runAutobuild: resolveFunction(partialCodeql, "runAutobuild"),
extractScannedLanguage: resolveFunction(
partialCodeql,
"extractScannedLanguage"
"extractScannedLanguage",
),
finalizeDatabase: resolveFunction(partialCodeql, "finalizeDatabase"),
resolveLanguages: resolveFunction(partialCodeql, "resolveLanguages"),
betterResolveLanguages: resolveFunction(
partialCodeql,
"betterResolveLanguages"
"betterResolveLanguages",
),
resolveQueries: resolveFunction(partialCodeql, "resolveQueries"),
resolveBuildEnvironment: resolveFunction(
partialCodeql,
"resolveBuildEnvironment"
"resolveBuildEnvironment",
),
packDownload: resolveFunction(partialCodeql, "packDownload"),
databaseCleanup: resolveFunction(partialCodeql, "databaseCleanup"),
@@ -441,15 +441,15 @@ export function setCodeQL(partialCodeql: Partial<CodeQL>): CodeQL {
databaseRunQueries: resolveFunction(partialCodeql, "databaseRunQueries"),
databaseInterpretResults: resolveFunction(
partialCodeql,
"databaseInterpretResults"
"databaseInterpretResults",
),
databasePrintBaseline: resolveFunction(
partialCodeql,
"databasePrintBaseline"
"databasePrintBaseline",
),
databaseExportDiagnostics: resolveFunction(
partialCodeql,
"databaseExportDiagnostics"
"databaseExportDiagnostics",
),
diagnosticsExport: resolveFunction(partialCodeql, "diagnosticsExport"),
resolveExtractor: resolveFunction(partialCodeql, "resolveExtractor"),
@@ -477,7 +477,7 @@ export function getCachedCodeQL(): CodeQL {
* should also stub the toolrunner.ToolRunner constructor.
*/
export async function getCodeQLForTesting(
cmd = "codeql-for-testing"
cmd = "codeql-for-testing",
): Promise<CodeQL> {
return getCodeQLForCmd(cmd, false);
}
@@ -492,7 +492,7 @@ export async function getCodeQLForTesting(
*/
export async function getCodeQLForCmd(
cmd: string,
checkVersion: boolean
checkVersion: boolean,
): Promise<CodeQL> {
const codeql: CodeQL = {
getPath() {
@@ -515,10 +515,10 @@ export async function getCodeQLForCmd(
processName: string | undefined,
features: FeatureEnablement,
qlconfigFile: string | undefined,
logger: Logger
logger: Logger,
) {
const extraArgs = config.languages.map(
(language) => `--language=${language}`
(language) => `--language=${language}`,
);
if (config.languages.filter((l) => isTracedLanguage(l)).length > 0) {
extraArgs.push("--begin-tracing");
@@ -530,14 +530,14 @@ export async function getCodeQLForCmd(
// when tracing Go on Windows on these CodeQL versions.
(await util.codeQlVersionAbove(
this,
CODEQL_VERSION_LUA_TRACER_CONFIG
CODEQL_VERSION_LUA_TRACER_CONFIG,
)) &&
config.languages.includes(Language.go) &&
isTracedLanguage(Language.go) &&
process.platform === "win32" &&
!(await util.codeQlVersionAbove(
this,
CODEQL_VERSION_LUA_TRACING_GO_WINDOWS_FIXED
CODEQL_VERSION_LUA_TRACING_GO_WINDOWS_FIXED,
))
) {
extraArgs.push("--no-internal-use-lua-tracing");
@@ -549,7 +549,7 @@ export async function getCodeQLForCmd(
codeql,
config,
features,
logger
logger,
);
// Only pass external repository token if a config file is going to be parsed by the CLI.
let externalRepositoryToken: string | undefined;
@@ -578,14 +578,14 @@ export async function getCodeQLForCmd(
...extraArgs,
...getExtraOptionsFromEnv(["database", "init"]),
],
{ stdin: externalRepositoryToken }
{ stdin: externalRepositoryToken },
);
},
async runAutobuild(language: Language) {
const autobuildCmd = path.join(
await this.resolveExtractor(language),
"tools",
process.platform === "win32" ? "autobuild.cmd" : "autobuild.sh"
process.platform === "win32" ? "autobuild.cmd" : "autobuild.sh",
);
// Update JAVA_TOOL_OPTIONS to contain '-Dhttp.keepAlive=false'
@@ -624,7 +624,7 @@ export async function getCodeQLForCmd(
const traceCommand = path.resolve(
await this.resolveExtractor(language),
"tools",
`autobuild${ext}`
`autobuild${ext}`,
);
// Run trace command
await runTool(cmd, [
@@ -640,7 +640,7 @@ export async function getCodeQLForCmd(
async finalizeDatabase(
databasePath: string,
threadsFlag: string,
memoryFlag: string
memoryFlag: string,
) {
const args = [
"database",
@@ -658,13 +658,13 @@ export async function getCodeQLForCmd(
e instanceof CommandInvocationError &&
!(await util.codeQlVersionAbove(
this,
CODEQL_VERSION_BETTER_NO_CODE_ERROR_MESSAGE
CODEQL_VERSION_BETTER_NO_CODE_ERROR_MESSAGE,
)) &&
isNoCodeFoundError(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"
"https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build",
);
}
throw e;
@@ -683,7 +683,7 @@ export async function getCodeQLForCmd(
return JSON.parse(output);
} catch (e) {
throw new Error(
`Unexpected output from codeql resolve languages: ${e}`
`Unexpected output from codeql resolve languages: ${e}`,
);
}
},
@@ -701,13 +701,13 @@ export async function getCodeQLForCmd(
return JSON.parse(output);
} catch (e) {
throw new Error(
`Unexpected output from codeql resolve languages with --format=betterjson: ${e}`
`Unexpected output from codeql resolve languages with --format=betterjson: ${e}`,
);
}
},
async resolveQueries(
queries: string[],
extraSearchPath: string | undefined
extraSearchPath: string | undefined,
) {
const codeqlArgs = [
"resolve",
@@ -729,7 +729,7 @@ export async function getCodeQLForCmd(
},
async resolveBuildEnvironment(
workingDir: string | undefined,
language: Language
language: Language,
) {
const codeqlArgs = [
"resolve",
@@ -746,7 +746,7 @@ export async function getCodeQLForCmd(
return JSON.parse(output);
} catch (e) {
throw new Error(
`Unexpected output from codeql resolve build-environment: ${e} in\n${output}`
`Unexpected output from codeql resolve build-environment: ${e} in\n${output}`,
);
}
},
@@ -755,7 +755,7 @@ export async function getCodeQLForCmd(
extraSearchPath: string | undefined,
querySuitePath: string | undefined,
flags: string[],
optimizeForLastQueryRun: boolean
optimizeForLastQueryRun: boolean,
): Promise<void> {
const codeqlArgs = [
"database",
@@ -790,11 +790,11 @@ export async function getCodeQLForCmd(
automationDetailsId: string | undefined,
config: Config,
features: FeatureEnablement,
logger: Logger
logger: Logger,
): Promise<string> {
const shouldExportDiagnostics = await features.getValue(
Feature.ExportDiagnosticsEnabled,
this
this,
);
// Update this to take into account the CodeQL version when we have a version with the fix.
const shouldWorkaroundInvalidNotifications = shouldExportDiagnostics;
@@ -822,7 +822,7 @@ export async function getCodeQLForCmd(
if (
await util.codeQlVersionAbove(
this,
CODEQL_VERSION_FILE_BASELINE_INFORMATION
CODEQL_VERSION_FILE_BASELINE_INFORMATION,
)
) {
codeqlArgs.push("--sarif-add-baseline-file-info");
@@ -877,7 +877,7 @@ export async function getCodeQLForCmd(
*/
async packDownload(
packs: string[],
qlconfigFile: string | undefined
qlconfigFile: string | undefined,
): Promise<PackDownloadOutput> {
const qlconfigArg = qlconfigFile
? [`--qlconfig-file=${qlconfigFile}`]
@@ -910,13 +910,13 @@ export async function getCodeQLForCmd(
}
} catch (e) {
throw new Error(
`Attempted to download specified packs but got an error:\n${output}\n${e}`
`Attempted to download specified packs but got an error:\n${output}\n${e}`,
);
}
},
async databaseCleanup(
databasePath: string,
cleanupLevel: string
cleanupLevel: string,
): Promise<void> {
const codeqlArgs = [
"database",
@@ -930,7 +930,7 @@ export async function getCodeQLForCmd(
async databaseBundle(
databasePath: string,
outputFilePath: string,
databaseName: string
databaseName: string,
): Promise<void> {
const args = [
"database",
@@ -947,7 +947,7 @@ export async function getCodeQLForCmd(
sarifFile: string,
automationDetailsId: string | undefined,
tempDir: string,
logger: Logger
logger: Logger,
): Promise<void> {
// Update this to take into account the CodeQL version when we have a version with the fix.
const shouldWorkaroundInvalidNotifications = true;
@@ -978,7 +978,7 @@ export async function getCodeQLForCmd(
async diagnosticsExport(
sarifFile: string,
automationDetailsId: string | undefined,
config: Config
config: Config,
): Promise<void> {
const args = [
"diagnostics",
@@ -1016,7 +1016,7 @@ export async function getCodeQLForCmd(
process.stderr.write(data);
},
},
}
},
).exec();
return JSON.parse(extractorPath);
},
@@ -1034,7 +1034,7 @@ export async function getCodeQLForCmd(
!(await util.codeQlVersionAbove(codeql, CODEQL_MINIMUM_VERSION))
) {
throw new Error(
`Expected a CodeQL CLI with version at least ${CODEQL_MINIMUM_VERSION} but got version ${await codeql.getVersion()}`
`Expected a CodeQL CLI with version at least ${CODEQL_MINIMUM_VERSION} but got version ${await codeql.getVersion()}`,
);
} else if (
checkVersion &&
@@ -1051,7 +1051,7 @@ export async function getCodeQLForCmd(
"Alternatively, if you want to continue using CodeQL CLI version " +
`${await codeql.getVersion()}, you can replace 'github/codeql-action/*@v2' by ` +
"'github/codeql-action/*@v2.20.4' in your code scanning workflow to ensure you continue " +
"using this version of the CodeQL Action."
"using this version of the CodeQL Action.",
);
core.exportVariable(EnvVar.SUPPRESS_DEPRECATED_SOON_WARNING, "true");
}
@@ -1077,7 +1077,7 @@ function asExtraOptions(options: any, pathInfo: string[]): string[] {
}
if (!Array.isArray(options)) {
const msg = `The extra options for '${pathInfo.join(
"."
".",
)}' ('${JSON.stringify(options)}') are not in an array.`;
throw new Error(msg);
}
@@ -1085,7 +1085,7 @@ function asExtraOptions(options: any, pathInfo: string[]): string[] {
const t = typeof o;
if (t !== "string" && t !== "number" && t !== "boolean") {
const msg = `The extra option for '${pathInfo.join(
"."
".",
)}' ('${JSON.stringify(o)}') is not a primitive value.`;
throw new Error(msg);
}
@@ -1104,7 +1104,7 @@ function asExtraOptions(options: any, pathInfo: string[]): string[] {
export function getExtraOptions(
options: any,
paths: string[],
pathInfo: string[]
pathInfo: string[],
): string[] {
const all = asExtraOptions(options?.["*"], pathInfo.concat("*"));
const specific =
@@ -1113,7 +1113,7 @@ export function getExtraOptions(
: getExtraOptions(
options?.[paths[0]],
paths?.slice(1),
pathInfo.concat(paths[0])
pathInfo.concat(paths[0]),
);
return all.concat(specific);
}
@@ -1131,7 +1131,7 @@ const maxErrorSize = 20_000;
async function runTool(
cmd: string,
args: string[] = [],
opts: { stdin?: string } = {}
opts: { stdin?: string } = {},
) {
let output = "";
let error = "";
@@ -1235,7 +1235,7 @@ async function generateCodeScanningConfig(
codeql: CodeQL,
config: Config,
features: FeatureEnablement,
logger: Logger
logger: Logger,
): Promise<string | undefined> {
if (!(await useCodeScanningConfigInCli(codeql, features))) {
return;
@@ -1249,7 +1249,7 @@ async function generateCodeScanningConfig(
if (config.augmentationProperties.queriesInput) {
if (config.augmentationProperties.queriesInputCombines) {
augmentedConfig.queries = (augmentedConfig.queries || []).concat(
config.augmentationProperties.queriesInput
config.augmentationProperties.queriesInput,
);
} else {
augmentedConfig.queries = config.augmentationProperties.queriesInput;
@@ -1265,7 +1265,7 @@ async function generateCodeScanningConfig(
// At this point, we already know that this is a single-language analysis
if (Array.isArray(augmentedConfig.packs)) {
augmentedConfig.packs = (augmentedConfig.packs || []).concat(
config.augmentationProperties.packsInput
config.augmentationProperties.packsInput,
);
} else if (!augmentedConfig.packs) {
augmentedConfig.packs = config.augmentationProperties.packsInput;
@@ -1299,7 +1299,7 @@ async function generateCodeScanningConfig(
}
}
logger.info(
`Writing augmented user configuration file to ${codeScanningConfigFile}`
`Writing augmented user configuration file to ${codeScanningConfigFile}`,
);
logger.startGroup("Augmented user configuration file contents");
logger.info(yaml.dump(augmentedConfig));
@@ -1321,14 +1321,14 @@ function cloneObject<T>(obj: T): T {
*/
async function getCodeScanningConfigExportArguments(
config: Config,
codeql: CodeQL
codeql: CodeQL,
): Promise<string[]> {
const codeScanningConfigPath = getGeneratedCodeScanningConfigPath(config);
if (
fs.existsSync(codeScanningConfigPath) &&
(await util.codeQlVersionAbove(
codeql,
CODEQL_VERSION_EXPORT_CODE_SCANNING_CONFIG
CODEQL_VERSION_EXPORT_CODE_SCANNING_CONFIG,
))
) {
return ["--sarif-codescanning-config", codeScanningConfigPath];
@@ -1340,19 +1340,19 @@ async function getCodeScanningConfigExportArguments(
const TRAP_CACHE_SIZE_MB = 1024;
export async function getTrapCachingExtractorConfigArgs(
config: Config
config: Config,
): Promise<string[]> {
const result: string[][] = [];
for (const language of config.languages)
result.push(
await getTrapCachingExtractorConfigArgsForLang(config, language)
await getTrapCachingExtractorConfigArgsForLang(config, language),
);
return result.flat();
}
export async function getTrapCachingExtractorConfigArgsForLang(
config: Config,
language: Language
language: Language,
): Promise<string[]> {
const cacheDir = config.trapCaches[language];
if (cacheDir === undefined) return [];

File diff suppressed because it is too large Load Diff

View File

@@ -292,7 +292,7 @@ const DISABLED_BUILTIN_QUERIES: { [language: string]: string[] } = {
function queryIsDisabled(language, query): boolean {
return (DISABLED_BUILTIN_QUERIES[language] || []).some((disabledQuery) =>
query.endsWith(disabledQuery)
query.endsWith(disabledQuery),
);
}
@@ -308,20 +308,20 @@ function validateQueries(resolvedQueries: ResolveQueriesOutput) {
`${
"The following queries do not declare a language. " +
"Their qlpack.yml files are either missing or is invalid.\n"
}${noDeclaredLanguageQueries.join("\n")}`
}${noDeclaredLanguageQueries.join("\n")}`,
);
}
const multipleDeclaredLanguages = resolvedQueries.multipleDeclaredLanguages;
const multipleDeclaredLanguagesQueries = Object.keys(
multipleDeclaredLanguages
multipleDeclaredLanguages,
);
if (multipleDeclaredLanguagesQueries.length !== 0) {
throw new UserError(
`${
"The following queries declare multiple languages. " +
"Their qlpack.yml files are either missing or is invalid.\n"
}${multipleDeclaredLanguagesQueries.join("\n")}`
}${multipleDeclaredLanguagesQueries.join("\n")}`,
);
}
}
@@ -338,11 +338,11 @@ async function runResolveQueries(
codeQL: CodeQL,
resultMap: Queries,
toResolve: string[],
extraSearchPath: string | undefined
extraSearchPath: string | undefined,
) {
const resolvedQueries = await codeQL.resolveQueries(
toResolve,
extraSearchPath
extraSearchPath,
);
if (extraSearchPath !== undefined) {
@@ -350,7 +350,7 @@ async function runResolveQueries(
}
for (const [language, queryPaths] of Object.entries(
resolvedQueries.byLanguage
resolvedQueries.byLanguage,
)) {
if (resultMap[language] === undefined) {
resultMap[language] = {
@@ -359,7 +359,7 @@ async function runResolveQueries(
};
}
const queries = Object.keys(queryPaths).filter(
(q) => !queryIsDisabled(language, q)
(q) => !queryIsDisabled(language, q),
);
if (extraSearchPath !== undefined) {
resultMap[language].custom.push({
@@ -378,7 +378,7 @@ async function runResolveQueries(
async function addDefaultQueries(
codeQL: CodeQL,
languages: string[],
resultMap: Queries
resultMap: Queries,
) {
const suites = languages.map((l) => `${l}-code-scanning.qls`);
await runResolveQueries(codeQL, resultMap, suites, undefined);
@@ -403,7 +403,7 @@ async function addBuiltinSuiteQueries(
packs: Packs,
suiteName: string,
features: FeatureEnablement,
configFile?: string
configFile?: string,
): Promise<boolean> {
let injectedMlQueries = false;
const found = builtinSuites.find((suite) => suite === suiteName);
@@ -414,13 +414,13 @@ async function addBuiltinSuiteQueries(
suiteName === "security-experimental" &&
!(await codeQlVersionAbove(
codeQL,
CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE
CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE,
))
) {
throw new UserError(
`The 'security-experimental' suite is not supported on CodeQL CLI versions earlier than
${CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE}. Please upgrade to CodeQL CLI version
${CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE} or later.`
${CODEQL_VERSION_SECURITY_EXPERIMENTAL_SUITE} or later.`,
);
}
@@ -459,7 +459,7 @@ async function addLocalQueries(
resultMap: Queries,
localQueryPath: string,
workspacePath: string,
configFile?: string
configFile?: string,
) {
// Resolve the local path against the workspace so that when this is
// passed to codeql it resolves to exactly the path we expect it to resolve to.
@@ -476,11 +476,11 @@ async function addLocalQueries(
// Check the local path doesn't jump outside the repo using '..' or symlinks
if (
!(absoluteQueryPath + path.sep).startsWith(
fs.realpathSync(workspacePath) + path.sep
fs.realpathSync(workspacePath) + path.sep,
)
) {
throw new UserError(
getLocalPathOutsideOfRepository(configFile, localQueryPath)
getLocalPathOutsideOfRepository(configFile, localQueryPath),
);
}
@@ -490,7 +490,7 @@ async function addLocalQueries(
codeQL,
resultMap,
[absoluteQueryPath],
extraSearchPath
extraSearchPath,
);
}
@@ -504,7 +504,7 @@ async function addRemoteQueries(
tempDir: string,
apiDetails: api.GitHubApiExternalRepoDetails,
logger: Logger,
configFile?: string
configFile?: string,
) {
let tok = queryUses.split("@");
if (tok.length !== 2) {
@@ -532,7 +532,7 @@ async function addRemoteQueries(
ref,
apiDetails,
tempDir,
logger
logger,
);
const queryPath =
@@ -567,7 +567,7 @@ async function parseQueryUses(
apiDetails: api.GitHubApiExternalRepoDetails,
features: FeatureEnablement,
logger: Logger,
configFile?: string
configFile?: string,
): Promise<boolean> {
queryUses = queryUses.trim();
if (queryUses === "") {
@@ -581,7 +581,7 @@ async function parseQueryUses(
resultMap,
queryUses.slice(2),
workspacePath,
configFile
configFile,
);
return false;
}
@@ -595,7 +595,7 @@ async function parseQueryUses(
packs,
queryUses,
features,
configFile
configFile,
);
}
@@ -610,7 +610,7 @@ async function parseQueryUses(
tempDir,
apiDetails,
logger,
configFile
configFile,
);
}
return false;
@@ -631,7 +631,7 @@ export function validateAndSanitisePath(
originalPath: string,
propertyName: string,
configFile: string,
logger: Logger
logger: Logger,
): string {
// Take a copy so we don't modify the original path, so we can still construct error messages
let newPath = originalPath;
@@ -653,8 +653,8 @@ export function validateAndSanitisePath(
configFile,
propertyName,
`"${originalPath}" is not an invalid path. ` +
`It is not necessary to include it, and it is not allowed to exclude it.`
)
`It is not necessary to include it, and it is not allowed to exclude it.`,
),
);
}
@@ -665,8 +665,8 @@ export function validateAndSanitisePath(
configFile,
propertyName,
`"${originalPath}" contains an invalid "**" wildcard. ` +
`They must be immediately preceded and followed by a slash as in "/**/", or come at the start or end.`
)
`They must be immediately preceded and followed by a slash as in "/**/", or come at the start or end.`,
),
);
}
@@ -678,8 +678,8 @@ export function validateAndSanitisePath(
configFile,
propertyName,
`"${originalPath}" contains an unsupported character. ` +
`The filter pattern characters ?, +, [, ], ! are not supported and will be matched literally.`
)
`The filter pattern characters ?, +, [, ], ! are not supported and will be matched literally.`,
),
);
}
@@ -692,8 +692,8 @@ export function validateAndSanitisePath(
configFile,
propertyName,
`"${originalPath}" contains an "\\" character. These are not allowed in filters. ` +
`If running on windows we recommend using "/" instead for path filters.`
)
`If running on windows we recommend using "/" instead for path filters.`,
),
);
}
@@ -707,7 +707,7 @@ export function getNameInvalid(configFile: string): string {
return getConfigFilePropertyError(
configFile,
NAME_PROPERTY,
"must be a non-empty string"
"must be a non-empty string",
);
}
@@ -715,7 +715,7 @@ export function getDisableDefaultQueriesInvalid(configFile: string): string {
return getConfigFilePropertyError(
configFile,
DISABLE_DEFAULT_QUERIES_PROPERTY,
"must be a boolean"
"must be a boolean",
);
}
@@ -723,7 +723,7 @@ export function getQueriesInvalid(configFile: string): string {
return getConfigFilePropertyError(
configFile,
QUERIES_PROPERTY,
"must be an array"
"must be an array",
);
}
@@ -731,22 +731,22 @@ export function getQueriesMissingUses(configFile: string): string {
return getConfigFilePropertyError(
configFile,
QUERIES_PROPERTY,
"must be an array, with each entry having a 'uses' property"
"must be an array, with each entry having a 'uses' property",
);
}
export function getQueryUsesInvalid(
configFile: string | undefined,
queryUses?: string
queryUses?: string,
): string {
return getConfigFilePropertyError(
configFile,
`${QUERIES_PROPERTY}.${QUERIES_USES_PROPERTY}`,
`must be a built-in suite (${builtinSuites.join(
" or "
" or ",
)}), a relative path, or be of the form "owner/repo[/path]@ref"${
queryUses !== undefined ? `\n Found: ${queryUses}` : ""
}`
}`,
);
}
@@ -754,7 +754,7 @@ export function getPathsIgnoreInvalid(configFile: string): string {
return getConfigFilePropertyError(
configFile,
PATHS_IGNORE_PROPERTY,
"must be an array of non-empty strings"
"must be an array of non-empty strings",
);
}
@@ -762,7 +762,7 @@ export function getPathsInvalid(configFile: string): string {
return getConfigFilePropertyError(
configFile,
PATHS_PROPERTY,
"must be an array of non-empty strings"
"must be an array of non-empty strings",
);
}
@@ -770,7 +770,7 @@ function getPacksRequireLanguage(lang: string, configFile: string): string {
return getConfigFilePropertyError(
configFile,
PACKS_PROPERTY,
`has "${lang}", but it is not a valid language.`
`has "${lang}", but it is not a valid language.`,
);
}
@@ -778,7 +778,7 @@ export function getPacksInvalidSplit(configFile: string): string {
return getConfigFilePropertyError(
configFile,
PACKS_PROPERTY,
"must split packages by language"
"must split packages by language",
);
}
@@ -786,59 +786,59 @@ export function getPacksInvalid(configFile: string): string {
return getConfigFilePropertyError(
configFile,
PACKS_PROPERTY,
"must be an array of non-empty strings"
"must be an array of non-empty strings",
);
}
export function getPacksStrInvalid(
packStr: string,
configFile?: string
configFile?: string,
): string {
return configFile
? getConfigFilePropertyError(
configFile,
PACKS_PROPERTY,
`"${packStr}" is not a valid pack`
`"${packStr}" is not a valid pack`,
)
: `"${packStr}" is not a valid pack`;
}
export function getLocalPathOutsideOfRepository(
configFile: string | undefined,
localPath: string
localPath: string,
): string {
return getConfigFilePropertyError(
configFile,
`${QUERIES_PROPERTY}.${QUERIES_USES_PROPERTY}`,
`is invalid as the local path "${localPath}" is outside of the repository`
`is invalid as the local path "${localPath}" is outside of the repository`,
);
}
export function getLocalPathDoesNotExist(
configFile: string | undefined,
localPath: string
localPath: string,
): string {
return getConfigFilePropertyError(
configFile,
`${QUERIES_PROPERTY}.${QUERIES_USES_PROPERTY}`,
`is invalid as the local path "${localPath}" does not exist in the repository`
`is invalid as the local path "${localPath}" does not exist in the repository`,
);
}
export function getConfigFileOutsideWorkspaceErrorMessage(
configFile: string
configFile: string,
): string {
return `The configuration file "${configFile}" is outside of the workspace`;
}
export function getConfigFileDoesNotExistErrorMessage(
configFile: string
configFile: string,
): string {
return `The configuration file "${configFile}" does not exist`;
}
export function getConfigFileRepoFormatInvalidMessage(
configFile: string
configFile: string,
): string {
let error = `The configuration file "${configFile}" is not a supported remote file reference.`;
error += " Expected format <owner>/<repository>/<file-path>@<ref>";
@@ -857,7 +857,7 @@ export function getConfigFileDirectoryGivenMessage(configFile: string): string {
function getConfigFilePropertyError(
configFile: string | undefined,
property: string,
error: string
error: string,
): string {
if (configFile === undefined) {
return `The workflow property "${property}" is invalid: ${error}`;
@@ -883,7 +883,7 @@ export function getUnknownLanguagesError(languages: string[]): string {
*/
export async function getLanguagesInRepo(
repository: RepositoryNwo,
logger: Logger
logger: Logger,
): Promise<LanguageOrAlias[]> {
logger.debug(`GitHub repo ${repository.owner} ${repository.repo}`);
const response = await api.getApiClient().rest.repos.listLanguages({
@@ -921,13 +921,13 @@ export async function getLanguages(
codeQL: CodeQL,
languagesInput: string | undefined,
repository: RepositoryNwo,
logger: Logger
logger: Logger,
): Promise<Language[]> {
// Obtain languages without filtering them.
const { rawLanguages, autodetected } = await getRawLanguages(
languagesInput,
repository,
logger
logger,
);
let languages = rawLanguages.map(resolveAlias);
@@ -981,7 +981,7 @@ export async function getLanguages(
export async function getRawLanguages(
languagesInput: string | undefined,
repository: RepositoryNwo,
logger: Logger
logger: Logger,
) {
// Obtain from action input 'languages' if set
let rawLanguages = (languagesInput || "")
@@ -1010,7 +1010,7 @@ async function addQueriesAndPacksFromWorkflow(
workspacePath: string,
apiDetails: api.GitHubApiExternalRepoDetails,
features: FeatureEnablement,
logger: Logger
logger: Logger,
): Promise<boolean> {
let injectedMlQueries = false;
queriesInput = queriesInput.trim();
@@ -1028,7 +1028,7 @@ async function addQueriesAndPacksFromWorkflow(
workspacePath,
apiDetails,
features,
logger
logger,
);
injectedMlQueries = injectedMlQueries || didInject;
}
@@ -1067,13 +1067,13 @@ export async function getDefaultConfig(
gitHubVersion: GitHubVersion,
apiDetails: api.GitHubApiCombinedDetails,
features: FeatureEnablement,
logger: Logger
logger: Logger,
): Promise<Config> {
const languages = await getLanguages(
codeQL,
languagesInput,
repository,
logger
logger,
);
const queries: Queries = {};
for (const language of languages) {
@@ -1086,7 +1086,7 @@ export async function getDefaultConfig(
const augmentationProperties = calculateAugmentation(
rawPacksInput,
rawQueriesInput,
languages
languages,
);
const packs = augmentationProperties.packsInput
? {
@@ -1105,7 +1105,7 @@ export async function getDefaultConfig(
workspacePath,
apiDetails,
features,
logger
logger,
);
}
@@ -1113,7 +1113,7 @@ export async function getDefaultConfig(
trapCachingEnabled,
codeQL,
languages,
logger
logger,
);
return {
@@ -1140,7 +1140,7 @@ async function downloadCacheWithTime(
trapCachingEnabled: boolean,
codeQL: CodeQL,
languages: Language[],
logger: Logger
logger: Logger,
): Promise<{
trapCaches: Partial<Record<Language, string>>;
trapCacheDownloadTime: number;
@@ -1175,7 +1175,7 @@ async function loadConfig(
gitHubVersion: GitHubVersion,
apiDetails: api.GitHubApiCombinedDetails,
features: FeatureEnablement,
logger: Logger
logger: Logger,
): Promise<Config> {
let parsedYAML: UserConfig;
@@ -1202,7 +1202,7 @@ async function loadConfig(
codeQL,
languagesInput,
repository,
logger
logger,
);
const queries: Queries = {};
@@ -1228,7 +1228,7 @@ async function loadConfig(
const augmentationProperties = calculateAugmentation(
rawPacksInput,
rawQueriesInput,
languages
languages,
);
const packs = parsePacks(
parsedYAML[PACKS_PROPERTY] ?? {},
@@ -1236,7 +1236,7 @@ async function loadConfig(
augmentationProperties.packsInputCombines,
languages,
configFile,
logger
logger,
);
// If queries were provided using `with` in the action configuration,
@@ -1255,7 +1255,7 @@ async function loadConfig(
workspacePath,
apiDetails,
features,
logger
logger,
);
}
if (
@@ -1281,7 +1281,7 @@ async function loadConfig(
apiDetails,
features,
logger,
configFile
configFile,
);
}
}
@@ -1299,8 +1299,8 @@ async function loadConfig(
ignorePath,
PATHS_IGNORE_PROPERTY,
configFile,
logger
)
logger,
),
);
}
}
@@ -1314,7 +1314,12 @@ async function loadConfig(
throw new UserError(getPathsInvalid(configFile));
}
paths.push(
validateAndSanitisePath(includePath, PATHS_PROPERTY, configFile, logger)
validateAndSanitisePath(
includePath,
PATHS_PROPERTY,
configFile,
logger,
),
);
}
}
@@ -1323,7 +1328,7 @@ async function loadConfig(
trapCachingEnabled,
codeQL,
languages,
logger
logger,
);
return {
@@ -1368,18 +1373,18 @@ async function loadConfig(
export function calculateAugmentation(
rawPacksInput: string | undefined,
rawQueriesInput: string | undefined,
languages: Language[]
languages: Language[],
): AugmentationProperties {
const packsInputCombines = shouldCombine(rawPacksInput);
const packsInput = parsePacksFromInput(
rawPacksInput,
languages,
packsInputCombines
packsInputCombines,
);
const queriesInputCombines = shouldCombine(rawQueriesInput);
const queriesInput = parseQueriesFromInput(
rawQueriesInput,
queriesInputCombines
queriesInputCombines,
);
return {
@@ -1393,7 +1398,7 @@ export function calculateAugmentation(
function parseQueriesFromInput(
rawQueriesInput: string | undefined,
queriesInputCombines: boolean
queriesInputCombines: boolean,
) {
if (!rawQueriesInput) {
return undefined;
@@ -1407,8 +1412,8 @@ function parseQueriesFromInput(
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."
)
"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() }));
@@ -1430,7 +1435,7 @@ export function parsePacksFromConfig(
packsByLanguage: string[] | Record<string, string[]>,
languages: Language[],
configFile: string,
logger: Logger
logger: Logger,
): Packs {
const packs = {};
@@ -1455,7 +1460,7 @@ export function parsePacksFromConfig(
// This particular language is not being analyzed in this run.
if (Language[lang as Language]) {
logger.info(
`Ignoring packs for ${lang} since this language is not being analyzed in this run.`
`Ignoring packs for ${lang} since this language is not being analyzed in this run.`,
);
continue;
} else {
@@ -1465,7 +1470,7 @@ export function parsePacksFromConfig(
}
packs[lang] = packsArr.map((packStr) =>
validatePackSpecification(packStr, configFile)
validatePackSpecification(packStr, configFile),
);
}
return packs;
@@ -1474,7 +1479,7 @@ export function parsePacksFromConfig(
function parsePacksFromInput(
rawPacksInput: string | undefined,
languages: Language[],
packsInputCombines: boolean
packsInputCombines: boolean,
): Packs | undefined {
if (!rawPacksInput?.trim()) {
return undefined;
@@ -1482,11 +1487,11 @@ function parsePacksFromInput(
if (languages.length > 1) {
throw new UserError(
"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) {
throw new UserError(
"No languages specified. Cannot process the packs input."
"No languages specified. Cannot process the packs input.",
);
}
@@ -1498,8 +1503,8 @@ function parsePacksFromInput(
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."
)
"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.",
),
);
}
}
@@ -1532,7 +1537,7 @@ function parsePacksFromInput(
*/
export function parsePacksSpecification(
packStr: string,
configFile?: string
configFile?: string,
): Pack {
if (typeof packStr !== "string") {
throw new UserError(getPacksStrInvalid(packStr, configFile));
@@ -1547,7 +1552,7 @@ export function parsePacksSpecification(
const packEnd = Math.min(
atIndex > 0 ? atIndex : Infinity,
colonIndex > 0 ? colonIndex : Infinity,
packStr.length
packStr.length,
);
const versionEnd = versionStart
? Math.min(colonIndex > 0 ? colonIndex : Infinity, packStr.length)
@@ -1610,19 +1615,19 @@ export function parsePacks(
packsInputCombines: boolean,
languages: Language[],
configFile: string,
logger: Logger
logger: Logger,
): Packs {
const packsFomConfig = parsePacksFromConfig(
rawPacksFromConfig,
languages,
configFile,
logger
logger,
);
const packsFromInput = parsePacksFromInput(
rawPacksFromInput,
languages,
packsInputCombines
packsInputCombines,
);
if (!packsFromInput) {
return packsFomConfig;
@@ -1689,7 +1694,7 @@ export function getMlPoweredJsQueriesStatus(config: Config): string {
const mlPoweredJsQueryPacks = (config.packs.javascript || [])
.map((p) => parsePacksSpecification(p))
.filter(
(pack) => pack.name === ML_POWERED_JS_QUERIES_PACK_NAME && !pack.path
(pack) => pack.name === ML_POWERED_JS_QUERIES_PACK_NAME && !pack.path,
);
switch (mlPoweredJsQueryPacks.length) {
case 1:
@@ -1708,7 +1713,7 @@ export function getMlPoweredJsQueriesStatus(config: Config): string {
function dbLocationOrDefault(
dbLocation: string | undefined,
tempDir: string
tempDir: string,
): string {
return dbLocation || path.resolve(tempDir, "codeql_databases");
}
@@ -1738,7 +1743,7 @@ export async function initConfig(
gitHubVersion: GitHubVersion,
apiDetails: api.GitHubApiCombinedDetails,
features: FeatureEnablement,
logger: Logger
logger: Logger,
): Promise<Config> {
let config: Config;
@@ -1746,7 +1751,7 @@ export async function initConfig(
if (configInput) {
if (configFile) {
logger.warning(
`Both a config file and config input were provided. Ignoring config file.`
`Both a config file and config input were provided. Ignoring config file.`,
);
}
configFile = path.resolve(workspacePath, "user-config-from-action.yml");
@@ -1773,7 +1778,7 @@ export async function initConfig(
gitHubVersion,
apiDetails,
features,
logger
logger,
);
} else {
config = await loadConfig(
@@ -1793,7 +1798,7 @@ export async function initConfig(
gitHubVersion,
apiDetails,
features,
logger
logger,
);
}
@@ -1813,7 +1818,7 @@ export async function initConfig(
if (!hasPacks && !hasBuiltinQueries && !hasCustomQueries) {
throw new UserError(
`Did not detect any queries to run for ${language}. ` +
"Please make sure that the default queries are enabled, or you are specifying queries to run."
"Please make sure that the default queries are enabled, or you are specifying queries to run.",
);
}
}
@@ -1825,7 +1830,7 @@ export async function initConfig(
apiDetails,
registriesInput,
config.tempDir,
logger
logger,
);
}
@@ -1835,7 +1840,7 @@ export async function initConfig(
}
function parseRegistries(
registriesInput: string | undefined
registriesInput: string | undefined,
): RegistryConfigWithCredentials[] | undefined {
try {
return registriesInput
@@ -1871,11 +1876,11 @@ function getLocalConfig(configFile: string, workspacePath: string): UserConfig {
async function getRemoteConfig(
configFile: string,
apiDetails: api.GitHubApiCombinedDetails
apiDetails: api.GitHubApiCombinedDetails,
): Promise<UserConfig> {
// retrieve the various parts of the config location, and ensure they're present
const format = new RegExp(
"(?<owner>[^/]+)/(?<repo>[^/]+)/(?<path>[^@]+)@(?<ref>.*)"
"(?<owner>[^/]+)/(?<repo>[^/]+)/(?<path>[^@]+)@(?<ref>.*)",
);
const pieces = format.exec(configFile);
// 5 = 4 groups + the whole expression
@@ -1902,7 +1907,7 @@ async function getRemoteConfig(
}
return yaml.load(
Buffer.from(fileContents, "base64").toString("binary")
Buffer.from(fileContents, "base64").toString("binary"),
) as UserConfig;
}
@@ -1931,7 +1936,7 @@ async function saveConfig(config: Config, logger: Logger) {
*/
export async function getConfig(
tempDir: string,
logger: Logger
logger: Logger,
): Promise<Config | undefined> {
const configFile = getPathToParsedConfigFile(tempDir);
if (!fs.existsSync(configFile)) {
@@ -1950,14 +1955,14 @@ export async function downloadPacks(
apiDetails: api.GitHubApiDetails,
registriesInput: string | undefined,
tempDir: string,
logger: Logger
logger: Logger,
) {
// This code path is only used when config parsing occurs in the Action.
const { registriesAuthTokens, qlconfigFile } = await generateRegistries(
registriesInput,
codeQL,
tempDir,
logger
logger,
);
await wrapEnvironment(
{
@@ -1973,13 +1978,13 @@ export async function downloadPacks(
logger.info(`Downloading custom packs for ${language}`);
const results = await codeQL.packDownload(
packsWithVersion,
qlconfigFile
qlconfigFile,
);
numPacksDownloaded += results.packs.length;
logger.info(
`Downloaded: ${results.packs
.map((r) => `${r.name}@${r.version || "latest"}`)
.join(", ")}`
.join(", ")}`,
);
}
}
@@ -1987,13 +1992,13 @@ export async function downloadPacks(
logger.info(
`Downloaded ${numPacksDownloaded} ${
numPacksDownloaded === 1 ? "pack" : "packs"
}`
}`,
);
} else {
logger.info("No packs to download");
}
logger.endGroup();
}
},
);
}
@@ -2013,7 +2018,7 @@ export async function generateRegistries(
registriesInput: string | undefined,
codeQL: CodeQL,
tempDir: string,
logger: Logger
logger: Logger,
) {
const registries = parseRegistries(registriesInput);
let registriesAuthTokens: string | undefined;
@@ -2023,7 +2028,7 @@ export async function generateRegistries(
!(await codeQlVersionAbove(codeQL, CODEQL_VERSION_GHES_PACK_DOWNLOAD))
) {
throw new UserError(
`The 'registries' input is not supported on CodeQL CLI versions earlier than ${CODEQL_VERSION_GHES_PACK_DOWNLOAD}. Please upgrade to CodeQL CLI version ${CODEQL_VERSION_GHES_PACK_DOWNLOAD} or later.`
`The 'registries' input is not supported on CodeQL CLI versions earlier than ${CODEQL_VERSION_GHES_PACK_DOWNLOAD}. Please upgrade to CodeQL CLI version ${CODEQL_VERSION_GHES_PACK_DOWNLOAD} or later.`,
);
}
@@ -2042,7 +2047,7 @@ export async function generateRegistries(
if (typeof process.env.CODEQL_REGISTRIES_AUTH === "string") {
logger.debug(
"Using CODEQL_REGISTRIES_AUTH environment variable to authenticate with registries."
"Using CODEQL_REGISTRIES_AUTH environment variable to authenticate with registries.",
);
}
@@ -2062,7 +2067,7 @@ function createRegistriesBlock(registries: RegistryConfigWithCredentials[]): {
registries.some((r) => !r.url || !r.packages)
) {
throw new UserError(
"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.",
);
}
@@ -2092,7 +2097,7 @@ function createRegistriesBlock(registries: RegistryConfigWithCredentials[]): {
*/
export async function wrapEnvironment(
env: Record<string, string | undefined>,
operation: Function
operation: Function,
) {
// Remember the original env
const oldEnv = { ...process.env };

View File

@@ -74,7 +74,7 @@ async function mockHttpRequests(databaseUploadStatusCode: number) {
databaseUploadSpy.resolves(undefined);
} else {
databaseUploadSpy.throws(
new HTTPError("some error message", databaseUploadStatusCode)
new HTTPError("some error message", databaseUploadStatusCode),
);
}
@@ -95,14 +95,15 @@ test("Abort database upload if 'upload-database' input set to false", async (t)
testRepoName,
getTestConfig(tmpDir),
testApiDetails,
getRecordingLogger(loggedMessages)
getRecordingLogger(loggedMessages),
);
t.assert(
loggedMessages.find(
(v: LoggedMessage) =>
v.type === "debug" &&
v.message === "Database upload disabled in workflow. Skipping upload."
) !== undefined
v.message ===
"Database upload disabled in workflow. Skipping upload.",
) !== undefined,
);
});
});
@@ -124,14 +125,14 @@ test("Abort database upload if running against GHES", async (t) => {
testRepoName,
config,
testApiDetails,
getRecordingLogger(loggedMessages)
getRecordingLogger(loggedMessages),
);
t.assert(
loggedMessages.find(
(v: LoggedMessage) =>
v.type === "debug" &&
v.message === "Not running against github.com. Skipping upload."
) !== undefined
v.message === "Not running against github.com. Skipping upload.",
) !== undefined,
);
});
});
@@ -153,14 +154,14 @@ test("Abort database upload if running against GHAE", async (t) => {
testRepoName,
config,
testApiDetails,
getRecordingLogger(loggedMessages)
getRecordingLogger(loggedMessages),
);
t.assert(
loggedMessages.find(
(v: LoggedMessage) =>
v.type === "debug" &&
v.message === "Not running against github.com. Skipping upload."
) !== undefined
v.message === "Not running against github.com. Skipping upload.",
) !== undefined,
);
});
});
@@ -179,14 +180,14 @@ test("Abort database upload if not analyzing default branch", async (t) => {
testRepoName,
getTestConfig(tmpDir),
testApiDetails,
getRecordingLogger(loggedMessages)
getRecordingLogger(loggedMessages),
);
t.assert(
loggedMessages.find(
(v: LoggedMessage) =>
v.type === "debug" &&
v.message === "Not analyzing default branch. Skipping upload."
) !== undefined
v.message === "Not analyzing default branch. Skipping upload.",
) !== undefined,
);
});
});
@@ -213,7 +214,7 @@ test("Don't crash if uploading a database fails", async (t) => {
testRepoName,
getTestConfig(tmpDir),
testApiDetails,
getRecordingLogger(loggedMessages)
getRecordingLogger(loggedMessages),
);
t.assert(
@@ -221,8 +222,8 @@ test("Don't crash if uploading a database fails", async (t) => {
(v) =>
v.type === "warning" &&
v.message ===
"Failed to upload database for javascript: Error: some error message"
) !== undefined
"Failed to upload database for javascript: Error: some error message",
) !== undefined,
);
});
});
@@ -249,14 +250,14 @@ test("Successfully uploading a database to api.github.com", async (t) => {
testRepoName,
getTestConfig(tmpDir),
testApiDetails,
getRecordingLogger(loggedMessages)
getRecordingLogger(loggedMessages),
);
t.assert(
loggedMessages.find(
(v) =>
v.type === "debug" &&
v.message === "Successfully uploaded database for javascript"
) !== undefined
v.message === "Successfully uploaded database for javascript",
) !== undefined,
);
});
});
@@ -283,14 +284,14 @@ test("Successfully uploading a database to uploads.github.com", async (t) => {
testRepoName,
getTestConfig(tmpDir),
testApiDetails,
getRecordingLogger(loggedMessages)
getRecordingLogger(loggedMessages),
);
t.assert(
loggedMessages.find(
(v) =>
v.type === "debug" &&
v.message === "Successfully uploaded database for javascript"
) !== undefined
v.message === "Successfully uploaded database for javascript",
) !== undefined,
);
});
});

View File

@@ -13,7 +13,7 @@ export async function uploadDatabases(
repositoryNwo: RepositoryNwo,
config: Config,
apiDetails: GitHubApiDetails,
logger: Logger
logger: Logger,
): Promise<void> {
if (actionsUtil.getRequiredInput("upload-database") !== "true") {
logger.debug("Database upload disabled in workflow. Skipping upload.");
@@ -58,7 +58,7 @@ export async function uploadDatabases(
"Content-Type": "application/zip",
"Content-Length": bundledDbSize,
},
}
},
);
logger.debug(`Successfully uploaded database for ${language}`);
} finally {

View File

@@ -5,19 +5,19 @@ import * as debugArtifacts from "./debug-artifacts";
test("sanitizeArifactName", (t) => {
t.deepEqual(
debugArtifacts.sanitizeArifactName("hello-world_"),
"hello-world_"
"hello-world_",
);
t.deepEqual(debugArtifacts.sanitizeArifactName("hello`world`"), "helloworld");
t.deepEqual(debugArtifacts.sanitizeArifactName("hello===123"), "hello123");
t.deepEqual(
debugArtifacts.sanitizeArifactName("*m)a&n^y%i££n+v!a:l[i]d"),
"manyinvalid"
"manyinvalid",
);
});
test("uploadDebugArtifacts", async (t) => {
// Test that no error is thrown if artifacts list is empty.
await t.notThrowsAsync(
debugArtifacts.uploadDebugArtifacts([], "rootDir", "artifactName")
debugArtifacts.uploadDebugArtifacts([], "rootDir", "artifactName"),
);
});

View File

@@ -26,7 +26,7 @@ export function sanitizeArifactName(name: string): string {
export async function uploadDebugArtifacts(
toUpload: string[],
rootDir: string,
artifactName: string
artifactName: string,
) {
if (toUpload.length === 0) {
return;
@@ -36,25 +36,25 @@ export async function uploadDebugArtifacts(
if (matrix) {
try {
for (const [, matrixVal] of Object.entries(
JSON.parse(matrix) as any[][]
JSON.parse(matrix) as any[][],
).sort())
suffix += `-${matrixVal}`;
} catch (e) {
core.info(
"Could not parse user-specified `matrix` input into JSON. The debug artifact will not be named with the user's `matrix` input."
"Could not parse user-specified `matrix` input into JSON. The debug artifact will not be named with the user's `matrix` input.",
);
}
}
await artifact.create().uploadArtifact(
sanitizeArifactName(`${artifactName}${suffix}`),
toUpload.map((file) => path.normalize(file)),
path.normalize(rootDir)
path.normalize(rootDir),
);
}
export async function uploadSarifDebugArtifact(
config: Config,
outputDir: string
outputDir: string,
) {
if (!doesDirectoryExist(outputDir)) {
return;
@@ -83,7 +83,7 @@ export async function uploadLogsDebugArtifact(config: Config) {
// Multilanguage tracing: there are additional logs in the root of the cluster
const multiLanguageTracingLogsDirectory = path.resolve(
config.dbLocation,
"log"
"log",
);
if (doesDirectoryExist(multiLanguageTracingLogsDirectory)) {
toUpload = toUpload.concat(listFolder(multiLanguageTracingLogsDirectory));
@@ -92,7 +92,7 @@ export async function uploadLogsDebugArtifact(config: Config) {
await uploadDebugArtifacts(
toUpload,
config.dbLocation,
config.debugArtifactName
config.debugArtifactName,
);
}
@@ -103,15 +103,15 @@ export async function uploadLogsDebugArtifact(config: Config) {
*/
async function createPartialDatabaseBundle(
config: Config,
language: Language
language: Language,
): Promise<string> {
const databasePath = getCodeQLDatabasePath(config, language);
const databaseBundlePath = path.resolve(
config.dbLocation,
`${config.debugDatabaseName}-${language}-partial.zip`
`${config.debugDatabaseName}-${language}-partial.zip`,
);
core.info(
`${config.debugDatabaseName}-${language} is not finalized. Uploading partial database bundle at ${databaseBundlePath}...`
`${config.debugDatabaseName}-${language} is not finalized. Uploading partial database bundle at ${databaseBundlePath}...`,
);
// See `bundleDb` for explanation behind deleting existing db bundle.
if (fs.existsSync(databaseBundlePath)) {
@@ -128,21 +128,21 @@ async function createPartialDatabaseBundle(
*/
async function createDatabaseBundleCli(
config: Config,
language: Language
language: Language,
): Promise<string> {
// Otherwise run `codeql database bundle` command.
const databaseBundlePath = await bundleDb(
config,
language,
await getCodeQL(config.codeQLCmd),
`${config.debugDatabaseName}-${language}`
`${config.debugDatabaseName}-${language}`,
);
return databaseBundlePath;
}
export async function uploadDatabaseBundleDebugArtifact(
config: Config,
logger: Logger
logger: Logger,
) {
for (const language of config.languages) {
try {
@@ -150,7 +150,7 @@ export async function uploadDatabaseBundleDebugArtifact(
if (!dbIsFinalized(config, language, logger)) {
databaseBundlePath = await createPartialDatabaseBundle(
config,
language
language,
);
} else {
databaseBundlePath = await createDatabaseBundleCli(config, language);
@@ -158,11 +158,11 @@ export async function uploadDatabaseBundleDebugArtifact(
await uploadDebugArtifacts(
[databaseBundlePath],
config.dbLocation,
config.debugArtifactName
config.debugArtifactName,
);
} catch (error) {
core.info(
`Failed to upload database debug bundle for ${config.debugDatabaseName}-${language}: ${error}`
`Failed to upload database debug bundle for ${config.debugDatabaseName}-${language}: ${error}`,
);
}
}

View File

@@ -50,7 +50,7 @@ test("checkoutExternalQueries", async (t) => {
stderr += data.toString();
},
},
}
},
).exec();
} catch (e) {
console.log(`Command failed: git ${command.join(" ")}`);
@@ -91,7 +91,7 @@ test("checkoutExternalQueries", async (t) => {
apiURL: undefined,
},
tmpDir,
getRunnerLogger(true)
getRunnerLogger(true),
);
t.true(fs.existsSync(path.join(tmpDir, repoName)));
t.true(fs.existsSync(path.join(tmpDir, repoName, commit1Sha)));
@@ -109,7 +109,7 @@ test("checkoutExternalQueries", async (t) => {
apiURL: undefined,
},
tmpDir,
getRunnerLogger(true)
getRunnerLogger(true),
);
t.true(fs.existsSync(path.join(tmpDir, repoName, commit2Sha)));
t.true(fs.existsSync(path.join(tmpDir, repoName, commit2Sha, "a")));
@@ -124,7 +124,7 @@ test("buildCheckoutURL", (t) => {
externalRepoAuth: undefined,
apiURL: undefined,
}),
"https://github.com/foo/bar"
"https://github.com/foo/bar",
);
t.deepEqual(
externalQueries.buildCheckoutURL("foo/bar", {
@@ -132,7 +132,7 @@ test("buildCheckoutURL", (t) => {
externalRepoAuth: undefined,
apiURL: undefined,
}),
"https://github.example.com/foo/bar"
"https://github.example.com/foo/bar",
);
t.deepEqual(
@@ -141,7 +141,7 @@ test("buildCheckoutURL", (t) => {
externalRepoAuth: "abc",
apiURL: undefined,
}),
"https://x-access-token:abc@github.com/foo/bar"
"https://x-access-token:abc@github.com/foo/bar",
);
t.deepEqual(
externalQueries.buildCheckoutURL("foo/bar", {
@@ -149,6 +149,6 @@ test("buildCheckoutURL", (t) => {
externalRepoAuth: "abc",
apiURL: undefined,
}),
"https://x-access-token:abc@github.example.com/foo/bar"
"https://x-access-token:abc@github.example.com/foo/bar",
);
});

View File

@@ -15,7 +15,7 @@ export async function checkoutExternalRepository(
ref: string,
apiDetails: GitHubApiExternalRepoDetails,
tempDir: string,
logger: Logger
logger: Logger,
): Promise<string> {
logger.info(`Checking out ${repository}`);
@@ -24,7 +24,7 @@ export async function checkoutExternalRepository(
if (!checkoutLocation.startsWith(tempDir)) {
// this still permits locations that mess with sibling repositories in `tempDir`, but that is acceptable
throw new Error(
`'${repository}@${ref}' is not a valid repository and reference.`
`'${repository}@${ref}' is not a valid repository and reference.`,
);
}
@@ -48,7 +48,7 @@ export async function checkoutExternalRepository(
export function buildCheckoutURL(
repository: string,
apiDetails: GitHubApiExternalRepoDetails
apiDetails: GitHubApiExternalRepoDetails,
): string {
const repoCloneURL = new URL(apiDetails.url);
if (apiDetails.externalRepoAuth !== undefined) {

View File

@@ -50,13 +50,13 @@ for (const variant of ALL_FEATURES_DISABLED_VARIANTS) {
const features = setUpFeatureFlagTests(
tmpDir,
getRecordingLogger(loggedMessages),
variant.gitHubVersion
variant.gitHubVersion,
);
for (const feature of Object.values(Feature)) {
t.deepEqual(
await features.getValue(feature, includeCodeQlIfRequired(feature)),
featureConfig[feature].defaultValue
featureConfig[feature].defaultValue,
);
}
@@ -65,8 +65,8 @@ for (const variant of ALL_FEATURES_DISABLED_VARIANTS) {
(v: LoggedMessage) =>
v.type === "debug" &&
v.message ===
"Not running against github.com. Disabling all toggleable features."
) !== undefined
"Not running against github.com. Disabling all toggleable features.",
) !== undefined,
);
});
});
@@ -77,7 +77,7 @@ test("API response missing and features use default value", async (t) => {
const loggedMessages: LoggedMessage[] = [];
const features = setUpFeatureFlagTests(
tmpDir,
getRecordingLogger(loggedMessages)
getRecordingLogger(loggedMessages),
);
mockFeatureFlagApiEndpoint(403, {});
@@ -85,7 +85,7 @@ test("API response missing and features use default value", async (t) => {
for (const feature of Object.values(Feature)) {
t.assert(
(await features.getValue(feature, includeCodeQlIfRequired(feature))) ===
featureConfig[feature].defaultValue
featureConfig[feature].defaultValue,
);
}
assertAllFeaturesUndefinedInApi(t, loggedMessages);
@@ -97,7 +97,7 @@ test("Features use default value if they're not returned in API response", async
const loggedMessages: LoggedMessage[] = [];
const features = setUpFeatureFlagTests(
tmpDir,
getRecordingLogger(loggedMessages)
getRecordingLogger(loggedMessages),
);
mockFeatureFlagApiEndpoint(200, {});
@@ -105,7 +105,7 @@ test("Features use default value if they're not returned in API response", async
for (const feature of Object.values(Feature)) {
t.assert(
(await features.getValue(feature, includeCodeQlIfRequired(feature))) ===
featureConfig[feature].defaultValue
featureConfig[feature].defaultValue,
);
}
@@ -123,12 +123,12 @@ test("Feature flags exception is propagated if the API request errors", async (t
async () =>
features.getValue(
Feature.MlPoweredQueriesEnabled,
includeCodeQlIfRequired(Feature.MlPoweredQueriesEnabled)
includeCodeQlIfRequired(Feature.MlPoweredQueriesEnabled),
),
{
message:
"Encountered an error while trying to determine feature enablement: Error: some error message",
}
},
);
});
});
@@ -150,7 +150,7 @@ for (const feature of Object.keys(featureConfig)) {
for (const f of Object.keys(featureConfig)) {
actualFeatureEnablement[f] = await features.getValue(
f as Feature,
includeCodeQlIfRequired(f)
includeCodeQlIfRequired(f),
);
}
@@ -170,8 +170,8 @@ for (const feature of Object.keys(featureConfig)) {
t.assert(
!(await features.getValue(
feature as Feature,
includeCodeQlIfRequired(feature)
))
includeCodeQlIfRequired(feature),
)),
);
// set env var to true and check that the feature is now enabled
@@ -179,8 +179,8 @@ for (const feature of Object.keys(featureConfig)) {
t.assert(
await features.getValue(
feature as Feature,
includeCodeQlIfRequired(feature)
)
includeCodeQlIfRequired(feature),
),
);
});
});
@@ -196,8 +196,8 @@ for (const feature of Object.keys(featureConfig)) {
t.assert(
await features.getValue(
feature as Feature,
includeCodeQlIfRequired(feature)
)
includeCodeQlIfRequired(feature),
),
);
// set env var to false and check that the feature is now disabled
@@ -205,8 +205,8 @@ for (const feature of Object.keys(featureConfig)) {
t.assert(
!(await features.getValue(
feature as Feature,
includeCodeQlIfRequired(feature)
))
includeCodeQlIfRequired(feature),
)),
);
});
});
@@ -265,13 +265,13 @@ for (const feature of Object.keys(featureConfig)) {
test("At least one feature has a minimum version specified", (t) => {
t.assert(
Object.values(featureConfig).some((f) => f.minimumVersion !== undefined),
"At least one feature should have a minimum version specified"
"At least one feature should have a minimum version specified",
);
// An even less likely scenario is that we no longer have any features.
t.assert(
Object.values(featureConfig).length > 0,
"There should be at least one feature"
"There should be at least one feature",
);
});
@@ -285,24 +285,24 @@ test("Feature flags are saved to disk", async (t) => {
t.false(
fs.existsSync(cachedFeatureFlags),
"Feature flag cached file should not exist before getting feature flags"
"Feature flag cached file should not exist before getting feature flags",
);
t.true(
await features.getValue(
Feature.CliConfigFileEnabled,
includeCodeQlIfRequired(Feature.CliConfigFileEnabled)
includeCodeQlIfRequired(Feature.CliConfigFileEnabled),
),
"Feature flag should be enabled initially"
"Feature flag should be enabled initially",
);
t.true(
fs.existsSync(cachedFeatureFlags),
"Feature flag cached file should exist after getting feature flags"
"Feature flag cached file should exist after getting feature flags",
);
const actualFeatureEnablement = JSON.parse(
fs.readFileSync(cachedFeatureFlags, "utf8")
fs.readFileSync(cachedFeatureFlags, "utf8"),
);
t.deepEqual(actualFeatureEnablement, expectedFeatureEnablement);
@@ -310,7 +310,7 @@ test("Feature flags are saved to disk", async (t) => {
actualFeatureEnablement[Feature.CliConfigFileEnabled] = false;
fs.writeFileSync(
cachedFeatureFlags,
JSON.stringify(actualFeatureEnablement)
JSON.stringify(actualFeatureEnablement),
);
// delete the in memory cache so that we are forced to use the cached file
@@ -319,9 +319,9 @@ test("Feature flags are saved to disk", async (t) => {
t.false(
await features.getValue(
Feature.CliConfigFileEnabled,
includeCodeQlIfRequired(Feature.CliConfigFileEnabled)
includeCodeQlIfRequired(Feature.CliConfigFileEnabled),
),
"Feature flag should be enabled after reading from cached file"
"Feature flag should be enabled after reading from cached file",
);
});
});
@@ -336,23 +336,23 @@ test("Environment variable can override feature flag cache", async (t) => {
t.true(
await features.getValue(
Feature.CliConfigFileEnabled,
includeCodeQlIfRequired(Feature.CliConfigFileEnabled)
includeCodeQlIfRequired(Feature.CliConfigFileEnabled),
),
"Feature flag should be enabled initially"
"Feature flag should be enabled initially",
);
t.true(
fs.existsSync(cachedFeatureFlags),
"Feature flag cached file should exist after getting feature flags"
"Feature flag cached file should exist after getting feature flags",
);
process.env.CODEQL_PASS_CONFIG_TO_CLI = "false";
t.false(
await features.getValue(
Feature.CliConfigFileEnabled,
includeCodeQlIfRequired(Feature.CliConfigFileEnabled)
includeCodeQlIfRequired(Feature.CliConfigFileEnabled),
),
"Feature flag should be disabled after setting env var"
"Feature flag should be disabled after setting env var",
);
});
});
@@ -384,7 +384,7 @@ test("selects CLI v2.20.1 on Dotcom when feature flags enable v2.20.0 and v2.20.
mockFeatureFlagApiEndpoint(200, expectedFeatureEnablement);
const defaultCliVersion = await features.getDefaultCliVersion(
GitHubVariant.DOTCOM
GitHubVariant.DOTCOM,
);
t.deepEqual(defaultCliVersion, {
cliVersion: "2.20.1",
@@ -402,7 +402,7 @@ test("includes tag name when feature flags enable version greater than v2.13.4",
mockFeatureFlagApiEndpoint(200, expectedFeatureEnablement);
const defaultCliVersion = await features.getDefaultCliVersion(
GitHubVariant.DOTCOM
GitHubVariant.DOTCOM,
);
t.deepEqual(defaultCliVersion, {
cliVersion: "2.20.0",
@@ -419,7 +419,7 @@ test(`selects CLI from defaults.json on Dotcom when no default version feature f
mockFeatureFlagApiEndpoint(200, expectedFeatureEnablement);
const defaultCliVersion = await features.getDefaultCliVersion(
GitHubVariant.DOTCOM
GitHubVariant.DOTCOM,
);
t.deepEqual(defaultCliVersion, {
cliVersion: defaults.cliVersion,
@@ -438,7 +438,7 @@ test(`selects CLI from defaults.json on Dotcom when default version feature flag
mockFeatureFlagApiEndpoint(200, expectedFeatureEnablement);
const defaultCliVersion = await features.getDefaultCliVersion(
GitHubVariant.DOTCOM
GitHubVariant.DOTCOM,
);
t.deepEqual(defaultCliVersion, {
cliVersion: defaults.cliVersion,
@@ -453,7 +453,7 @@ test("ignores invalid version numbers in default version feature flags", async (
const loggedMessages = [];
const features = setUpFeatureFlagTests(
tmpDir,
getRecordingLogger(loggedMessages)
getRecordingLogger(loggedMessages),
);
const expectedFeatureEnablement = initializeFeatures(true);
expectedFeatureEnablement["default_codeql_version_2_20_0_enabled"] = true;
@@ -463,7 +463,7 @@ test("ignores invalid version numbers in default version feature flags", async (
mockFeatureFlagApiEndpoint(200, expectedFeatureEnablement);
const defaultCliVersion = await features.getDefaultCliVersion(
GitHubVariant.DOTCOM
GitHubVariant.DOTCOM,
);
t.deepEqual(defaultCliVersion, {
cliVersion: "2.20.1",
@@ -476,8 +476,8 @@ test("ignores invalid version numbers in default version feature flags", async (
(v: LoggedMessage) =>
v.type === "warning" &&
v.message ===
"Ignoring feature flag default_codeql_version_2_20_invalid_enabled as it does not specify a valid CodeQL version."
) !== undefined
"Ignoring feature flag default_codeql_version_2_20_invalid_enabled as it does not specify a valid CodeQL version.",
) !== undefined,
);
});
});
@@ -486,14 +486,14 @@ test("feature flags should end with _enabled", async (t) => {
for (const feature of Object.values(Feature)) {
t.assert(
feature.endsWith("_enabled"),
`${feature} should end with '_enabled'`
`${feature} should end with '_enabled'`,
);
}
});
function assertAllFeaturesUndefinedInApi(
t: ExecutionContext<unknown>,
loggedMessages: LoggedMessage[]
loggedMessages: LoggedMessage[],
) {
for (const feature of Object.keys(featureConfig)) {
t.assert(
@@ -501,8 +501,8 @@ function assertAllFeaturesUndefinedInApi(
(v) =>
v.type === "debug" &&
(v.message as string).includes(feature) &&
(v.message as string).includes("undefined in API response")
) !== undefined
(v.message as string).includes("undefined in API response"),
) !== undefined,
);
}
}
@@ -517,7 +517,7 @@ function initializeFeatures(initialValue: boolean) {
function setUpFeatureFlagTests(
tmpDir: string,
logger = getRunnerLogger(true),
gitHubVersion = { type: GitHubVariant.DOTCOM } as util.GitHubVersion
gitHubVersion = { type: GitHubVariant.DOTCOM } as util.GitHubVersion,
): FeatureEnablement {
setupActionsVars(tmpDir, tmpDir);

View File

@@ -32,7 +32,7 @@ export interface CodeQLDefaultVersionInfo {
export interface FeatureEnablement {
/** Gets the default version of the CodeQL tools. */
getDefaultCliVersion(
variant: util.GitHubVariant
variant: util.GitHubVariant,
): Promise<CodeQLDefaultVersionInfo>;
getValue(feature: Feature, codeql?: CodeQL): Promise<boolean>;
}
@@ -132,18 +132,18 @@ export class Features implements FeatureEnablement {
gitHubVersion: util.GitHubVersion,
repositoryNwo: RepositoryNwo,
tempDir: string,
private readonly logger: Logger
private readonly logger: Logger,
) {
this.gitHubFeatureFlags = new GitHubFeatureFlags(
gitHubVersion,
repositoryNwo,
path.join(tempDir, FEATURE_FLAGS_FILE_NAME),
logger
logger,
);
}
async getDefaultCliVersion(
variant: util.GitHubVariant
variant: util.GitHubVariant,
): Promise<CodeQLDefaultVersionInfo> {
return await this.gitHubFeatureFlags.getDefaultCliVersion(variant);
}
@@ -163,7 +163,7 @@ export class Features implements FeatureEnablement {
async getValue(feature: Feature, codeql?: CodeQL): Promise<boolean> {
if (!codeql && featureConfig[feature].minimumVersion) {
throw new Error(
`Internal error: A minimum version is specified for feature ${feature}, but no instance of CodeQL was provided.`
`Internal error: A minimum version is specified for feature ${feature}, but no instance of CodeQL was provided.`,
);
}
@@ -174,7 +174,7 @@ export class Features implements FeatureEnablement {
// Do not use this feature if user explicitly disables it via an environment variable.
if (envVar === "false") {
this.logger.debug(
`Feature ${feature} is disabled via the environment variable ${featureConfig[feature].envVar}.`
`Feature ${feature} is disabled via the environment variable ${featureConfig[feature].envVar}.`,
);
return false;
}
@@ -185,13 +185,13 @@ export class Features implements FeatureEnablement {
if (!(await util.codeQlVersionAbove(codeql, minimumVersion))) {
this.logger.debug(
`Feature ${feature} is disabled because the CodeQL CLI version is older than the minimum ` +
`version ${minimumVersion}.`
`version ${minimumVersion}.`,
);
return false;
} else {
this.logger.debug(
`CodeQL CLI version ${await codeql.getVersion()} is newer than the minimum ` +
`version ${minimumVersion} for feature ${feature}.`
`version ${minimumVersion} for feature ${feature}.`,
);
}
}
@@ -199,7 +199,7 @@ export class Features implements FeatureEnablement {
// Use this feature if user explicitly enables it via an environment variable.
if (envVar === "true") {
this.logger.debug(
`Feature ${feature} is enabled via the environment variable ${featureConfig[feature].envVar}.`
`Feature ${feature} is enabled via the environment variable ${featureConfig[feature].envVar}.`,
);
return true;
}
@@ -210,7 +210,7 @@ export class Features implements FeatureEnablement {
this.logger.debug(
`Feature ${feature} is ${
apiValue ? "enabled" : "disabled"
} via the GitHub API.`
} via the GitHub API.`,
);
return apiValue;
}
@@ -219,7 +219,7 @@ export class Features implements FeatureEnablement {
this.logger.debug(
`Feature ${feature} is ${
defaultValue ? "enabled" : "disabled"
} due to its default value.`
} due to its default value.`,
);
return defaultValue;
}
@@ -236,7 +236,7 @@ class GitHubFeatureFlags {
private readonly gitHubVersion: util.GitHubVersion,
private readonly repositoryNwo: RepositoryNwo,
private readonly featureFlagsFile: string,
private readonly logger: Logger
private readonly logger: Logger,
) {
this.hasAccessedRemoteFeatureFlags = false; // Not accessed by default.
}
@@ -251,13 +251,13 @@ class GitHubFeatureFlags {
const version = f
.substring(
DEFAULT_VERSION_FEATURE_FLAG_PREFIX.length,
f.length - DEFAULT_VERSION_FEATURE_FLAG_SUFFIX.length
f.length - DEFAULT_VERSION_FEATURE_FLAG_SUFFIX.length,
)
.replace(/_/g, ".");
if (!semver.valid(version)) {
this.logger.warning(
`Ignoring feature flag ${f} as it does not specify a valid CodeQL version.`
`Ignoring feature flag ${f} as it does not specify a valid CodeQL version.`,
);
return undefined;
}
@@ -265,7 +265,7 @@ class GitHubFeatureFlags {
}
async getDefaultCliVersion(
variant: util.GitHubVariant
variant: util.GitHubVariant,
): Promise<CodeQLDefaultVersionInfo> {
if (variant === util.GitHubVariant.DOTCOM) {
return await this.getDefaultDotcomCliVersion();
@@ -281,13 +281,13 @@ class GitHubFeatureFlags {
const enabledFeatureFlagCliVersions = Object.entries(response)
.map(([f, isEnabled]) =>
isEnabled ? this.getCliVersionFromFeatureFlag(f) : undefined
isEnabled ? this.getCliVersionFromFeatureFlag(f) : undefined,
)
.filter(
(f) =>
f !== undefined &&
// Only consider versions that have semantically versioned bundles.
semver.gte(f, CODEQL_VERSION_BUNDLE_SEMANTICALLY_VERSIONED)
semver.gte(f, CODEQL_VERSION_BUNDLE_SEMANTICALLY_VERSIONED),
)
.map((f) => f as string);
@@ -304,7 +304,7 @@ class GitHubFeatureFlags {
// version that would have been specified by the feature flags before they were misconfigured.
this.logger.warning(
"Feature flags do not specify a default CLI version. Falling back to the CLI version " +
`shipped with the Action. This is ${defaults.cliVersion}.`
`shipped with the Action. This is ${defaults.cliVersion}.`,
);
const result: CodeQLDefaultVersionInfo = {
cliVersion: defaults.cliVersion,
@@ -319,10 +319,10 @@ class GitHubFeatureFlags {
const maxCliVersion = enabledFeatureFlagCliVersions.reduce(
(maxVersion, currentVersion) =>
currentVersion > maxVersion ? currentVersion : maxVersion,
enabledFeatureFlagCliVersions[0]
enabledFeatureFlagCliVersions[0],
);
this.logger.debug(
`Derived default CLI version of ${maxCliVersion} from feature flags.`
`Derived default CLI version of ${maxCliVersion} from feature flags.`,
);
return {
cliVersion: maxCliVersion,
@@ -379,27 +379,27 @@ class GitHubFeatureFlags {
try {
if (fs.existsSync(this.featureFlagsFile)) {
this.logger.debug(
`Loading feature flags from ${this.featureFlagsFile}`
`Loading feature flags from ${this.featureFlagsFile}`,
);
return JSON.parse(fs.readFileSync(this.featureFlagsFile, "utf8"));
}
} catch (e) {
this.logger.warning(
`Error reading cached feature flags file ${this.featureFlagsFile}: ${e}. Requesting from GitHub instead.`
`Error reading cached feature flags file ${this.featureFlagsFile}: ${e}. Requesting from GitHub instead.`,
);
}
return undefined;
}
private async writeLocalFlags(
flags: GitHubFeatureFlagsApiResponse
flags: GitHubFeatureFlagsApiResponse,
): Promise<void> {
try {
this.logger.debug(`Writing feature flags to ${this.featureFlagsFile}`);
fs.writeFileSync(this.featureFlagsFile, JSON.stringify(flags));
} catch (e) {
this.logger.warning(
`Error writing cached feature flags file ${this.featureFlagsFile}: ${e}.`
`Error writing cached feature flags file ${this.featureFlagsFile}: ${e}.`,
);
}
}
@@ -408,7 +408,7 @@ class GitHubFeatureFlags {
// Do nothing when not running against github.com
if (this.gitHubVersion.type !== util.GitHubVariant.DOTCOM) {
this.logger.debug(
"Not running against github.com. Disabling all toggleable features."
"Not running against github.com. Disabling all toggleable features.",
);
this.hasAccessedRemoteFeatureFlags = false;
return {};
@@ -419,12 +419,12 @@ class GitHubFeatureFlags {
{
owner: this.repositoryNwo.owner,
repo: this.repositoryNwo.repo,
}
},
);
const remoteFlags = response.data;
this.logger.debug(
"Loaded the following default values for the feature flags from the Code Scanning API: " +
`${JSON.stringify(remoteFlags)}`
`${JSON.stringify(remoteFlags)}`,
);
this.hasAccessedRemoteFeatureFlags = true;
return remoteFlags;
@@ -434,7 +434,7 @@ class GitHubFeatureFlags {
"This run of the CodeQL Action does not have permission to access Code Scanning API endpoints. " +
"As a result, it will not be opted into any experimental features. " +
"This could be because the Action is running on a pull request from a fork. If not, " +
`please ensure the Action has the 'security-events: write' permission. Details: ${e.message}`
`please ensure the Action has the 'security-events: write' permission. Details: ${e.message}`,
);
this.hasAccessedRemoteFeatureFlags = false;
return {};
@@ -444,7 +444,7 @@ class GitHubFeatureFlags {
// therefore lead to alert churn. As a result, we crash if we cannot determine the value of
// the feature.
throw new Error(
`Encountered an error while trying to determine feature enablement: ${e}`
`Encountered an error while trying to determine feature enablement: ${e}`,
);
}
}
@@ -457,7 +457,7 @@ class GitHubFeatureFlags {
*/
export async function useCodeScanningConfigInCli(
codeql: CodeQL,
features: FeatureEnablement
features: FeatureEnablement,
): Promise<boolean> {
return await features.getValue(Feature.CliConfigFileEnabled, codeql);
}
@@ -465,15 +465,15 @@ export async function useCodeScanningConfigInCli(
export async function logCodeScanningConfigInCli(
codeql: CodeQL,
features: FeatureEnablement,
logger: Logger
logger: Logger,
) {
if (await useCodeScanningConfigInCli(codeql, features)) {
logger.info(
"Code Scanning configuration file being processed in the codeql CLI."
"Code Scanning configuration file being processed in the codeql CLI.",
);
} else {
logger.info(
"Code Scanning configuration file being processed in the codeql-action."
"Code Scanning configuration file being processed in the codeql-action.",
);
}
}

View File

@@ -14,7 +14,7 @@ setupTests(test);
async function testHash(
t: ava.Assertions,
input: string,
expectedHashes: string[]
expectedHashes: string[],
) {
await util.withTmpDir(async (tmpDir) => {
const tmpFile = path.resolve(tmpDir, "testfile");
@@ -78,7 +78,7 @@ test("hash", async (t: ava.Assertions) => {
"b3edc88f2938467e:1",
"c8e28b0b4002a3a0:1",
"c129715d7a2bc9a3:1",
]
],
);
await testHash(t, " hello; \t\nworld!!!\r\n\n\r \t\tGreetings\r End\r\n", [
"e9496ae3ebfced30:1",
@@ -117,7 +117,7 @@ test("hash", async (t: ava.Assertions) => {
"2c644846cb18d53e:1",
"f1b89f20de0d133:1",
"c129715d7a2bc9a3:1",
]
],
);
});
@@ -130,7 +130,7 @@ function testResolveUriToFile(uri: any, index: any, artifactsURIs: any[]) {
location,
artifacts,
process.cwd(),
getRunnerLogger(true)
getRunnerLogger(true),
);
}
@@ -154,20 +154,20 @@ test("resolveUriToFile", (t) => {
testResolveUriToFile(relativeFilepath, undefined, [])
?.split(path.sep)
.join("/"),
filepath
filepath,
);
t.is(
testResolveUriToFile(`file://${relativeFilepath}`, undefined, [])
?.split(path.sep)
.join("/"),
filepath
filepath,
);
// Absolute paths outside the src root are discarded
t.is(testResolveUriToFile("/src/foo/bar.js", undefined, []), undefined);
t.is(
testResolveUriToFile("file:///src/foo/bar.js", undefined, []),
undefined
undefined,
);
// Other schemes are discarded
@@ -200,14 +200,14 @@ test("addFingerprints", async (t) => {
const input = JSON.parse(
fs
.readFileSync(`${__dirname}/../src/testdata/fingerprinting.input.sarif`)
.toString()
.toString(),
) as util.SarifFile;
const expected = JSON.parse(
fs
.readFileSync(
`${__dirname}/../src/testdata/fingerprinting.expected.sarif`
`${__dirname}/../src/testdata/fingerprinting.expected.sarif`,
)
.toString()
.toString(),
);
// The URIs in the SARIF files resolve to files in the testdata directory
@@ -217,9 +217,9 @@ test("addFingerprints", async (t) => {
await fingerprints.addFingerprints(
input,
sourceRoot,
getRunnerLogger(true)
getRunnerLogger(true),
),
expected
expected,
);
});
@@ -228,14 +228,14 @@ test("missingRegions", async (t) => {
const input = JSON.parse(
fs
.readFileSync(`${__dirname}/../src/testdata/fingerprinting2.input.sarif`)
.toString()
.toString(),
) as util.SarifFile;
const expected = JSON.parse(
fs
.readFileSync(
`${__dirname}/../src/testdata/fingerprinting2.expected.sarif`
`${__dirname}/../src/testdata/fingerprinting2.expected.sarif`,
)
.toString()
.toString(),
);
// The URIs in the SARIF files resolve to files in the testdata directory
@@ -245,8 +245,8 @@ test("missingRegions", async (t) => {
await fingerprints.addFingerprints(
input,
sourceRoot,
getRunnerLogger(true)
getRunnerLogger(true),
),
expected
expected,
);
});

View File

@@ -139,7 +139,7 @@ export async function hash(callback: hashCallback, filepath: string) {
function locationUpdateCallback(
result: SarifResult,
location: any,
logger: Logger
logger: Logger,
): hashCallback {
let locationStartLine = location.physicalLocation?.region?.startLine;
if (locationStartLine === undefined) {
@@ -166,7 +166,7 @@ function locationUpdateCallback(
result.partialFingerprints.primaryLocationLineHash = hashValue;
} else if (existingFingerprint !== hashValue) {
logger.warning(
`Calculated fingerprint of ${hashValue} for file ${location.physicalLocation.artifactLocation.uri} line ${lineNumber}, but found existing inconsistent fingerprint value ${existingFingerprint}`
`Calculated fingerprint of ${hashValue} for file ${location.physicalLocation.artifactLocation.uri} line ${lineNumber}, but found existing inconsistent fingerprint value ${existingFingerprint}`,
);
}
};
@@ -180,7 +180,7 @@ export function resolveUriToFile(
location: any,
artifacts: any[],
sourceRoot: string,
logger: Logger
logger: Logger,
): string | undefined {
// This may be referencing an artifact
if (!location.uri && location.index !== undefined) {
@@ -217,7 +217,7 @@ export function resolveUriToFile(
}
if (uri.indexOf("://") !== -1) {
logger.debug(
`Ignoring location URI "${uri}" as the scheme is not recognised`
`Ignoring location URI "${uri}" as the scheme is not recognised`,
);
return undefined;
}
@@ -226,7 +226,7 @@ export function resolveUriToFile(
const srcRootPrefix = `${sourceRoot}/`;
if (uri.startsWith("/") && !uri.startsWith(srcRootPrefix)) {
logger.debug(
`Ignoring location URI "${uri}" as it is outside of the src root`
`Ignoring location URI "${uri}" as it is outside of the src root`,
);
return undefined;
}
@@ -257,7 +257,7 @@ export function resolveUriToFile(
export async function addFingerprints(
sarif: SarifFile,
sourceRoot: string,
logger: Logger
logger: Logger,
): Promise<SarifFile> {
// Gather together results for the same file and construct
// callbacks to accept hashes for that file and update the location
@@ -272,8 +272,8 @@ export async function addFingerprints(
if (!primaryLocation?.physicalLocation?.artifactLocation) {
logger.debug(
`Unable to compute fingerprint for invalid location: ${JSON.stringify(
primaryLocation
)}`
primaryLocation,
)}`,
);
continue;
}
@@ -287,7 +287,7 @@ export async function addFingerprints(
primaryLocation.physicalLocation.artifactLocation,
artifacts,
sourceRoot,
logger
logger,
);
if (!filepath) {
continue;
@@ -296,7 +296,7 @@ export async function addFingerprints(
callbacksByFile[filepath] = [];
}
callbacksByFile[filepath].push(
locationUpdateCallback(result, primaryLocation, logger)
locationUpdateCallback(result, primaryLocation, logger),
);
}
}

View File

@@ -40,7 +40,7 @@ test("post: init action with debug mode off", async (t) => {
printDebugLogsSpy,
parseRepositoryNwo("github/codeql-action"),
createFeatures([]),
getRunnerLogger(true)
getRunnerLogger(true),
);
t.assert(uploadDatabaseBundleSpy.notCalled);
@@ -74,7 +74,7 @@ test("post: init action with debug mode on", async (t) => {
printDebugLogsSpy,
parseRepositoryNwo("github/codeql-action"),
createFeatures([]),
getRunnerLogger(true)
getRunnerLogger(true),
);
t.assert(uploadDatabaseBundleSpy.called);
@@ -220,7 +220,7 @@ for (const { uploadInput, shouldUpload } of UPLOAD_INPUT_TEST_CASES) {
if (!shouldUpload) {
t.is(
result.upload_failed_run_skipped_because,
"SARIF upload is disabled"
"SARIF upload is disabled",
);
}
});
@@ -280,7 +280,7 @@ test("uploading failed SARIF run fails when workflow uses a complex upload input
t.is(
result.upload_failed_run_error,
"Could not get upload input to github/codeql-action/analyze since it contained an " +
"unrecognized dynamic value."
"unrecognized dynamic value.",
);
});
@@ -297,13 +297,13 @@ test("uploading failed SARIF run fails when workflow does not reference github/c
t.is(
result.upload_failed_run_error,
"Could not get upload input to github/codeql-action/analyze since the analyze job does not " +
"call github/codeql-action/analyze."
"call github/codeql-action/analyze.",
);
t.truthy(result.upload_failed_run_stack_trace);
});
function createTestWorkflow(
steps: workflow.WorkflowJobStep[]
steps: workflow.WorkflowJobStep[],
): workflow.Workflow {
return {
name: "CodeQL",
@@ -340,7 +340,7 @@ async function testFailedSarifUpload(
expectUpload?: boolean;
exportDiagnosticsEnabled?: boolean;
matrix?: { [key: string]: string };
} = {}
} = {},
): Promise<initActionPostHelper.UploadFailedSarifResult> {
const config = {
codeQLCmd: "codeql",
@@ -364,7 +364,7 @@ async function testFailedSarifUpload(
sinon.stub(codeql, "getCodeQL").resolves(codeqlObject);
const databaseExportDiagnosticsStub = sinon.stub(
codeqlObject,
"databaseExportDiagnostics"
"databaseExportDiagnostics",
);
const diagnosticsExportStub = sinon.stub(codeqlObject, "diagnosticsExport");
@@ -386,7 +386,7 @@ async function testFailedSarifUpload(
config,
parseRepositoryNwo("github/codeql-action"),
createFeatures(features),
getRunnerLogger(true)
getRunnerLogger(true),
);
if (expectUpload) {
t.deepEqual(result, {
@@ -400,18 +400,18 @@ async function testFailedSarifUpload(
sinon.match.string,
category,
sinon.match.any,
sinon.match.any
sinon.match.any,
),
`Actual args were: ${databaseExportDiagnosticsStub.args}`
`Actual args were: ${databaseExportDiagnosticsStub.args}`,
);
} else {
t.true(
diagnosticsExportStub.calledOnceWith(
sinon.match.string,
category,
config
config,
),
`Actual args were: ${diagnosticsExportStub.args}`
`Actual args were: ${diagnosticsExportStub.args}`,
);
}
t.true(
@@ -419,14 +419,14 @@ async function testFailedSarifUpload(
sinon.match.string,
sinon.match.string,
category,
sinon.match.any
sinon.match.any,
),
`Actual args were: ${uploadFromActions.args}`
`Actual args were: ${uploadFromActions.args}`,
);
t.true(
waitForProcessing.calledOnceWith(sinon.match.any, "42", sinon.match.any, {
isUnsuccessfulExecution: true,
})
}),
);
} else {
t.true(diagnosticsExportStub.notCalled);

View File

@@ -31,7 +31,7 @@ export interface UploadFailedSarifResult extends uploadLib.UploadStatusReport {
}
function createFailedUploadFailedSarifResult(
error: unknown
error: unknown,
): UploadFailedSarifResult {
const wrappedError = wrapError(error);
return {
@@ -48,7 +48,7 @@ async function maybeUploadFailedSarif(
config: Config,
repositoryNwo: RepositoryNwo,
features: FeatureEnablement,
logger: Logger
logger: Logger,
): Promise<UploadFailedSarifResult> {
if (!config.codeQLCmd) {
return { upload_failed_run_skipped_because: "CodeQL command not found" };
@@ -63,7 +63,7 @@ async function maybeUploadFailedSarif(
const shouldUpload = getUploadInputOrThrow(workflow, jobName, matrix);
if (
!["always", "failure-only"].includes(
actionsUtil.getUploadValue(shouldUpload)
actionsUtil.getUploadValue(shouldUpload),
) ||
isInTestMode()
) {
@@ -88,7 +88,7 @@ async function maybeUploadFailedSarif(
sarifFile,
category,
config.tempDir,
logger
logger,
);
}
@@ -97,13 +97,13 @@ async function maybeUploadFailedSarif(
sarifFile,
checkoutPath,
category,
logger
logger,
);
await uploadLib.waitForProcessing(
repositoryNwo,
uploadResult.sarifID,
logger,
{ isUnsuccessfulExecution: true }
{ isUnsuccessfulExecution: true },
);
return uploadResult?.statusReport ?? {};
}
@@ -112,7 +112,7 @@ export async function tryUploadSarifIfRunFailed(
config: Config,
repositoryNwo: RepositoryNwo,
features: FeatureEnablement,
logger: Logger
logger: Logger,
): Promise<UploadFailedSarifResult> {
if (process.env[EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY] !== "true") {
try {
@@ -120,11 +120,11 @@ export async function tryUploadSarifIfRunFailed(
config,
repositoryNwo,
features,
logger
logger,
);
} catch (e) {
logger.debug(
`Failed to upload a SARIF file for this failed CodeQL code scanning run. ${e}`
`Failed to upload a SARIF file for this failed CodeQL code scanning run. ${e}`,
);
return createFailedUploadFailedSarifResult(e);
}
@@ -142,12 +142,12 @@ export async function run(
printDebugLogs: Function,
repositoryNwo: RepositoryNwo,
features: FeatureEnablement,
logger: Logger
logger: Logger,
) {
const config = await getConfig(actionsUtil.getTemporaryDirectory(), logger);
if (config === undefined) {
logger.warning(
"Debugging artifacts are unavailable since the 'init' Action failed before it could produce any."
"Debugging artifacts are unavailable since the 'init' Action failed before it could produce any.",
);
return;
}
@@ -156,13 +156,13 @@ export async function run(
config,
repositoryNwo,
features,
logger
logger,
);
if (uploadFailedSarifResult.upload_failed_run_skipped_because) {
logger.debug(
"Won't upload a failed SARIF file for this CodeQL code scanning run because: " +
`${uploadFailedSarifResult.upload_failed_run_skipped_because}.`
`${uploadFailedSarifResult.upload_failed_run_skipped_because}.`,
);
}
// Throw an error if in integration tests, we expected to upload a SARIF file for a failed run
@@ -174,14 +174,14 @@ export async function run(
const error = JSON.stringify(uploadFailedSarifResult);
throw new Error(
"Expected to upload a failed SARIF file for this CodeQL code scanning run, " +
`but the result was instead ${error}.`
`but the result was instead ${error}.`,
);
}
// Upload appropriate Actions artifacts for debugging
if (config.debugMode) {
core.info(
"Debug mode is on. Uploading available database bundles and logs as Actions debugging artifacts..."
"Debug mode is on. Uploading available database bundles and logs as Actions debugging artifacts...",
);
await uploadDatabaseBundleDebugArtifact(config, logger);
await uploadLogsDebugArtifact(config);

View File

@@ -43,13 +43,13 @@ async function runWrapper() {
checkGitHubVersionInRange(gitHubVersion, logger);
const repositoryNwo = parseRepositoryNwo(
getRequiredEnvParam("GITHUB_REPOSITORY")
getRequiredEnvParam("GITHUB_REPOSITORY"),
);
const features = new Features(
gitHubVersion,
repositoryNwo,
getTemporaryDirectory(),
logger
logger,
);
uploadFailedSarifResult = await initActionPostHelper.run(
@@ -58,7 +58,7 @@ async function runWrapper() {
printDebugLogs,
repositoryNwo,
features,
logger
logger,
);
} catch (unwrappedError) {
const error = wrapError(unwrappedError);
@@ -70,15 +70,15 @@ async function runWrapper() {
getActionsStatus(error),
startedAt,
error.message,
error.stack
)
error.stack,
),
);
return;
}
const statusReportBase = await createStatusReportBase(
"init-post",
"success",
startedAt
startedAt,
);
const statusReport: InitPostStatusReport = {
...statusReportBase,

View File

@@ -96,14 +96,14 @@ async function sendCompletedStatusReport(
toolsSource: ToolsSource,
toolsVersion: string,
logger: Logger,
error?: Error
error?: Error,
) {
const statusReportBase = await createStatusReportBase(
"init",
getActionsStatus(error),
startedAt,
error?.message,
error?.stack
error?.stack,
);
const workflowLanguages = getOptionalInput("languages");
@@ -130,7 +130,7 @@ async function sendCompletedStatusReport(
const languages = config.languages.join(",");
const paths = (config.originalUserInput.paths || []).join(",");
const pathsIgnore = (config.originalUserInput["paths-ignore"] || []).join(
","
",",
);
const disableDefaultQueries = config.originalUserInput[
"disable-default-queries"
@@ -142,7 +142,7 @@ async function sendCompletedStatusReport(
let queriesInput = getOptionalInput("queries")?.trim();
if (queriesInput === undefined || queriesInput.startsWith("+")) {
queries.push(
...(config.originalUserInput.queries || []).map((q) => q.uses)
...(config.originalUserInput.queries || []).map((q) => q.uses),
);
}
if (queriesInput !== undefined) {
@@ -163,7 +163,7 @@ async function sendCompletedStatusReport(
queries: queries.join(","),
trap_cache_languages: Object.keys(config.trapCaches).join(","),
trap_cache_download_size_bytes: Math.round(
await getTotalCacheSize(config.trapCaches, logger)
await getTotalCacheSize(config.trapCaches, logger),
),
trap_cache_download_duration_ms: Math.round(config.trapCacheDownloadTime),
};
@@ -199,7 +199,7 @@ async function run() {
checkGitHubVersionInRange(gitHubVersion, logger);
const repositoryNwo = parseRepositoryNwo(
getRequiredEnvParam("GITHUB_REPOSITORY")
getRequiredEnvParam("GITHUB_REPOSITORY"),
);
const registriesInput = getOptionalInput("registries");
@@ -208,7 +208,7 @@ async function run() {
gitHubVersion,
repositoryNwo,
getTemporaryDirectory(),
logger
logger,
);
core.exportVariable(EnvVar.JOB_RUN_UUID, uuidV4());
@@ -222,15 +222,15 @@ async function run() {
"init",
"starting",
startedAt,
workflowErrors
)
workflowErrors,
),
))
) {
return;
}
const codeQLDefaultVersionInfo = await features.getDefaultCliVersion(
gitHubVersion.type
gitHubVersion.type,
);
toolsFeatureFlagsValid = codeQLDefaultVersionInfo.toolsFeatureFlagsValid;
const initCodeQLResult = await initCodeQL(
@@ -239,7 +239,7 @@ async function run() {
getTemporaryDirectory(),
gitHubVersion.type,
codeQLDefaultVersionInfo,
logger
logger,
);
codeql = initCodeQLResult.codeql;
toolsDownloadDurationMs = initCodeQLResult.toolsDownloadDurationMs;
@@ -269,7 +269,7 @@ async function run() {
gitHubVersion,
apiDetails,
features,
logger
logger,
);
if (
@@ -279,7 +279,7 @@ async function run() {
if (
await features.getValue(
Feature.DisablePythonDependencyInstallationEnabled,
codeql
codeql,
)
) {
logger.info("Skipping python dependency installation");
@@ -289,7 +289,7 @@ async function run() {
} catch (unwrappedError) {
const error = wrapError(unwrappedError);
logger.warning(
`${error.message} You can call this action with 'setup-python-dependencies: false' to disable this process`
`${error.message} You can call this action with 'setup-python-dependencies: false' to disable this process`,
);
}
}
@@ -303,8 +303,8 @@ async function run() {
error instanceof UserError ? "user-error" : "aborted",
startedAt,
error.message,
error.stack
)
error.stack,
),
);
return;
}
@@ -315,7 +315,7 @@ async function run() {
if (goFlags) {
core.exportVariable("GOFLAGS", goFlags);
core.warning(
"Passing the GOFLAGS env parameter to the init action is deprecated. Please move this to the analyze action."
"Passing the GOFLAGS env parameter to the init action is deprecated. Please move this to the analyze action.",
);
}
@@ -329,12 +329,12 @@ async function run() {
process.env["CODEQL_RAM"] ||
getMemoryFlagValue(
getOptionalInput("ram"),
await features.getValue(Feature.ScalingReservedRamEnabled)
).toString()
await features.getValue(Feature.ScalingReservedRamEnabled),
).toString(),
);
core.exportVariable(
"CODEQL_THREADS",
getThreadsFlagValue(getOptionalInput("threads"), logger).toString()
getThreadsFlagValue(getOptionalInput("threads"), logger).toString(),
);
// Disable Kotlin extractor if feature flag set
@@ -346,18 +346,18 @@ async function run() {
if (
await features.getValue(
Feature.DisablePythonDependencyInstallationEnabled,
codeql
codeql,
)
) {
core.exportVariable(
"CODEQL_EXTRACTOR_PYTHON_DISABLE_LIBRARY_EXTRACTION",
"true"
"true",
);
}
const sourceRoot = path.resolve(
getRequiredEnvParam("GITHUB_WORKSPACE"),
getOptionalInput("source-root") || ""
getOptionalInput("source-root") || "",
);
const tracerConfig = await runInit(
@@ -368,7 +368,7 @@ async function run() {
registriesInput,
features,
apiDetails,
logger
logger,
);
if (tracerConfig !== undefined) {
for (const [key, value] of Object.entries(tracerConfig.env)) {
@@ -388,7 +388,7 @@ async function run() {
toolsSource,
toolsVersion,
logger,
error
error,
);
return;
}
@@ -399,7 +399,7 @@ async function run() {
toolsFeatureFlagsValid,
toolsSource,
toolsVersion,
logger
logger,
);
}

View File

@@ -25,7 +25,7 @@ export async function initCodeQL(
tempDir: string,
variant: util.GitHubVariant,
defaultCliVersion: CodeQLDefaultVersionInfo,
logger: Logger
logger: Logger,
): Promise<{
codeql: CodeQL;
toolsDownloadDurationMs?: number;
@@ -41,7 +41,7 @@ export async function initCodeQL(
variant,
defaultCliVersion,
logger,
true
true,
);
await codeql.printVersion();
logger.endGroup();
@@ -67,7 +67,7 @@ export async function initConfig(
gitHubVersion: util.GitHubVersion,
apiDetails: GitHubApiCombinedDetails,
features: FeatureEnablement,
logger: Logger
logger: Logger,
): Promise<configUtils.Config> {
logger.startGroup("Load language configuration");
const config = await configUtils.initConfig(
@@ -89,7 +89,7 @@ export async function initConfig(
gitHubVersion,
apiDetails,
features,
logger
logger,
);
analysisPaths.printPathFiltersWarning(config, logger);
logger.endGroup();
@@ -104,7 +104,7 @@ export async function runInit(
registriesInput: string | undefined,
features: FeatureEnablement,
apiDetails: GitHubApiCombinedDetails,
logger: Logger
logger: Logger,
): Promise<TracerConfig | undefined> {
fs.mkdirSync(config.dbLocation, { recursive: true });
try {
@@ -120,7 +120,7 @@ export async function runInit(
registriesInput,
codeql,
config.tempDir,
logger
logger,
));
}
await configUtils.wrapEnvironment(
@@ -137,8 +137,8 @@ export async function runInit(
processName,
features,
qlconfigFile,
logger
)
logger,
),
);
} catch (e) {
throw processError(e);
@@ -166,7 +166,7 @@ function processError(e: any): Error {
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}`
`Is the "init" action called twice in the same job? ${e.message}`,
);
}
@@ -194,7 +194,7 @@ export async function installPythonDeps(codeql: CodeQL, logger: Logger) {
]).exec();
} else {
await new toolrunner.ToolRunner(
path.join(scriptsFolder, "install_tools.sh")
path.join(scriptsFolder, "install_tools.sh"),
).exec();
}
const script = "auto_install_packages.py";
@@ -218,7 +218,7 @@ export async function installPythonDeps(codeql: CodeQL, logger: Logger) {
`An error occurred while trying to automatically install Python dependencies: ${e}\n` +
"Please make sure any necessary dependencies are installed before calling the codeql-action/analyze " +
"step, and add a 'setup-python-dependencies: false' argument to this step to disable our automatic " +
"dependency installation and avoid this warning."
"dependency installation and avoid this warning.",
);
return;
}

View File

@@ -29,7 +29,7 @@ async function run() {
try {
if (
!(await sendStatusReport(
await createStatusReportBase(ACTION_NAME, "starting", startedAt)
await createStatusReportBase(ACTION_NAME, "starting", startedAt),
))
) {
return;
@@ -41,7 +41,7 @@ async function run() {
const config = await configUtils.getConfig(getTemporaryDirectory(), logger);
if (config === undefined) {
throw new Error(
"Config file could not be found at expected location. Has the 'init' action been called?"
"Config file could not be found at expected location. Has the 'init' action been called?",
);
}
@@ -50,7 +50,7 @@ async function run() {
config.codeQLCmd,
logger,
workingDirectory,
language
language,
);
core.setOutput(ENVIRONMENT_OUTPUT_NAME, result);
} catch (unwrappedError) {
@@ -61,12 +61,12 @@ async function run() {
// we just return an empty JSON object and proceed with the workflow.
core.setOutput(ENVIRONMENT_OUTPUT_NAME, {});
logger.warning(
`Failed to resolve a build environment suitable for automatically building your code. ${error.message}`
`Failed to resolve a build environment suitable for automatically building your code. ${error.message}`,
);
} else {
// For any other error types, something has more seriously gone wrong and we fail.
core.setFailed(
`Failed to resolve a build environment suitable for automatically building your code. ${error.message}`
`Failed to resolve a build environment suitable for automatically building your code. ${error.message}`,
);
await sendStatusReport(
@@ -75,8 +75,8 @@ async function run() {
getActionsStatus(error),
startedAt,
error.message,
error.stack
)
error.stack,
),
);
}
@@ -84,7 +84,7 @@ async function run() {
}
await sendStatusReport(
await createStatusReportBase(ACTION_NAME, "success", startedAt)
await createStatusReportBase(ACTION_NAME, "success", startedAt),
);
}

View File

@@ -7,7 +7,7 @@ export async function runResolveBuildEnvironment(
cmd: string,
logger: Logger,
workingDir: string | undefined,
language: Language
language: Language,
) {
logger.startGroup(`Attempting to resolve build environment for ${language}`);
@@ -21,7 +21,7 @@ export async function runResolveBuildEnvironment(
) {
logger.warning(
"Unsupported CodeQL CLI version for `resolve build-environment` command, " +
"returning an empty configuration."
"returning an empty configuration.",
);
} else {
if (workingDir !== undefined) {

View File

@@ -29,9 +29,9 @@ test.beforeEach(() => {
test("parse codeql bundle url version", (t) => {
t.deepEqual(
setupCodeql.getCodeQLURLVersion(
"https://github.com/.../codeql-bundle-20200601/..."
"https://github.com/.../codeql-bundle-20200601/...",
),
"20200601"
"20200601",
);
});
@@ -49,7 +49,7 @@ test("convert to semver", (t) => {
try {
const parsedVersion = setupCodeql.convertToSemVer(
version,
getRunnerLogger(true)
getRunnerLogger(true),
);
t.deepEqual(parsedVersion, expectedVersion);
} catch (e) {
@@ -86,7 +86,7 @@ test("getCodeQLSource sets CLI version for a semver tagged bundle", async (t) =>
SAMPLE_DEFAULT_CLI_VERSION,
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
getRunnerLogger(true)
getRunnerLogger(true),
);
t.is(source.sourceType, "download");

View File

@@ -48,7 +48,7 @@ export function getCodeQLActionRepository(logger: Logger): string {
// e.g. our integration tests which use the Action code from the current checkout.
// In these cases, the GITHUB_ACTION_REPOSITORY environment variable is not set.
logger.info(
"The CodeQL Action is checked out locally. Using the default CodeQL Action repository."
"The CodeQL Action is checked out locally. Using the default CodeQL Action repository.",
);
return CODEQL_DEFAULT_ACTION_REPOSITORY;
}
@@ -58,7 +58,7 @@ export function getCodeQLActionRepository(logger: Logger): string {
function tryGetCodeQLCliVersionForRelease(
release,
logger: Logger
logger: Logger,
): string | undefined {
const cliVersionsFromMarkerFiles = release.assets
.map((asset) => asset.name.match(/cli-version-(.*)\.txt/)?.[1])
@@ -66,12 +66,12 @@ function tryGetCodeQLCliVersionForRelease(
.map((v) => v as string);
if (cliVersionsFromMarkerFiles.length > 1) {
logger.warning(
`Ignoring release ${release.tag_name} with multiple CLI version marker files.`
`Ignoring release ${release.tag_name} with multiple CLI version marker files.`,
);
return undefined;
} else if (cliVersionsFromMarkerFiles.length === 0) {
logger.debug(
`Failed to find the CodeQL CLI version for release ${release.tag_name}.`
`Failed to find the CodeQL CLI version for release ${release.tag_name}.`,
);
return undefined;
}
@@ -80,11 +80,11 @@ function tryGetCodeQLCliVersionForRelease(
export async function tryFindCliVersionDotcomOnly(
tagName: string,
logger: Logger
logger: Logger,
): Promise<string | undefined> {
try {
logger.debug(
`Fetching the GitHub Release for the CodeQL bundle tagged ${tagName}.`
`Fetching the GitHub Release for the CodeQL bundle tagged ${tagName}.`,
);
const apiClient = api.getApiClient();
const codeQLActionRepository = getCodeQLActionRepository(logger);
@@ -98,7 +98,7 @@ export async function tryFindCliVersionDotcomOnly(
logger.debug(
`Failed to find the CLI version for the CodeQL bundle tagged ${tagName}. ${
wrapError(e).message
}`
}`,
);
return undefined;
}
@@ -108,7 +108,7 @@ async function getCodeQLBundleDownloadURL(
tagName: string,
apiDetails: api.GitHubApiDetails,
variant: util.GitHubVariant,
logger: Logger
logger: Logger,
): Promise<string> {
const codeQLActionRepository = getCodeQLActionRepository(logger);
const potentialDownloadSources = [
@@ -124,7 +124,7 @@ async function getCodeQLBundleDownloadURL(
const uniqueDownloadSources = potentialDownloadSources.filter(
(source, index, self) => {
return !self.slice(0, index).some((other) => deepEqual(source, other));
}
},
);
const codeQLBundleName = getCodeQLBundleName();
if (variant === util.GitHubVariant.GHAE) {
@@ -140,23 +140,23 @@ async function getCodeQLBundleDownloadURL(
.getApiClient()
.request(
"GET /enterprise/code-scanning/codeql-bundle/download/{asset_id}",
{ asset_id: assetID }
{ asset_id: assetID },
);
const downloadURL = download.data.url;
logger.info(
`Found CodeQL bundle at GitHub AE endpoint with URL ${downloadURL}.`
`Found CodeQL bundle at GitHub AE endpoint with URL ${downloadURL}.`,
);
return downloadURL;
} else {
logger.info(
`Attempted to fetch bundle from GitHub AE endpoint but the bundle ${codeQLBundleName} was not found in the assets ${JSON.stringify(
release.data.assets
)}.`
release.data.assets,
)}.`,
);
}
} catch (e) {
logger.info(
`Attempted to fetch bundle from GitHub AE endpoint but got error ${e}.`
`Attempted to fetch bundle from GitHub AE endpoint but got error ${e}.`,
);
}
}
@@ -179,14 +179,14 @@ async function getCodeQLBundleDownloadURL(
for (const asset of release.data.assets) {
if (asset.name === codeQLBundleName) {
logger.info(
`Found CodeQL bundle in ${downloadSource[1]} on ${downloadSource[0]} with URL ${asset.url}.`
`Found CodeQL bundle in ${downloadSource[1]} on ${downloadSource[0]} with URL ${asset.url}.`,
);
return asset.url;
}
}
} catch (e) {
logger.info(
`Looked for CodeQL bundle in ${downloadSource[1]} on ${downloadSource[0]} but got error ${e}.`
`Looked for CodeQL bundle in ${downloadSource[1]} on ${downloadSource[0]} but got error ${e}.`,
);
}
}
@@ -195,7 +195,7 @@ async function getCodeQLBundleDownloadURL(
function tryGetBundleVersionFromTagName(
tagName: string,
logger: Logger
logger: Logger,
): string | undefined {
const match = tagName.match(/^codeql-bundle-(.*)$/);
if (match === null || match.length < 2) {
@@ -216,7 +216,7 @@ function tryGetTagNameFromUrl(url: string, logger: Logger): string | undefined {
export function tryGetBundleVersionFromUrl(
url: string,
logger: Logger
logger: Logger,
): string | undefined {
const tagName = tryGetTagNameFromUrl(url, logger);
if (tagName === undefined) {
@@ -228,7 +228,7 @@ export function tryGetBundleVersionFromUrl(
export function convertToSemVer(version: string, logger: Logger): string {
if (!semver.valid(version)) {
logger.debug(
`Bundle version ${version} is not in SemVer format. Will treat it as pre-release 0.0.0-${version}.`
`Bundle version ${version} is not in SemVer format. Will treat it as pre-release 0.0.0-${version}.`,
);
version = `0.0.0-${version}`;
}
@@ -270,7 +270,7 @@ type CodeQLToolsSource =
*/
async function findOverridingToolsInCache(
humanReadableVersion: string,
logger: Logger
logger: Logger,
): Promise<CodeQLToolsSource | undefined> {
const candidates = toolcache
.findAllVersions("CodeQL")
@@ -284,7 +284,7 @@ async function findOverridingToolsInCache(
if (candidates.length === 1) {
const candidate = candidates[0];
logger.debug(
`CodeQL tools version ${candidate.version} in toolcache overriding version ${humanReadableVersion}.`
`CodeQL tools version ${candidate.version} in toolcache overriding version ${humanReadableVersion}.`,
);
return {
codeqlFolder: candidate.folder,
@@ -293,12 +293,12 @@ async function findOverridingToolsInCache(
};
} else if (candidates.length === 0) {
logger.debug(
"Did not find any candidate pinned versions of the CodeQL tools in the toolcache."
"Did not find any candidate pinned versions of the CodeQL tools in the toolcache.",
);
} else {
logger.debug(
"Could not use CodeQL tools from the toolcache since more than one candidate pinned " +
"version was found in the toolcache."
"version was found in the toolcache.",
);
}
return undefined;
@@ -309,7 +309,7 @@ export async function getCodeQLSource(
defaultCliVersion: CodeQLDefaultVersionInfo,
apiDetails: api.GitHubApiDetails,
variant: util.GitHubVariant,
logger: Logger
logger: Logger,
): Promise<CodeQLToolsSource> {
if (toolsInput && toolsInput !== "latest" && !toolsInput.startsWith("http")) {
return {
@@ -330,7 +330,7 @@ export async function getCodeQLSource(
if (forceShippedTools) {
logger.info(
"Overriding the version of the CodeQL tools by the version shipped with the Action since " +
`"tools: latest" was requested.`
`"tools: latest" was requested.`,
);
}
@@ -379,7 +379,7 @@ export async function getCodeQLSource(
"Attempting to obtain CodeQL tools. " +
`CLI version: ${cliVersion ?? "unknown"}, ` +
`bundle tag name: ${tagName ?? "unknown"}, ` +
`URL: ${url ?? "unspecified"}.`
`URL: ${url ?? "unspecified"}.`,
);
let codeqlFolder: string | undefined;
@@ -392,34 +392,34 @@ export async function getCodeQLSource(
if (!codeqlFolder) {
logger.debug(
"Didn't find a version of the CodeQL tools in the toolcache with a version number " +
`exactly matching ${cliVersion}.`
`exactly matching ${cliVersion}.`,
);
const allVersions = toolcache.findAllVersions("CodeQL");
logger.debug(
`Found the following versions of the CodeQL tools in the toolcache: ${JSON.stringify(
allVersions
)}.`
allVersions,
)}.`,
);
// If there is exactly one version of the CodeQL tools in the toolcache, and that version is
// the form `x.y.z-<tagName>`, then use it.
const candidateVersions = allVersions.filter((version) =>
version.startsWith(`${cliVersion}-`)
version.startsWith(`${cliVersion}-`),
);
if (candidateVersions.length === 1) {
logger.debug(
`Exactly one version of the CodeQL tools starting with ${cliVersion} found in the ` +
"toolcache, using that."
"toolcache, using that.",
);
codeqlFolder = toolcache.find("CodeQL", candidateVersions[0]);
} else if (candidateVersions.length === 0) {
logger.debug(
`Didn't find any versions of the CodeQL tools starting with ${cliVersion} ` +
`in the toolcache. Trying next fallback method.`
`in the toolcache. Trying next fallback method.`,
);
} else {
logger.warning(
`Found ${candidateVersions.length} versions of the CodeQL tools starting with ` +
`${cliVersion} in the toolcache, but at most one was expected.`
`${cliVersion} in the toolcache, but at most one was expected.`,
);
logger.debug("Trying next fallback method.");
}
@@ -431,25 +431,25 @@ export async function getCodeQLSource(
const fallbackVersion = await tryGetFallbackToolcacheVersion(
cliVersion,
tagName,
logger
logger,
);
if (fallbackVersion) {
codeqlFolder = toolcache.find("CodeQL", fallbackVersion);
} else {
logger.debug(
"Could not determine a fallback toolcache version number for CodeQL tools version " +
`${humanReadableVersion}.`
`${humanReadableVersion}.`,
);
}
}
if (codeqlFolder) {
logger.info(
`Found CodeQL tools version ${humanReadableVersion} in the toolcache.`
`Found CodeQL tools version ${humanReadableVersion} in the toolcache.`,
);
} else {
logger.info(
`Did not find CodeQL tools version ${humanReadableVersion} in the toolcache.`
`Did not find CodeQL tools version ${humanReadableVersion} in the toolcache.`,
);
}
@@ -471,7 +471,7 @@ export async function getCodeQLSource(
) {
const result = await findOverridingToolsInCache(
humanReadableVersion,
logger
logger,
);
if (result !== undefined) {
return result;
@@ -483,7 +483,7 @@ export async function getCodeQLSource(
tagName!,
apiDetails,
variant,
logger
logger,
);
}
@@ -503,7 +503,7 @@ export async function getCodeQLSource(
export async function tryGetFallbackToolcacheVersion(
cliVersion: string | undefined,
tagName: string,
logger: Logger
logger: Logger,
): Promise<string | undefined> {
const bundleVersion = tryGetBundleVersionFromTagName(tagName, logger);
if (!bundleVersion) {
@@ -512,7 +512,7 @@ export async function tryGetFallbackToolcacheVersion(
const fallbackVersion = convertToSemVer(bundleVersion, logger);
logger.debug(
`Computed a fallback toolcache version number of ${fallbackVersion} for CodeQL version ` +
`${cliVersion ?? tagName}.`
`${cliVersion ?? tagName}.`,
);
return fallbackVersion;
}
@@ -524,7 +524,7 @@ export async function downloadCodeQL(
apiDetails: api.GitHubApiDetails,
variant: util.GitHubVariant,
tempDir: string,
logger: Logger
logger: Logger,
): Promise<{
toolsVersion: string;
codeqlFolder: string;
@@ -549,13 +549,13 @@ export async function downloadCodeQL(
logger.debug("Downloading CodeQL tools without an authorization token.");
}
logger.info(
`Downloading CodeQL tools from ${codeqlURL}. This may take a while.`
`Downloading CodeQL tools from ${codeqlURL}. This may take a while.`,
);
const dest = path.join(tempDir, uuidV4());
const finalHeaders = Object.assign(
{ "User-Agent": "CodeQL Action" },
headers
headers,
);
const toolsDownloadStart = performance.now();
@@ -563,10 +563,10 @@ export async function downloadCodeQL(
codeqlURL,
dest,
authorization,
finalHeaders
finalHeaders,
);
const toolsDownloadDurationMs = Math.round(
performance.now() - toolsDownloadStart
performance.now() - toolsDownloadStart,
);
logger.debug(`CodeQL bundle download to ${codeqlPath} complete.`);
@@ -579,7 +579,7 @@ export async function downloadCodeQL(
if (bundleVersion === undefined) {
logger.debug(
"Could not cache CodeQL tools because we could not determine the bundle version from the " +
`URL ${codeqlURL}.`
`URL ${codeqlURL}.`,
);
return {
toolsVersion: maybeCliVersion ?? "unknown",
@@ -596,7 +596,7 @@ export async function downloadCodeQL(
) {
maybeCliVersion = await tryFindCliVersionDotcomOnly(
`codeql-bundle-${bundleVersion}`,
logger
logger,
);
}
@@ -617,7 +617,7 @@ export async function downloadCodeQL(
codeqlFolder: await toolcache.cacheDir(
codeqlExtracted,
"CodeQL",
toolcacheVersion
toolcacheVersion,
),
toolsDownloadDurationMs,
};
@@ -627,7 +627,7 @@ export function getCodeQLURLVersion(url: string): string {
const match = url.match(/\/codeql-bundle-(.*)\//);
if (match === null || match.length < 2) {
throw new Error(
`Malformed tools url: ${url}. Version could not be inferred`
`Malformed tools url: ${url}. Version could not be inferred`,
);
}
return match[1];
@@ -652,7 +652,7 @@ export async function setupCodeQLBundle(
tempDir: string,
variant: util.GitHubVariant,
defaultCliVersion: CodeQLDefaultVersionInfo,
logger: Logger
logger: Logger,
): Promise<{
codeqlFolder: string;
toolsDownloadDurationMs?: number;
@@ -664,7 +664,7 @@ export async function setupCodeQLBundle(
defaultCliVersion,
apiDetails,
variant,
logger
logger,
);
let codeqlFolder: string;
@@ -689,7 +689,7 @@ export async function setupCodeQLBundle(
apiDetails,
variant,
tempDir,
logger
logger,
);
toolsVersion = result.toolsVersion;
codeqlFolder = result.codeqlFolder;

View File

@@ -43,7 +43,7 @@ function wrapOutput(context: TestContext) {
return (
chunk: Uint8Array | string,
encoding?: string,
cb?: (err?: Error) => void
cb?: (err?: Error) => void,
): boolean => {
// Work out which method overload we are in
if (cb === undefined && typeof encoding === "function") {
@@ -88,7 +88,7 @@ export function setupTests(test: TestFn<any>) {
// environment variable on Windows isn't preserved, i.e. `process.env.PATH`
// is not the same as `process.env.Path`.
const pathKeys = Object.keys(process.env).filter(
(k) => k.toLowerCase() === "path"
(k) => k.toLowerCase() === "path",
);
if (pathKeys.length > 0) {
process.env.PATH = process.env[pathKeys[0]];
@@ -161,7 +161,7 @@ export function getRecordingLogger(messages: LoggedMessage[]): Logger {
/** Mock the HTTP request to the feature flags enablement API endpoint. */
export function mockFeatureFlagApiEndpoint(
responseStatusCode: number,
response: { [flagName: string]: boolean }
response: { [flagName: string]: boolean },
) {
// Passing an auth token is required, so we just use a dummy value
const client = github.getOctokit("123");
@@ -169,7 +169,7 @@ export function mockFeatureFlagApiEndpoint(
const requestSpy = sinon.stub(client, "request");
const optInSpy = requestSpy.withArgs(
"GET /repos/:owner/:repo/code-scanning/codeql-action/features"
"GET /repos/:owner/:repo/code-scanning/codeql-action/features",
);
if (responseStatusCode < 300) {
optInSpy.resolves({
@@ -271,8 +271,8 @@ export function mockBundleDownloadApi({
200,
path.join(
__dirname,
`/../src/testdata/codeql-bundle${isPinned ? "-pinned" : ""}.tar.gz`
)
`/../src/testdata/codeql-bundle${isPinned ? "-pinned" : ""}.tar.gz`,
),
);
return `${baseUrl}${relativeUrl}`;

View File

@@ -61,12 +61,12 @@ test("getCombinedTracerConfig - with start-tracing.json environment file", async
const tracingEnvironmentDir = path.join(
config.dbLocation,
"temp",
"tracingEnvironment"
"tracingEnvironment",
);
fs.mkdirSync(tracingEnvironmentDir, { recursive: true });
const startTracingJson = path.join(
tracingEnvironmentDir,
"start-tracing.json"
"start-tracing.json",
);
fs.writeFileSync(startTracingJson, JSON.stringify(startTracingEnv));
@@ -78,17 +78,17 @@ test("getCombinedTracerConfig - with start-tracing.json environment file", async
if (process.platform === "win32") {
expectedEnv["CODEQL_RUNNER"] = path.join(
bundlePath,
"tools/win64/runner.exe"
"tools/win64/runner.exe",
);
} else if (process.platform === "darwin") {
expectedEnv["CODEQL_RUNNER"] = path.join(
bundlePath,
"tools/osx64/runner"
"tools/osx64/runner",
);
} else {
expectedEnv["CODEQL_RUNNER"] = path.join(
bundlePath,
"tools/linux64/runner"
"tools/linux64/runner",
);
}

View File

@@ -9,23 +9,23 @@ export type TracerConfig = {
};
export async function endTracingForCluster(
config: configUtils.Config
config: configUtils.Config,
): Promise<void> {
// If there are no traced languages, we don't need to do anything.
if (!config.languages.some((l) => isTracedLanguage(l))) return;
const envVariablesFile = path.resolve(
config.dbLocation,
"temp/tracingEnvironment/end-tracing.json"
"temp/tracingEnvironment/end-tracing.json",
);
if (!fs.existsSync(envVariablesFile)) {
throw new Error(
`Environment file for ending tracing not found: ${envVariablesFile}`
`Environment file for ending tracing not found: ${envVariablesFile}`,
);
}
try {
const endTracingEnvVariables: Map<string, string | null> = JSON.parse(
fs.readFileSync(envVariablesFile, "utf8")
fs.readFileSync(envVariablesFile, "utf8"),
);
for (const [key, value] of Object.entries(endTracingEnvVariables)) {
if (value !== null) {
@@ -36,22 +36,22 @@ export async function endTracingForCluster(
}
} catch (e) {
throw new Error(
`Failed to parse file containing end tracing environment variables: ${e}`
`Failed to parse file containing end tracing environment variables: ${e}`,
);
}
}
export async function getTracerConfigForCluster(
config: configUtils.Config
config: configUtils.Config,
): Promise<TracerConfig> {
const tracingEnvVariables = JSON.parse(
fs.readFileSync(
path.resolve(
config.dbLocation,
"temp/tracingEnvironment/start-tracing.json"
"temp/tracingEnvironment/start-tracing.json",
),
"utf8"
)
"utf8",
),
);
return {
env: tracingEnvVariables,
@@ -59,7 +59,7 @@ export async function getTracerConfigForCluster(
}
export async function getCombinedTracerConfig(
config: configUtils.Config
config: configUtils.Config,
): Promise<TracerConfig | undefined> {
// Abort if there are no traced languages as there's nothing to do
const tracedLanguages = config.languages.filter((l) => isTracedLanguage(l));
@@ -78,7 +78,7 @@ export async function getCombinedTracerConfig(
mainTracerConfig.env["CODEQL_DIST"],
"tools",
mainTracerConfig.env["CODEQL_PLATFORM"],
runnerExeName
runnerExeName,
);
return mainTracerConfig;

View File

@@ -126,7 +126,7 @@ test("check flags for JS, analyzing default branch", async (t) => {
sinon.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
const result = await getTrapCachingExtractorConfigArgsForLang(
config,
Language.javascript
Language.javascript,
);
t.deepEqual(result, [
`-O=javascript.trap.cache.dir=${path.resolve(tmpDir, "jsCache")}`,
@@ -158,7 +158,7 @@ test("get languages that support TRAP caching", async (t) => {
const languagesSupportingCaching = await getLanguagesSupportingCaching(
stubCodeql,
[Language.javascript, Language.cpp],
logger
logger,
);
t.deepEqual(languagesSupportingCaching, [Language.javascript]);
});
@@ -177,8 +177,8 @@ test("upload cache key contains right fields", async (t) => {
sinon
.match("somesha")
.and(sinon.match("2.10.3"))
.and(sinon.match("javascript"))
)
.and(sinon.match("javascript")),
),
);
});
@@ -200,12 +200,12 @@ test("download cache looks for the right key and creates dir", async (t) => {
sha: "somesha",
},
},
})
}),
);
await downloadTrapCaches(
stubCodeql,
[Language.javascript, Language.cpp],
logger
logger,
);
t.assert(
stubRestore.calledOnceWith(
@@ -215,8 +215,8 @@ test("download cache looks for the right key and creates dir", async (t) => {
sinon
.match("somesha")
.and(sinon.match("2.10.3"))
.and(sinon.match("javascript"))
)
.and(sinon.match("javascript")),
),
);
t.assert(fs.existsSync(path.resolve(tmpDir, "trapCaches", "javascript")));
});

View File

@@ -38,22 +38,22 @@ const MAX_CACHE_OPERATION_MS = 120_000; // Two minutes
export async function downloadTrapCaches(
codeql: CodeQL,
languages: Language[],
logger: Logger
logger: Logger,
): Promise<Partial<Record<Language, string>>> {
const result: Partial<Record<Language, string>> = {};
const languagesSupportingCaching = await getLanguagesSupportingCaching(
codeql,
languages,
logger
logger,
);
logger.info(
`Found ${languagesSupportingCaching.length} languages that support TRAP caching`
`Found ${languagesSupportingCaching.length} languages that support TRAP caching`,
);
if (languagesSupportingCaching.length === 0) return result;
const cachesDir = path.join(
actionsUtil.getTemporaryDirectory(),
"trapCaches"
"trapCaches",
);
for (const language of languagesSupportingCaching) {
const cacheDir = path.join(cachesDir, language);
@@ -63,7 +63,7 @@ export async function downloadTrapCaches(
if (await actionsUtil.isAnalyzingDefaultBranch()) {
logger.info(
"Analyzing default branch. Skipping downloading of TRAP caches."
"Analyzing default branch. Skipping downloading of TRAP caches.",
);
return result;
}
@@ -83,7 +83,7 @@ export async function downloadTrapCaches(
// The SHA from the base of the PR is the most similar commit we might have a cache for
const preferredKey = await cacheKey(codeql, language, baseSha);
logger.info(
`Looking in Actions cache for TRAP cache with key ${preferredKey}`
`Looking in Actions cache for TRAP cache with key ${preferredKey}`,
);
const found = await withTimeout(
MAX_CACHE_OPERATION_MS,
@@ -93,9 +93,9 @@ export async function downloadTrapCaches(
]),
() => {
logger.info(
`Timed out downloading cache for ${language}, will continue without it`
`Timed out downloading cache for ${language}, will continue without it`,
);
}
},
);
if (found === undefined) {
// We didn't find a TRAP cache in the Actions cache, so the directory on disk is
@@ -119,7 +119,7 @@ export async function downloadTrapCaches(
export async function uploadTrapCaches(
codeql: CodeQL,
config: Config,
logger: Logger
logger: Logger,
): Promise<boolean> {
if (!(await actionsUtil.isAnalyzingDefaultBranch())) return false; // Only upload caches from the default branch
@@ -129,20 +129,20 @@ export async function uploadTrapCaches(
const trapFolderSize = await tryGetFolderBytes(cacheDir, logger);
if (trapFolderSize === undefined) {
logger.info(
`Skipping upload of TRAP cache for ${language} as we couldn't determine its size`
`Skipping upload of TRAP cache for ${language} as we couldn't determine its size`,
);
continue;
}
if (trapFolderSize < MINIMUM_CACHE_MB_TO_UPLOAD * 1_048_576) {
logger.info(
`Skipping upload of TRAP cache for ${language} as it is too small`
`Skipping upload of TRAP cache for ${language} as it is too small`,
);
continue;
}
const key = await cacheKey(
codeql,
language,
process.env.GITHUB_SHA || "unknown"
process.env.GITHUB_SHA || "unknown",
);
logger.info(`Uploading TRAP cache to Actions cache with key ${key}`);
await withTimeout(
@@ -150,9 +150,9 @@ export async function uploadTrapCaches(
cache.saveCache([cacheDir], key),
() => {
logger.info(
`Timed out waiting for TRAP cache for ${language} to upload, will continue without uploading`
`Timed out waiting for TRAP cache for ${language} to upload, will continue without uploading`,
);
}
},
);
}
return true;
@@ -161,7 +161,7 @@ export async function uploadTrapCaches(
export async function getLanguagesSupportingCaching(
codeql: CodeQL,
languages: Language[],
logger: Logger
logger: Logger,
): Promise<Language[]> {
const result: Language[] = [];
if (
@@ -173,13 +173,13 @@ export async function getLanguagesSupportingCaching(
const extractorsForLanguage = resolveResult.extractors[lang];
if (extractorsForLanguage === undefined) {
logger.info(
`${lang} does not support TRAP caching (couldn't find an extractor)`
`${lang} does not support TRAP caching (couldn't find an extractor)`,
);
continue;
}
if (extractorsForLanguage.length !== 1) {
logger.info(
`${lang} does not support TRAP caching (found multiple extractors)`
`${lang} does not support TRAP caching (found multiple extractors)`,
);
continue;
}
@@ -188,14 +188,14 @@ export async function getLanguagesSupportingCaching(
extractor.extractor_options?.trap?.properties?.cache?.properties;
if (trapCacheOptions === undefined) {
logger.info(
`${lang} does not support TRAP caching (missing option group)`
`${lang} does not support TRAP caching (missing option group)`,
);
continue;
}
for (const requiredOpt of ["dir", "bound", "write"]) {
if (!(requiredOpt in trapCacheOptions)) {
logger.info(
`${lang} does not support TRAP caching (missing ${requiredOpt} option)`
`${lang} does not support TRAP caching (missing ${requiredOpt} option)`,
);
continue outer;
}
@@ -207,12 +207,12 @@ export async function getLanguagesSupportingCaching(
export async function getTotalCacheSize(
trapCaches: Partial<Record<Language, string>>,
logger: Logger
logger: Logger,
): Promise<number> {
const sizes = await Promise.all(
Object.values(trapCaches).map((cacheDir) =>
tryGetFolderBytes(cacheDir, logger)
)
tryGetFolderBytes(cacheDir, logger),
),
);
return sizes.map((a) => a || 0).reduce((a, b) => a + b, 0);
}
@@ -220,14 +220,14 @@ export async function getTotalCacheSize(
async function cacheKey(
codeql: CodeQL,
language: Language,
baseSha: string
baseSha: string,
): Promise<string> {
return `${await cachePrefix(codeql, language)}${baseSha}`;
}
async function cachePrefix(
codeql: CodeQL,
language: Language
language: Language,
): Promise<string> {
return `codeql-trap-${CACHE_VERSION}-${await codeql.getVersion()}-${language}-`;
}

View File

@@ -18,14 +18,14 @@ test.beforeEach(() => {
test("validateSarifFileSchema - valid", (t) => {
const inputFile = `${__dirname}/../src/testdata/valid-sarif.sarif`;
t.notThrows(() =>
uploadLib.validateSarifFileSchema(inputFile, getRunnerLogger(true))
uploadLib.validateSarifFileSchema(inputFile, getRunnerLogger(true)),
);
});
test("validateSarifFileSchema - invalid", (t) => {
const inputFile = `${__dirname}/../src/testdata/invalid-sarif.sarif`;
t.throws(() =>
uploadLib.validateSarifFileSchema(inputFile, getRunnerLogger(true))
uploadLib.validateSarifFileSchema(inputFile, getRunnerLogger(true)),
);
});
@@ -42,7 +42,7 @@ test("validate correct payload used for push, PR merge commit, and PR head", asy
"/opt/src",
undefined,
["CodeQL", "eslint"],
"mergeBaseCommit"
"mergeBaseCommit",
);
// Not triggered by a pull request
t.falsy(pushPayload.base_ref);
@@ -65,7 +65,7 @@ test("validate correct payload used for push, PR merge commit, and PR head", asy
"/opt/src",
undefined,
["CodeQL", "eslint"],
"mergeBaseCommit"
"mergeBaseCommit",
);
// Uploads for a merge commit use the merge base
t.deepEqual(prMergePayload.base_ref, "refs/heads/master");
@@ -82,13 +82,13 @@ test("validate correct payload used for push, PR merge commit, and PR head", asy
"/opt/src",
undefined,
["CodeQL", "eslint"],
"mergeBaseCommit"
"mergeBaseCommit",
);
// Uploads for the head use the PR base
t.deepEqual(prHeadPayload.base_ref, "refs/heads/master");
t.deepEqual(
prHeadPayload.base_sha,
"f95f852bd8fca8fcc58a9a2d6c842781e32a215e"
"f95f852bd8fca8fcc58a9a2d6c842781e32a215e",
);
});
@@ -113,7 +113,7 @@ test("finding SARIF files", async (t) => {
fs.symlinkSync(
path.join(tmpDir, "a.sarif"),
path.join(tmpDir, "dir3", "symlink2.sarif"),
"file"
"file",
);
const sarifFiles = uploadLib.findSarifFilesInDir(tmpDir);
@@ -142,7 +142,7 @@ test("populateRunAutomationDetails", (t) => {
sarif,
"language:javascript/os:linux",
analysisKey,
'{"language": "other", "os": "other"}'
'{"language": "other", "os": "other"}',
);
t.deepEqual(modifiedSarif, expectedSarif);
@@ -151,7 +151,7 @@ test("populateRunAutomationDetails", (t) => {
sarif,
"language:javascript/os:linux/",
analysisKey,
""
"",
);
t.deepEqual(modifiedSarif, expectedSarif);
@@ -162,7 +162,7 @@ test("populateRunAutomationDetails", (t) => {
sarif,
undefined,
analysisKey,
'{"os": "linux", "language": "javascript"}'
'{"os": "linux", "language": "javascript"}',
);
t.deepEqual(modifiedSarif, expectedSarif);
@@ -182,7 +182,7 @@ test("populateRunAutomationDetails", (t) => {
sarif,
undefined,
analysisKey,
'{"os": "linux", "language": "javascript"}'
'{"os": "linux", "language": "javascript"}',
);
t.deepEqual(modifiedSarif, expectedSarif);
});
@@ -203,7 +203,7 @@ test("validateUniqueCategory for automation details id", (t) => {
// Our category sanitization is not perfect. Here are some examples
// of where we see false clashes
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif("abc/def"))
uploadLib.validateUniqueCategory(createMockSarif("abc/def")),
);
t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc@def")));
t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc_def")));
@@ -211,69 +211,69 @@ test("validateUniqueCategory for automation details id", (t) => {
// this one is fine
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif("abc_ def"))
uploadLib.validateUniqueCategory(createMockSarif("abc_ def")),
);
});
test("validateUniqueCategory for tool name", (t) => {
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc"))
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc")),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc"))
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc")),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "AbC"))
uploadLib.validateUniqueCategory(createMockSarif(undefined, "AbC")),
);
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "def"))
uploadLib.validateUniqueCategory(createMockSarif(undefined, "def")),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "def"))
uploadLib.validateUniqueCategory(createMockSarif(undefined, "def")),
);
// Our category sanitization is not perfect. Here are some examples
// of where we see false clashes
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc/def"))
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc/def")),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc@def"))
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc@def")),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc_def"))
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc_def")),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc def"))
uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc def")),
);
// this one is fine
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif("abc_ def"))
uploadLib.validateUniqueCategory(createMockSarif("abc_ def")),
);
});
test("validateUniqueCategory for automation details id and tool name", (t) => {
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif("abc", "abc"))
uploadLib.validateUniqueCategory(createMockSarif("abc", "abc")),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif("abc", "abc"))
uploadLib.validateUniqueCategory(createMockSarif("abc", "abc")),
);
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif("abc_", "def"))
uploadLib.validateUniqueCategory(createMockSarif("abc_", "def")),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif("abc_", "def"))
uploadLib.validateUniqueCategory(createMockSarif("abc_", "def")),
);
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif("ghi", "_jkl"))
uploadLib.validateUniqueCategory(createMockSarif("ghi", "_jkl")),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif("ghi", "_jkl"))
uploadLib.validateUniqueCategory(createMockSarif("ghi", "_jkl")),
);
// Our category sanitization is not perfect. Here are some examples
@@ -282,15 +282,15 @@ test("validateUniqueCategory for automation details id and tool name", (t) => {
t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc", "_")));
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif("abc", "def__"))
uploadLib.validateUniqueCategory(createMockSarif("abc", "def__")),
);
t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc_def")));
t.notThrows(() =>
uploadLib.validateUniqueCategory(createMockSarif("mno_", "pqr"))
uploadLib.validateUniqueCategory(createMockSarif("mno_", "pqr")),
);
t.throws(() =>
uploadLib.validateUniqueCategory(createMockSarif("mno", "_pqr"))
uploadLib.validateUniqueCategory(createMockSarif("mno", "_pqr")),
);
});
@@ -374,7 +374,7 @@ test("accept results with invalid artifactLocation.uri value", (t) => {
t.deepEqual(loggedMessages.length, 1);
t.deepEqual(
loggedMessages[0],
"Warning: 'not a valid URI' is not a valid URI in 'instance.runs[0].results[0].locations[0].physicalLocation.artifactLocation.uri'."
"Warning: 'not a valid URI' is not a valid URI in 'instance.runs[0].results[0].locations[0].physicalLocation.artifactLocation.uri'.",
);
});
const affectedCodeQLVersion = {

View File

@@ -27,14 +27,14 @@ function combineSarifFiles(sarifFiles: string[]): SarifFile {
for (const sarifFile of sarifFiles) {
const sarifObject = JSON.parse(
fs.readFileSync(sarifFile, "utf8")
fs.readFileSync(sarifFile, "utf8"),
) as SarifFile;
// Check SARIF version
if (combinedSarif.version === null) {
combinedSarif.version = sarifObject.version;
} else if (combinedSarif.version !== sarifObject.version) {
throw new Error(
`Different SARIF versions encountered: ${combinedSarif.version} and ${sarifObject.version}`
`Different SARIF versions encountered: ${combinedSarif.version} and ${sarifObject.version}`,
);
}
@@ -50,7 +50,7 @@ export function populateRunAutomationDetails(
sarif: SarifFile,
category: string | undefined,
analysis_key: string,
environment: string | undefined
environment: string | undefined,
): SarifFile {
const automationID = getAutomationID(category, analysis_key, environment);
@@ -70,7 +70,7 @@ export function populateRunAutomationDetails(
function getAutomationID(
category: string | undefined,
analysis_key: string,
environment: string | undefined
environment: string | undefined,
): string | undefined {
if (category !== undefined) {
let automationID = category;
@@ -88,7 +88,7 @@ function getAutomationID(
async function uploadPayload(
payload: any,
repositoryNwo: RepositoryNwo,
logger: Logger
logger: Logger,
) {
logger.info("Uploading results");
@@ -96,10 +96,10 @@ async function uploadPayload(
if (util.isInTestMode()) {
const payloadSaveFile = path.join(
actionsUtil.getTemporaryDirectory(),
"payload.json"
"payload.json",
);
logger.info(
`In test mode. Results are not uploaded. Saving to ${payloadSaveFile}`
`In test mode. Results are not uploaded. Saving to ${payloadSaveFile}`,
);
logger.info(`Payload: ${JSON.stringify(payload, null, 2)}`);
fs.writeFileSync(payloadSaveFile, JSON.stringify(payload, null, 2));
@@ -114,7 +114,7 @@ async function uploadPayload(
owner: repositoryNwo.owner,
repo: repositoryNwo.repo,
data: payload,
}
},
);
logger.debug(`response status: ${response.status}`);
@@ -161,7 +161,7 @@ export async function uploadFromActions(
sarifPath: string,
checkoutPath: string,
category: string | undefined,
logger: Logger
logger: Logger,
): Promise<UploadResult> {
return await uploadFiles(
getSarifFilePaths(sarifPath),
@@ -175,7 +175,7 @@ export async function uploadFromActions(
actionsUtil.getWorkflowRunAttempt(),
checkoutPath,
actionsUtil.getRequiredInput("matrix"),
logger
logger,
);
}
@@ -204,7 +204,7 @@ function countResultsInSarif(sarif: string): number {
parsedSarif = JSON.parse(sarif);
} catch (e) {
throw new Error(
`Invalid SARIF. JSON syntax error: ${wrapError(e).message}`
`Invalid SARIF. JSON syntax error: ${wrapError(e).message}`,
);
}
if (!Array.isArray(parsedSarif.runs)) {
@@ -230,15 +230,15 @@ export function validateSarifFileSchema(sarifFilePath: string, logger: Logger) {
// Filter errors related to invalid URIs in the artifactLocation field as this
// is a breaking change. See https://github.com/github/codeql-action/issues/1703
const errors = (result.errors || []).filter(
(err) => err.argument !== "uri-reference"
(err) => err.argument !== "uri-reference",
);
const warnings = (result.errors || []).filter(
(err) => err.argument === "uri-reference"
(err) => err.argument === "uri-reference",
);
for (const warning of warnings) {
logger.info(
`Warning: '${warning.instance}' is not a valid URI in '${warning.property}'.`
`Warning: '${warning.instance}' is not a valid URI in '${warning.property}'.`,
);
}
@@ -255,8 +255,8 @@ export function validateSarifFileSchema(sarifFilePath: string, logger: Logger) {
const sarifErrors = errors.map((e) => `- ${e.stack}`);
throw new Error(
`Unable to upload "${sarifFilePath}" as it is not valid SARIF:\n${sarifErrors.join(
"\n"
)}`
"\n",
)}`,
);
}
}
@@ -274,7 +274,7 @@ export function buildPayload(
checkoutURI: string,
environment: string | undefined,
toolNames: string[],
mergeBaseCommitOid: string | undefined
mergeBaseCommitOid: string | undefined,
) {
const payloadObj = {
commit_oid: commitOid,
@@ -301,7 +301,7 @@ export function buildPayload(
// and were able to determine the merge base.
// So we use that as the most accurate base.
payloadObj.base_ref = `refs/heads/${util.getRequiredEnvParam(
"GITHUB_BASE_REF"
"GITHUB_BASE_REF",
)}`;
payloadObj.base_sha = mergeBaseCommitOid;
} else if (process.env.GITHUB_EVENT_PATH) {
@@ -309,7 +309,7 @@ export function buildPayload(
// or we could not determine the merge base.
// Using the PR base is the only option here
const githubEvent = JSON.parse(
fs.readFileSync(process.env.GITHUB_EVENT_PATH, "utf8")
fs.readFileSync(process.env.GITHUB_EVENT_PATH, "utf8"),
);
payloadObj.base_ref = `refs/heads/${githubEvent.pull_request.base.ref}`;
payloadObj.base_sha = githubEvent.pull_request.base.sha;
@@ -332,7 +332,7 @@ async function uploadFiles(
workflowRunAttempt: number,
sourceRoot: string,
environment: string | undefined,
logger: Logger
logger: Logger,
): Promise<UploadResult> {
logger.startGroup("Uploading results");
logger.info(`Processing sarif files: ${JSON.stringify(sarifFiles)}`);
@@ -349,7 +349,7 @@ async function uploadFiles(
sarif,
category,
analysisKey,
environment
environment,
);
if (env["CODEQL_DISABLE_SARIF_PRUNING"] !== "true")
@@ -373,7 +373,7 @@ async function uploadFiles(
checkoutURI,
environment,
toolNames,
await actionsUtil.determineMergeBaseCommitOid()
await actionsUtil.determineMergeBaseCommitOid(),
);
// Log some useful debug info about the info
@@ -418,7 +418,7 @@ export async function waitForProcessing(
logger: Logger,
options: { isUnsuccessfulExecution: boolean } = {
isUnsuccessfulExecution: false,
}
},
): Promise<void> {
logger.startGroup("Waiting for processing to finish");
try {
@@ -435,7 +435,7 @@ export async function waitForProcessing(
// It's possible the analysis will eventually finish processing, but it's not worth spending more
// Actions time waiting.
logger.warning(
"Timed out waiting for analysis to finish processing. Continuing."
"Timed out waiting for analysis to finish processing. Continuing.",
);
break;
}
@@ -447,11 +447,11 @@ export async function waitForProcessing(
owner: repositoryNwo.owner,
repo: repositoryNwo.repo,
sarif_id: sarifID,
}
},
);
} catch (e) {
logger.warning(
`An error occurred checking the status of the delivery. ${e} It should still be processed in the background, but errors that occur during processing may not be reported.`
`An error occurred checking the status of the delivery. ${e} It should still be processed in the background, but errors that occur during processing may not be reported.`,
);
break;
}
@@ -466,14 +466,14 @@ export async function waitForProcessing(
handleProcessingResultForUnsuccessfulExecution(
response,
status,
logger
logger,
);
break;
} else if (status === "complete") {
break;
} else if (status === "failed") {
throw new Error(
`Code Scanning could not process the submitted SARIF file:\n${response.data.errors}`
`Code Scanning could not process the submitted SARIF file:\n${response.data.errors}`,
);
} else {
util.assertNever(status);
@@ -495,7 +495,7 @@ export async function waitForProcessing(
function handleProcessingResultForUnsuccessfulExecution(
response: OctokitResponse<any, number>,
status: Exclude<ProcessingStatus, "pending">,
logger: Logger
logger: Logger,
): void {
if (
status === "failed" &&
@@ -505,12 +505,12 @@ function handleProcessingResultForUnsuccessfulExecution(
) {
logger.debug(
"Successfully uploaded a SARIF file for the unsuccessful execution. Received expected " +
'"unsuccessful execution" processing error, and no other errors.'
'"unsuccessful execution" processing error, and no other errors.',
);
} else if (status === "failed") {
logger.warning(
`Failed to upload a SARIF file for the unsuccessful execution. Code scanning status ` +
`information for the repository may be out of date as a result. Processing errors: ${response.data.errors}`
`information for the repository may be out of date as a result. Processing errors: ${response.data.errors}`,
);
} else if (status === "complete") {
// There is a known transient issue with the code scanning API where it sometimes reports
@@ -518,7 +518,7 @@ function handleProcessingResultForUnsuccessfulExecution(
logger.debug(
"Uploaded a SARIF file for the unsuccessful execution, but did not receive the expected " +
'"unsuccessful execution" processing error. This is a known transient issue with the ' +
"code scanning API, and does not cause out of date code scanning status information."
"code scanning API, and does not cause out of date code scanning status information.",
);
} else {
util.assertNever(status);
@@ -544,7 +544,7 @@ export function validateUniqueCategory(sarif: SarifFile): void {
"Aborting upload: only one run of the codeql/analyze or codeql/upload-sarif actions is allowed per job per tool/category. " +
"The easiest fix is to specify a unique value for the `category` input. If .runs[].automationDetails.id is specified " +
"in the sarif file, that will take precedence over your configured `category`. " +
`Category: (${id ? id : "none"}) Tool: (${tool ? tool : "none"})`
`Category: (${id ? id : "none"}) Tool: (${tool ? tool : "none"})`,
);
}
core.exportVariable(sentinelEnvVar, sentinelEnvVar);
@@ -566,7 +566,7 @@ function sanitize(str?: string) {
export function pruneInvalidResults(
sarif: SarifFile,
logger: Logger
logger: Logger,
): SarifFile {
let pruned = 0;
const newRuns: SarifRun[] = [];
@@ -597,7 +597,7 @@ export function pruneInvalidResults(
}
if (pruned > 0) {
logger.info(
`Pruned ${pruned} results believed to be invalid from SARIF file.`
`Pruned ${pruned} results believed to be invalid from SARIF file.`,
);
}
return { ...sarif, runs: newRuns };

View File

@@ -19,12 +19,12 @@ interface UploadSarifStatusReport
async function sendSuccessStatusReport(
startedAt: Date,
uploadStats: upload_lib.UploadStatusReport
uploadStats: upload_lib.UploadStatusReport,
) {
const statusReportBase = await createStatusReportBase(
"upload-sarif",
"success",
startedAt
startedAt,
);
const statusReport: UploadSarifStatusReport = {
...statusReportBase,
@@ -38,7 +38,7 @@ async function run() {
initializeEnvironment(getActionVersion());
if (
!(await sendStatusReport(
await createStatusReportBase("upload-sarif", "starting", startedAt)
await createStatusReportBase("upload-sarif", "starting", startedAt),
))
) {
return;
@@ -49,7 +49,7 @@ async function run() {
actionsUtil.getRequiredInput("sarif_file"),
actionsUtil.getRequiredInput("checkout_path"),
actionsUtil.getOptionalInput("category"),
getActionsLogger()
getActionsLogger(),
);
core.setOutput("sarif-id", uploadResult.sarifID);
@@ -60,7 +60,7 @@ async function run() {
await upload_lib.waitForProcessing(
parseRepositoryNwo(getRequiredEnvParam("GITHUB_REPOSITORY")),
uploadResult.sarifID,
getActionsLogger()
getActionsLogger(),
);
}
await sendSuccessStatusReport(startedAt, uploadResult.statusReport);
@@ -75,8 +75,8 @@ async function run() {
actionsUtil.getActionsStatus(error),
startedAt,
message,
error.stack
)
error.stack,
),
);
return;
}
@@ -87,7 +87,7 @@ async function runWrapper() {
await run();
} catch (error) {
core.setFailed(
`codeql/upload-sarif action failed: ${wrapError(error).message}`
`codeql/upload-sarif action failed: ${wrapError(error).message}`,
);
}
}

View File

@@ -13,7 +13,7 @@ setupTests(test);
test("getToolNames", (t) => {
const input = fs.readFileSync(
`${__dirname}/../src/testdata/tool-names.sarif`,
"utf8"
"utf8",
);
const toolNames = util.getToolNames(JSON.parse(input) as util.SarifFile);
t.deepEqual(toolNames, ["CodeQL command-line toolchain", "ESLint"]);
@@ -82,14 +82,14 @@ for (const {
input,
totalMemoryMb * 1024 * 1024,
platform,
withScaling
withScaling,
);
t.deepEqual(
flag,
withScaling ? expectedMemoryValueWithScaling : expectedMemoryValue
withScaling ? expectedMemoryValueWithScaling : expectedMemoryValue,
);
}
}
},
);
}
@@ -168,48 +168,48 @@ test("parseGitHubUrl", (t) => {
t.deepEqual(util.parseGitHubUrl("https://github.com"), "https://github.com");
t.deepEqual(
util.parseGitHubUrl("https://api.github.com"),
"https://github.com"
"https://github.com",
);
t.deepEqual(
util.parseGitHubUrl("https://github.com/foo/bar"),
"https://github.com"
"https://github.com",
);
t.deepEqual(
util.parseGitHubUrl("github.example.com"),
"https://github.example.com/"
"https://github.example.com/",
);
t.deepEqual(
util.parseGitHubUrl("https://github.example.com"),
"https://github.example.com/"
"https://github.example.com/",
);
t.deepEqual(
util.parseGitHubUrl("https://api.github.example.com"),
"https://github.example.com/"
"https://github.example.com/",
);
t.deepEqual(
util.parseGitHubUrl("https://github.example.com/api/v3"),
"https://github.example.com/"
"https://github.example.com/",
);
t.deepEqual(
util.parseGitHubUrl("https://github.example.com:1234"),
"https://github.example.com:1234/"
"https://github.example.com:1234/",
);
t.deepEqual(
util.parseGitHubUrl("https://api.github.example.com:1234"),
"https://github.example.com:1234/"
"https://github.example.com:1234/",
);
t.deepEqual(
util.parseGitHubUrl("https://github.example.com:1234/api/v3"),
"https://github.example.com:1234/"
"https://github.example.com:1234/",
);
t.deepEqual(
util.parseGitHubUrl("https://github.example.com/base/path"),
"https://github.example.com/base/path/"
"https://github.example.com/base/path/",
);
t.deepEqual(
util.parseGitHubUrl("https://github.example.com/base/path/api/v3"),
"https://github.example.com/base/path/"
"https://github.example.com/base/path/",
);
t.throws(() => util.parseGitHubUrl(""), {
@@ -231,11 +231,11 @@ test("allowed API versions", async (t) => {
t.is(util.apiVersionInRange("2.0.1", "1.33", "2.0"), undefined);
t.is(
util.apiVersionInRange("1.32.0", "1.33", "2.0"),
util.DisallowedAPIVersionReason.ACTION_TOO_NEW
util.DisallowedAPIVersionReason.ACTION_TOO_NEW,
);
t.is(
util.apiVersionInRange("2.1.0", "1.33", "2.0"),
util.DisallowedAPIVersionReason.ACTION_TOO_OLD
util.DisallowedAPIVersionReason.ACTION_TOO_OLD,
);
});
@@ -328,7 +328,7 @@ test("withTimeout doesn't call callback if promise resolves", async (t) => {
});
function createMockSarifWithNotification(
locations: util.SarifLocation[]
locations: util.SarifLocation[],
): util.SarifFile {
return {
runs: [
@@ -364,7 +364,7 @@ test("fixInvalidNotifications leaves notifications with unique locations alone",
const messages: LoggedMessage[] = [];
const result = util.fixInvalidNotifications(
createMockSarifWithNotification([stubLocation]),
getRecordingLogger(messages)
getRecordingLogger(messages),
);
t.deepEqual(result, createMockSarifWithNotification([stubLocation]));
t.is(messages.length, 1);
@@ -378,7 +378,7 @@ test("fixInvalidNotifications removes duplicate locations", (t) => {
const messages: LoggedMessage[] = [];
const result = util.fixInvalidNotifications(
createMockSarifWithNotification([stubLocation, stubLocation]),
getRecordingLogger(messages)
getRecordingLogger(messages),
);
t.deepEqual(result, createMockSarifWithNotification([stubLocation]));
t.is(messages.length, 1);

View File

@@ -109,7 +109,7 @@ export function getExtraOptionsEnvParam(): object {
} catch (unwrappedError) {
const error = wrapError(unwrappedError);
throw new Error(
`${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}`,
);
}
}
@@ -136,7 +136,7 @@ export function getToolNames(sarif: SarifFile): string[] {
// Creates a random temporary directory, runs the given body, and then deletes the directory.
// Mostly intended for use within tests.
export async function withTmpDir<T>(
body: (tmpDir: string) => Promise<T>
body: (tmpDir: string) => Promise<T>,
): Promise<T> {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "codeql-action-"));
const result = await body(tmpDir);
@@ -154,7 +154,7 @@ export async function withTmpDir<T>(
function getSystemReservedMemoryMegaBytes(
totalMemoryMegaBytes: number,
platform: string,
isScalingReservedRamEnabled: boolean
isScalingReservedRamEnabled: boolean,
): number {
// Windows needs more memory for OS processes.
const fixedAmount = 1024 * (platform === "win32" ? 1.5 : 1);
@@ -180,7 +180,7 @@ export function getMemoryFlagValueForPlatform(
userInput: string | undefined,
totalMemoryBytes: number,
platform: string,
isScalingReservedRamEnabled: boolean
isScalingReservedRamEnabled: boolean,
): number {
let memoryToUseMegaBytes: number;
if (userInput) {
@@ -193,7 +193,7 @@ export function getMemoryFlagValueForPlatform(
const reservedMemoryMegaBytes = getSystemReservedMemoryMegaBytes(
totalMemoryMegaBytes,
platform,
isScalingReservedRamEnabled
isScalingReservedRamEnabled,
);
memoryToUseMegaBytes = totalMemoryMegaBytes - reservedMemoryMegaBytes;
}
@@ -209,13 +209,13 @@ export function getMemoryFlagValueForPlatform(
*/
export function getMemoryFlagValue(
userInput: string | undefined,
isScalingReservedRamEnabled: boolean
isScalingReservedRamEnabled: boolean,
): number {
return getMemoryFlagValueForPlatform(
userInput,
os.totalmem(),
process.platform,
isScalingReservedRamEnabled
isScalingReservedRamEnabled,
);
}
@@ -228,7 +228,7 @@ export function getMemoryFlagValue(
*/
export function getMemoryFlag(
userInput: string | undefined,
isScalingReservedRamEnabled: boolean
isScalingReservedRamEnabled: boolean,
): string {
const megabytes = getMemoryFlagValue(userInput, isScalingReservedRamEnabled);
return `--ram=${megabytes}`;
@@ -240,7 +240,7 @@ export function getMemoryFlag(
* @returns string
*/
export function getAddSnippetsFlag(
userInput: string | boolean | undefined
userInput: string | boolean | undefined,
): string {
if (typeof userInput === "string") {
// have to process specifically because any non-empty string is truthy
@@ -259,7 +259,7 @@ export function getAddSnippetsFlag(
*/
export function getThreadsFlagValue(
userInput: string | undefined,
logger: Logger
logger: Logger,
): number {
let numThreads: number;
const maxThreads = os.cpus().length;
@@ -270,14 +270,14 @@ export function getThreadsFlagValue(
}
if (numThreads > maxThreads) {
logger.info(
`Clamping desired number of threads (${numThreads}) to max available (${maxThreads}).`
`Clamping desired number of threads (${numThreads}) to max available (${maxThreads}).`,
);
numThreads = maxThreads;
}
const minThreads = -maxThreads;
if (numThreads < minThreads) {
logger.info(
`Clamping desired number of free threads (${numThreads}) to max available (${minThreads}).`
`Clamping desired number of free threads (${numThreads}) to max available (${minThreads}).`,
);
numThreads = minThreads;
}
@@ -298,7 +298,7 @@ export function getThreadsFlagValue(
*/
export function getThreadsFlag(
userInput: string | undefined,
logger: Logger
logger: Logger,
): string {
return `--threads=${getThreadsFlagValue(userInput, logger)}`;
}
@@ -372,7 +372,7 @@ export type GitHubVersion =
export function checkGitHubVersionInRange(
version: GitHubVersion,
logger: Logger
logger: Logger,
) {
if (hasBeenWarnedAboutVersion || version.type !== GitHubVariant.GHES) {
return;
@@ -381,21 +381,21 @@ export function checkGitHubVersionInRange(
const disallowedAPIVersionReason = apiVersionInRange(
version.version,
apiCompatibility.minimumVersion,
apiCompatibility.maximumVersion
apiCompatibility.maximumVersion,
);
if (
disallowedAPIVersionReason === DisallowedAPIVersionReason.ACTION_TOO_OLD
) {
logger.warning(
`The CodeQL Action version you are using is too old to be compatible with GitHub Enterprise ${version.version}. If you experience issues, please upgrade to a more recent version of the CodeQL Action.`
`The CodeQL Action version you are using is too old to be compatible with GitHub Enterprise ${version.version}. If you experience issues, please upgrade to a more recent version of the CodeQL Action.`,
);
}
if (
disallowedAPIVersionReason === DisallowedAPIVersionReason.ACTION_TOO_NEW
) {
logger.warning(
`GitHub Enterprise ${version.version} is too old to be compatible with this version of the CodeQL Action. If you experience issues, please upgrade to a more recent version of GitHub Enterprise or use an older version of the CodeQL Action.`
`GitHub Enterprise ${version.version} is too old to be compatible with this version of the CodeQL Action. If you experience issues, please upgrade to a more recent version of GitHub Enterprise or use an older version of the CodeQL Action.`,
);
}
hasBeenWarnedAboutVersion = true;
@@ -410,7 +410,7 @@ export enum DisallowedAPIVersionReason {
export function apiVersionInRange(
version: string,
minimumVersion: string,
maximumVersion: string
maximumVersion: string,
): DisallowedAPIVersionReason | undefined {
if (!semver.satisfies(version, `>=${minimumVersion}`)) {
return DisallowedAPIVersionReason.ACTION_TOO_NEW;
@@ -499,7 +499,7 @@ export function getCachedCodeQlVersion(): undefined | string {
export async function codeQlVersionAbove(
codeql: CodeQL,
requiredVersion: string
requiredVersion: string,
): Promise<boolean> {
return semver.gte(await codeql.getVersion(), requiredVersion);
}
@@ -509,7 +509,7 @@ export async function bundleDb(
config: Config,
language: Language,
codeql: CodeQL,
dbName: string
dbName: string,
) {
const databasePath = getCodeQLDatabasePath(config, language);
const databaseBundlePath = path.resolve(config.dbLocation, `${dbName}.zip`);
@@ -532,7 +532,7 @@ export async function bundleDb(
*/
export async function delay(
milliseconds: number,
{ allowProcessExit }: { allowProcessExit: boolean }
{ allowProcessExit }: { allowProcessExit: boolean },
) {
return new Promise((resolve) => {
const timer = setTimeout(resolve, milliseconds);
@@ -552,7 +552,7 @@ export function isGoodVersion(versionSpec: string) {
* Checks whether the CodeQL CLI supports the `--expect-discarded-cache` command-line flag.
*/
export async function supportExpectDiscardedCache(
codeQL: CodeQL
codeQL: CodeQL,
): Promise<boolean> {
return codeQlVersionAbove(codeQL, "2.12.1");
}
@@ -607,7 +607,7 @@ export function listFolder(dir: string): string[] {
*/
export async function tryGetFolderBytes(
cacheDir: string,
logger: Logger
logger: Logger,
): Promise<number | undefined> {
try {
return await promisify<string, number>(getFolderSize)(cacheDir);
@@ -642,7 +642,7 @@ let hadTimeout = false;
export async function withTimeout<T>(
timeoutMs: number,
promise: Promise<T>,
onTimeout: () => void
onTimeout: () => void,
): Promise<T | undefined> {
let finished = false;
const mainTask = async () => {
@@ -674,7 +674,7 @@ export async function withTimeout<T>(
export async function checkForTimeout() {
if (hadTimeout === true) {
core.info(
"A timeout occurred, force exiting the process after 30 seconds to prevent hanging."
"A timeout occurred, force exiting the process after 30 seconds to prevent hanging.",
);
await delay(30_000, { allowProcessExit: true });
process.exit();
@@ -703,7 +703,7 @@ export function isHostedRunner() {
}
export function parseMatrixInput(
matrixInput: string | undefined
matrixInput: string | undefined,
): { [key: string]: string } | undefined {
if (matrixInput === undefined || matrixInput === "null") {
return undefined;
@@ -725,7 +725,7 @@ function removeDuplicateLocations(locations: SarifLocation[]): SarifLocation[] {
export function fixInvalidNotifications(
sarif: SarifFile,
logger: Logger
logger: Logger,
): SarifFile {
if (!Array.isArray(sarif.runs)) {
return sarif;
@@ -759,7 +759,7 @@ export function fixInvalidNotifications(
return notification;
}
const newLocations = removeDuplicateLocations(
notification.locations
notification.locations,
);
numDuplicateLocationsRemoved +=
notification.locations.length - newLocations.length;
@@ -777,7 +777,7 @@ export function fixInvalidNotifications(
if (numDuplicateLocationsRemoved > 0) {
logger.info(
`Removed ${numDuplicateLocationsRemoved} duplicate locations from SARIF notification ` +
"objects."
"objects.",
);
} else {
logger.debug("No duplicate locations found in SARIF notification objects.");
@@ -798,12 +798,12 @@ export function fixInvalidNotifications(
export function fixInvalidNotificationsInFile(
inputPath: string,
outputPath: string,
logger: Logger
logger: Logger,
): void {
if (process.env[EnvVar.DISABLE_DUPLICATE_LOCATION_FIX] === "true") {
logger.info(
"SARIF notification object duplicate location fix disabled by the " +
`${EnvVar.DISABLE_DUPLICATE_LOCATION_FIX} environment variable.`
`${EnvVar.DISABLE_DUPLICATE_LOCATION_FIX} environment variable.`,
);
fs.renameSync(inputPath, outputPath);
} else {
@@ -825,7 +825,7 @@ export const ML_POWERED_JS_QUERIES_PACK_NAME =
* queries beta.
*/
export async function getMlPoweredJsQueriesPack(
codeQL: CodeQL
codeQL: CodeQL,
): Promise<string> {
let version;
if (await codeQlVersionAbove(codeQL, "2.11.3")) {

View File

@@ -15,7 +15,7 @@ import {
function errorCodes(
actual: CodedError[],
expected: CodedError[]
expected: CodedError[],
): [string[], string[]] {
return [actual.map(({ code }) => code), expected.map(({ code }) => code)];
}
@@ -78,7 +78,7 @@ test("getWorkflowErrors() when on.push is correct with empty objects", (t) => {
on:
push:
pull_request:
`) as Workflow
`) as Workflow,
);
t.deepEqual(...errorCodes(errors, []));
@@ -104,8 +104,8 @@ test("getWorkflowErrors() for a range of malformed workflows", (t) => {
pull_request: 1,
},
} as Workflow),
[]
)
[],
),
);
t.deepEqual(
@@ -113,8 +113,8 @@ test("getWorkflowErrors() for a range of malformed workflows", (t) => {
getWorkflowErrors({
on: 1,
} as Workflow),
[]
)
[],
),
);
t.deepEqual(
@@ -124,8 +124,8 @@ test("getWorkflowErrors() for a range of malformed workflows", (t) => {
on: 1,
jobs: 1,
} as any),
[]
)
[],
),
);
t.deepEqual(
@@ -135,8 +135,8 @@ test("getWorkflowErrors() for a range of malformed workflows", (t) => {
on: 1,
jobs: [1],
} as any),
[]
)
[],
),
);
t.deepEqual(
@@ -145,8 +145,8 @@ test("getWorkflowErrors() for a range of malformed workflows", (t) => {
on: 1,
jobs: { 1: 1 },
} as Workflow),
[]
)
[],
),
);
t.deepEqual(
@@ -155,8 +155,8 @@ test("getWorkflowErrors() for a range of malformed workflows", (t) => {
on: 1,
jobs: { test: 1 },
} as Workflow),
[]
)
[],
),
);
t.deepEqual(
@@ -165,8 +165,8 @@ test("getWorkflowErrors() for a range of malformed workflows", (t) => {
on: 1,
jobs: { test: [1] },
} as Workflow),
[]
)
[],
),
);
t.deepEqual(
@@ -176,8 +176,8 @@ test("getWorkflowErrors() for a range of malformed workflows", (t) => {
on: 1,
jobs: { test: { steps: 1 } },
} as any),
[]
)
[],
),
);
t.deepEqual(
@@ -187,8 +187,8 @@ test("getWorkflowErrors() for a range of malformed workflows", (t) => {
on: 1,
jobs: { test: { steps: [{ notrun: "git checkout HEAD^2" }] } },
} as any),
[]
)
[],
),
);
t.deepEqual(
@@ -197,8 +197,8 @@ test("getWorkflowErrors() for a range of malformed workflows", (t) => {
on: 1,
jobs: { test: [undefined] },
} as Workflow),
[]
)
[],
),
);
t.deepEqual(...errorCodes(getWorkflowErrors(1 as Workflow), []));
@@ -216,8 +216,8 @@ test("getWorkflowErrors() for a range of malformed workflows", (t) => {
},
},
} as any),
[]
)
[],
),
);
});
@@ -293,7 +293,7 @@ test("patternIsSuperset()", (t) => {
t.false(patternIsSuperset("a/main-**/c", "a/**/c"));
t.true(patternIsSuperset("/robin/*/release/*", "/robin/moose/release/goose"));
t.false(
patternIsSuperset("/robin/moose/release/goose", "/robin/*/release/*")
patternIsSuperset("/robin/moose/release/goose", "/robin/*/release/*"),
);
});
@@ -306,7 +306,7 @@ test("getWorkflowErrors() when branches contain dots", (t) => {
pull_request:
# The branches below must be a subset of the branches above
branches: [4.1, master]
`) as Workflow
`) as Workflow,
);
t.deepEqual(...errorCodes(errors, []));
@@ -322,7 +322,7 @@ test("getWorkflowErrors() when on.push has a trailing comma", (t) => {
pull_request:
# The branches below must be a subset of the branches above
branches: [master]
`) as Workflow
`) as Workflow,
);
t.deepEqual(...errorCodes(errors, []));
@@ -351,7 +351,7 @@ test("getWorkflowErrors() should only report the current job's CheckoutWrongHead
test3:
steps: []
`) as Workflow
`) as Workflow,
);
t.deepEqual(...errorCodes(errors, [WorkflowErrors.CheckoutWrongHead]));
@@ -380,7 +380,7 @@ test("getWorkflowErrors() should not report a different job's CheckoutWrongHead"
test3:
steps: []
`) as Workflow
`) as Workflow,
);
t.deepEqual(...errorCodes(errors, []));
@@ -390,7 +390,7 @@ test("getWorkflowErrors() when on is missing", (t) => {
const errors = getWorkflowErrors(
yaml.load(`
name: "CodeQL"
`) as Workflow
`) as Workflow,
);
t.deepEqual(...errorCodes(errors, []));
@@ -403,10 +403,10 @@ test("getWorkflowErrors() with a different on setup", (t) => {
yaml.load(`
name: "CodeQL"
on: "workflow_dispatch"
`) as Workflow
`) as Workflow,
),
[]
)
[],
),
);
t.deepEqual(
@@ -415,10 +415,10 @@ test("getWorkflowErrors() with a different on setup", (t) => {
yaml.load(`
name: "CodeQL"
on: [workflow_dispatch]
`) as Workflow
`) as Workflow,
),
[]
)
[],
),
);
t.deepEqual(
@@ -428,10 +428,10 @@ test("getWorkflowErrors() with a different on setup", (t) => {
name: "CodeQL"
on:
workflow_dispatch: {}
`) as Workflow
`) as Workflow,
),
[]
)
[],
),
);
});
@@ -444,10 +444,10 @@ test("getWorkflowErrors() should not report an error if PRs are totally unconfig
on:
push:
branches: [master]
`) as Workflow
`) as Workflow,
),
[]
)
[],
),
);
t.deepEqual(
@@ -456,10 +456,10 @@ test("getWorkflowErrors() should not report an error if PRs are totally unconfig
yaml.load(`
name: "CodeQL"
on: ["push"]
`) as Workflow
`) as Workflow,
),
[]
)
[],
),
);
});
@@ -479,9 +479,9 @@ test("getCategoryInputOrThrow returns category for simple workflow with category
category: some-category
`) as Workflow,
"analysis",
{}
{},
),
"some-category"
"some-category",
);
});
@@ -499,9 +499,9 @@ test("getCategoryInputOrThrow returns undefined for simple workflow without cate
- uses: github/codeql-action/analyze@v2
`) as Workflow,
"analysis",
{}
{},
),
undefined
undefined,
);
});
@@ -531,9 +531,9 @@ test("getCategoryInputOrThrow returns category for workflow with multiple jobs",
category: bar-category
`) as Workflow,
"bar",
{}
{},
),
"bar-category"
"bar-category",
);
});
@@ -558,9 +558,9 @@ test("getCategoryInputOrThrow finds category for workflow with language matrix",
category: "/language:\${{ matrix.language }}"
`) as Workflow,
"analysis",
{ language: "javascript" }
{ language: "javascript" },
),
"/language:javascript"
"/language:javascript",
);
});
@@ -580,13 +580,13 @@ test("getCategoryInputOrThrow throws error for workflow with dynamic category",
category: "\${{ github.workflow }}"
`) as Workflow,
"analysis",
{}
{},
),
{
message:
"Could not get category input to github/codeql-action/analyze since it contained " +
"an unrecognized dynamic value.",
}
},
);
});
@@ -610,12 +610,12 @@ test("getCategoryInputOrThrow throws error for workflow with multiple calls to a
category: another-category
`) as Workflow,
"analysis",
{}
{},
),
{
message:
"Could not get category input to github/codeql-action/analyze since the analysis job " +
"calls github/codeql-action/analyze multiple times.",
}
},
);
});

View File

@@ -70,7 +70,7 @@ function patternToRegExp(value) {
}
return arr;
}, [])
.join("")}$`
.join("")}$`,
);
}
@@ -88,10 +88,13 @@ export interface CodedError {
function toCodedErrors(errors: {
[code: string]: string;
}): Record<string, CodedError> {
return Object.entries(errors).reduce((acc, [code, message]) => {
acc[code] = { message, code };
return acc;
}, {} as Record<string, CodedError>);
return Object.entries(errors).reduce(
(acc, [code, message]) => {
acc[code] = { message, code };
return acc;
},
{} as Record<string, CodedError>,
);
}
// code to send back via status report
@@ -144,7 +147,7 @@ export function getWorkflowErrors(doc: Workflow): CodedError[] {
const hasPush = Object.prototype.hasOwnProperty.call(doc.on, "push");
const hasPullRequest = Object.prototype.hasOwnProperty.call(
doc.on,
"pull_request"
"pull_request",
);
if (!hasPush && hasPullRequest) {
@@ -160,7 +163,7 @@ export function getWorkflowErrors(doc: Workflow): CodedError[] {
}
export async function validateWorkflow(
logger: Logger
logger: Logger,
): Promise<undefined | string> {
let workflow: Workflow;
try {
@@ -210,10 +213,10 @@ export async function getWorkflow(logger: Logger): Promise<Workflow> {
const maybeWorkflow = process.env["CODE_SCANNING_WORKFLOW_FILE"];
if (maybeWorkflow) {
logger.debug(
"Using the workflow specified by the CODE_SCANNING_WORKFLOW_FILE environment variable."
"Using the workflow specified by the CODE_SCANNING_WORKFLOW_FILE environment variable.",
);
return yaml.load(
zlib.gunzipSync(Buffer.from(maybeWorkflow, "base64")).toString()
zlib.gunzipSync(Buffer.from(maybeWorkflow, "base64")).toString(),
) as Workflow;
}
@@ -228,12 +231,12 @@ async function getWorkflowAbsolutePath(logger: Logger): Promise<string> {
const relativePath = await api.getWorkflowRelativePath();
const absolutePath = path.join(
getRequiredEnvParam("GITHUB_WORKSPACE"),
relativePath
relativePath,
);
if (fs.existsSync(absolutePath)) {
logger.debug(
`Derived the following absolute path for the currently executing workflow: ${absolutePath}.`
`Derived the following absolute path for the currently executing workflow: ${absolutePath}.`,
);
return absolutePath;
}
@@ -241,23 +244,23 @@ async function getWorkflowAbsolutePath(logger: Logger): Promise<string> {
throw new Error(
`Expected to find a code scanning workflow file at ${absolutePath}, but no such file existed. ` +
"This can happen if the currently running workflow checks out a branch that doesn't contain " +
"the corresponding workflow file."
"the corresponding workflow file.",
);
}
function getStepsCallingAction(
job: WorkflowJob,
actionName: string
actionName: string,
): WorkflowJobStep[] {
if (job.uses) {
throw new Error(
`Could not get steps calling ${actionName} since the job calls a reusable workflow.`
`Could not get steps calling ${actionName} since the job calls a reusable workflow.`,
);
}
const steps = job.steps;
if (!Array.isArray(steps)) {
throw new Error(
`Could not get steps calling ${actionName} since job.steps was not an array.`
`Could not get steps calling ${actionName} since job.steps was not an array.`,
);
}
return steps.filter((step) => step.uses?.includes(actionName));
@@ -278,7 +281,7 @@ function getInputOrThrow(
jobName: string,
actionName: string,
inputName: string,
matrixVars: { [key: string]: string } | undefined
matrixVars: { [key: string]: string } | undefined,
) {
const preamble = `Could not get ${inputName} input to ${actionName} since`;
if (!workflow.jobs) {
@@ -290,16 +293,16 @@ function getInputOrThrow(
const stepsCallingAction = getStepsCallingAction(
workflow.jobs[jobName],
actionName
actionName,
);
if (stepsCallingAction.length === 0) {
throw new Error(
`${preamble} the ${jobName} job does not call ${actionName}.`
`${preamble} the ${jobName} job does not call ${actionName}.`,
);
} else if (stepsCallingAction.length > 1) {
throw new Error(
`${preamble} the ${jobName} job calls ${actionName} multiple times.`
`${preamble} the ${jobName} job calls ${actionName} multiple times.`,
);
}
@@ -315,7 +318,7 @@ function getInputOrThrow(
}
if (input !== undefined && input.includes("${{")) {
throw new Error(
`Could not get ${inputName} input to ${actionName} since it contained an unrecognized dynamic value.`
`Could not get ${inputName} input to ${actionName} since it contained an unrecognized dynamic value.`,
);
}
return input;
@@ -349,14 +352,14 @@ function getAnalyzeActionName() {
export function getCategoryInputOrThrow(
workflow: Workflow,
jobName: string,
matrixVars: { [key: string]: string } | undefined
matrixVars: { [key: string]: string } | undefined,
): string | undefined {
return getInputOrThrow(
workflow,
jobName,
getAnalyzeActionName(),
"category",
matrixVars
matrixVars,
);
}
@@ -372,14 +375,14 @@ export function getCategoryInputOrThrow(
export function getUploadInputOrThrow(
workflow: Workflow,
jobName: string,
matrixVars: { [key: string]: string } | undefined
matrixVars: { [key: string]: string } | undefined,
): string | undefined {
return getInputOrThrow(
workflow,
jobName,
getAnalyzeActionName(),
"upload",
matrixVars
matrixVars,
);
}
@@ -395,7 +398,7 @@ export function getUploadInputOrThrow(
export function getCheckoutPathInputOrThrow(
workflow: Workflow,
jobName: string,
matrixVars: { [key: string]: string } | undefined
matrixVars: { [key: string]: string } | undefined,
): string {
return (
getInputOrThrow(
@@ -403,7 +406,7 @@ export function getCheckoutPathInputOrThrow(
jobName,
getAnalyzeActionName(),
"checkout_path",
matrixVars
matrixVars,
) || getRequiredEnvParam("GITHUB_WORKSPACE") // if unspecified, checkout_path defaults to ${{ github.workspace }}
);
}