Merge remote-tracking branch 'upstream/main' into rvermeulen/extend-init-complete-status-report
This commit is contained in:
commit
7c2bec0cc3
2390 changed files with 80665 additions and 3034 deletions
|
|
@ -14,7 +14,7 @@ import {
|
|||
ConfigurationError,
|
||||
} from "./util";
|
||||
|
||||
// eslint-disable-next-line import/no-commonjs
|
||||
// eslint-disable-next-line import/no-commonjs, @typescript-eslint/no-require-imports
|
||||
const pkg = require("../package.json") as JSONSchemaForNPMPackageJsonFiles;
|
||||
|
||||
/**
|
||||
|
|
@ -83,7 +83,7 @@ export const getCommitOid = async function (
|
|||
},
|
||||
).exec();
|
||||
return commitOid.trim();
|
||||
} catch (e) {
|
||||
} catch {
|
||||
if (stderr.includes("not a git repository")) {
|
||||
core.info(
|
||||
"Could not determine current commit SHA using git. Continuing with data from user input or environment. " +
|
||||
|
|
@ -154,7 +154,7 @@ export const determineMergeBaseCommitOid = async function (
|
|||
return baseOid;
|
||||
}
|
||||
return undefined;
|
||||
} catch (e) {
|
||||
} catch {
|
||||
if (stderr.includes("not a git repository")) {
|
||||
core.info(
|
||||
"The checkout path provided to the action does not appear to be a git repository. " +
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ test("analyze action with RAM & threads from environment variables", async (t) =
|
|||
|
||||
const runFinalizeStub = sinon.stub(analyze, "runFinalize");
|
||||
const runQueriesStub = sinon.stub(analyze, "runQueries");
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const analyzeAction = require("./analyze-action");
|
||||
|
||||
// When analyze-action.ts loads, it runs an async function from the top
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ test("analyze action with RAM & threads from action inputs", async (t) => {
|
|||
|
||||
const runFinalizeStub = sinon.stub(analyze, "runFinalize");
|
||||
const runQueriesStub = sinon.stub(analyze, "runQueries");
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const analyzeAction = require("./analyze-action");
|
||||
|
||||
// When analyze-action.ts loads, it runs an async function from the top
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ export function dbIsFinalized(
|
|||
fs.readFileSync(path.resolve(dbPath, "codeql-database.yml"), "utf8"),
|
||||
) as { inProgress?: boolean };
|
||||
return !("inProgress" in dbInfo);
|
||||
} catch (e) {
|
||||
} catch {
|
||||
logger.warning(
|
||||
`Could not check whether database for ${language} was finalized. Assuming it is not.`,
|
||||
);
|
||||
|
|
@ -339,7 +339,6 @@ export async function runQueries(
|
|||
automationDetailsId,
|
||||
config,
|
||||
features,
|
||||
logger,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -197,36 +197,28 @@ test("downloads an explicitly requested bundle even if a different version is ca
|
|||
|
||||
const EXPLICITLY_REQUESTED_BUNDLE_TEST_CASES = [
|
||||
{
|
||||
cliVersion: "2.10.0",
|
||||
expectedToolcacheVersion: "2.10.0-20200610",
|
||||
tagName: "codeql-bundle-2.17.6",
|
||||
expectedToolcacheVersion: "2.17.6",
|
||||
},
|
||||
{
|
||||
cliVersion: "2.10.0-pre",
|
||||
expectedToolcacheVersion: "0.0.0-20200610",
|
||||
},
|
||||
{
|
||||
cliVersion: "2.10.0+202006100101",
|
||||
expectedToolcacheVersion: "0.0.0-20200610",
|
||||
tagName: "codeql-bundle-20240805",
|
||||
expectedToolcacheVersion: "0.0.0-20240805",
|
||||
},
|
||||
];
|
||||
|
||||
for (const {
|
||||
cliVersion,
|
||||
tagName,
|
||||
expectedToolcacheVersion,
|
||||
} of EXPLICITLY_REQUESTED_BUNDLE_TEST_CASES) {
|
||||
test(`caches an explicitly requested bundle containing CLI ${cliVersion} as ${expectedToolcacheVersion}`, async (t) => {
|
||||
test(`caches explicitly requested bundle ${tagName} as ${expectedToolcacheVersion}`, async (t) => {
|
||||
await util.withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
|
||||
mockApiDetails(SAMPLE_DOTCOM_API_DETAILS);
|
||||
sinon.stub(actionsUtil, "isRunningLocalAction").returns(true);
|
||||
|
||||
const releaseApiMock = mockReleaseApi({
|
||||
assetNames: [`cli-version-${cliVersion}.txt`],
|
||||
tagName: "codeql-bundle-20200610",
|
||||
});
|
||||
const url = mockBundleDownloadApi({
|
||||
tagName: "codeql-bundle-20200610",
|
||||
tagName,
|
||||
});
|
||||
|
||||
const result = await codeql.setupCodeQL(
|
||||
|
|
@ -238,9 +230,8 @@ for (const {
|
|||
getRunnerLogger(true),
|
||||
false,
|
||||
);
|
||||
t.assert(releaseApiMock.isDone(), "Releases API should have been called");
|
||||
t.assert(toolcache.find("CodeQL", expectedToolcacheVersion));
|
||||
t.deepEqual(result.toolsVersion, cliVersion);
|
||||
t.deepEqual(result.toolsVersion, expectedToolcacheVersion);
|
||||
t.is(result.toolsSource, ToolsSource.Download);
|
||||
t.assert(Number.isInteger(result.toolsDownloadDurationMs));
|
||||
});
|
||||
|
|
@ -386,7 +377,7 @@ test("bundle URL from another repo is cached as 0.0.0-bundleVersion", async (t)
|
|||
mockApiDetails(SAMPLE_DOTCOM_API_DETAILS);
|
||||
sinon.stub(actionsUtil, "isRunningLocalAction").returns(true);
|
||||
const releasesApiMock = mockReleaseApi({
|
||||
assetNames: ["cli-version-2.12.6.txt"],
|
||||
assetNames: ["cli-version-2.13.5.txt"],
|
||||
tagName: "codeql-bundle-20230203",
|
||||
});
|
||||
mockBundleDownloadApi({
|
||||
|
|
@ -689,7 +680,7 @@ test("passes a code scanning config AND qlconfig to the CLI", async (t: Executio
|
|||
await util.withTmpDir(async (tempDir) => {
|
||||
const runnerConstructorStub = stubToolRunnerConstructor();
|
||||
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.12.6"));
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.17.6"));
|
||||
|
||||
await codeqlObject.databaseInitCluster(
|
||||
{ ...stubConfig, tempDir },
|
||||
|
|
@ -718,7 +709,7 @@ test("does not pass a qlconfig to the CLI when it is undefined", async (t: Execu
|
|||
await util.withTmpDir(async (tempDir) => {
|
||||
const runnerConstructorStub = stubToolRunnerConstructor();
|
||||
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.12.6"));
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.17.6"));
|
||||
|
||||
await codeqlObject.databaseInitCluster(
|
||||
{ ...stubConfig, tempDir },
|
||||
|
|
@ -759,7 +750,7 @@ const NEW_ANALYSIS_SUMMARY_TEST_CASES = [
|
|||
codeqlVersion: makeVersionInfo("2.15.0"),
|
||||
githubVersion: {
|
||||
type: util.GitHubVariant.GHES,
|
||||
version: "3.9.0",
|
||||
version: "3.10.0",
|
||||
},
|
||||
flagPassed: true,
|
||||
negativeFlagPassed: false,
|
||||
|
|
@ -804,7 +795,6 @@ for (const {
|
|||
"",
|
||||
Object.assign({}, stubConfig, { gitHubVersion: githubVersion }),
|
||||
createFeatures([]),
|
||||
getRunnerLogger(true),
|
||||
);
|
||||
const actualArgs = runnerConstructorStub.firstCall.args[1] as string[];
|
||||
t.is(
|
||||
|
|
@ -822,32 +812,6 @@ for (const {
|
|||
});
|
||||
}
|
||||
|
||||
test("database finalize does not override no code found error on CodeQL 2.12.6", async (t) => {
|
||||
const cliMessage =
|
||||
"CodeQL did not detect any code written in languages supported by CodeQL. Review our troubleshooting guide at " +
|
||||
"https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build.";
|
||||
stubToolRunnerConstructor(32, cliMessage);
|
||||
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.12.6"));
|
||||
// safeWhich throws because of the test CodeQL object.
|
||||
sinon.stub(safeWhich, "safeWhich").resolves("");
|
||||
|
||||
await t.throwsAsync(
|
||||
async () =>
|
||||
await codeqlObject.finalizeDatabase(
|
||||
"db",
|
||||
"--threads=2",
|
||||
"--ram=2048",
|
||||
false,
|
||||
),
|
||||
{
|
||||
message:
|
||||
'Encountered a fatal error while running "codeql-for-testing database finalize --finalize-dataset --threads=2 --ram=2048 db". ' +
|
||||
`Exit code was 32 and last log line was: ${cliMessage} See the logs for more details.`,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test("runTool summarizes several fatal errors", async (t) => {
|
||||
const heapError =
|
||||
"A fatal error occurred: Evaluator heap must be at least 384.00 MiB";
|
||||
|
|
@ -858,7 +822,7 @@ test("runTool summarizes several fatal errors", async (t) => {
|
|||
`${heapError}\n${datasetImportError}.`;
|
||||
stubToolRunnerConstructor(32, cliStderr);
|
||||
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.12.6"));
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.17.6"));
|
||||
// safeWhich throws because of the test CodeQL object.
|
||||
sinon.stub(safeWhich, "safeWhich").resolves("");
|
||||
|
||||
|
|
@ -899,7 +863,7 @@ test("runTool summarizes autobuilder errors", async (t) => {
|
|||
`;
|
||||
stubToolRunnerConstructor(1, stderr);
|
||||
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.12.6"));
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.17.6"));
|
||||
sinon.stub(codeqlObject, "resolveExtractor").resolves("/path/to/extractor");
|
||||
// safeWhich throws because of the test CodeQL object.
|
||||
sinon.stub(safeWhich, "safeWhich").resolves("");
|
||||
|
|
@ -926,7 +890,7 @@ test("runTool truncates long autobuilder errors", async (t) => {
|
|||
).join("\n");
|
||||
stubToolRunnerConstructor(1, stderr);
|
||||
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.12.6"));
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.17.6"));
|
||||
sinon.stub(codeqlObject, "resolveExtractor").resolves("/path/to/extractor");
|
||||
// safeWhich throws because of the test CodeQL object.
|
||||
sinon.stub(safeWhich, "safeWhich").resolves("");
|
||||
|
|
@ -954,7 +918,7 @@ test("runTool recognizes fatal internal errors", async (t) => {
|
|||
Severe disk cache trouble (corruption or out of space) at /home/runner/work/_temp/codeql_databases/go/db-go/default/cache/pages/28/33.pack: Failed to write item to disk`;
|
||||
stubToolRunnerConstructor(1, stderr);
|
||||
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.12.6"));
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.17.6"));
|
||||
sinon.stub(codeqlObject, "resolveExtractor").resolves("/path/to/extractor");
|
||||
// safeWhich throws because of the test CodeQL object.
|
||||
sinon.stub(safeWhich, "safeWhich").resolves("");
|
||||
|
|
@ -964,7 +928,7 @@ test("runTool recognizes fatal internal errors", async (t) => {
|
|||
await codeqlObject.databaseRunQueries(stubConfig.dbLocation, []),
|
||||
{
|
||||
instanceOf: CommandInvocationError,
|
||||
message: `Encountered a fatal error while running "codeql-for-testing database run-queries --expect-discarded-cache --min-disk-free=1024 -v". Exit code was 1 and error was: Oops! A fatal internal error occurred. Details:
|
||||
message: `Encountered a fatal error while running "codeql-for-testing database run-queries --expect-discarded-cache --min-disk-free=1024 -v --intra-layer-parallelism". Exit code was 1 and error was: Oops! A fatal internal error occurred. Details:
|
||||
com.semmle.util.exception.CatastrophicError: An error occurred while evaluating ControlFlowGraph::ControlFlow::Root.isRootOf/1#dispred#f610e6ed/2@86282cc8
|
||||
Severe disk cache trouble (corruption or out of space) at /home/runner/work/_temp/codeql_databases/go/db-go/default/cache/pages/28/33.pack: Failed to write item to disk. See the logs for more details.`,
|
||||
},
|
||||
|
|
@ -975,7 +939,7 @@ test("runTool outputs last line of stderr if fatal error could not be found", as
|
|||
const cliStderr = "line1\nline2\nline3\nline4\nline5";
|
||||
stubToolRunnerConstructor(32, cliStderr);
|
||||
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.12.6"));
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.17.6"));
|
||||
// safeWhich throws because of the test CodeQL object.
|
||||
sinon.stub(safeWhich, "safeWhich").resolves("");
|
||||
|
||||
|
|
@ -1000,7 +964,7 @@ test("runTool outputs last line of stderr if fatal error could not be found", as
|
|||
test("Avoids duplicating --overwrite flag if specified in CODEQL_ACTION_EXTRA_OPTIONS", async (t) => {
|
||||
const runnerConstructorStub = stubToolRunnerConstructor();
|
||||
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.12.6"));
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.17.6"));
|
||||
// safeWhich throws because of the test CodeQL object.
|
||||
sinon.stub(safeWhich, "safeWhich").resolves("");
|
||||
|
||||
|
|
|
|||
|
|
@ -168,7 +168,6 @@ export interface CodeQL {
|
|||
automationDetailsId: string | undefined,
|
||||
config: Config,
|
||||
features: FeatureEnablement,
|
||||
logger: Logger,
|
||||
): Promise<string>;
|
||||
/**
|
||||
* Run 'codeql database print-baseline'.
|
||||
|
|
@ -184,8 +183,6 @@ export interface CodeQL {
|
|||
databasePath: string,
|
||||
sarifFile: string,
|
||||
automationDetailsId: string | undefined,
|
||||
tempDir: string,
|
||||
logger: Logger,
|
||||
): Promise<void>;
|
||||
/**
|
||||
* Run 'codeql diagnostics export'.
|
||||
|
|
@ -277,7 +274,7 @@ let cachedCodeQL: CodeQL | undefined = undefined;
|
|||
* The version flags below can be used to conditionally enable certain features
|
||||
* on versions newer than this.
|
||||
*/
|
||||
const CODEQL_MINIMUM_VERSION = "2.12.6";
|
||||
const CODEQL_MINIMUM_VERSION = "2.13.5";
|
||||
|
||||
/**
|
||||
* This version will shortly become the oldest version of CodeQL that the Action will run with.
|
||||
|
|
@ -305,16 +302,6 @@ const EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++";
|
|||
* flag is older than the oldest supported version above, it may be removed.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Versions 2.13.1+ of the CodeQL CLI fix a bug where diagnostics export could produce invalid SARIF.
|
||||
*/
|
||||
export const CODEQL_VERSION_DIAGNOSTICS_EXPORT_FIXED = "2.13.1";
|
||||
|
||||
/**
|
||||
* Versions 2.13.4+ of the CodeQL CLI support the `resolve build-environment` command.
|
||||
*/
|
||||
export const CODEQL_VERSION_RESOLVE_ENVIRONMENT = "2.13.4";
|
||||
|
||||
/**
|
||||
* Versions 2.14.2+ of the CodeQL CLI support language-specific baseline configuration.
|
||||
*/
|
||||
|
|
@ -538,7 +525,7 @@ export async function getCodeQLForCmd(
|
|||
const output = await runTool(cmd, ["version", "--format=json"]);
|
||||
try {
|
||||
result = JSON.parse(output) as VersionInfo;
|
||||
} catch (err) {
|
||||
} catch {
|
||||
throw Error(
|
||||
`Invalid JSON output from \`version --format=json\`: ${output}`,
|
||||
);
|
||||
|
|
@ -846,25 +833,18 @@ export async function getCodeQLForCmd(
|
|||
automationDetailsId: string | undefined,
|
||||
config: Config,
|
||||
features: FeatureEnablement,
|
||||
logger: Logger,
|
||||
): Promise<string> {
|
||||
const shouldExportDiagnostics = await features.getValue(
|
||||
Feature.ExportDiagnosticsEnabled,
|
||||
this,
|
||||
);
|
||||
const shouldWorkaroundInvalidNotifications =
|
||||
shouldExportDiagnostics &&
|
||||
!(await isDiagnosticsExportInvalidSarifFixed(this));
|
||||
const codeqlOutputFile = shouldWorkaroundInvalidNotifications
|
||||
? path.join(config.tempDir, "codeql-intermediate-results.sarif")
|
||||
: sarifFile;
|
||||
const codeqlArgs = [
|
||||
"database",
|
||||
"interpret-results",
|
||||
threadsFlag,
|
||||
"--format=sarif-latest",
|
||||
verbosityFlag,
|
||||
`--output=${codeqlOutputFile}`,
|
||||
`--output=${sarifFile}`,
|
||||
addSnippetsFlag,
|
||||
"--print-diagnostics-summary",
|
||||
"--print-metrics-summary",
|
||||
|
|
@ -912,15 +892,9 @@ export async function getCodeQLForCmd(
|
|||
}
|
||||
// Capture the stdout, which contains the analysis summary. Don't stream it to the Actions
|
||||
// logs to avoid printing it twice.
|
||||
const analysisSummary = await runTool(cmd, codeqlArgs, {
|
||||
return await runTool(cmd, codeqlArgs, {
|
||||
noStreamStdout: true,
|
||||
});
|
||||
|
||||
if (shouldWorkaroundInvalidNotifications) {
|
||||
util.fixInvalidNotificationsInFile(codeqlOutputFile, sarifFile, logger);
|
||||
}
|
||||
|
||||
return analysisSummary;
|
||||
},
|
||||
async databasePrintBaseline(databasePath: string): Promise<string> {
|
||||
const codeqlArgs = [
|
||||
|
|
@ -1016,21 +990,14 @@ export async function getCodeQLForCmd(
|
|||
databasePath: string,
|
||||
sarifFile: string,
|
||||
automationDetailsId: string | undefined,
|
||||
tempDir: string,
|
||||
logger: Logger,
|
||||
): Promise<void> {
|
||||
const shouldWorkaroundInvalidNotifications =
|
||||
!(await isDiagnosticsExportInvalidSarifFixed(this));
|
||||
const codeqlOutputFile = shouldWorkaroundInvalidNotifications
|
||||
? path.join(tempDir, "codeql-intermediate-results.sarif")
|
||||
: sarifFile;
|
||||
const args = [
|
||||
"database",
|
||||
"export-diagnostics",
|
||||
`${databasePath}`,
|
||||
"--db-cluster", // Database is always a cluster for CodeQL versions that support diagnostics.
|
||||
"--format=sarif-latest",
|
||||
`--output=${codeqlOutputFile}`,
|
||||
`--output=${sarifFile}`,
|
||||
"--sarif-include-diagnostics", // ExportDiagnosticsEnabled is always true if this command is run.
|
||||
"-vvv",
|
||||
...getExtraOptionsFromEnv(["diagnostics", "export"]),
|
||||
|
|
@ -1039,11 +1006,6 @@ export async function getCodeQLForCmd(
|
|||
args.push("--sarif-category", automationDetailsId);
|
||||
}
|
||||
await new toolrunner.ToolRunner(cmd, args).exec();
|
||||
|
||||
if (shouldWorkaroundInvalidNotifications) {
|
||||
// Fix invalid notifications in the SARIF file output by CodeQL.
|
||||
util.fixInvalidNotificationsInFile(codeqlOutputFile, sarifFile, logger);
|
||||
}
|
||||
},
|
||||
async diagnosticsExport(
|
||||
sarifFile: string,
|
||||
|
|
@ -1381,15 +1343,6 @@ export function getGeneratedCodeScanningConfigPath(config: Config): string {
|
|||
return path.resolve(config.tempDir, "user-config.yaml");
|
||||
}
|
||||
|
||||
async function isDiagnosticsExportInvalidSarifFixed(
|
||||
codeql: CodeQL,
|
||||
): Promise<boolean> {
|
||||
return await util.codeQlVersionAtLeast(
|
||||
codeql,
|
||||
CODEQL_VERSION_DIAGNOSTICS_EXPORT_FIXED,
|
||||
);
|
||||
}
|
||||
|
||||
async function getLanguageAliasingArguments(codeql: CodeQL): Promise<string[]> {
|
||||
if (
|
||||
await util.codeQlVersionAtLeast(codeql, CODEQL_VERSION_LANGUAGE_ALIASING)
|
||||
|
|
|
|||
|
|
@ -770,7 +770,7 @@ export function parsePacksSpecification(packStr: string): Pack {
|
|||
if (version) {
|
||||
try {
|
||||
new semver.Range(version);
|
||||
} catch (e) {
|
||||
} catch {
|
||||
// The range string is invalid. OK to ignore the caught error
|
||||
throw new ConfigurationError(getPacksStrInvalid(packStr));
|
||||
}
|
||||
|
|
@ -874,7 +874,7 @@ function parseRegistries(
|
|||
return registriesInput
|
||||
? (yaml.load(registriesInput) as RegistryConfigWithCredentials[])
|
||||
: undefined;
|
||||
} catch (e) {
|
||||
} catch {
|
||||
throw new ConfigurationError(
|
||||
"Invalid registries input. Must be a YAML string.",
|
||||
);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ export async function uploadDebugArtifacts(
|
|||
JSON.parse(matrix) as any[][],
|
||||
).sort())
|
||||
suffix += `-${matrixVal}`;
|
||||
} catch (e) {
|
||||
} catch {
|
||||
core.info(
|
||||
"Could not parse user-specified `matrix` input into JSON. The debug artifact will not be named with the user's `matrix` input.",
|
||||
);
|
||||
|
|
|
|||
|
|
@ -404,7 +404,7 @@ test("selects CLI v2.20.1 on Dotcom when feature flags enable v2.20.0 and v2.20.
|
|||
});
|
||||
});
|
||||
|
||||
test("includes tag name when feature flags enable version greater than v2.13.4", async (t) => {
|
||||
test("includes tag name", async (t) => {
|
||||
await withTmpDir(async (tmpDir) => {
|
||||
const features = setUpFeatureFlagTests(tmpDir);
|
||||
const expectedFeatureEnablement = initializeFeatures(true);
|
||||
|
|
@ -439,25 +439,6 @@ test(`selects CLI from defaults.json on Dotcom when no default version feature f
|
|||
});
|
||||
});
|
||||
|
||||
test(`selects CLI from defaults.json on Dotcom when default version feature flags are unsupported`, async (t) => {
|
||||
await withTmpDir(async (tmpDir) => {
|
||||
const features = setUpFeatureFlagTests(tmpDir);
|
||||
const expectedFeatureEnablement = initializeFeatures(true);
|
||||
// Doesn't have a semantically versioned bundle
|
||||
expectedFeatureEnablement["default_codeql_version_2_13_3_enabled"] = true;
|
||||
mockFeatureFlagApiEndpoint(200, expectedFeatureEnablement);
|
||||
|
||||
const defaultCliVersion = await features.getDefaultCliVersion(
|
||||
GitHubVariant.DOTCOM,
|
||||
);
|
||||
t.deepEqual(defaultCliVersion, {
|
||||
cliVersion: defaults.cliVersion,
|
||||
tagName: defaults.bundleVersion,
|
||||
toolsFeatureFlagsValid: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test("ignores invalid version numbers in default version feature flags", async (t) => {
|
||||
await withTmpDir(async (tmpDir) => {
|
||||
const loggedMessages = [];
|
||||
|
|
|
|||
|
|
@ -14,11 +14,6 @@ import * as util from "./util";
|
|||
const DEFAULT_VERSION_FEATURE_FLAG_PREFIX = "default_codeql_version_";
|
||||
const DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled";
|
||||
|
||||
/**
|
||||
* Versions 2.13.4+ of the CodeQL CLI have an associated CodeQL Bundle release that is semantically versioned.
|
||||
*/
|
||||
export const CODEQL_VERSION_BUNDLE_SEMANTICALLY_VERSIONED = "2.13.4";
|
||||
|
||||
/**
|
||||
* Evaluator fine-grained parallelism (aka intra-layer parallelism) is only safe to enable in 2.15.1 onwards.
|
||||
* (Some earlier versions recognize the command-line flag, but they contain a bug which makes it unsafe to use).
|
||||
|
|
@ -323,13 +318,7 @@ class GitHubFeatureFlags {
|
|||
.map(([f, isEnabled]) =>
|
||||
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),
|
||||
)
|
||||
.map((f) => f as string);
|
||||
.filter((f): f is string => f !== undefined);
|
||||
|
||||
if (enabledFeatureFlagCliVersions.length === 0) {
|
||||
// We expect at least one default CLI version to be enabled on Dotcom at any time. However if
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ export function resolveUriToFile(
|
|||
let uri: string;
|
||||
try {
|
||||
uri = decodeURIComponent(location.uri as string);
|
||||
} catch (e: any) {
|
||||
} catch {
|
||||
logger.debug(`Ignoring location as URI "${location.uri}" is invalid`);
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -359,7 +359,7 @@ async function testFailedSarifUpload(
|
|||
|
||||
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||
sinon.stub(codeql, "getCodeQL").resolves(codeqlObject);
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.12.6"));
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.17.6"));
|
||||
const databaseExportDiagnosticsStub = sinon.stub(
|
||||
codeqlObject,
|
||||
"databaseExportDiagnostics",
|
||||
|
|
@ -398,8 +398,6 @@ async function testFailedSarifUpload(
|
|||
config.dbLocation,
|
||||
sinon.match.string,
|
||||
category,
|
||||
sinon.match.any,
|
||||
sinon.match.any,
|
||||
),
|
||||
`Actual args were: ${databaseExportDiagnosticsStub.args}`,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -94,13 +94,7 @@ async function maybeUploadFailedSarif(
|
|||
await codeql.diagnosticsExport(sarifFile, category, config);
|
||||
} else {
|
||||
// We call 'database export-diagnostics' to find any per-database diagnostics.
|
||||
await codeql.databaseExportDiagnostics(
|
||||
databasePath,
|
||||
sarifFile,
|
||||
category,
|
||||
config.tempDir,
|
||||
logger,
|
||||
);
|
||||
await codeql.databaseExportDiagnostics(databasePath, sarifFile, category);
|
||||
}
|
||||
|
||||
logger.info(`Uploading failed SARIF file ${sarifFile}`);
|
||||
|
|
|
|||
|
|
@ -485,10 +485,7 @@ async function run() {
|
|||
|
||||
const kotlinLimitVar =
|
||||
"CODEQL_EXTRACTOR_KOTLIN_OVERRIDE_MAXIMUM_VERSION_LIMIT";
|
||||
if (
|
||||
(await codeQlVersionAtLeast(codeql, "2.13.4")) &&
|
||||
!(await codeQlVersionAtLeast(codeql, "2.14.4"))
|
||||
) {
|
||||
if (!(await codeQlVersionAtLeast(codeql, "2.14.4"))) {
|
||||
core.exportVariable(kotlinLimitVar, "1.9.20");
|
||||
}
|
||||
|
||||
|
|
@ -542,7 +539,7 @@ async function run() {
|
|||
|
||||
// From 2.16.0 the default for the python extractor is to not perform any
|
||||
// dependency extraction. For versions before that, you needed to set this flag to
|
||||
// enable this behavior (supported since 2.13.1).
|
||||
// enable this behavior.
|
||||
|
||||
if (await codeQlVersionAtLeast(codeql, "2.17.1")) {
|
||||
// disabled by default, no warning
|
||||
|
|
@ -552,17 +549,11 @@ async function run() {
|
|||
"CODEQL_EXTRACTOR_PYTHON_DISABLE_LIBRARY_EXTRACTION",
|
||||
"true",
|
||||
);
|
||||
} else if (await codeQlVersionAtLeast(codeql, "2.13.1")) {
|
||||
} else {
|
||||
core.exportVariable(
|
||||
"CODEQL_EXTRACTOR_PYTHON_DISABLE_LIBRARY_EXTRACTION",
|
||||
"true",
|
||||
);
|
||||
} else {
|
||||
logger.warning(
|
||||
`CodeQL Action versions 3.25.0 and later, and versions 2.25.0 and later no longer install Python dependencies. We recommend upgrading to at least CodeQL Bundle 2.16.0 to avoid any potential problems due to this (you are currently using ${
|
||||
(await codeql.getVersion()).version
|
||||
}). Alternatively, we recommend downgrading the CodeQL Action to version 3.24.10 (for customers using GitHub.com or GitHub Enterprise Server v3.12 or later) or 2.24.10 (for customers using GitHub Enterprise Server v3.11 or earlier).`,
|
||||
);
|
||||
}
|
||||
|
||||
if (getOptionalInput("setup-python-dependencies") !== undefined) {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
import {
|
||||
CODEQL_VERSION_LANGUAGE_ALIASING,
|
||||
CODEQL_VERSION_RESOLVE_ENVIRONMENT,
|
||||
getCodeQL,
|
||||
} from "./codeql";
|
||||
import { CODEQL_VERSION_LANGUAGE_ALIASING, getCodeQL } from "./codeql";
|
||||
import { parseLanguage } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import * as util from "./util";
|
||||
|
|
@ -34,28 +30,12 @@ export async function runResolveBuildEnvironment(
|
|||
language = parsedLanguage;
|
||||
}
|
||||
|
||||
let result = {};
|
||||
|
||||
// If the CodeQL version in use does not support the `resolve build-environment`
|
||||
// command, just return an empty configuration. Otherwise invoke the CLI.
|
||||
if (
|
||||
!(await util.codeQlVersionAtLeast(
|
||||
codeql,
|
||||
CODEQL_VERSION_RESOLVE_ENVIRONMENT,
|
||||
))
|
||||
) {
|
||||
logger.warning(
|
||||
"Unsupported CodeQL CLI version for `resolve build-environment` command, " +
|
||||
"returning an empty configuration.",
|
||||
);
|
||||
} else {
|
||||
if (workingDir !== undefined) {
|
||||
logger.info(`Using ${workingDir} as the working directory.`);
|
||||
}
|
||||
|
||||
result = await codeql.resolveBuildEnvironment(workingDir, language);
|
||||
if (workingDir !== undefined) {
|
||||
logger.info(`Using ${workingDir} as the working directory.`);
|
||||
}
|
||||
|
||||
const result = await codeql.resolveBuildEnvironment(workingDir, language);
|
||||
|
||||
logger.endGroup();
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,13 +15,10 @@ import * as api from "./api-client";
|
|||
// creation scripts. Ensure that any changes to the format of this file are compatible with both of
|
||||
// these dependents.
|
||||
import * as defaults from "./defaults.json";
|
||||
import {
|
||||
CODEQL_VERSION_BUNDLE_SEMANTICALLY_VERSIONED,
|
||||
CodeQLDefaultVersionInfo,
|
||||
} from "./feature-flags";
|
||||
import { CodeQLDefaultVersionInfo } from "./feature-flags";
|
||||
import { Logger } from "./logging";
|
||||
import * as util from "./util";
|
||||
import { isGoodVersion, wrapError } from "./util";
|
||||
import { isGoodVersion } from "./util";
|
||||
|
||||
export enum ToolsSource {
|
||||
Unknown = "UNKNOWN",
|
||||
|
|
@ -62,54 +59,6 @@ export function getCodeQLActionRepository(logger: Logger): string {
|
|||
return util.getRequiredEnvParam("GITHUB_ACTION_REPOSITORY");
|
||||
}
|
||||
|
||||
function tryGetCodeQLCliVersionForRelease(
|
||||
release,
|
||||
logger: Logger,
|
||||
): string | undefined {
|
||||
const cliVersionsFromMarkerFiles = (release.assets as Array<{ name: string }>)
|
||||
.map((asset) => asset.name.match(/cli-version-(.*)\.txt/)?.[1])
|
||||
.filter((v) => v)
|
||||
.map((v) => v as string);
|
||||
if (cliVersionsFromMarkerFiles.length > 1) {
|
||||
logger.warning(
|
||||
`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}.`,
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
return cliVersionsFromMarkerFiles[0];
|
||||
}
|
||||
|
||||
export async function tryFindCliVersionDotcomOnly(
|
||||
tagName: string,
|
||||
logger: Logger,
|
||||
): Promise<string | undefined> {
|
||||
try {
|
||||
logger.debug(
|
||||
`Fetching the GitHub Release for the CodeQL bundle tagged ${tagName}.`,
|
||||
);
|
||||
const apiClient = api.getApiClient();
|
||||
const codeQLActionRepository = getCodeQLActionRepository(logger);
|
||||
const release = await apiClient.rest.repos.getReleaseByTag({
|
||||
owner: codeQLActionRepository.split("/")[0],
|
||||
repo: codeQLActionRepository.split("/")[1],
|
||||
tag: tagName,
|
||||
});
|
||||
return tryGetCodeQLCliVersionForRelease(release.data, logger);
|
||||
} catch (e) {
|
||||
logger.debug(
|
||||
`Failed to find the CLI version for the CodeQL bundle tagged ${tagName}. ${
|
||||
wrapError(e).message
|
||||
}`,
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
async function getCodeQLBundleDownloadURL(
|
||||
tagName: string,
|
||||
apiDetails: api.GitHubApiDetails,
|
||||
|
|
@ -519,7 +468,6 @@ export const downloadCodeQL = async function (
|
|||
maybeBundleVersion: string | undefined,
|
||||
maybeCliVersion: string | undefined,
|
||||
apiDetails: api.GitHubApiDetails,
|
||||
variant: util.GitHubVariant,
|
||||
tempDir: string,
|
||||
logger: Logger,
|
||||
): Promise<{
|
||||
|
|
@ -597,18 +545,6 @@ export const downloadCodeQL = async function (
|
|||
};
|
||||
}
|
||||
|
||||
// Try to compute the CLI version for this bundle
|
||||
if (
|
||||
maybeCliVersion === undefined &&
|
||||
variant === util.GitHubVariant.DOTCOM &&
|
||||
codeqlURL.includes(`/${CODEQL_DEFAULT_ACTION_REPOSITORY}/`)
|
||||
) {
|
||||
maybeCliVersion = await tryFindCliVersionDotcomOnly(
|
||||
`codeql-bundle-${bundleVersion}`,
|
||||
logger,
|
||||
);
|
||||
}
|
||||
|
||||
logger.debug("Caching CodeQL bundle.");
|
||||
const toolcacheVersion = getCanonicalToolcacheVersion(
|
||||
maybeCliVersion,
|
||||
|
|
@ -669,14 +605,9 @@ function getCanonicalToolcacheVersion(
|
|||
if (!cliVersion?.match(/^[0-9]+\.[0-9]+\.[0-9]+$/)) {
|
||||
return convertToSemVer(bundleVersion, logger);
|
||||
}
|
||||
// If the bundle is semantically versioned, it can be looked up based on just the CLI version
|
||||
// number, so version it in the toolcache using just the CLI version number.
|
||||
if (semver.gte(cliVersion, CODEQL_VERSION_BUNDLE_SEMANTICALLY_VERSIONED)) {
|
||||
return cliVersion;
|
||||
}
|
||||
// Include both the CLI version and the bundle version in the toolcache version number. That way
|
||||
// we can find the bundle in the toolcache based on either the CLI version or the bundle version.
|
||||
return `${cliVersion}-${bundleVersion}`;
|
||||
// Bundles are now semantically versioned and can be looked up based on just the CLI version
|
||||
// number, so we can version them in the toolcache using just the CLI version number.
|
||||
return cliVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -733,7 +664,6 @@ export async function setupCodeQLBundle(
|
|||
source.bundleVersion,
|
||||
source.cliVersion,
|
||||
apiDetails,
|
||||
variant,
|
||||
tempDir,
|
||||
logger,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -155,6 +155,7 @@ async function runWrapper() {
|
|||
await util.delay(1000);
|
||||
}
|
||||
if (subprocessError) {
|
||||
// eslint-disable-next-line @typescript-eslint/only-throw-error
|
||||
throw subprocessError;
|
||||
}
|
||||
core.info(`Proxy started on ${host}:${port}`);
|
||||
|
|
|
|||
|
|
@ -443,6 +443,7 @@ export function validateSarifFileSchema(sarifFilePath: string, logger: Logger) {
|
|||
`Invalid SARIF. JSON syntax error: ${wrapError(e).message}`,
|
||||
);
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const schema = require("../src/sarif-schema-2.1.0.json") as jsonschema.Schema;
|
||||
|
||||
const result = new jsonschema.Validator().validate(sarif, schema);
|
||||
|
|
|
|||
|
|
@ -516,7 +516,7 @@ export function parseGitHubUrl(inputUrl: string): string {
|
|||
let url: URL;
|
||||
try {
|
||||
url = new URL(inputUrl);
|
||||
} catch (e) {
|
||||
} catch {
|
||||
throw new ConfigurationError(`"${originalUrl}" is not a valid URL`);
|
||||
}
|
||||
|
||||
|
|
@ -753,7 +753,7 @@ export function doesDirectoryExist(dirPath: string): boolean {
|
|||
try {
|
||||
const stats = fs.lstatSync(dirPath);
|
||||
return stats.isDirectory();
|
||||
} catch (e) {
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue