mirror of
https://github.com/github/codeql-action.git
synced 2026-05-07 14:20:19 +00:00
Consume precomputed diff ranges in analyze and avoid getting them from the API.
This commit is contained in:
Generated
+19
-169
@@ -90112,29 +90112,6 @@ var persistInputs = function() {
|
||||
);
|
||||
core4.saveState(persistedInputsKey, JSON.stringify(inputEnvironmentVariables));
|
||||
};
|
||||
function getPullRequestBranches() {
|
||||
const pullRequest = github.context.payload.pull_request;
|
||||
if (pullRequest) {
|
||||
return {
|
||||
base: pullRequest.base.ref,
|
||||
// We use the head label instead of the head ref here, because the head
|
||||
// ref lacks owner information and by itself does not uniquely identify
|
||||
// the head branch (which may be in a forked repository).
|
||||
head: pullRequest.head.label
|
||||
};
|
||||
}
|
||||
const codeScanningRef = process.env.CODE_SCANNING_REF;
|
||||
const codeScanningBaseBranch = process.env.CODE_SCANNING_BASE_BRANCH;
|
||||
if (codeScanningRef && codeScanningBaseBranch) {
|
||||
return {
|
||||
base: codeScanningBaseBranch,
|
||||
// PR analysis under Default Setup analyzes the PR head commit instead of
|
||||
// the merge commit, so we can use the provided ref directly.
|
||||
head: codeScanningRef
|
||||
};
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
var qualityCategoryMapping = {
|
||||
"c#": "csharp",
|
||||
cpp: "c-cpp",
|
||||
@@ -91534,34 +91511,9 @@ var GitHubFeatureFlags = class {
|
||||
};
|
||||
|
||||
// src/diff-informed-analysis-utils.ts
|
||||
async function getDiffInformedAnalysisBranches(codeql, features, logger) {
|
||||
if (!await features.getValue("diff_informed_queries" /* DiffInformedQueries */, codeql)) {
|
||||
return void 0;
|
||||
}
|
||||
const gitHubVersion = await getGitHubVersion();
|
||||
if (gitHubVersion.type === 1 /* GHES */ && satisfiesGHESVersion(gitHubVersion.version, "<3.19", true)) {
|
||||
return void 0;
|
||||
}
|
||||
const branches = getPullRequestBranches();
|
||||
if (!branches) {
|
||||
logger.info(
|
||||
"Not performing diff-informed analysis because we are not analyzing a pull request."
|
||||
);
|
||||
}
|
||||
return branches;
|
||||
}
|
||||
function getDiffRangesJsonFilePath() {
|
||||
return path9.join(getTemporaryDirectory(), "pr-diff-range.json");
|
||||
}
|
||||
function writeDiffRangesJsonFile(logger, ranges) {
|
||||
const jsonContents = JSON.stringify(ranges, null, 2);
|
||||
const jsonFilePath = getDiffRangesJsonFilePath();
|
||||
fs8.writeFileSync(jsonFilePath, jsonContents);
|
||||
logger.debug(
|
||||
`Wrote pr-diff-range JSON file to ${jsonFilePath}:
|
||||
${jsonContents}`
|
||||
);
|
||||
}
|
||||
function readDiffRangesJsonFile(logger) {
|
||||
const jsonFilePath = getDiffRangesJsonFilePath();
|
||||
if (!fs8.existsSync(jsonFilePath)) {
|
||||
@@ -91575,117 +91527,6 @@ ${jsonContents}`
|
||||
);
|
||||
return JSON.parse(jsonContents);
|
||||
}
|
||||
async function getPullRequestEditedDiffRanges(branches, logger) {
|
||||
const fileDiffs = await getFileDiffsWithBasehead(branches, logger);
|
||||
if (fileDiffs === void 0) {
|
||||
return void 0;
|
||||
}
|
||||
if (fileDiffs.length >= 300) {
|
||||
logger.warning(
|
||||
`Cannot retrieve the full diff because there are too many (${fileDiffs.length}) changed files in the pull request.`
|
||||
);
|
||||
return void 0;
|
||||
}
|
||||
const results = [];
|
||||
for (const filediff of fileDiffs) {
|
||||
const diffRanges = getDiffRanges(filediff, logger);
|
||||
if (diffRanges === void 0) {
|
||||
return void 0;
|
||||
}
|
||||
results.push(...diffRanges);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
async function getFileDiffsWithBasehead(branches, logger) {
|
||||
const repositoryNwo = getRepositoryNwoFromEnv(
|
||||
"CODE_SCANNING_REPOSITORY",
|
||||
"GITHUB_REPOSITORY"
|
||||
);
|
||||
const basehead = `${branches.base}...${branches.head}`;
|
||||
try {
|
||||
const response = await getApiClient().rest.repos.compareCommitsWithBasehead(
|
||||
{
|
||||
owner: repositoryNwo.owner,
|
||||
repo: repositoryNwo.repo,
|
||||
basehead,
|
||||
per_page: 1
|
||||
}
|
||||
);
|
||||
logger.debug(
|
||||
`Response from compareCommitsWithBasehead(${basehead}):
|
||||
${JSON.stringify(response, null, 2)}`
|
||||
);
|
||||
return response.data.files;
|
||||
} catch (error2) {
|
||||
if (error2.status) {
|
||||
logger.warning(`Error retrieving diff ${basehead}: ${error2.message}`);
|
||||
logger.debug(
|
||||
`Error running compareCommitsWithBasehead(${basehead}):
|
||||
Request: ${JSON.stringify(error2.request, null, 2)}
|
||||
Error Response: ${JSON.stringify(error2.response, null, 2)}`
|
||||
);
|
||||
return void 0;
|
||||
} else {
|
||||
throw error2;
|
||||
}
|
||||
}
|
||||
}
|
||||
function getDiffRanges(fileDiff, logger) {
|
||||
const filename = path9.join(getRequiredInput("checkout_path"), fileDiff.filename).replaceAll(path9.sep, "/");
|
||||
if (fileDiff.patch === void 0) {
|
||||
if (fileDiff.changes === 0) {
|
||||
return [];
|
||||
}
|
||||
return [
|
||||
{
|
||||
path: filename,
|
||||
startLine: 0,
|
||||
endLine: 0
|
||||
}
|
||||
];
|
||||
}
|
||||
let currentLine = 0;
|
||||
let additionRangeStartLine = void 0;
|
||||
const diffRanges = [];
|
||||
const diffLines = fileDiff.patch.split("\n");
|
||||
diffLines.push(" ");
|
||||
for (const diffLine of diffLines) {
|
||||
if (diffLine.startsWith("-")) {
|
||||
continue;
|
||||
}
|
||||
if (diffLine.startsWith("+")) {
|
||||
if (additionRangeStartLine === void 0) {
|
||||
additionRangeStartLine = currentLine;
|
||||
}
|
||||
currentLine++;
|
||||
continue;
|
||||
}
|
||||
if (additionRangeStartLine !== void 0) {
|
||||
diffRanges.push({
|
||||
path: filename,
|
||||
startLine: additionRangeStartLine,
|
||||
endLine: currentLine - 1
|
||||
});
|
||||
additionRangeStartLine = void 0;
|
||||
}
|
||||
if (diffLine.startsWith("@@ ")) {
|
||||
const match = diffLine.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/);
|
||||
if (match === null) {
|
||||
logger.warning(
|
||||
`Cannot parse diff hunk header for ${fileDiff.filename}: ${diffLine}`
|
||||
);
|
||||
return void 0;
|
||||
}
|
||||
currentLine = parseInt(match[1], 10);
|
||||
continue;
|
||||
}
|
||||
if (diffLine.startsWith(" ")) {
|
||||
currentLine++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return diffRanges;
|
||||
}
|
||||
|
||||
// src/trap-caching.ts
|
||||
var actionsCache2 = __toESM(require_cache3());
|
||||
@@ -93747,14 +93588,29 @@ async function finalizeDatabaseCreation(codeql, config, threadsFlag, memoryFlag,
|
||||
trap_import_duration_ms: Math.round(trapImportTime)
|
||||
};
|
||||
}
|
||||
async function setupDiffInformedQueryRun(branches, logger) {
|
||||
async function setupDiffInformedQueryRun(logger) {
|
||||
return await withGroupAsync(
|
||||
"Generating diff range extension pack",
|
||||
async () => {
|
||||
let diffRanges;
|
||||
try {
|
||||
diffRanges = readDiffRangesJsonFile(logger);
|
||||
} catch (e) {
|
||||
logger.debug(
|
||||
`Failed to read precomputed diff ranges: ${getErrorMessage(e)}`
|
||||
);
|
||||
diffRanges = void 0;
|
||||
}
|
||||
if (diffRanges === void 0) {
|
||||
logger.info(
|
||||
"No precomputed diff ranges found; skipping diff-informed analysis stage."
|
||||
);
|
||||
return void 0;
|
||||
}
|
||||
const fileCount = new Set(diffRanges.filter((r) => r.path).map((r) => r.path)).size;
|
||||
logger.info(
|
||||
`Calculating diff ranges for ${branches.base}...${branches.head}`
|
||||
`Using precomputed diff ranges (${diffRanges.length} ranges across ${fileCount} files).`
|
||||
);
|
||||
const diffRanges = await getPullRequestEditedDiffRanges(branches, logger);
|
||||
const packDir = writeDiffRangeDataExtensionPack(logger, diffRanges);
|
||||
if (packDir === void 0) {
|
||||
logger.warning(
|
||||
@@ -93817,7 +93673,6 @@ extensions:
|
||||
`Wrote pr-diff-range extension pack to ${extensionFilePath}:
|
||||
${extensionContents}`
|
||||
);
|
||||
writeDiffRangesJsonFile(logger, ranges);
|
||||
return diffRangeDir;
|
||||
}
|
||||
var defaultSuites = /* @__PURE__ */ new Set([
|
||||
@@ -96206,12 +96061,7 @@ async function run() {
|
||||
getOptionalInput("ram") || process.env["CODEQL_RAM"],
|
||||
logger
|
||||
);
|
||||
const branches = await getDiffInformedAnalysisBranches(
|
||||
codeql,
|
||||
features,
|
||||
logger
|
||||
);
|
||||
const diffRangePackDir = branches ? await setupDiffInformedQueryRun(branches, logger) : void 0;
|
||||
const diffRangePackDir = await setupDiffInformedQueryRun(logger);
|
||||
await warnIfGoInstalledAfterInit(config, logger);
|
||||
await runAutobuildIfLegacyGoWorkflow(config, logger);
|
||||
dbCreationTimings = await runFinalize(
|
||||
|
||||
Generated
-6
@@ -91255,16 +91255,10 @@ async function computeAndPersistDiffRangesEarly(codeql, features, logger) {
|
||||
logger
|
||||
);
|
||||
if (!branches) {
|
||||
logger.debug(
|
||||
"Diff-informed analysis not enabled (feature flag or context); skipping diff range computation."
|
||||
);
|
||||
return;
|
||||
}
|
||||
const ranges = await getPullRequestEditedDiffRanges(branches, logger);
|
||||
if (ranges === void 0) {
|
||||
logger.info(
|
||||
"Diff ranges unavailable (API limits, truncation, or error); will fall back to analyze-time computation."
|
||||
);
|
||||
return;
|
||||
}
|
||||
writeDiffRangesJsonFile(logger, ranges);
|
||||
|
||||
@@ -30,7 +30,6 @@ import {
|
||||
DependencyCacheUploadStatusReport,
|
||||
uploadDependencyCaches,
|
||||
} from "./dependency-caching";
|
||||
import { getDiffInformedAnalysisBranches } from "./diff-informed-analysis-utils";
|
||||
import { EnvVar } from "./environment";
|
||||
import { Feature, Features } from "./feature-flags";
|
||||
import { KnownLanguage } from "./languages";
|
||||
@@ -299,14 +298,8 @@ async function run() {
|
||||
logger,
|
||||
);
|
||||
|
||||
const branches = await getDiffInformedAnalysisBranches(
|
||||
codeql,
|
||||
features,
|
||||
logger,
|
||||
);
|
||||
const diffRangePackDir = branches
|
||||
? await setupDiffInformedQueryRun(branches, logger)
|
||||
: undefined;
|
||||
// Setup diff informed analysis if needed (based on whether init created the file)
|
||||
const diffRangePackDir = await setupDiffInformedQueryRun(logger);
|
||||
|
||||
await warnIfGoInstalledAfterInit(config, logger);
|
||||
await runAutobuildIfLegacyGoWorkflow(config, logger);
|
||||
|
||||
+24
-13
@@ -6,7 +6,7 @@ import * as io from "@actions/io";
|
||||
import * as del from "del";
|
||||
import * as yaml from "js-yaml";
|
||||
|
||||
import { getTemporaryDirectory, PullRequestBranches } from "./actions-util";
|
||||
import { getTemporaryDirectory } from "./actions-util";
|
||||
import * as analyses from "./analyses";
|
||||
// (getApiClient import removed; no longer needed after diff refactor)
|
||||
import { setupCppAutobuild } from "./autobuild";
|
||||
@@ -14,11 +14,7 @@ import { type CodeQL } from "./codeql";
|
||||
import * as configUtils from "./config-utils";
|
||||
import { getJavaTempDependencyDir } from "./dependency-caching";
|
||||
import { addDiagnostic, makeDiagnostic } from "./diagnostics";
|
||||
import {
|
||||
DiffThunkRange,
|
||||
writeDiffRangesJsonFile,
|
||||
getPullRequestEditedDiffRanges,
|
||||
} from "./diff-informed-analysis-utils";
|
||||
import { DiffThunkRange, readDiffRangesJsonFile } from "./diff-informed-analysis-utils";
|
||||
import { EnvVar } from "./environment";
|
||||
import { FeatureEnablement, Feature } from "./feature-flags";
|
||||
import { KnownLanguage, Language } from "./languages";
|
||||
@@ -284,17 +280,35 @@ async function finalizeDatabaseCreation(
|
||||
* the diff range information, or `undefined` if the feature is disabled.
|
||||
*/
|
||||
export async function setupDiffInformedQueryRun(
|
||||
branches: PullRequestBranches,
|
||||
logger: Logger,
|
||||
): Promise<string | undefined> {
|
||||
return await withGroupAsync(
|
||||
"Generating diff range extension pack",
|
||||
async () => {
|
||||
// Only use precomputed diff ranges; never recompute here.
|
||||
let diffRanges: DiffThunkRange[] | undefined;
|
||||
try {
|
||||
diffRanges = readDiffRangesJsonFile(logger);
|
||||
} catch (e) {
|
||||
logger.debug(
|
||||
`Failed to read precomputed diff ranges: ${util.getErrorMessage(e)}`,
|
||||
);
|
||||
diffRanges = undefined;
|
||||
}
|
||||
|
||||
if (diffRanges === undefined) {
|
||||
logger.info(
|
||||
"No precomputed diff ranges found; skipping diff-informed analysis stage.",
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const fileCount = new Set(diffRanges.filter((r) => r.path).map((r) => r.path)).size;
|
||||
logger.info(
|
||||
`Calculating diff ranges for ${branches.base}...${branches.head}`,
|
||||
`Using precomputed diff ranges (${diffRanges.length} ranges across ${fileCount} files).`,
|
||||
);
|
||||
const diffRanges = await getPullRequestEditedDiffRanges(branches, logger);
|
||||
const packDir = writeDiffRangeDataExtensionPack(logger, diffRanges);
|
||||
|
||||
const packDir = writeDiffRangeDataExtensionPack(logger, diffRanges);
|
||||
if (packDir === undefined) {
|
||||
logger.warning(
|
||||
"Cannot create diff range extension pack for diff-informed queries; " +
|
||||
@@ -392,9 +406,6 @@ extensions:
|
||||
`Wrote pr-diff-range extension pack to ${extensionFilePath}:\n${extensionContents}`,
|
||||
);
|
||||
|
||||
// Write the diff ranges to a JSON file, for action-side alert filtering by the
|
||||
// upload-lib module.
|
||||
writeDiffRangesJsonFile(logger, ranges);
|
||||
|
||||
return diffRangeDir;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user