Refactor getOverlayDatabaseMode and add new disablement reason

This commit is contained in:
Henry Mercer
2026-03-04 13:53:12 +01:00
parent 776fd85f8c
commit b371ccd8ea
4 changed files with 278 additions and 177 deletions
+110 -73
View File
@@ -106388,9 +106388,12 @@ var OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES = {
rust: "overlay_analysis_code_scanning_rust" /* OverlayAnalysisCodeScanningRust */,
swift: "overlay_analysis_code_scanning_swift" /* OverlayAnalysisCodeScanningSwift */
};
async function getOverlayFeatureDisabledReason(features, codeql, languages, codeScanningConfig) {
async function checkOverlayAnalysisFeatureEnabled(features, codeql, languages, codeScanningConfig) {
if (!await features.getValue("overlay_analysis" /* OverlayAnalysis */, codeql)) {
return "overall-feature-not-enabled" /* OverallFeatureNotEnabled */;
return {
enabled: false,
reason: "overall-feature-not-enabled" /* OverallFeatureNotEnabled */
};
}
let enableForCodeScanningOnly = false;
for (const language of languages) {
@@ -106403,15 +106406,18 @@ async function getOverlayFeatureDisabledReason(features, codeql, languages, code
enableForCodeScanningOnly = true;
continue;
}
return "language-not-enabled" /* LanguageNotEnabled */;
return { enabled: false, reason: "language-not-enabled" /* LanguageNotEnabled */ };
}
if (enableForCodeScanningOnly) {
const isCodeScanningOnly = codeScanningConfig["disable-default-queries"] !== true && codeScanningConfig.packs === void 0 && codeScanningConfig.queries === void 0 && codeScanningConfig["query-filters"] === void 0;
if (!isCodeScanningOnly) {
return "non-default-queries" /* NonDefaultQueries */;
return {
enabled: false,
reason: "non-default-queries" /* NonDefaultQueries */
};
}
}
return void 0;
return { enabled: true };
}
function runnerHasSufficientDiskSpace(diskUsage, logger, useV2ResourceChecks) {
const minimumDiskSpaceBytes = useV2ResourceChecks ? OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_BYTES : OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_BYTES;
@@ -106447,97 +106453,128 @@ async function runnerHasSufficientMemory(codeql, ramInput, logger) {
);
return true;
}
async function getResourceDisabledReason(codeql, diskUsage, ramInput, logger, useV2ResourceChecks) {
if (diskUsage === void 0) {
logger.info(
`Unable to determine available disk space for overlay analysis. Setting overlay database mode to ${"none" /* None */}.`
);
return "unable-to-determine-disk-usage" /* UnableToDetermineDiskUsage */;
}
async function checkRunnerResources(codeql, diskUsage, ramInput, logger, useV2ResourceChecks) {
if (!runnerHasSufficientDiskSpace(diskUsage, logger, useV2ResourceChecks)) {
return "insufficient-disk-space" /* InsufficientDiskSpace */;
return {
sufficient: false,
reason: "insufficient-disk-space" /* InsufficientDiskSpace */
};
}
if (!await runnerHasSufficientMemory(codeql, ramInput, logger)) {
return "insufficient-memory" /* InsufficientMemory */;
return {
sufficient: false,
reason: "insufficient-memory" /* InsufficientMemory */
};
}
return void 0;
return { sufficient: true };
}
async function getOverlayDatabaseMode(codeql, features, languages, sourceRoot, buildMode, ramInput, codeScanningConfig, repositoryProperties, gitVersion, logger) {
let overlayDatabaseMode = "none" /* None */;
let useOverlayDatabaseCaching = false;
let disabledReason;
const disabledResult = (reason) => ({
overlayDatabaseMode: "none" /* None */,
useOverlayDatabaseCaching: false,
disabledReason: reason
});
const modeEnv = process.env.CODEQL_OVERLAY_DATABASE_MODE;
if (modeEnv === "overlay" /* Overlay */ || modeEnv === "overlay-base" /* OverlayBase */ || modeEnv === "none" /* None */) {
overlayDatabaseMode = modeEnv;
logger.info(
`Setting overlay database mode to ${overlayDatabaseMode} from the CODEQL_OVERLAY_DATABASE_MODE environment variable.`
`Setting overlay database mode to ${modeEnv} from the CODEQL_OVERLAY_DATABASE_MODE environment variable.`
);
} else if (repositoryProperties["github-codeql-disable-overlay" /* DISABLE_OVERLAY */] === true) {
return validateOverlayDatabaseMode(
modeEnv,
false,
codeql,
languages,
sourceRoot,
buildMode,
gitVersion,
logger
);
}
if (repositoryProperties["github-codeql-disable-overlay" /* DISABLE_OVERLAY */] === true) {
logger.info(
`Setting overlay database mode to ${"none" /* None */} because the ${"github-codeql-disable-overlay" /* DISABLE_OVERLAY */} repository property is set to true.`
);
overlayDatabaseMode = "none" /* None */;
disabledReason = "disabled-by-repository-property" /* DisabledByRepositoryProperty */;
} else if ((disabledReason = await getOverlayFeatureDisabledReason(
return disabledResult("disabled-by-repository-property" /* DisabledByRepositoryProperty */);
}
const featureResult = await checkOverlayAnalysisFeatureEnabled(
features,
codeql,
languages,
codeScanningConfig
)) === void 0) {
const performResourceChecks = !await features.getValue(
"overlay_analysis_skip_resource_checks" /* OverlayAnalysisSkipResourceChecks */,
codeql
);
const useV2ResourceChecks = await features.getValue(
"overlay_analysis_resource_checks_v2" /* OverlayAnalysisResourceChecksV2 */
);
const checkOverlayStatus = await features.getValue(
"overlay_analysis_status_check" /* OverlayAnalysisStatusCheck */
);
const diskUsage = performResourceChecks || checkOverlayStatus ? await checkDiskUsage(logger) : void 0;
let resourceDisabledReason;
if (performResourceChecks && (resourceDisabledReason = await getResourceDisabledReason(
codeql,
diskUsage,
ramInput,
logger,
useV2ResourceChecks
)) !== void 0) {
overlayDatabaseMode = "none" /* None */;
disabledReason = resourceDisabledReason;
} else if (checkOverlayStatus && diskUsage === void 0) {
logger.warning(
`Unable to determine disk usage, therefore setting overlay database mode to ${"none" /* None */}.`
);
overlayDatabaseMode = "none" /* None */;
disabledReason = "unable-to-determine-disk-usage" /* UnableToDetermineDiskUsage */;
} else if (checkOverlayStatus && diskUsage && await shouldSkipOverlayAnalysis(codeql, languages, diskUsage, logger)) {
logger.info(
`Setting overlay database mode to ${"none" /* None */} because overlay analysis previously failed with this combination of languages, disk space, and CodeQL version.`
);
overlayDatabaseMode = "none" /* None */;
disabledReason = "skipped-due-to-cached-status" /* SkippedDueToCachedStatus */;
} else if (isAnalyzingPullRequest()) {
overlayDatabaseMode = "overlay" /* Overlay */;
useOverlayDatabaseCaching = true;
logger.info(
`Setting overlay database mode to ${overlayDatabaseMode} with caching because we are analyzing a pull request.`
);
} else if (await isAnalyzingDefaultBranch()) {
overlayDatabaseMode = "overlay-base" /* OverlayBase */;
useOverlayDatabaseCaching = true;
logger.info(
`Setting overlay database mode to ${overlayDatabaseMode} with caching because we are analyzing the default branch.`
);
}
);
if (!featureResult.enabled) {
return disabledResult(featureResult.reason);
}
const performResourceChecks = !await features.getValue(
"overlay_analysis_skip_resource_checks" /* OverlayAnalysisSkipResourceChecks */,
codeql
);
const useV2ResourceChecks = await features.getValue(
"overlay_analysis_resource_checks_v2" /* OverlayAnalysisResourceChecksV2 */
);
const checkOverlayStatus = await features.getValue(
"overlay_analysis_status_check" /* OverlayAnalysisStatusCheck */
);
const diskUsage = performResourceChecks || checkOverlayStatus ? await checkDiskUsage(logger) : void 0;
if ((performResourceChecks || checkOverlayStatus) && diskUsage === void 0) {
logger.warning(
`Unable to determine disk usage, therefore setting overlay database mode to ${"none" /* None */}.`
);
return disabledResult("unable-to-determine-disk-usage" /* UnableToDetermineDiskUsage */);
}
const resourceResult = performResourceChecks && diskUsage ? await checkRunnerResources(
codeql,
diskUsage,
ramInput,
logger,
useV2ResourceChecks
) : { sufficient: true };
if (!resourceResult.sufficient) {
return disabledResult(resourceResult.reason);
}
if (checkOverlayStatus && diskUsage && await shouldSkipOverlayAnalysis(codeql, languages, diskUsage, logger)) {
logger.info(
`Setting overlay database mode to ${"none" /* None */} because overlay analysis previously failed with this combination of languages, disk space, and CodeQL version.`
);
return disabledResult("skipped-due-to-cached-status" /* SkippedDueToCachedStatus */);
}
let overlayDatabaseMode;
if (isAnalyzingPullRequest()) {
overlayDatabaseMode = "overlay" /* Overlay */;
logger.info(
`Setting overlay database mode to ${overlayDatabaseMode} with caching because we are analyzing a pull request.`
);
} else if (await isAnalyzingDefaultBranch()) {
overlayDatabaseMode = "overlay-base" /* OverlayBase */;
logger.info(
`Setting overlay database mode to ${overlayDatabaseMode} with caching because we are analyzing the default branch.`
);
} else {
return disabledResult("not-pull-request-or-default-branch" /* NotPullRequestOrDefaultBranch */);
}
return validateOverlayDatabaseMode(
overlayDatabaseMode,
true,
codeql,
languages,
sourceRoot,
buildMode,
gitVersion,
logger
);
}
async function validateOverlayDatabaseMode(overlayDatabaseMode, useOverlayDatabaseCaching, codeql, languages, sourceRoot, buildMode, gitVersion, logger) {
const disabledResult = (reason) => ({
overlayDatabaseMode: "none" /* None */,
useOverlayDatabaseCaching: false,
disabledReason: reason
});
if (overlayDatabaseMode === "none" /* None */) {
return disabledResult(disabledReason);
return {
overlayDatabaseMode: "none" /* None */,
useOverlayDatabaseCaching: false,
disabledReason: void 0
};
}
if (buildMode !== "none" /* None */ && (await Promise.all(
languages.map(
@@ -106580,7 +106617,7 @@ async function getOverlayDatabaseMode(codeql, features, languages, sourceRoot, b
return {
overlayDatabaseMode,
useOverlayDatabaseCaching,
disabledReason
disabledReason: void 0
};
}
function dbLocationOrDefault(dbLocation, tempDir) {
+1
View File
@@ -1165,6 +1165,7 @@ test(
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.NotPullRequestOrDefaultBranch,
},
);
+165 -104
View File
@@ -655,17 +655,21 @@ const OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES: Record<Language, Feature> = {
/**
* Checks whether the overlay analysis feature is enabled for the given
* languages and configuration, returning the specific reason it is disabled,
* or `undefined` if it is enabled.
* languages and configuration.
*/
async function getOverlayFeatureDisabledReason(
async function checkOverlayAnalysisFeatureEnabled(
features: FeatureEnablement,
codeql: CodeQL,
languages: Language[],
codeScanningConfig: UserConfig,
): Promise<OverlayDisabledReason | undefined> {
): Promise<
{ enabled: true } | { enabled: false; reason: OverlayDisabledReason }
> {
if (!(await features.getValue(Feature.OverlayAnalysis, codeql))) {
return OverlayDisabledReason.OverallFeatureNotEnabled;
return {
enabled: false,
reason: OverlayDisabledReason.OverallFeatureNotEnabled,
};
}
let enableForCodeScanningOnly = false;
for (const language of languages) {
@@ -682,7 +686,7 @@ async function getOverlayFeatureDisabledReason(
enableForCodeScanningOnly = true;
continue;
}
return OverlayDisabledReason.LanguageNotEnabled;
return { enabled: false, reason: OverlayDisabledReason.LanguageNotEnabled };
}
if (enableForCodeScanningOnly) {
// A code-scanning configuration runs only the (default) code-scanning suite
@@ -694,10 +698,13 @@ async function getOverlayFeatureDisabledReason(
codeScanningConfig.queries === undefined &&
codeScanningConfig["query-filters"] === undefined;
if (!isCodeScanningOnly) {
return OverlayDisabledReason.NonDefaultQueries;
return {
enabled: false,
reason: OverlayDisabledReason.NonDefaultQueries,
};
}
}
return undefined;
return { enabled: true };
}
/** Checks if the runner has enough disk space for overlay analysis. */
@@ -756,30 +763,30 @@ async function runnerHasSufficientMemory(
/**
* Checks if the runner has sufficient disk space and memory for overlay
* analysis, returning the specific reason if not, or `undefined` if resources
* are sufficient.
* analysis.
*/
async function getResourceDisabledReason(
async function checkRunnerResources(
codeql: CodeQL,
diskUsage: DiskUsage | undefined,
diskUsage: DiskUsage,
ramInput: string | undefined,
logger: Logger,
useV2ResourceChecks: boolean,
): Promise<OverlayDisabledReason | undefined> {
if (diskUsage === undefined) {
logger.info(
`Unable to determine available disk space for overlay analysis. ` +
`Setting overlay database mode to ${OverlayDatabaseMode.None}.`,
);
return OverlayDisabledReason.UnableToDetermineDiskUsage;
}
): Promise<
{ sufficient: true } | { sufficient: false; reason: OverlayDisabledReason }
> {
if (!runnerHasSufficientDiskSpace(diskUsage, logger, useV2ResourceChecks)) {
return OverlayDisabledReason.InsufficientDiskSpace;
return {
sufficient: false,
reason: OverlayDisabledReason.InsufficientDiskSpace,
};
}
if (!(await runnerHasSufficientMemory(codeql, ramInput, logger))) {
return OverlayDisabledReason.InsufficientMemory;
return {
sufficient: false,
reason: OverlayDisabledReason.InsufficientMemory,
};
}
return undefined;
return { sufficient: true };
}
/**
@@ -819,9 +826,11 @@ export async function getOverlayDatabaseMode(
useOverlayDatabaseCaching: boolean;
disabledReason: OverlayDisabledReason | undefined;
}> {
let overlayDatabaseMode = OverlayDatabaseMode.None;
let useOverlayDatabaseCaching = false;
let disabledReason: OverlayDisabledReason | undefined;
const disabledResult = (reason: OverlayDisabledReason | undefined) => ({
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: reason,
});
const modeEnv = process.env.CODEQL_OVERLAY_DATABASE_MODE;
// Any unrecognized CODEQL_OVERLAY_DATABASE_MODE value will be ignored and
@@ -831,98 +840,150 @@ export async function getOverlayDatabaseMode(
modeEnv === OverlayDatabaseMode.OverlayBase ||
modeEnv === OverlayDatabaseMode.None
) {
overlayDatabaseMode = modeEnv;
logger.info(
`Setting overlay database mode to ${overlayDatabaseMode} ` +
`Setting overlay database mode to ${modeEnv} ` +
"from the CODEQL_OVERLAY_DATABASE_MODE environment variable.",
);
} else if (
repositoryProperties[RepositoryPropertyName.DISABLE_OVERLAY] === true
) {
return validateOverlayDatabaseMode(
modeEnv,
false,
codeql,
languages,
sourceRoot,
buildMode,
gitVersion,
logger,
);
}
if (repositoryProperties[RepositoryPropertyName.DISABLE_OVERLAY] === true) {
logger.info(
`Setting overlay database mode to ${OverlayDatabaseMode.None} ` +
`because the ${RepositoryPropertyName.DISABLE_OVERLAY} repository property is set to true.`,
);
overlayDatabaseMode = OverlayDatabaseMode.None;
disabledReason = OverlayDisabledReason.DisabledByRepositoryProperty;
} else if (
(disabledReason = await getOverlayFeatureDisabledReason(
features,
codeql,
languages,
codeScanningConfig,
)) === undefined
) {
const performResourceChecks = !(await features.getValue(
Feature.OverlayAnalysisSkipResourceChecks,
codeql,
));
const useV2ResourceChecks = await features.getValue(
Feature.OverlayAnalysisResourceChecksV2,
);
const checkOverlayStatus = await features.getValue(
Feature.OverlayAnalysisStatusCheck,
);
const diskUsage =
performResourceChecks || checkOverlayStatus
? await checkDiskUsage(logger)
: undefined;
let resourceDisabledReason: OverlayDisabledReason | undefined;
if (
performResourceChecks &&
(resourceDisabledReason = await getResourceDisabledReason(
codeql,
diskUsage,
ramInput,
logger,
useV2ResourceChecks,
)) !== undefined
) {
overlayDatabaseMode = OverlayDatabaseMode.None;
disabledReason = resourceDisabledReason;
} else if (checkOverlayStatus && diskUsage === undefined) {
logger.warning(
`Unable to determine disk usage, therefore setting overlay database mode to ${OverlayDatabaseMode.None}.`,
);
overlayDatabaseMode = OverlayDatabaseMode.None;
disabledReason = OverlayDisabledReason.UnableToDetermineDiskUsage;
} else if (
checkOverlayStatus &&
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.",
);
overlayDatabaseMode = OverlayDatabaseMode.None;
disabledReason = OverlayDisabledReason.SkippedDueToCachedStatus;
} else if (isAnalyzingPullRequest()) {
overlayDatabaseMode = OverlayDatabaseMode.Overlay;
useOverlayDatabaseCaching = true;
logger.info(
`Setting overlay database mode to ${overlayDatabaseMode} ` +
"with caching because we are analyzing a pull request.",
);
} else if (await isAnalyzingDefaultBranch()) {
overlayDatabaseMode = OverlayDatabaseMode.OverlayBase;
useOverlayDatabaseCaching = true;
logger.info(
`Setting overlay database mode to ${overlayDatabaseMode} ` +
"with caching because we are analyzing the default branch.",
);
}
return disabledResult(OverlayDisabledReason.DisabledByRepositoryProperty);
}
const disabledResult = (reason: OverlayDisabledReason | undefined) => ({
const featureResult = await checkOverlayAnalysisFeatureEnabled(
features,
codeql,
languages,
codeScanningConfig,
);
if (!featureResult.enabled) {
return disabledResult(featureResult.reason);
}
const performResourceChecks = !(await features.getValue(
Feature.OverlayAnalysisSkipResourceChecks,
codeql,
));
const useV2ResourceChecks = await features.getValue(
Feature.OverlayAnalysisResourceChecksV2,
);
const checkOverlayStatus = await features.getValue(
Feature.OverlayAnalysisStatusCheck,
);
const diskUsage =
performResourceChecks || checkOverlayStatus
? await checkDiskUsage(logger)
: undefined;
if (
(performResourceChecks || checkOverlayStatus) &&
diskUsage === undefined
) {
logger.warning(
`Unable to determine disk usage, therefore setting overlay database mode to ${OverlayDatabaseMode.None}.`,
);
return disabledResult(OverlayDisabledReason.UnableToDetermineDiskUsage);
}
const resourceResult =
performResourceChecks && diskUsage
? await checkRunnerResources(
codeql,
diskUsage,
ramInput,
logger,
useV2ResourceChecks,
)
: { sufficient: true as const };
if (!resourceResult.sufficient) {
return disabledResult(resourceResult.reason);
}
if (
checkOverlayStatus &&
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.",
);
return disabledResult(OverlayDisabledReason.SkippedDueToCachedStatus);
}
let overlayDatabaseMode: OverlayDatabaseMode;
if (isAnalyzingPullRequest()) {
overlayDatabaseMode = OverlayDatabaseMode.Overlay;
logger.info(
`Setting overlay database mode to ${overlayDatabaseMode} ` +
"with caching because we are analyzing a pull request.",
);
} else if (await isAnalyzingDefaultBranch()) {
overlayDatabaseMode = OverlayDatabaseMode.OverlayBase;
logger.info(
`Setting overlay database mode to ${overlayDatabaseMode} ` +
"with caching because we are analyzing the default branch.",
);
} else {
return disabledResult(OverlayDisabledReason.NotPullRequestOrDefaultBranch);
}
return validateOverlayDatabaseMode(
overlayDatabaseMode,
true,
codeql,
languages,
sourceRoot,
buildMode,
gitVersion,
logger,
);
}
/**
* Validates that the given overlay database mode is compatible with the current
* configuration (build mode, CodeQL version, git repository, git version). Returns
* the mode unchanged if all checks pass, or falls back to `None` with the
* appropriate disabled reason.
*/
async function validateOverlayDatabaseMode(
overlayDatabaseMode: OverlayDatabaseMode,
useOverlayDatabaseCaching: boolean,
codeql: CodeQL,
languages: Language[],
sourceRoot: string,
buildMode: BuildMode | undefined,
gitVersion: GitVersionInfo | undefined,
logger: Logger,
): Promise<{
overlayDatabaseMode: OverlayDatabaseMode;
useOverlayDatabaseCaching: boolean;
disabledReason: OverlayDisabledReason | undefined;
}> {
const disabledResult = (reason: OverlayDisabledReason) => ({
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: reason,
});
if (overlayDatabaseMode === OverlayDatabaseMode.None) {
return disabledResult(disabledReason);
return {
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: undefined,
};
}
if (
@@ -983,7 +1044,7 @@ export async function getOverlayDatabaseMode(
return {
overlayDatabaseMode,
useOverlayDatabaseCaching,
disabledReason,
disabledReason: undefined,
};
}
+2
View File
@@ -31,6 +31,8 @@ export enum OverlayDisabledReason {
* queries or packs, disables default queries, or specifies query filters.
*/
NonDefaultQueries = "non-default-queries",
/** We are not analyzing a pull request or the default branch. */
NotPullRequestOrDefaultBranch = "not-pull-request-or-default-branch",
/** The top-level overlay analysis feature flag is not enabled. */
OverallFeatureNotEnabled = "overall-feature-not-enabled",
/** Overlay analysis was skipped because it previously failed with similar hardware resources. */