diff --git a/lib/init-action.js b/lib/init-action.js index ac85956f06..dc4cd8fb63 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -106023,6 +106023,7 @@ var OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_BYTES = OVERLAY_MINIMUM_AVAILABLE_DISK_ var OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_MB = 14e3; var OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_BYTES = OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_MB * 1e6; var OVERLAY_MINIMUM_MEMORY_MB = 5 * 1024; +var CODEQL_VERSION_REDUCED_OVERLAY_MEMORY_USAGE = "2.24.3"; async function getSupportedLanguageMap(codeql, logger) { const resolveSupportedLanguagesUsingCli = await codeql.supportsFeature( "builtinExtractorsSpecifyDefaultQueries" /* BuiltinExtractorsSpecifyDefaultQueries */ @@ -106282,7 +106283,7 @@ async function isOverlayAnalysisFeatureEnabled(features, codeql, languages, code } return true; } -async function runnerSupportsOverlayAnalysis(diskUsage, ramInput, logger, useV2ResourceChecks) { +function runnerHasSufficientDiskSpace(diskUsage, logger, useV2ResourceChecks) { const minimumDiskSpaceBytes = useV2ResourceChecks ? OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_BYTES : OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_BYTES; if (diskUsage === void 0 || diskUsage.numAvailableBytes < minimumDiskSpaceBytes) { const diskSpaceMb = diskUsage === void 0 ? 0 : Math.round(diskUsage.numAvailableBytes / 1e6); @@ -106292,6 +106293,18 @@ async function runnerSupportsOverlayAnalysis(diskUsage, ramInput, logger, useV2R ); return false; } + return true; +} +async function runnerHasSufficientMemory(codeql, ramInput, logger) { + if (await codeQlVersionAtLeast( + codeql, + CODEQL_VERSION_REDUCED_OVERLAY_MEMORY_USAGE + )) { + logger.debug( + `Skipping memory check for overlay analysis because CodeQL version is at least ${CODEQL_VERSION_REDUCED_OVERLAY_MEMORY_USAGE}.` + ); + return true; + } const memoryFlagValue = getCodeQLMemoryLimit(ramInput, logger); if (memoryFlagValue < OVERLAY_MINIMUM_MEMORY_MB) { logger.info( @@ -106299,6 +106312,18 @@ async function runnerSupportsOverlayAnalysis(diskUsage, ramInput, logger, useV2R ); return false; } + logger.debug( + `Memory available for CodeQL analysis is ${memoryFlagValue} MB, which is above the minimum of ${OVERLAY_MINIMUM_MEMORY_MB} MB.` + ); + return true; +} +async function runnerSupportsOverlayAnalysis(codeql, diskUsage, ramInput, logger, useV2ResourceChecks) { + if (!runnerHasSufficientDiskSpace(diskUsage, logger, useV2ResourceChecks)) { + return false; + } + if (!await runnerHasSufficientMemory(codeql, ramInput, logger)) { + return false; + } return true; } async function getOverlayDatabaseMode(codeql, features, languages, sourceRoot, buildMode, ramInput, codeScanningConfig, repositoryProperties, gitVersion, logger) { @@ -106335,6 +106360,7 @@ async function getOverlayDatabaseMode(codeql, features, languages, sourceRoot, b ); const diskUsage = performResourceChecks || checkOverlayStatus ? await checkDiskUsage(logger) : void 0; if (performResourceChecks && !await runnerSupportsOverlayAnalysis( + codeql, diskUsage, ramInput, logger, diff --git a/src/config-utils.test.ts b/src/config-utils.test.ts index 7624f1a2da..6f780b29bf 100644 --- a/src/config-utils.test.ts +++ b/src/config-utils.test.ts @@ -1365,6 +1365,25 @@ test( }, ); +test( + getOverlayDatabaseModeMacro, + "Overlay-base database on default branch if memory flag is too low but CodeQL >= 2.24.3", + { + languages: [KnownLanguage.javascript], + features: [ + Feature.OverlayAnalysis, + Feature.OverlayAnalysisCodeScanningJavascript, + ], + isDefaultBranch: true, + memoryFlagValue: 3072, + codeqlVersion: "2.24.3", + }, + { + overlayDatabaseMode: OverlayDatabaseMode.OverlayBase, + useOverlayDatabaseCaching: true, + }, +); + test( getOverlayDatabaseModeMacro, "Overlay-base database on default branch if memory flag is too low and skip resource checks flag is enabled", @@ -1683,6 +1702,25 @@ test( }, ); +test( + getOverlayDatabaseModeMacro, + "Overlay analysis on PR if memory flag is too low but CodeQL >= 2.24.3", + { + languages: [KnownLanguage.javascript], + features: [ + Feature.OverlayAnalysis, + Feature.OverlayAnalysisCodeScanningJavascript, + ], + isPullRequest: true, + memoryFlagValue: 3072, + codeqlVersion: "2.24.3", + }, + { + overlayDatabaseMode: OverlayDatabaseMode.Overlay, + useOverlayDatabaseCaching: true, + }, +); + test( getOverlayDatabaseModeMacro, "Overlay analysis on PR if memory flag is too low and skip resource checks flag is enabled", diff --git a/src/config-utils.ts b/src/config-utils.ts index 3b23a12bd7..14274a7238 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -92,13 +92,23 @@ const OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_BYTES = OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_MB * 1_000_000; /** - * The minimum memory (in MB) that must be available for CodeQL to perform overlay - * analysis. If CodeQL will be given less memory than this threshold, then the - * action will not perform overlay analysis unless overlay analysis has been - * explicitly enabled via environment variable. + * The minimum memory (in MB) that must be available for CodeQL to perform overlay analysis. If + * CodeQL will be given less memory than this threshold, then the action will not perform overlay + * analysis unless overlay analysis has been explicitly enabled via environment variable. + * + * This check is not performed for CodeQL >= `CODEQL_VERSION_REDUCED_OVERLAY_MEMORY_USAGE` since + * improved memory usage in that version makes the check unnecessary. */ const OVERLAY_MINIMUM_MEMORY_MB = 5 * 1024; +/** + * Versions 2.24.3+ of CodeQL reduce overlay analysis's peak RAM usage. + * + * In particular, RAM usage with overlay analysis enabled should generally be no higher than it is + * without overlay analysis for these versions. + */ +const CODEQL_VERSION_REDUCED_OVERLAY_MEMORY_USAGE = "2.24.3"; + export type RegistryConfigWithCredentials = RegistryConfigNoCredentials & { // Token to use when downloading packs from this registry. token: string; @@ -683,16 +693,12 @@ async function isOverlayAnalysisFeatureEnabled( return true; } -/** - * Checks if the runner supports overlay analysis based on available disk space - * and the maximum memory CodeQL will be allowed to use. - */ -async function runnerSupportsOverlayAnalysis( +/** Checks if the runner has enough disk space for overlay analysis. */ +function runnerHasSufficientDiskSpace( diskUsage: DiskUsage | undefined, - ramInput: string | undefined, logger: Logger, useV2ResourceChecks: boolean, -): Promise { +): boolean { const minimumDiskSpaceBytes = useV2ResourceChecks ? OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_BYTES : OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_BYTES; @@ -711,6 +717,26 @@ async function runnerSupportsOverlayAnalysis( ); return false; } + return true; +} + +/** Checks if the runner has enough memory for overlay analysis. */ +async function runnerHasSufficientMemory( + codeql: CodeQL, + ramInput: string | undefined, + logger: Logger, +): Promise { + if ( + await codeQlVersionAtLeast( + codeql, + CODEQL_VERSION_REDUCED_OVERLAY_MEMORY_USAGE, + ) + ) { + logger.debug( + `Skipping memory check for overlay analysis because CodeQL version is at least ${CODEQL_VERSION_REDUCED_OVERLAY_MEMORY_USAGE}.`, + ); + return true; + } const memoryFlagValue = getCodeQLMemoryLimit(ramInput, logger); if (memoryFlagValue < OVERLAY_MINIMUM_MEMORY_MB) { @@ -721,6 +747,29 @@ async function runnerSupportsOverlayAnalysis( return false; } + logger.debug( + `Memory available for CodeQL analysis is ${memoryFlagValue} MB, which is above the minimum of ${OVERLAY_MINIMUM_MEMORY_MB} MB.`, + ); + return true; +} + +/** + * Checks if the runner supports overlay analysis based on available disk space + * and the maximum memory CodeQL will be allowed to use. + */ +async function runnerSupportsOverlayAnalysis( + codeql: CodeQL, + diskUsage: DiskUsage | undefined, + ramInput: string | undefined, + logger: Logger, + useV2ResourceChecks: boolean, +): Promise { + if (!runnerHasSufficientDiskSpace(diskUsage, logger, useV2ResourceChecks)) { + return false; + } + if (!(await runnerHasSufficientMemory(codeql, ramInput, logger))) { + return false; + } return true; } @@ -812,6 +861,7 @@ export async function getOverlayDatabaseMode( if ( performResourceChecks && !(await runnerSupportsOverlayAnalysis( + codeql, diskUsage, ramInput, logger,