Skip to content

Commit dae1626

Browse files
committed
Filter alerts by pr-diff-range JSON file
1 parent 77bc2a5 commit dae1626

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

src/diff-filtering-utils.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,18 @@ export function writeDiffRangesJsonFile(
2525
`Wrote pr-diff-range JSON file to ${jsonFilePath}:\n${jsonContents}`,
2626
);
2727
}
28+
29+
export function readDiffRangesJsonFile(
30+
logger: Logger,
31+
): DiffThunkRange[] | undefined {
32+
const jsonFilePath = getDiffRangesJsonFilePath();
33+
if (!fs.existsSync(jsonFilePath)) {
34+
logger.debug(`Diff ranges JSON file does not exist at ${jsonFilePath}`);
35+
return undefined;
36+
}
37+
const jsonContents = fs.readFileSync(jsonFilePath, "utf8");
38+
logger.debug(
39+
`Read pr-diff-range JSON file from ${jsonFilePath}:\n${jsonContents}`,
40+
);
41+
return JSON.parse(jsonContents) as DiffThunkRange[];
42+
}

src/upload-lib.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import * as api from "./api-client";
1414
import { getGitHubVersion, wrapApiConfigurationError } from "./api-client";
1515
import { CodeQL, getCodeQL } from "./codeql";
1616
import { getConfig } from "./config-utils";
17+
import { readDiffRangesJsonFile } from "./diff-filtering-utils";
1718
import { EnvVar } from "./environment";
1819
import { FeatureEnablement } from "./feature-flags";
1920
import * as fingerprints from "./fingerprints";
@@ -578,6 +579,7 @@ export async function uploadFiles(
578579
features,
579580
logger,
580581
);
582+
sarif = filterAlertsByDiffRange(logger, sarif);
581583
sarif = await fingerprints.addFingerprints(sarif, checkoutPath, logger);
582584

583585
const analysisKey = await api.getAnalysisKey();
@@ -848,3 +850,50 @@ export class InvalidSarifUploadError extends Error {
848850
super(message);
849851
}
850852
}
853+
854+
function filterAlertsByDiffRange(logger: Logger, sarif: SarifFile): SarifFile {
855+
const diffRanges = readDiffRangesJsonFile(logger);
856+
if (!diffRanges?.length) {
857+
return sarif;
858+
}
859+
860+
const checkoutPath = actionsUtil.getRequiredInput("checkout_path");
861+
862+
for (const run of sarif.runs) {
863+
if (run.results) {
864+
run.results = run.results.filter((result) => {
865+
const locations = [
866+
...(result.locations || []).map((loc) => loc.physicalLocation),
867+
...(result.relatedLocations || []).map((loc) => loc.physicalLocation),
868+
];
869+
870+
return locations.some((physicalLocation) => {
871+
const locationUri = physicalLocation?.artifactLocation?.uri;
872+
const locationStartLine = physicalLocation?.region?.startLine;
873+
if (!locationUri || locationStartLine === undefined) {
874+
return false;
875+
}
876+
// CodeQL always uses forward slashes as the path separator, so on Windows we
877+
// need to replace any backslashes with forward slashes.
878+
const locationPath = path
879+
.join(checkoutPath, locationUri)
880+
.replaceAll(path.sep, "/");
881+
// Alert filtering here replicates the same behavior as the restrictAlertsTo
882+
// extensible predicate in CodeQL. See the restrictAlertsTo documentation
883+
// https://codeql.github.com/codeql-standard-libraries/csharp/codeql/util/AlertFiltering.qll/predicate.AlertFiltering$restrictAlertsTo.3.html
884+
// for more details, such as why the filtering applies only to the first line
885+
// of an alert location.
886+
return diffRanges.some(
887+
(range) =>
888+
range.path === locationPath &&
889+
((range.startLine <= locationStartLine &&
890+
range.endLine >= locationStartLine) ||
891+
(range.startLine === 0 && range.endLine === 0)),
892+
);
893+
});
894+
});
895+
}
896+
}
897+
898+
return sarif;
899+
}

src/util.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,16 @@ export interface SarifResult {
9696
};
9797
};
9898
}>;
99+
relatedLocations?: Array<{
100+
physicalLocation: {
101+
artifactLocation: {
102+
uri: string;
103+
};
104+
region?: {
105+
startLine?: number;
106+
};
107+
};
108+
}>;
99109
partialFingerprints: {
100110
primaryLocationLineHash?: string;
101111
};

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy