Merge remote-tracking branch 'origin/main' into kaspersv/move-diff-range-absolute-path-conversion

* origin/main: (32 commits)
  Add changelog note
  Update default bundle to codeql-bundle-v2.24.3
  Bump tar from 7.5.7 to 7.5.10
  Rebuild
  Rebuild
  Bump actions/upload-artifact from 6 to 7 in /.github/workflows
  Bump actions/download-artifact from 7 to 8 in /.github/workflows
  Bump the npm-minor group with 2 updates
  Fix some tests that should be serial
  Update method naming and JSDoc
  Rename to `EnabledOverlayConfig`
  Address review comments
  Use `Result`s for enablement return types
  Add disabled by env var disablement reason
  Rename to `usesDefaultQueriesOnly`
  Update `NonDefaultQueries` documentation
  Refactor `getOverlayDatabaseMode` and add new disablement reason
  Address review comments
  Add JSDoc
  Sort `OverlayDisabledReason` enum
  ...
This commit is contained in:
Sam Robson
2026-03-06 09:10:13 +00:00
43 changed files with 1089 additions and 1039 deletions
+136 -208
View File
@@ -40,6 +40,8 @@ import {
withTmpDir,
BuildMode,
DiskUsage,
Success,
Failure,
} from "./util";
import * as util from "./util";
@@ -942,55 +944,46 @@ for (const { displayName, language, feature } of [
feature: Feature.DisableCsharpBuildless,
},
]) {
test.serial(
`Build mode not overridden when disable ${displayName} buildless feature flag disabled`,
async (t) => {
const messages: LoggedMessage[] = [];
const buildMode = await configUtils.parseBuildModeInput(
"none",
[language],
createFeatures([]),
getRecordingLogger(messages),
);
t.is(buildMode, BuildMode.None);
t.deepEqual(messages, []);
},
);
test(`Build mode not overridden when disable ${displayName} buildless feature flag disabled`, async (t) => {
const messages: LoggedMessage[] = [];
const buildMode = await configUtils.parseBuildModeInput(
"none",
[language],
createFeatures([]),
getRecordingLogger(messages),
);
t.is(buildMode, BuildMode.None);
t.deepEqual(messages, []);
});
test.serial(
`Build mode not overridden for other languages when disable ${displayName} buildless feature flag enabled`,
async (t) => {
const messages: LoggedMessage[] = [];
const buildMode = await configUtils.parseBuildModeInput(
"none",
[KnownLanguage.python],
createFeatures([feature]),
getRecordingLogger(messages),
);
t.is(buildMode, BuildMode.None);
t.deepEqual(messages, []);
},
);
test(`Build mode not overridden for other languages when disable ${displayName} buildless feature flag enabled`, async (t) => {
const messages: LoggedMessage[] = [];
const buildMode = await configUtils.parseBuildModeInput(
"none",
[KnownLanguage.python],
createFeatures([feature]),
getRecordingLogger(messages),
);
t.is(buildMode, BuildMode.None);
t.deepEqual(messages, []);
});
test.serial(
`Build mode overridden when analyzing ${displayName} and disable ${displayName} buildless feature flag enabled`,
async (t) => {
const messages: LoggedMessage[] = [];
const buildMode = await configUtils.parseBuildModeInput(
"none",
[language],
createFeatures([feature]),
getRecordingLogger(messages),
);
t.is(buildMode, BuildMode.Autobuild);
t.deepEqual(messages, [
{
message: `Scanning ${displayName} code without a build is temporarily unavailable. Falling back to 'autobuild' build mode.`,
type: "warning",
},
]);
},
);
test(`Build mode overridden when analyzing ${displayName} and disable ${displayName} buildless feature flag enabled`, async (t) => {
const messages: LoggedMessage[] = [];
const buildMode = await configUtils.parseBuildModeInput(
"none",
[language],
createFeatures([feature]),
getRecordingLogger(messages),
);
t.is(buildMode, BuildMode.Autobuild);
t.deepEqual(messages, [
{
message: `Scanning ${displayName} code without a build is temporarily unavailable. Falling back to 'autobuild' build mode.`,
type: "warning",
},
]);
});
}
interface OverlayDatabaseModeTestSetup {
@@ -1033,16 +1026,19 @@ const defaultOverlayDatabaseModeTestSetup: OverlayDatabaseModeTestSetup = {
repositoryProperties: {},
};
const getOverlayDatabaseModeMacro = test.macro({
const checkOverlayEnablementMacro = test.macro({
exec: async (
t: ExecutionContext,
_title: string,
setupOverrides: Partial<OverlayDatabaseModeTestSetup>,
expected: {
overlayDatabaseMode: OverlayDatabaseMode;
useOverlayDatabaseCaching: boolean;
disabledReason?: OverlayDisabledReason;
},
expected:
| {
overlayDatabaseMode: OverlayDatabaseMode;
useOverlayDatabaseCaching: boolean;
}
| {
disabledReason: OverlayDisabledReason;
},
) => {
return await withTmpDir(async (tempDir) => {
const messages: LoggedMessage[] = [];
@@ -1100,7 +1096,7 @@ const getOverlayDatabaseModeMacro = test.macro({
.stub(gitUtils, "isAnalyzingDefaultBranch")
.resolves(setup.isDefaultBranch);
const result = await configUtils.getOverlayDatabaseMode(
const result = await configUtils.checkOverlayEnablement(
codeql,
features,
setup.languages,
@@ -1113,22 +1109,22 @@ const getOverlayDatabaseModeMacro = test.macro({
logger,
);
if (!("disabledReason" in expected)) {
expected.disabledReason = undefined;
if ("disabledReason" in expected) {
t.deepEqual(result, new Failure(expected.disabledReason));
} else {
t.deepEqual(result, new Success(expected));
}
t.deepEqual(result, expected);
} finally {
// Restore the original environment
process.env = originalEnv;
}
});
},
title: (_, title) => `getOverlayDatabaseMode: ${title}`,
title: (_, title) => `checkOverlayEnablement: ${title}`,
});
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Environment variable override - Overlay",
{
overlayDatabaseEnvVar: "overlay",
@@ -1140,7 +1136,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Environment variable override - OverlayBase",
{
overlayDatabaseEnvVar: "overlay-base",
@@ -1152,45 +1148,41 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Environment variable override - None",
{
overlayDatabaseEnvVar: "none",
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.DisabledByEnvironmentVariable,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Ignore invalid environment variable",
{
overlayDatabaseEnvVar: "invalid-mode",
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.FeatureNotEnabled,
disabledReason: OverlayDisabledReason.OverallFeatureNotEnabled,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Ignore feature flag when analyzing non-default branch",
{
languages: [KnownLanguage.javascript],
features: [Feature.OverlayAnalysis, Feature.OverlayAnalysisJavascript],
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.NotPullRequestOrDefaultBranch,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Overlay-base database on default branch when feature enabled",
{
languages: [KnownLanguage.javascript],
@@ -1204,7 +1196,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Overlay-base database on default branch when feature enabled with custom analysis",
{
languages: [KnownLanguage.javascript],
@@ -1221,7 +1213,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Overlay-base database on default branch when code-scanning feature enabled",
{
languages: [KnownLanguage.javascript],
@@ -1238,7 +1230,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay-base database on default branch if runner disk space is too low",
{
languages: [KnownLanguage.javascript],
@@ -1253,14 +1245,12 @@ test.serial(
},
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.InsufficientResources,
disabledReason: OverlayDisabledReason.InsufficientDiskSpace,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay-base database on default branch if we can't determine runner disk space",
{
languages: [KnownLanguage.javascript],
@@ -1272,14 +1262,12 @@ test.serial(
diskUsage: undefined,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.InsufficientResources,
disabledReason: OverlayDisabledReason.UnableToDetermineDiskUsage,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Overlay-base database on default branch if runner disk space is too low and skip resource checks flag is enabled",
{
languages: [KnownLanguage.javascript],
@@ -1301,7 +1289,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay-base database on default branch if runner disk space is below v2 limit and v2 resource checks enabled",
{
languages: [KnownLanguage.javascript],
@@ -1317,14 +1305,12 @@ test.serial(
},
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.InsufficientResources,
disabledReason: OverlayDisabledReason.InsufficientDiskSpace,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Overlay-base database on default branch if runner disk space is between v2 and v1 limits and v2 resource checks enabled",
{
languages: [KnownLanguage.javascript],
@@ -1346,7 +1332,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay-base database on default branch if runner disk space is between v2 and v1 limits and v2 resource checks not enabled",
{
languages: [KnownLanguage.javascript],
@@ -1361,14 +1347,12 @@ test.serial(
},
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.InsufficientResources,
disabledReason: OverlayDisabledReason.InsufficientDiskSpace,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay-base database on default branch if memory flag is too low",
{
languages: [KnownLanguage.javascript],
@@ -1380,14 +1364,12 @@ test.serial(
memoryFlagValue: 3072,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.InsufficientResources,
disabledReason: OverlayDisabledReason.InsufficientMemory,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Overlay-base database on default branch if memory flag is too low but CodeQL >= 2.24.3",
{
languages: [KnownLanguage.javascript],
@@ -1406,7 +1388,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Overlay-base database on default branch if memory flag is too low and skip resource checks flag is enabled",
{
languages: [KnownLanguage.javascript],
@@ -1425,7 +1407,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay-base database on default branch when cached status indicates previous failure",
{
languages: [KnownLanguage.javascript],
@@ -1438,14 +1420,12 @@ test.serial(
shouldSkipOverlayAnalysisDueToCachedStatus: true,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.SkippedDueToCachedStatus,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay analysis on PR when cached status indicates previous failure",
{
languages: [KnownLanguage.javascript],
@@ -1458,14 +1438,12 @@ test.serial(
shouldSkipOverlayAnalysisDueToCachedStatus: true,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.SkippedDueToCachedStatus,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay-base database on default branch when code-scanning feature enabled with disable-default-queries",
{
languages: [KnownLanguage.javascript],
@@ -1479,14 +1457,12 @@ test.serial(
isDefaultBranch: true,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.FeatureNotEnabled,
disabledReason: OverlayDisabledReason.NonDefaultQueries,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay-base database on default branch when code-scanning feature enabled with packs",
{
languages: [KnownLanguage.javascript],
@@ -1500,14 +1476,12 @@ test.serial(
isDefaultBranch: true,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.FeatureNotEnabled,
disabledReason: OverlayDisabledReason.NonDefaultQueries,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay-base database on default branch when code-scanning feature enabled with queries",
{
languages: [KnownLanguage.javascript],
@@ -1521,14 +1495,12 @@ test.serial(
isDefaultBranch: true,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.FeatureNotEnabled,
disabledReason: OverlayDisabledReason.NonDefaultQueries,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay-base database on default branch when code-scanning feature enabled with query-filters",
{
languages: [KnownLanguage.javascript],
@@ -1542,14 +1514,12 @@ test.serial(
isDefaultBranch: true,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.FeatureNotEnabled,
disabledReason: OverlayDisabledReason.NonDefaultQueries,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay-base database on default branch when only language-specific feature enabled",
{
languages: [KnownLanguage.javascript],
@@ -1557,14 +1527,12 @@ test.serial(
isDefaultBranch: true,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.FeatureNotEnabled,
disabledReason: OverlayDisabledReason.OverallFeatureNotEnabled,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay-base database on default branch when only code-scanning feature enabled",
{
languages: [KnownLanguage.javascript],
@@ -1572,14 +1540,12 @@ test.serial(
isDefaultBranch: true,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.FeatureNotEnabled,
disabledReason: OverlayDisabledReason.OverallFeatureNotEnabled,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay-base database on default branch when language-specific feature disabled",
{
languages: [KnownLanguage.javascript],
@@ -1587,14 +1553,12 @@ test.serial(
isDefaultBranch: true,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.FeatureNotEnabled,
disabledReason: OverlayDisabledReason.LanguageNotEnabled,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Overlay analysis on PR when feature enabled",
{
languages: [KnownLanguage.javascript],
@@ -1608,7 +1572,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Overlay analysis on PR when feature enabled with custom analysis",
{
languages: [KnownLanguage.javascript],
@@ -1625,7 +1589,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Overlay analysis on PR when code-scanning feature enabled",
{
languages: [KnownLanguage.javascript],
@@ -1642,7 +1606,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay analysis on PR if runner disk space is too low",
{
languages: [KnownLanguage.javascript],
@@ -1657,14 +1621,12 @@ test.serial(
},
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.InsufficientResources,
disabledReason: OverlayDisabledReason.InsufficientDiskSpace,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Overlay analysis on PR if runner disk space is too low and skip resource checks flag is enabled",
{
languages: [KnownLanguage.javascript],
@@ -1686,7 +1648,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay analysis on PR if we can't determine runner disk space",
{
languages: [KnownLanguage.javascript],
@@ -1698,14 +1660,12 @@ test.serial(
diskUsage: undefined,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.InsufficientResources,
disabledReason: OverlayDisabledReason.UnableToDetermineDiskUsage,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay analysis on PR if memory flag is too low",
{
languages: [KnownLanguage.javascript],
@@ -1717,14 +1677,12 @@ test.serial(
memoryFlagValue: 3072,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.InsufficientResources,
disabledReason: OverlayDisabledReason.InsufficientMemory,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Overlay analysis on PR if memory flag is too low but CodeQL >= 2.24.3",
{
languages: [KnownLanguage.javascript],
@@ -1743,7 +1701,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Overlay analysis on PR if memory flag is too low and skip resource checks flag is enabled",
{
languages: [KnownLanguage.javascript],
@@ -1762,7 +1720,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay analysis on PR when code-scanning feature enabled with disable-default-queries",
{
languages: [KnownLanguage.javascript],
@@ -1776,14 +1734,12 @@ test.serial(
isPullRequest: true,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.FeatureNotEnabled,
disabledReason: OverlayDisabledReason.NonDefaultQueries,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay analysis on PR when code-scanning feature enabled with packs",
{
languages: [KnownLanguage.javascript],
@@ -1797,14 +1753,12 @@ test.serial(
isPullRequest: true,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.FeatureNotEnabled,
disabledReason: OverlayDisabledReason.NonDefaultQueries,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay analysis on PR when code-scanning feature enabled with queries",
{
languages: [KnownLanguage.javascript],
@@ -1818,14 +1772,12 @@ test.serial(
isPullRequest: true,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.FeatureNotEnabled,
disabledReason: OverlayDisabledReason.NonDefaultQueries,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay analysis on PR when code-scanning feature enabled with query-filters",
{
languages: [KnownLanguage.javascript],
@@ -1839,14 +1791,12 @@ test.serial(
isPullRequest: true,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.FeatureNotEnabled,
disabledReason: OverlayDisabledReason.NonDefaultQueries,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay analysis on PR when only language-specific feature enabled",
{
languages: [KnownLanguage.javascript],
@@ -1854,14 +1804,12 @@ test.serial(
isPullRequest: true,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.FeatureNotEnabled,
disabledReason: OverlayDisabledReason.OverallFeatureNotEnabled,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay analysis on PR when only code-scanning feature enabled",
{
languages: [KnownLanguage.javascript],
@@ -1869,14 +1817,12 @@ test.serial(
isPullRequest: true,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.FeatureNotEnabled,
disabledReason: OverlayDisabledReason.OverallFeatureNotEnabled,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay analysis on PR when language-specific feature disabled",
{
languages: [KnownLanguage.javascript],
@@ -1884,14 +1830,12 @@ test.serial(
isPullRequest: true,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.FeatureNotEnabled,
disabledReason: OverlayDisabledReason.LanguageNotEnabled,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Overlay PR analysis by env",
{
overlayDatabaseEnvVar: "overlay",
@@ -1903,7 +1847,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Overlay PR analysis by env on a runner with low disk space",
{
overlayDatabaseEnvVar: "overlay",
@@ -1916,7 +1860,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Overlay PR analysis by feature flag",
{
languages: [KnownLanguage.javascript],
@@ -1930,7 +1874,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Fallback due to autobuild with traced language",
{
overlayDatabaseEnvVar: "overlay",
@@ -1938,14 +1882,12 @@ test.serial(
languages: [KnownLanguage.java],
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.IncompatibleBuildMode,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Fallback due to no build mode with traced language",
{
overlayDatabaseEnvVar: "overlay",
@@ -1953,70 +1895,60 @@ test.serial(
languages: [KnownLanguage.java],
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.IncompatibleBuildMode,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Fallback due to old CodeQL version",
{
overlayDatabaseEnvVar: "overlay",
codeqlVersion: "2.14.0",
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.IncompatibleCodeQl,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Fallback due to missing git root",
{
overlayDatabaseEnvVar: "overlay",
gitRoot: undefined,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.NoGitRoot,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Fallback due to old git version",
{
overlayDatabaseEnvVar: "overlay",
gitVersion: new GitVersionInfo("2.30.0", "2.30.0"), // Version below required 2.38.0
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.IncompatibleGit,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Fallback when git version cannot be determined",
{
overlayDatabaseEnvVar: "overlay",
gitVersion: undefined,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.IncompatibleGit,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"No overlay when disabled via repository property",
{
languages: [KnownLanguage.javascript],
@@ -2027,14 +1959,12 @@ test.serial(
},
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.DisabledByRepositoryProperty,
},
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Overlay not disabled when repository property is false",
{
languages: [KnownLanguage.javascript],
@@ -2051,7 +1981,7 @@ test.serial(
);
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
"Environment variable override takes precedence over repository property",
{
overlayDatabaseEnvVar: "overlay",
@@ -2068,7 +1998,7 @@ test.serial(
// Exercise language-specific overlay analysis features code paths
for (const language in KnownLanguage) {
test.serial(
getOverlayDatabaseModeMacro,
checkOverlayEnablementMacro,
`Check default overlay analysis feature for ${language}`,
{
languages: [language],
@@ -2076,9 +2006,7 @@ for (const language in KnownLanguage) {
isPullRequest: true,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: OverlayDisabledReason.FeatureNotEnabled,
disabledReason: OverlayDisabledReason.LanguageNotEnabled,
},
);
}
+175 -140
View File
@@ -69,6 +69,9 @@ import {
isInTestMode,
joinAtMost,
DiskUsage,
Result,
Success,
Failure,
} from "./util";
/**
@@ -653,14 +656,18 @@ const OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES: Record<Language, Feature> = {
swift: Feature.OverlayAnalysisCodeScanningSwift,
};
async function isOverlayAnalysisFeatureEnabled(
/**
* Checks whether the overlay analysis feature is enabled for the given
* languages and configuration.
*/
async function checkOverlayAnalysisFeatureEnabled(
features: FeatureEnablement,
codeql: CodeQL,
languages: Language[],
codeScanningConfig: UserConfig,
): Promise<boolean> {
): Promise<Result<void, OverlayDisabledReason>> {
if (!(await features.getValue(Feature.OverlayAnalysis, codeql))) {
return false;
return new Failure(OverlayDisabledReason.OverallFeatureNotEnabled);
}
let enableForCodeScanningOnly = false;
for (const language of languages) {
@@ -677,39 +684,35 @@ async function isOverlayAnalysisFeatureEnabled(
enableForCodeScanningOnly = true;
continue;
}
return false;
return new Failure(OverlayDisabledReason.LanguageNotEnabled);
}
if (enableForCodeScanningOnly) {
// A code-scanning configuration runs only the (default) code-scanning suite
// if the default queries are not disabled, and no packs, queries, or
// query-filters are specified.
return (
const usesDefaultQueriesOnly =
codeScanningConfig["disable-default-queries"] !== true &&
codeScanningConfig.packs === undefined &&
codeScanningConfig.queries === undefined &&
codeScanningConfig["query-filters"] === undefined
);
codeScanningConfig["query-filters"] === undefined;
if (!usesDefaultQueriesOnly) {
return new Failure(OverlayDisabledReason.NonDefaultQueries);
}
}
return true;
return new Success(undefined);
}
/** Checks if the runner has enough disk space for overlay analysis. */
function runnerHasSufficientDiskSpace(
diskUsage: DiskUsage | undefined,
diskUsage: DiskUsage,
logger: Logger,
useV2ResourceChecks: boolean,
): boolean {
const minimumDiskSpaceBytes = useV2ResourceChecks
? OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_V2_BYTES
: OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_BYTES;
if (
diskUsage === undefined ||
diskUsage.numAvailableBytes < minimumDiskSpaceBytes
) {
const diskSpaceMb =
diskUsage === undefined
? 0
: Math.round(diskUsage.numAvailableBytes / 1_000_000);
if (diskUsage.numAvailableBytes < minimumDiskSpaceBytes) {
const diskSpaceMb = Math.round(diskUsage.numAvailableBytes / 1_000_000);
const minimumDiskSpaceMb = Math.round(minimumDiskSpaceBytes / 1_000_000);
logger.info(
`Setting overlay database mode to ${OverlayDatabaseMode.None} ` +
@@ -754,23 +757,28 @@ async function runnerHasSufficientMemory(
}
/**
* Checks if the runner supports overlay analysis based on available disk space
* and the maximum memory CodeQL will be allowed to use.
* Checks if the runner has sufficient disk space and memory for overlay
* analysis.
*/
async function runnerSupportsOverlayAnalysis(
async function checkRunnerResources(
codeql: CodeQL,
diskUsage: DiskUsage | undefined,
diskUsage: DiskUsage,
ramInput: string | undefined,
logger: Logger,
useV2ResourceChecks: boolean,
): Promise<boolean> {
): Promise<Result<void, OverlayDisabledReason>> {
if (!runnerHasSufficientDiskSpace(diskUsage, logger, useV2ResourceChecks)) {
return false;
return new Failure(OverlayDisabledReason.InsufficientDiskSpace);
}
if (!(await runnerHasSufficientMemory(codeql, ramInput, logger))) {
return false;
return new Failure(OverlayDisabledReason.InsufficientMemory);
}
return true;
return new Success(undefined);
}
interface EnabledOverlayConfig {
overlayDatabaseMode: Exclude<OverlayDatabaseMode, OverlayDatabaseMode.None>;
useOverlayDatabaseCaching: boolean;
}
/**
@@ -791,10 +799,11 @@ async function runnerSupportsOverlayAnalysis(
* For `Overlay` and `OverlayBase`, the function performs further checks and
* reverts to `None` if any check should fail.
*
* @returns An object containing the overlay database mode and whether the
* action should perform overlay-base database caching.
* @returns A `Success` containing the overlay database mode and whether the
* action should perform overlay-base database caching, or a `Failure`
* containing the reason why overlay analysis is disabled.
*/
export async function getOverlayDatabaseMode(
export async function checkOverlayEnablement(
codeql: CodeQL,
features: FeatureEnablement,
languages: Language[],
@@ -805,15 +814,7 @@ export async function getOverlayDatabaseMode(
repositoryProperties: RepositoryProperties,
gitVersion: GitVersionInfo | undefined,
logger: Logger,
): Promise<{
overlayDatabaseMode: OverlayDatabaseMode;
useOverlayDatabaseCaching: boolean;
disabledReason: OverlayDisabledReason | undefined;
}> {
let overlayDatabaseMode = OverlayDatabaseMode.None;
let useOverlayDatabaseCaching = false;
let disabledReason: OverlayDisabledReason | undefined;
): Promise<Result<EnabledOverlayConfig, OverlayDisabledReason>> {
const modeEnv = process.env.CODEQL_OVERLAY_DATABASE_MODE;
// Any unrecognized CODEQL_OVERLAY_DATABASE_MODE value will be ignored and
// treated as if the environment variable was not set.
@@ -822,101 +823,132 @@ 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
) {
if (modeEnv === OverlayDatabaseMode.None) {
return new Failure(OverlayDisabledReason.DisabledByEnvironmentVariable);
}
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 (
await isOverlayAnalysisFeatureEnabled(
features,
codeql,
languages,
codeScanningConfig,
)
return new Failure(OverlayDisabledReason.DisabledByRepositoryProperty);
}
const featureResult = await checkOverlayAnalysisFeatureEnabled(
features,
codeql,
languages,
codeScanningConfig,
);
if (featureResult.isFailure()) {
return featureResult;
}
const performResourceChecks = !(await features.getValue(
Feature.OverlayAnalysisSkipResourceChecks,
codeql,
));
const useV2ResourceChecks = await features.getValue(
Feature.OverlayAnalysisResourceChecksV2,
);
const checkOverlayStatus = await features.getValue(
Feature.OverlayAnalysisStatusCheck,
);
const needDiskUsage = performResourceChecks || checkOverlayStatus;
const diskUsage = needDiskUsage ? await checkDiskUsage(logger) : undefined;
if (needDiskUsage && diskUsage === undefined) {
logger.warning(
`Unable to determine disk usage, therefore setting overlay database mode to ${OverlayDatabaseMode.None}.`,
);
return new Failure(OverlayDisabledReason.UnableToDetermineDiskUsage);
}
const resourceResult =
performResourceChecks && diskUsage !== undefined
? await checkRunnerResources(
codeql,
diskUsage,
ramInput,
logger,
useV2ResourceChecks,
)
: new Success<void>(undefined);
if (resourceResult.isFailure()) {
return resourceResult;
}
if (
checkOverlayStatus &&
diskUsage !== undefined &&
(await shouldSkipOverlayAnalysis(codeql, languages, diskUsage, logger))
) {
const performResourceChecks = !(await features.getValue(
Feature.OverlayAnalysisSkipResourceChecks,
codeql,
));
const useV2ResourceChecks = await features.getValue(
Feature.OverlayAnalysisResourceChecksV2,
logger.info(
`Setting overlay database mode to ${OverlayDatabaseMode.None} ` +
"because overlay analysis previously failed with this combination of languages, " +
"disk space, and CodeQL version.",
);
const checkOverlayStatus = await features.getValue(
Feature.OverlayAnalysisStatusCheck,
return new Failure(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.",
);
const diskUsage =
performResourceChecks || checkOverlayStatus
? await checkDiskUsage(logger)
: undefined;
if (
performResourceChecks &&
!(await runnerSupportsOverlayAnalysis(
codeql,
diskUsage,
ramInput,
logger,
useV2ResourceChecks,
))
) {
overlayDatabaseMode = OverlayDatabaseMode.None;
disabledReason = OverlayDisabledReason.InsufficientResources;
} 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.",
);
}
} else {
disabledReason = OverlayDisabledReason.FeatureNotEnabled;
return new Failure(OverlayDisabledReason.NotPullRequestOrDefaultBranch);
}
const disabledResult = (reason: OverlayDisabledReason | undefined) => ({
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
disabledReason: reason,
});
if (overlayDatabaseMode === OverlayDatabaseMode.None) {
return disabledResult(disabledReason);
}
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: Exclude<OverlayDatabaseMode, OverlayDatabaseMode.None>,
useOverlayDatabaseCaching: boolean,
codeql: CodeQL,
languages: Language[],
sourceRoot: string,
buildMode: BuildMode | undefined,
gitVersion: GitVersionInfo | undefined,
logger: Logger,
): Promise<Result<EnabledOverlayConfig, OverlayDisabledReason>> {
if (
buildMode !== BuildMode.None &&
(
@@ -937,7 +969,7 @@ export async function getOverlayDatabaseMode(
`build-mode is set to "${buildMode}" instead of "none". ` +
"Falling back to creating a normal full database instead.",
);
return disabledResult(OverlayDisabledReason.IncompatibleBuildMode);
return new Failure(OverlayDisabledReason.IncompatibleBuildMode);
}
if (!(await codeQlVersionAtLeast(codeql, CODEQL_OVERLAY_MINIMUM_VERSION))) {
logger.warning(
@@ -945,7 +977,7 @@ export async function getOverlayDatabaseMode(
`the CodeQL CLI is older than ${CODEQL_OVERLAY_MINIMUM_VERSION}. ` +
"Falling back to creating a normal full database instead.",
);
return disabledResult(OverlayDisabledReason.IncompatibleCodeQl);
return new Failure(OverlayDisabledReason.IncompatibleCodeQl);
}
if ((await getGitRoot(sourceRoot)) === undefined) {
logger.warning(
@@ -953,7 +985,7 @@ export async function getOverlayDatabaseMode(
`the source root "${sourceRoot}" is not inside a git repository. ` +
"Falling back to creating a normal full database instead.",
);
return disabledResult(OverlayDisabledReason.NoGitRoot);
return new Failure(OverlayDisabledReason.NoGitRoot);
}
if (gitVersion === undefined) {
logger.warning(
@@ -961,7 +993,7 @@ export async function getOverlayDatabaseMode(
"the Git version could not be determined. " +
"Falling back to creating a normal full database instead.",
);
return disabledResult(OverlayDisabledReason.IncompatibleGit);
return new Failure(OverlayDisabledReason.IncompatibleGit);
}
if (!gitVersion.isAtLeast(GIT_MINIMUM_VERSION_FOR_OVERLAY)) {
logger.warning(
@@ -969,14 +1001,13 @@ export async function getOverlayDatabaseMode(
`the installed Git version is older than ${GIT_MINIMUM_VERSION_FOR_OVERLAY}. ` +
"Falling back to creating a normal full database instead.",
);
return disabledResult(OverlayDisabledReason.IncompatibleGit);
return new Failure(OverlayDisabledReason.IncompatibleGit);
}
return {
return new Success({
overlayDatabaseMode,
useOverlayDatabaseCaching,
disabledReason,
};
});
}
function dbLocationOrDefault(
@@ -1122,11 +1153,7 @@ export async function initConfig(
// and queries, which in turn depends on the user config and the augmentation
// properties. So we need to calculate the overlay database mode after the
// rest of the config has been populated.
const {
overlayDatabaseMode,
useOverlayDatabaseCaching,
disabledReason: overlayDisabledReason,
} = await getOverlayDatabaseMode(
const overlayDatabaseModeResult = await checkOverlayEnablement(
inputs.codeql,
inputs.features,
config.languages,
@@ -1138,14 +1165,22 @@ export async function initConfig(
gitVersion,
logger,
);
logger.info(
`Using overlay database mode: ${overlayDatabaseMode} ` +
`${useOverlayDatabaseCaching ? "with" : "without"} caching.`,
);
config.overlayDatabaseMode = overlayDatabaseMode;
config.useOverlayDatabaseCaching = useOverlayDatabaseCaching;
if (overlayDisabledReason !== undefined) {
if (overlayDatabaseModeResult.isSuccess()) {
const { overlayDatabaseMode, useOverlayDatabaseCaching } =
overlayDatabaseModeResult.value;
logger.info(
`Using overlay database mode: ${overlayDatabaseMode} ` +
`${useOverlayDatabaseCaching ? "with" : "without"} caching.`,
);
config.overlayDatabaseMode = overlayDatabaseMode;
config.useOverlayDatabaseCaching = useOverlayDatabaseCaching;
} else {
const overlayDisabledReason = overlayDatabaseModeResult.value;
logger.info(
`Using overlay database mode: ${OverlayDatabaseMode.None} without caching.`,
);
config.overlayDatabaseMode = OverlayDatabaseMode.None;
config.useOverlayDatabaseCaching = false;
await addOverlayDisablementDiagnostics(
config,
inputs.codeql,
@@ -1154,7 +1189,7 @@ export async function initConfig(
}
if (
overlayDatabaseMode === OverlayDatabaseMode.Overlay ||
config.overlayDatabaseMode === OverlayDatabaseMode.Overlay ||
(await shouldPerformDiffInformedAnalysis(
inputs.codeql,
inputs.features,
+4 -4
View File
@@ -1,6 +1,6 @@
{
"bundleVersion": "codeql-bundle-v2.24.2",
"cliVersion": "2.24.2",
"priorBundleVersion": "codeql-bundle-v2.24.1",
"priorCliVersion": "2.24.1"
"bundleVersion": "codeql-bundle-v2.24.3",
"cliVersion": "2.24.3",
"priorBundleVersion": "codeql-bundle-v2.24.2",
"priorCliVersion": "2.24.2"
}
+19 -4
View File
@@ -10,20 +10,35 @@ import { RepositoryPropertyName } from "../feature-flags/properties";
/** Reason why overlay analysis was disabled. */
export enum OverlayDisabledReason {
/** Overlay analysis was disabled by the CODEQL_OVERLAY_DATABASE_MODE environment variable being set to "none". */
DisabledByEnvironmentVariable = "disabled-by-environment-variable",
/** Overlay analysis was disabled by a repository property. */
DisabledByRepositoryProperty = "disabled-by-repository-property",
/** Overlay analysis feature was not enabled. */
FeatureNotEnabled = "feature-not-enabled",
/** The build mode is incompatible with overlay analysis. */
IncompatibleBuildMode = "incompatible-build-mode",
/** The CodeQL CLI version is too old to support overlay analysis. */
IncompatibleCodeQl = "incompatible-codeql",
/** The Git version could not be determined or is too old. */
IncompatibleGit = "incompatible-git",
/** The runner does not have enough disk space or memory. */
InsufficientResources = "insufficient-resources",
/** The runner does not have enough disk space to perform overlay analysis. */
InsufficientDiskSpace = "insufficient-disk-space",
/** The runner does not have enough memory to perform overlay analysis. */
InsufficientMemory = "insufficient-memory",
/** Overlay analysis is not enabled for one or more of the configured languages. */
LanguageNotEnabled = "language-not-enabled",
/** The source root is not inside a git repository. */
NoGitRoot = "no-git-root",
/**
* For one or more of the configured languages, overlay analysis is only
* enabled when using the default query suite, but the config customises the
* queries by disabling default queries, specifying custom queries or packs,
* or adding 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. */
SkippedDueToCachedStatus = "skipped-due-to-cached-status",
/** Disk usage could not be determined during the overlay status check. */