diff --git a/lib/entry-points.js b/lib/entry-points.js index a4821cbe6..039e345be 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -149647,10 +149647,15 @@ async function cachePrefix(codeql, language) { } // src/config-utils.ts -var OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_MB = 2e4; -var OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_BYTES = OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_MB * 1e6; -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_AVAILABLE_DISK_SPACE_MB = 14e3; +var OVERLAY_MINIMUM_DISK_SPACE_FEATURES = [ + ["overlay_analysis_min_disk_8_gb" /* OverlayAnalysisMinDisk8Gb */, 8e3], + ["overlay_analysis_min_disk_9_gb" /* OverlayAnalysisMinDisk9Gb */, 9e3], + ["overlay_analysis_min_disk_10_gb" /* OverlayAnalysisMinDisk10Gb */, 1e4], + ["overlay_analysis_min_disk_11_gb" /* OverlayAnalysisMinDisk11Gb */, 11e3], + ["overlay_analysis_min_disk_12_gb" /* OverlayAnalysisMinDisk12Gb */, 12e3], + ["overlay_analysis_min_disk_13_gb" /* OverlayAnalysisMinDisk13Gb */, 13e3] +]; var OVERLAY_MINIMUM_MEMORY_MB = 5 * 1024; var CODEQL_VERSION_REDUCED_OVERLAY_MEMORY_USAGE = "2.24.3"; async function getSupportedLanguageMap(codeql, logger) { @@ -149900,16 +149905,26 @@ async function checkOverlayAnalysisFeatureEnabled(features, codeql, languages, c } return new Success(void 0); } -function runnerHasSufficientDiskSpace(diskUsage, logger, useV2ResourceChecks) { - const minimumDiskSpaceBytes = useV2ResourceChecks ? OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_BYTES : OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_BYTES; - if (diskUsage.numAvailableBytes < minimumDiskSpaceBytes) { - const diskSpaceMb = Math.round(diskUsage.numAvailableBytes / 1e6); - const minimumDiskSpaceMb = Math.round(minimumDiskSpaceBytes / 1e6); +async function getMinimumDiskSpaceMb(features) { + let minimumMb = OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_MB; + for (const [feature, thresholdMb] of OVERLAY_MINIMUM_DISK_SPACE_FEATURES) { + if (await features.getValue(feature)) { + minimumMb = Math.min(minimumMb, thresholdMb); + } + } + return minimumMb; +} +function runnerHasSufficientDiskSpace(diskUsage, logger, minimumDiskSpaceMb) { + const diskSpaceMb = Math.round(diskUsage.numAvailableBytes / 1e6); + if (diskUsage.numAvailableBytes < minimumDiskSpaceMb * 1e6) { logger.info( `Setting overlay database mode to ${"none" /* None */} due to insufficient disk space (${diskSpaceMb} MB, needed ${minimumDiskSpaceMb} MB).` ); return false; } + logger.debug( + `Disk space available for CodeQL analysis is ${diskSpaceMb} MB, which is above the minimum of ${minimumDiskSpaceMb} MB.` + ); return true; } async function runnerHasSufficientMemory(codeql, ramInput, logger) { @@ -149934,8 +149949,9 @@ async function runnerHasSufficientMemory(codeql, ramInput, logger) { ); return true; } -async function checkRunnerResources(codeql, diskUsage, ramInput, logger, useV2ResourceChecks) { - if (!runnerHasSufficientDiskSpace(diskUsage, logger, useV2ResourceChecks)) { +async function checkRunnerResources(codeql, features, diskUsage, ramInput, logger) { + const minimumDiskSpaceMb = await getMinimumDiskSpaceMb(features); + if (!runnerHasSufficientDiskSpace(diskUsage, logger, minimumDiskSpaceMb)) { return new Failure("insufficient-disk-space" /* InsufficientDiskSpace */); } if (!await runnerHasSufficientMemory(codeql, ramInput, logger)) { @@ -149983,9 +149999,6 @@ async function checkOverlayEnablement(codeql, features, languages, sourceRoot, b "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 */ ); @@ -149999,10 +150012,10 @@ async function checkOverlayEnablement(codeql, features, languages, sourceRoot, b } const resourceResult = performResourceChecks && diskUsage !== void 0 ? await checkRunnerResources( codeql, + features, diskUsage, ramInput, - logger, - useV2ResourceChecks + logger ) : new Success(void 0); if (resourceResult.isFailure()) { return resourceResult; diff --git a/src/config-utils.test.ts b/src/config-utils.test.ts index 84c709e72..f4a664c79 100644 --- a/src/config-utils.test.ts +++ b/src/config-utils.test.ts @@ -1295,33 +1295,12 @@ checkOverlayEnablementMacro.serial( ); checkOverlayEnablementMacro.serial( - "No overlay-base database on default branch if runner disk space is below v2 limit and v2 resource checks enabled", + "Overlay-base database on default branch if runner disk space is above the default limit", { languages: [BuiltInLanguage.javascript], features: [ Feature.OverlayAnalysis, Feature.OverlayAnalysisCodeScanningJavascript, - Feature.OverlayAnalysisResourceChecksV2, - ], - isDefaultBranch: true, - diskUsage: { - numAvailableBytes: 5_000_000_000, - numTotalBytes: 100_000_000_000, - }, - }, - { - disabledReason: OverlayDisabledReason.InsufficientDiskSpace, - }, -); - -checkOverlayEnablementMacro.serial( - "Overlay-base database on default branch if runner disk space is between v2 and v1 limits and v2 resource checks enabled", - { - languages: [BuiltInLanguage.javascript], - features: [ - Feature.OverlayAnalysis, - Feature.OverlayAnalysisCodeScanningJavascript, - Feature.OverlayAnalysisResourceChecksV2, ], isDefaultBranch: true, diskUsage: { @@ -1336,7 +1315,7 @@ checkOverlayEnablementMacro.serial( ); checkOverlayEnablementMacro.serial( - "No overlay-base database on default branch if runner disk space is between v2 and v1 limits and v2 resource checks not enabled", + "No overlay-base database on default branch if runner disk space is below the default limit", { languages: [BuiltInLanguage.javascript], features: [ @@ -1345,7 +1324,71 @@ checkOverlayEnablementMacro.serial( ], isDefaultBranch: true, diskUsage: { - numAvailableBytes: 15_000_000_000, + numAvailableBytes: 10_000_000_000, + numTotalBytes: 100_000_000_000, + }, + }, + { + disabledReason: OverlayDisabledReason.InsufficientDiskSpace, + }, +); + +checkOverlayEnablementMacro.serial( + "Overlay-base database on default branch if runner disk space is above the limit lowered by a feature flag", + { + languages: [BuiltInLanguage.javascript], + features: [ + Feature.OverlayAnalysis, + Feature.OverlayAnalysisCodeScanningJavascript, + Feature.OverlayAnalysisMinDisk10Gb, + ], + isDefaultBranch: true, + diskUsage: { + numAvailableBytes: 11_000_000_000, + numTotalBytes: 100_000_000_000, + }, + }, + { + overlayDatabaseMode: OverlayDatabaseMode.OverlayBase, + useOverlayDatabaseCaching: true, + }, +); + +checkOverlayEnablementMacro.serial( + "Overlay-base database on default branch if runner disk space is exactly at the lowest limit enabled by a feature flag", + { + languages: [BuiltInLanguage.javascript], + features: [ + Feature.OverlayAnalysis, + Feature.OverlayAnalysisCodeScanningJavascript, + Feature.OverlayAnalysisMinDisk9Gb, + Feature.OverlayAnalysisMinDisk12Gb, + ], + isDefaultBranch: true, + diskUsage: { + numAvailableBytes: 9_000_000_000, + numTotalBytes: 100_000_000_000, + }, + }, + { + overlayDatabaseMode: OverlayDatabaseMode.OverlayBase, + useOverlayDatabaseCaching: true, + }, +); + +checkOverlayEnablementMacro.serial( + "No overlay-base database on default branch if runner disk space is below the lowest limit enabled by a feature flag", + { + languages: [BuiltInLanguage.javascript], + features: [ + Feature.OverlayAnalysis, + Feature.OverlayAnalysisCodeScanningJavascript, + Feature.OverlayAnalysisMinDisk9Gb, + Feature.OverlayAnalysisMinDisk12Gb, + ], + isDefaultBranch: true, + diskUsage: { + numAvailableBytes: 8_500_000_000, numTotalBytes: 100_000_000_000, }, }, diff --git a/src/config-utils.ts b/src/config-utils.ts index b5a880ba7..dac83aa2c 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -48,7 +48,7 @@ import { import { prepareDiffInformedAnalysis } from "./diff-informed-analysis-utils"; import { EnvVar } from "./environment"; import * as errorMessages from "./error-messages"; -import { Feature, FeatureEnablement } from "./feature-flags"; +import { Feature, FeatureEnablement, FeatureWithoutCLI } from "./feature-flags"; import { RepositoryProperties, RepositoryPropertyName, @@ -101,19 +101,28 @@ export { type Config } from "./config/action-config"; * whether to perform overlay analysis, then the action will not perform overlay * analysis unless overlay analysis has been explicitly enabled via environment * variable. + * + * This threshold can be lowered by the feature flags in + * `OVERLAY_MINIMUM_DISK_SPACE_FEATURES`. */ -const OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_MB = 20000; -const OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_BYTES = - OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_MB * 1_000_000; +const OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_MB = 14000; /** - * The v2 minimum available disk space (in MB) required to perform overlay - * analysis. This is a lower threshold than the v1 limit, allowing overlay - * analysis to run on runners with less available disk space. + * Feature flags that lower the minimum available disk space required to perform + * overlay analysis, paired with the threshold (in MB) that each one enables. + * + * If several of these are enabled, the lowest threshold takes effect. */ -const OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_MB = 14000; -const OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_BYTES = - OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_MB * 1_000_000; +const OVERLAY_MINIMUM_DISK_SPACE_FEATURES: ReadonlyArray< + [FeatureWithoutCLI, number] +> = [ + [Feature.OverlayAnalysisMinDisk8Gb, 8000], + [Feature.OverlayAnalysisMinDisk9Gb, 9000], + [Feature.OverlayAnalysisMinDisk10Gb, 10000], + [Feature.OverlayAnalysisMinDisk11Gb, 11000], + [Feature.OverlayAnalysisMinDisk12Gb, 12000], + [Feature.OverlayAnalysisMinDisk13Gb, 13000], +]; /** * The minimum memory (in MB) that must be available for CodeQL to perform overlay analysis. If @@ -588,24 +597,42 @@ async function checkOverlayAnalysisFeatureEnabled( return new Success(undefined); } +/** + * Returns the minimum available disk space (in MB) required to perform overlay + * analysis, which is the lowest threshold enabled by a feature flag, or the + * default threshold if no such feature flag is enabled. + */ +async function getMinimumDiskSpaceMb( + features: FeatureEnablement, +): Promise { + let minimumMb = OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_MB; + for (const [feature, thresholdMb] of OVERLAY_MINIMUM_DISK_SPACE_FEATURES) { + if (await features.getValue(feature)) { + minimumMb = Math.min(minimumMb, thresholdMb); + } + } + return minimumMb; +} + /** Checks if the runner has enough disk space for overlay analysis. */ function runnerHasSufficientDiskSpace( diskUsage: DiskUsage, logger: Logger, - useV2ResourceChecks: boolean, + minimumDiskSpaceMb: number, ): boolean { - const minimumDiskSpaceBytes = useV2ResourceChecks - ? OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_BYTES - : OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_BYTES; - if (diskUsage.numAvailableBytes < minimumDiskSpaceBytes) { - const diskSpaceMb = Math.round(diskUsage.numAvailableBytes / 1_000_000); - const minimumDiskSpaceMb = Math.round(minimumDiskSpaceBytes / 1_000_000); + const diskSpaceMb = Math.round(diskUsage.numAvailableBytes / 1_000_000); + if (diskUsage.numAvailableBytes < minimumDiskSpaceMb * 1_000_000) { logger.info( `Setting overlay database mode to ${OverlayDatabaseMode.None} ` + `due to insufficient disk space (${diskSpaceMb} MB, needed ${minimumDiskSpaceMb} MB).`, ); return false; } + + logger.debug( + `Disk space available for CodeQL analysis is ${diskSpaceMb} MB, which is above the minimum ` + + `of ${minimumDiskSpaceMb} MB.`, + ); return true; } @@ -648,12 +675,13 @@ async function runnerHasSufficientMemory( */ async function checkRunnerResources( codeql: CodeQL, + features: FeatureEnablement, diskUsage: DiskUsage, ramInput: string | undefined, logger: Logger, - useV2ResourceChecks: boolean, ): Promise> { - if (!runnerHasSufficientDiskSpace(diskUsage, logger, useV2ResourceChecks)) { + const minimumDiskSpaceMb = await getMinimumDiskSpaceMb(features); + if (!runnerHasSufficientDiskSpace(diskUsage, logger, minimumDiskSpaceMb)) { return new Failure(OverlayDisabledReason.InsufficientDiskSpace); } if (!(await runnerHasSufficientMemory(codeql, ramInput, logger))) { @@ -752,9 +780,6 @@ export async function checkOverlayEnablement( Feature.OverlayAnalysisSkipResourceChecks, codeql, )); - const useV2ResourceChecks = await features.getValue( - Feature.OverlayAnalysisResourceChecksV2, - ); const checkOverlayStatus = await features.getValue( Feature.OverlayAnalysisStatusCheck, ); @@ -770,10 +795,10 @@ export async function checkOverlayEnablement( performResourceChecks && diskUsage !== undefined ? await checkRunnerResources( codeql, + features, diskUsage, ramInput, logger, - useV2ResourceChecks, ) : new Success(undefined); if (resourceResult.isFailure()) {