Merge branch 'main' into update-bundle/codeql-bundle-v2.21.3
This commit is contained in:
commit
e93b90025f
27 changed files with 166 additions and 102 deletions
|
|
@ -26,7 +26,6 @@ import { getRepositoryNwoFromEnv } from "./repository";
|
|||
import { DatabaseCreationTimings, EventReport } from "./status-report";
|
||||
import { ToolsFeature } from "./tools-features";
|
||||
import { endTracingForCluster } from "./tracer-config";
|
||||
import { validateSarifFileSchema } from "./upload-lib";
|
||||
import * as util from "./util";
|
||||
import { BuildMode } from "./util";
|
||||
|
||||
|
|
@ -630,7 +629,7 @@ export async function runQueries(
|
|||
logger.info(analysisSummary);
|
||||
|
||||
if (await features.getValue(Feature.QaTelemetryEnabled)) {
|
||||
const perQueryAlertCounts = getPerQueryAlertCounts(sarifFile, logger);
|
||||
const perQueryAlertCounts = getPerQueryAlertCounts(sarifFile);
|
||||
|
||||
const perQueryAlertCountEventReport: EventReport = {
|
||||
event: "codeql database interpret-results",
|
||||
|
|
@ -682,11 +681,7 @@ export async function runQueries(
|
|||
}
|
||||
|
||||
/** Get an object with all queries and their counts parsed from a SARIF file path. */
|
||||
function getPerQueryAlertCounts(
|
||||
sarifPath: string,
|
||||
log: Logger,
|
||||
): Record<string, number> {
|
||||
validateSarifFileSchema(sarifPath, log);
|
||||
function getPerQueryAlertCounts(sarifPath: string): Record<string, number> {
|
||||
const sarifObject = JSON.parse(
|
||||
fs.readFileSync(sarifPath, "utf8"),
|
||||
) as util.SarifFile;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"maximumVersion": "3.17", "minimumVersion": "3.12"}
|
||||
{"maximumVersion": "3.17", "minimumVersion": "3.13"}
|
||||
|
|
|
|||
|
|
@ -285,17 +285,17 @@ const CODEQL_MINIMUM_VERSION = "2.15.5";
|
|||
/**
|
||||
* This version will shortly become the oldest version of CodeQL that the Action will run with.
|
||||
*/
|
||||
const CODEQL_NEXT_MINIMUM_VERSION = "2.15.5";
|
||||
const CODEQL_NEXT_MINIMUM_VERSION = "2.16.6";
|
||||
|
||||
/**
|
||||
* This is the version of GHES that was most recently deprecated.
|
||||
*/
|
||||
const GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.11";
|
||||
const GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.12";
|
||||
|
||||
/**
|
||||
* This is the deprecation date for the version of GHES that was most recently deprecated.
|
||||
*/
|
||||
const GHES_MOST_RECENT_DEPRECATION_DATE = "2024-12-19";
|
||||
const GHES_MOST_RECENT_DEPRECATION_DATE = "2025-04-03";
|
||||
|
||||
/** The CLI verbosity level to use for extraction in debug mode. */
|
||||
const EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++";
|
||||
|
|
|
|||
|
|
@ -547,7 +547,8 @@ async function run() {
|
|||
);
|
||||
core.exportVariable(
|
||||
"CODEQL_THREADS",
|
||||
getThreadsFlagValue(getOptionalInput("threads"), logger).toString(),
|
||||
process.env["CODEQL_THREADS"] ||
|
||||
getThreadsFlagValue(getOptionalInput("threads"), logger).toString(),
|
||||
);
|
||||
|
||||
// Disable Kotlin extractor if feature flag set
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import {
|
|||
assertNever,
|
||||
BuildMode,
|
||||
getErrorMessage,
|
||||
getTestingEnvironment,
|
||||
} from "./util";
|
||||
|
||||
export enum ActionName {
|
||||
|
|
@ -277,10 +278,10 @@ export async function createStatusReportBase(
|
|||
const runnerOs = getRequiredEnvParam("RUNNER_OS");
|
||||
const codeQlCliVersion = getCachedCodeQlVersion();
|
||||
const actionRef = process.env["GITHUB_ACTION_REF"] || "";
|
||||
const testingEnvironment = process.env[EnvVar.TESTING_ENVIRONMENT] || "";
|
||||
const testingEnvironment = getTestingEnvironment();
|
||||
// re-export the testing environment variable so that it is available to subsequent steps,
|
||||
// even if it was only set for this step
|
||||
if (testingEnvironment !== "") {
|
||||
if (testingEnvironment) {
|
||||
core.exportVariable(EnvVar.TESTING_ENVIRONMENT, testingEnvironment);
|
||||
}
|
||||
const isSteadyStateDefaultSetupRun =
|
||||
|
|
@ -303,7 +304,7 @@ export async function createStatusReportBase(
|
|||
started_at: workflowStartedAt,
|
||||
status,
|
||||
steady_state_default_setup: isSteadyStateDefaultSetupRun,
|
||||
testing_environment: testingEnvironment,
|
||||
testing_environment: testingEnvironment || "",
|
||||
workflow_name: workflowName,
|
||||
workflow_run_attempt: workflowRunAttempt,
|
||||
workflow_run_id: workflowRunID,
|
||||
|
|
|
|||
|
|
@ -17,14 +17,22 @@ test.beforeEach(() => {
|
|||
test("validateSarifFileSchema - valid", (t) => {
|
||||
const inputFile = `${__dirname}/../src/testdata/valid-sarif.sarif`;
|
||||
t.notThrows(() =>
|
||||
uploadLib.validateSarifFileSchema(inputFile, getRunnerLogger(true)),
|
||||
uploadLib.validateSarifFileSchema(
|
||||
uploadLib.readSarifFile(inputFile),
|
||||
inputFile,
|
||||
getRunnerLogger(true),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test("validateSarifFileSchema - invalid", (t) => {
|
||||
const inputFile = `${__dirname}/../src/testdata/invalid-sarif.sarif`;
|
||||
t.throws(() =>
|
||||
uploadLib.validateSarifFileSchema(inputFile, getRunnerLogger(true)),
|
||||
uploadLib.validateSarifFileSchema(
|
||||
uploadLib.readSarifFile(inputFile),
|
||||
inputFile,
|
||||
getRunnerLogger(true),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
|
|
@ -314,7 +322,11 @@ test("accept results with invalid artifactLocation.uri value", (t) => {
|
|||
} as Logger;
|
||||
|
||||
const sarifFile = `${__dirname}/../src/testdata/with-invalid-uri.sarif`;
|
||||
uploadLib.validateSarifFileSchema(sarifFile, mockLogger);
|
||||
uploadLib.validateSarifFileSchema(
|
||||
uploadLib.readSarifFile(sarifFile),
|
||||
sarifFile,
|
||||
mockLogger,
|
||||
);
|
||||
|
||||
t.deepEqual(loggedMessages.length, 3);
|
||||
t.deepEqual(
|
||||
|
|
|
|||
|
|
@ -434,18 +434,35 @@ function countResultsInSarif(sarif: string): number {
|
|||
return numResults;
|
||||
}
|
||||
|
||||
// Validates that the given file path refers to a valid SARIF file.
|
||||
// Throws an error if the file is invalid.
|
||||
export function validateSarifFileSchema(sarifFilePath: string, logger: Logger) {
|
||||
logger.info(`Validating ${sarifFilePath}`);
|
||||
let sarif;
|
||||
export function readSarifFile(sarifFilePath: string): SarifFile {
|
||||
try {
|
||||
sarif = JSON.parse(fs.readFileSync(sarifFilePath, "utf8")) as SarifFile;
|
||||
return JSON.parse(fs.readFileSync(sarifFilePath, "utf8")) as SarifFile;
|
||||
} catch (e) {
|
||||
throw new InvalidSarifUploadError(
|
||||
`Invalid SARIF. JSON syntax error: ${getErrorMessage(e)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Validates the given SARIF object and throws an error if the SARIF object is invalid.
|
||||
// The file path is only used in error messages to improve clarity.
|
||||
export function validateSarifFileSchema(
|
||||
sarif: SarifFile,
|
||||
sarifFilePath: string,
|
||||
logger: Logger,
|
||||
) {
|
||||
if (
|
||||
areAllRunsProducedByCodeQL([sarif]) &&
|
||||
// We want to validate CodeQL SARIF in testing environments.
|
||||
!util.getTestingEnvironment()
|
||||
) {
|
||||
logger.debug(
|
||||
`Skipping SARIF schema validation for ${sarifFilePath} as all runs are produced by CodeQL.`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info(`Validating ${sarifFilePath}`);
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const schema = require("../src/sarif-schema-2.1.0.json") as jsonschema.Schema;
|
||||
|
||||
|
|
@ -551,41 +568,44 @@ export function buildPayload(
|
|||
}
|
||||
|
||||
/**
|
||||
* Uploads a single SARIF file or a directory of SARIF files depending on what `sarifPath` refers
|
||||
* Uploads a single SARIF file or a directory of SARIF files depending on what `inputSarifPath` refers
|
||||
* to.
|
||||
*/
|
||||
export async function uploadFiles(
|
||||
sarifPath: string,
|
||||
inputSarifPath: string,
|
||||
checkoutPath: string,
|
||||
category: string | undefined,
|
||||
features: FeatureEnablement,
|
||||
logger: Logger,
|
||||
): Promise<UploadResult> {
|
||||
const sarifFiles = getSarifFilePaths(sarifPath);
|
||||
const sarifPaths = getSarifFilePaths(inputSarifPath);
|
||||
|
||||
logger.startGroup("Uploading results");
|
||||
logger.info(`Processing sarif files: ${JSON.stringify(sarifFiles)}`);
|
||||
logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`);
|
||||
|
||||
const gitHubVersion = await getGitHubVersion();
|
||||
|
||||
try {
|
||||
let sarif: SarifFile;
|
||||
|
||||
if (sarifPaths.length > 1) {
|
||||
// Validate that the files we were asked to upload are all valid SARIF files
|
||||
for (const file of sarifFiles) {
|
||||
validateSarifFileSchema(file, logger);
|
||||
for (const sarifPath of sarifPaths) {
|
||||
const parsedSarif = readSarifFile(sarifPath);
|
||||
validateSarifFileSchema(parsedSarif, sarifPath, logger);
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof SyntaxError) {
|
||||
throw new InvalidSarifUploadError(e.message);
|
||||
}
|
||||
throw e;
|
||||
|
||||
sarif = await combineSarifFilesUsingCLI(
|
||||
sarifPaths,
|
||||
gitHubVersion,
|
||||
features,
|
||||
logger,
|
||||
);
|
||||
} else {
|
||||
const sarifPath = sarifPaths[0];
|
||||
sarif = readSarifFile(sarifPath);
|
||||
validateSarifFileSchema(sarif, sarifPath, logger);
|
||||
}
|
||||
|
||||
let sarif = await combineSarifFilesUsingCLI(
|
||||
sarifFiles,
|
||||
gitHubVersion,
|
||||
features,
|
||||
logger,
|
||||
);
|
||||
sarif = filterAlertsByDiffRange(logger, sarif);
|
||||
sarif = await fingerprints.addFingerprints(sarif, checkoutPath, logger);
|
||||
|
||||
|
|
|
|||
19
src/util.ts
19
src/util.ts
|
|
@ -750,8 +750,8 @@ export function isGoodVersion(versionSpec: string) {
|
|||
return !BROKEN_VERSIONS.includes(versionSpec);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns whether we are in test mode.
|
||||
/**
|
||||
* Returns whether we are in test mode. This is used by CodeQL Action PR checks.
|
||||
*
|
||||
* In test mode, we don't upload SARIF results or status reports to the GitHub API.
|
||||
*/
|
||||
|
|
@ -759,7 +759,20 @@ export function isInTestMode(): boolean {
|
|||
return process.env[EnvVar.TEST_MODE] === "true";
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Get the testing environment.
|
||||
*
|
||||
* This is set if the CodeQL Action is running in a non-production environment.
|
||||
*/
|
||||
export function getTestingEnvironment(): string | undefined {
|
||||
const testingEnvironment = process.env[EnvVar.TESTING_ENVIRONMENT] || "";
|
||||
if (testingEnvironment === "") {
|
||||
return undefined;
|
||||
}
|
||||
return testingEnvironment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the path in the argument represents an existing directory.
|
||||
*/
|
||||
export function doesDirectoryExist(dirPath: string): boolean {
|
||||
|
|
|
|||
|
|
@ -7,9 +7,12 @@ import * as yaml from "js-yaml";
|
|||
|
||||
import * as api from "./api-client";
|
||||
import { CodeQL } from "./codeql";
|
||||
import { EnvVar } from "./environment";
|
||||
import { Logger } from "./logging";
|
||||
import { getRequiredEnvParam, isInTestMode } from "./util";
|
||||
import {
|
||||
getRequiredEnvParam,
|
||||
getTestingEnvironment,
|
||||
isInTestMode,
|
||||
} from "./util";
|
||||
|
||||
export interface WorkflowJobStep {
|
||||
name?: string;
|
||||
|
|
@ -358,10 +361,7 @@ function getInputOrThrow(
|
|||
* This allows us to test workflow parsing functionality as a CodeQL Action PR check.
|
||||
*/
|
||||
function getAnalyzeActionName() {
|
||||
if (
|
||||
isInTestMode() ||
|
||||
process.env[EnvVar.TESTING_ENVIRONMENT] === "codeql-action-pr-checks"
|
||||
) {
|
||||
if (isInTestMode() || getTestingEnvironment() === "codeql-action-pr-checks") {
|
||||
return "./analyze";
|
||||
} else {
|
||||
return "github/codeql-action/analyze";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue