mirror of
https://github.com/github/codeql-action.git
synced 2026-04-27 17:39:15 +00:00
Skip overlay analysis based on cached status
This commit is contained in:
@@ -19,6 +19,7 @@ import { GitVersionInfo } from "./git-utils";
|
||||
import { KnownLanguage, Language } from "./languages";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
import { CODEQL_OVERLAY_MINIMUM_VERSION, OverlayDatabaseMode } from "./overlay";
|
||||
import * as overlayStatus from "./overlay/status";
|
||||
import { parseRepositoryNwo } from "./repository";
|
||||
import {
|
||||
setupTests,
|
||||
@@ -981,6 +982,7 @@ interface OverlayDatabaseModeTestSetup {
|
||||
codeScanningConfig: configUtils.UserConfig;
|
||||
diskUsage: DiskUsage | undefined;
|
||||
memoryFlagValue: number;
|
||||
shouldSkipOverlayAnalysisDueToCachedStatus: boolean;
|
||||
}
|
||||
|
||||
const defaultOverlayDatabaseModeTestSetup: OverlayDatabaseModeTestSetup = {
|
||||
@@ -1002,6 +1004,7 @@ const defaultOverlayDatabaseModeTestSetup: OverlayDatabaseModeTestSetup = {
|
||||
numTotalBytes: 100_000_000_000,
|
||||
},
|
||||
memoryFlagValue: 6920,
|
||||
shouldSkipOverlayAnalysisDueToCachedStatus: false,
|
||||
};
|
||||
|
||||
const getOverlayDatabaseModeMacro = test.macro({
|
||||
@@ -1036,6 +1039,10 @@ const getOverlayDatabaseModeMacro = test.macro({
|
||||
|
||||
sinon.stub(util, "checkDiskUsage").resolves(setup.diskUsage);
|
||||
|
||||
sinon
|
||||
.stub(overlayStatus, "shouldSkipOverlayAnalysis")
|
||||
.resolves(setup.shouldSkipOverlayAnalysisDueToCachedStatus);
|
||||
|
||||
// Mock feature flags
|
||||
const features = createFeatures(setup.features);
|
||||
|
||||
@@ -1295,6 +1302,36 @@ test(
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
getOverlayDatabaseModeMacro,
|
||||
"No overlay-base database on default branch when cached status indicates previous failure",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
features: [Feature.OverlayAnalysis, Feature.OverlayAnalysisJavascript],
|
||||
isDefaultBranch: true,
|
||||
shouldSkipOverlayAnalysisDueToCachedStatus: true,
|
||||
},
|
||||
{
|
||||
overlayDatabaseMode: OverlayDatabaseMode.None,
|
||||
useOverlayDatabaseCaching: false,
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
getOverlayDatabaseModeMacro,
|
||||
"No overlay analysis on PR when cached status indicates previous failure",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
features: [Feature.OverlayAnalysis, Feature.OverlayAnalysisJavascript],
|
||||
isPullRequest: true,
|
||||
shouldSkipOverlayAnalysisDueToCachedStatus: true,
|
||||
},
|
||||
{
|
||||
overlayDatabaseMode: OverlayDatabaseMode.None,
|
||||
useOverlayDatabaseCaching: false,
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
getOverlayDatabaseModeMacro,
|
||||
"No overlay-base database on default branch when code-scanning feature enabled with disable-default-queries",
|
||||
|
||||
+16
-2
@@ -45,6 +45,7 @@ import {
|
||||
import { KnownLanguage, Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import { CODEQL_OVERLAY_MINIMUM_VERSION, OverlayDatabaseMode } from "./overlay";
|
||||
import { shouldSkipOverlayAnalysis } from "./overlay/status";
|
||||
import { RepositoryNwo } from "./repository";
|
||||
import { ToolsFeature } from "./tools-features";
|
||||
import { downloadTrapCaches } from "./trap-caching";
|
||||
@@ -60,6 +61,7 @@ import {
|
||||
getErrorMessage,
|
||||
isInTestMode,
|
||||
joinAtMost,
|
||||
DiskUsage,
|
||||
} from "./util";
|
||||
|
||||
export * from "./config/db-config";
|
||||
@@ -672,10 +674,10 @@ async function isOverlayAnalysisFeatureEnabled(
|
||||
* and the maximum memory CodeQL will be allowed to use.
|
||||
*/
|
||||
async function runnerSupportsOverlayAnalysis(
|
||||
diskUsage: DiskUsage | undefined,
|
||||
ramInput: string | undefined,
|
||||
logger: Logger,
|
||||
): Promise<boolean> {
|
||||
const diskUsage = await checkDiskUsage(logger);
|
||||
if (
|
||||
diskUsage === undefined ||
|
||||
diskUsage.numAvailableBytes < OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_BYTES
|
||||
@@ -762,13 +764,25 @@ export async function getOverlayDatabaseMode(
|
||||
codeScanningConfig,
|
||||
)
|
||||
) {
|
||||
const diskUsage = await checkDiskUsage(logger);
|
||||
const performResourceChecks = !(await features.getValue(
|
||||
Feature.OverlayAnalysisSkipResourceChecks,
|
||||
codeql,
|
||||
));
|
||||
if (
|
||||
diskUsage &&
|
||||
(await shouldSkipOverlayAnalysis(codeql, languages, diskUsage, logger))
|
||||
) {
|
||||
logger.info(
|
||||
`Setting overlay database mode to ${OverlayDatabaseMode.None} ` +
|
||||
"because overlay analysis previously failed with this combination of languages, " +
|
||||
"disk space, and CodeQL version. " +
|
||||
"Consider running CodeQL analysis on a larger runner.",
|
||||
);
|
||||
overlayDatabaseMode = OverlayDatabaseMode.None;
|
||||
} else if (
|
||||
performResourceChecks &&
|
||||
!(await runnerSupportsOverlayAnalysis(ramInput, logger))
|
||||
!(await runnerSupportsOverlayAnalysis(diskUsage, ramInput, logger))
|
||||
) {
|
||||
overlayDatabaseMode = OverlayDatabaseMode.None;
|
||||
} else if (isAnalyzingPullRequest()) {
|
||||
|
||||
+30
-4
@@ -34,6 +34,32 @@ export interface OverlayStatus {
|
||||
builtOverlayBaseDatabase: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether overlay analysis should be skipped, based on the cached status for the given languages and disk usage.
|
||||
*/
|
||||
export async function shouldSkipOverlayAnalysis(
|
||||
codeql: CodeQL,
|
||||
languages: string[],
|
||||
diskUsage: DiskUsage,
|
||||
logger: Logger,
|
||||
): Promise<boolean> {
|
||||
const status = await getOverlayStatus(codeql, languages, diskUsage, logger);
|
||||
if (status === undefined) {
|
||||
logger.debug("No cached overlay status found.");
|
||||
return false;
|
||||
}
|
||||
if (!status.builtOverlayBaseDatabase) {
|
||||
logger.info(
|
||||
"Cached overlay status indicates that building an overlay base database was unsuccessful, so will skip overlay analysis.",
|
||||
);
|
||||
return true;
|
||||
}
|
||||
logger.debug(
|
||||
"Cached overlay status indicates that building an overlay base database was successful.",
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve overlay status from the Actions cache, if available.
|
||||
*
|
||||
@@ -60,17 +86,17 @@ export async function getOverlayStatus(
|
||||
MAX_CACHE_OPERATION_MS,
|
||||
actionsCache.restoreCache([statusFile], cacheKey),
|
||||
() => {
|
||||
logger.info("Timed out restoring overlay status from cache");
|
||||
logger.info("Timed out restoring overlay status from cache.");
|
||||
},
|
||||
);
|
||||
if (foundKey === undefined) {
|
||||
logger.debug("No overlay status found in Actions cache");
|
||||
logger.debug("No overlay status found in Actions cache.");
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!fs.existsSync(statusFile)) {
|
||||
logger.debug(
|
||||
"Overlay status cache entry found but status file is missing",
|
||||
"Overlay status cache entry found but status file is missing.",
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
@@ -114,7 +140,7 @@ export async function saveOverlayStatus(
|
||||
() => {},
|
||||
);
|
||||
if (cacheId === undefined) {
|
||||
logger.warning("Timed out saving overlay status to cache");
|
||||
logger.warning("Timed out saving overlay status to cache.");
|
||||
return false;
|
||||
}
|
||||
logger.info(`Saved overlay status to Actions cache with key ${cacheKey}`);
|
||||
|
||||
Reference in New Issue
Block a user