mirror of
https://github.com/github/codeql-action.git
synced 2025-12-24 08:10:06 +08:00
Add deprecation warning for merging SARIF files with non-unique categories
This commit is contained in:
52
lib/upload-lib.js
generated
52
lib/upload-lib.js
generated
@@ -73,14 +73,42 @@ function combineSarifFiles(sarifFiles, logger) {
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Checks whether all the runs in the given SARIF files were produced by CodeQL.
|
* Checks whether all the runs in the given SARIF files were produced by CodeQL.
|
||||||
* @param sarifFiles The list of SARIF files to check.
|
* @param sarifObjects The list of SARIF objects to check.
|
||||||
*/
|
*/
|
||||||
function areAllRunsProducedByCodeQL(sarifFiles) {
|
function areAllRunsProducedByCodeQL(sarifObjects) {
|
||||||
return sarifFiles.every((sarifFile) => {
|
return sarifObjects.every((sarifObject) => {
|
||||||
const sarifObject = JSON.parse(fs.readFileSync(sarifFile, "utf8"));
|
|
||||||
return sarifObject.runs?.every((run) => run.tool?.driver?.name === "CodeQL");
|
return sarifObject.runs?.every((run) => run.tool?.driver?.name === "CodeQL");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
function createRunKey(run) {
|
||||||
|
return {
|
||||||
|
name: run.tool?.driver?.name,
|
||||||
|
fullName: run.tool?.driver?.fullName,
|
||||||
|
version: run.tool?.driver?.version,
|
||||||
|
semanticVersion: run.tool?.driver?.semanticVersion,
|
||||||
|
guid: run.tool?.driver?.guid,
|
||||||
|
automationId: run?.automationDetails?.id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Checks whether all runs in the given SARIF files are unique (based on the
|
||||||
|
* criteria used by Code Scanning to determine analysis categories).
|
||||||
|
* @param sarifObjects The list of SARIF objects to check.
|
||||||
|
*/
|
||||||
|
function areAllRunsUnique(sarifObjects) {
|
||||||
|
const keys = new Set();
|
||||||
|
for (const sarifObject of sarifObjects) {
|
||||||
|
for (const run of sarifObject.runs) {
|
||||||
|
const key = JSON.stringify(createRunKey(run));
|
||||||
|
// If the key already exists, the runs are not unique.
|
||||||
|
if (keys.has(key)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
keys.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
// Takes a list of paths to sarif files and combines them together using the
|
// Takes a list of paths to sarif files and combines them together using the
|
||||||
// CLI `github merge-results` command when all SARIF files are produced by
|
// CLI `github merge-results` command when all SARIF files are produced by
|
||||||
// CodeQL. Otherwise, it will fall back to combining the files in the action.
|
// CodeQL. Otherwise, it will fall back to combining the files in the action.
|
||||||
@@ -90,8 +118,17 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo
|
|||||||
if (sarifFiles.length === 1) {
|
if (sarifFiles.length === 1) {
|
||||||
return JSON.parse(fs.readFileSync(sarifFiles[0], "utf8"));
|
return JSON.parse(fs.readFileSync(sarifFiles[0], "utf8"));
|
||||||
}
|
}
|
||||||
if (!areAllRunsProducedByCodeQL(sarifFiles)) {
|
const sarifObjects = sarifFiles.map((sarifFile) => {
|
||||||
|
return JSON.parse(fs.readFileSync(sarifFile, "utf8"));
|
||||||
|
});
|
||||||
|
if (!areAllRunsProducedByCodeQL(sarifObjects)) {
|
||||||
logger.debug("Not all SARIF files were produced by CodeQL. Merging files in the action.");
|
logger.debug("Not all SARIF files were produced by CodeQL. Merging files in the action.");
|
||||||
|
// Only give a deprecation warning when not all runs are unique
|
||||||
|
if (!areAllRunsUnique(sarifObjects) &&
|
||||||
|
!process.env.CODEQL_MERGE_SARIF_DEPRECATION_WARNING) {
|
||||||
|
logger.warning("Uploading multiple SARIF runs with the same category is deprecated and will be removed on June 4, 2025. Please update your workflow to upload a single run per category. For more information, see https://github.blog/changelog/TODO");
|
||||||
|
core.exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true");
|
||||||
|
}
|
||||||
// If not, use the naive method of combining the files.
|
// If not, use the naive method of combining the files.
|
||||||
return combineSarifFiles(sarifFiles, logger);
|
return combineSarifFiles(sarifFiles, logger);
|
||||||
}
|
}
|
||||||
@@ -119,6 +156,11 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo
|
|||||||
}
|
}
|
||||||
if (!(await codeQL.supportsFeature(tools_features_1.ToolsFeature.SarifMergeRunsFromEqualCategory))) {
|
if (!(await codeQL.supportsFeature(tools_features_1.ToolsFeature.SarifMergeRunsFromEqualCategory))) {
|
||||||
logger.warning("The CodeQL CLI does not support merging SARIF files. Merging files in the action.");
|
logger.warning("The CodeQL CLI does not support merging SARIF files. Merging files in the action.");
|
||||||
|
if (!areAllRunsUnique(sarifObjects) &&
|
||||||
|
!process.env.CODEQL_MERGE_SARIF_DEPRECATION_WARNING) {
|
||||||
|
logger.warning("Uploading multiple CodeQL runs with the same category is deprecated and will be removed on June 4, 2025. Please update your CodeQL CLI version or update your workflow to set a distinct category for each CodeQL run. For more information, see https://github.blog/changelog/TODO");
|
||||||
|
core.exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true");
|
||||||
|
}
|
||||||
return combineSarifFiles(sarifFiles, logger);
|
return combineSarifFiles(sarifFiles, logger);
|
||||||
}
|
}
|
||||||
const baseTempDir = path.resolve(tempDir, "combined-sarif");
|
const baseTempDir = path.resolve(tempDir, "combined-sarif");
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -26,6 +26,7 @@ import {
|
|||||||
getRequiredEnvParam,
|
getRequiredEnvParam,
|
||||||
GitHubVersion,
|
GitHubVersion,
|
||||||
SarifFile,
|
SarifFile,
|
||||||
|
SarifRun,
|
||||||
wrapError,
|
wrapError,
|
||||||
} from "./util";
|
} from "./util";
|
||||||
|
|
||||||
@@ -65,20 +66,60 @@ function combineSarifFiles(sarifFiles: string[], logger: Logger): SarifFile {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether all the runs in the given SARIF files were produced by CodeQL.
|
* Checks whether all the runs in the given SARIF files were produced by CodeQL.
|
||||||
* @param sarifFiles The list of SARIF files to check.
|
* @param sarifObjects The list of SARIF objects to check.
|
||||||
*/
|
*/
|
||||||
function areAllRunsProducedByCodeQL(sarifFiles: string[]): boolean {
|
function areAllRunsProducedByCodeQL(sarifObjects: SarifFile[]): boolean {
|
||||||
return sarifFiles.every((sarifFile) => {
|
return sarifObjects.every((sarifObject) => {
|
||||||
const sarifObject = JSON.parse(
|
|
||||||
fs.readFileSync(sarifFile, "utf8"),
|
|
||||||
) as SarifFile;
|
|
||||||
|
|
||||||
return sarifObject.runs?.every(
|
return sarifObject.runs?.every(
|
||||||
(run) => run.tool?.driver?.name === "CodeQL",
|
(run) => run.tool?.driver?.name === "CodeQL",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SarifRunKey = {
|
||||||
|
name: string | undefined;
|
||||||
|
fullName: string | undefined;
|
||||||
|
version: string | undefined;
|
||||||
|
semanticVersion: string | undefined;
|
||||||
|
guid: string | undefined;
|
||||||
|
automationId: string | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
function createRunKey(run: SarifRun): SarifRunKey {
|
||||||
|
return {
|
||||||
|
name: run.tool?.driver?.name,
|
||||||
|
fullName: run.tool?.driver?.fullName,
|
||||||
|
version: run.tool?.driver?.version,
|
||||||
|
semanticVersion: run.tool?.driver?.semanticVersion,
|
||||||
|
guid: run.tool?.driver?.guid,
|
||||||
|
automationId: run?.automationDetails?.id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether all runs in the given SARIF files are unique (based on the
|
||||||
|
* criteria used by Code Scanning to determine analysis categories).
|
||||||
|
* @param sarifObjects The list of SARIF objects to check.
|
||||||
|
*/
|
||||||
|
function areAllRunsUnique(sarifObjects: SarifFile[]): boolean {
|
||||||
|
const keys = new Set<string>();
|
||||||
|
|
||||||
|
for (const sarifObject of sarifObjects) {
|
||||||
|
for (const run of sarifObject.runs) {
|
||||||
|
const key = JSON.stringify(createRunKey(run));
|
||||||
|
|
||||||
|
// If the key already exists, the runs are not unique.
|
||||||
|
if (keys.has(key)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
keys.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Takes a list of paths to sarif files and combines them together using the
|
// Takes a list of paths to sarif files and combines them together using the
|
||||||
// CLI `github merge-results` command when all SARIF files are produced by
|
// CLI `github merge-results` command when all SARIF files are produced by
|
||||||
// CodeQL. Otherwise, it will fall back to combining the files in the action.
|
// CodeQL. Otherwise, it will fall back to combining the files in the action.
|
||||||
@@ -94,11 +135,26 @@ async function combineSarifFilesUsingCLI(
|
|||||||
return JSON.parse(fs.readFileSync(sarifFiles[0], "utf8")) as SarifFile;
|
return JSON.parse(fs.readFileSync(sarifFiles[0], "utf8")) as SarifFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!areAllRunsProducedByCodeQL(sarifFiles)) {
|
const sarifObjects = sarifFiles.map((sarifFile): SarifFile => {
|
||||||
|
return JSON.parse(fs.readFileSync(sarifFile, "utf8")) as SarifFile;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!areAllRunsProducedByCodeQL(sarifObjects)) {
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Not all SARIF files were produced by CodeQL. Merging files in the action.",
|
"Not all SARIF files were produced by CodeQL. Merging files in the action.",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Only give a deprecation warning when not all runs are unique
|
||||||
|
if (
|
||||||
|
!areAllRunsUnique(sarifObjects) &&
|
||||||
|
!process.env.CODEQL_MERGE_SARIF_DEPRECATION_WARNING
|
||||||
|
) {
|
||||||
|
logger.warning(
|
||||||
|
"Uploading multiple SARIF runs with the same category is deprecated and will be removed on June 4, 2025. Please update your workflow to upload a single run per category. For more information, see https://github.blog/changelog/TODO",
|
||||||
|
);
|
||||||
|
core.exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true");
|
||||||
|
}
|
||||||
|
|
||||||
// If not, use the naive method of combining the files.
|
// If not, use the naive method of combining the files.
|
||||||
return combineSarifFiles(sarifFiles, logger);
|
return combineSarifFiles(sarifFiles, logger);
|
||||||
}
|
}
|
||||||
@@ -149,6 +205,16 @@ async function combineSarifFilesUsingCLI(
|
|||||||
"The CodeQL CLI does not support merging SARIF files. Merging files in the action.",
|
"The CodeQL CLI does not support merging SARIF files. Merging files in the action.",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!areAllRunsUnique(sarifObjects) &&
|
||||||
|
!process.env.CODEQL_MERGE_SARIF_DEPRECATION_WARNING
|
||||||
|
) {
|
||||||
|
logger.warning(
|
||||||
|
"Uploading multiple CodeQL runs with the same category is deprecated and will be removed on June 4, 2025. Please update your CodeQL CLI version or update your workflow to set a distinct category for each CodeQL run. For more information, see https://github.blog/changelog/TODO",
|
||||||
|
);
|
||||||
|
core.exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true");
|
||||||
|
}
|
||||||
|
|
||||||
return combineSarifFiles(sarifFiles, logger);
|
return combineSarifFiles(sarifFiles, logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,8 +56,11 @@ export interface SarifFile {
|
|||||||
export interface SarifRun {
|
export interface SarifRun {
|
||||||
tool?: {
|
tool?: {
|
||||||
driver?: {
|
driver?: {
|
||||||
|
guid?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
fullName?: string;
|
||||||
semanticVersion?: string;
|
semanticVersion?: string;
|
||||||
|
version?: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
automationDetails?: {
|
automationDetails?: {
|
||||||
|
|||||||
Reference in New Issue
Block a user