Use overlay-aware CodeQL versions by default

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Henry Mercer
2026-10-15 11:01:45 +01:00
parent 0e72543776
commit 6d82d4f441
4 changed files with 162 additions and 73 deletions

19
lib/entry-points.js generated
View File

@@ -172084,11 +172084,6 @@ var featureConfig = {
envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_DISABLE_TRAP_CACHING",
minimumVersion: void 0
},
["overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION",
minimumVersion: void 0
},
["overlay_analysis_min_disk_8_gb" /* OverlayAnalysisMinDisk8Gb */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MIN_DISK_8_GB",
@@ -176278,13 +176273,10 @@ async function findOverridingToolsInCache(humanReadableVersion, logger2) {
}
return void 0;
}
async function getEnabledVersionsWithOverlayBaseDatabases(defaultCliVersion, rawLanguages, features, logger2) {
async function getEnabledVersionsWithOverlayBaseDatabases(defaultCliVersion, rawLanguages, logger2) {
if (rawLanguages === void 0 || rawLanguages.length === 0) {
return [];
}
if (!await features.getValue("overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */)) {
return [];
}
let cachedVersions;
try {
cachedVersions = await getCodeQlVersionsForOverlayBaseDatabases(
@@ -176309,14 +176301,13 @@ async function getEnabledVersionsWithOverlayBaseDatabases(defaultCliVersion, raw
}
return overlayVersions;
}
async function resolveDefaultCliVersion(defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, features, logger2) {
if (!useOverlayAwareDefaultCliVersion || !isAnalyzingPullRequest()) {
async function resolveDefaultCliVersion(defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, variant, logger2) {
if (!useOverlayAwareDefaultCliVersion || variant !== "GitHub.com" /* DOTCOM */ && variant !== "GitHub Enterprise Cloud with data residency" /* GHEC_DR */ || defaultCliVersion.enabledVersions.length === 1 || !isAnalyzingPullRequest()) {
return defaultCliVersion.enabledVersions[0];
}
const overlayVersions = await getEnabledVersionsWithOverlayBaseDatabases(
defaultCliVersion,
rawLanguages,
features,
logger2
);
if (overlayVersions.length > 0) {
@@ -176423,7 +176414,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, othe
defaultCliVersion,
rawLanguages,
useOverlayAwareDefaultCliVersion,
features,
variant,
logger2
);
cliVersion2 = version.cliVersion;
@@ -176443,7 +176434,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, othe
defaultCliVersion,
rawLanguages,
useOverlayAwareDefaultCliVersion,
features,
variant,
logger2
);
cliVersion2 = version.cliVersion;

View File

@@ -113,13 +113,6 @@ export enum Feature {
OverlayAnalysisGo = "overlay_analysis_go",
OverlayAnalysisJava = "overlay_analysis_java",
OverlayAnalysisJavascript = "overlay_analysis_javascript",
/**
* When set, chooses the default CodeQL CLI version as the highest version that is both enabled by
* feature flags and present as an overlay-base database in the Actions cache for the configured
* languages. Falls back to the highest feature flagged version if no intersecting overlay-base
* database exists in the cache.
*/
OverlayAnalysisMatchCodeqlVersion = "overlay_analysis_match_codeql_version",
/**
* Lowers the overlay minimum available disk space to 8 GB. The lowest enabled limit wins; if
* none are enabled, the default applies.
@@ -378,11 +371,6 @@ export const featureConfig = {
envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_DISABLE_TRAP_CACHING",
minimumVersion: undefined,
},
[Feature.OverlayAnalysisMatchCodeqlVersion]: {
defaultValue: false,
envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION",
minimumVersion: undefined,
},
[Feature.OverlayAnalysisMinDisk8Gb]: {
defaultValue: false,
envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MIN_DISK_8_GB",

View File

@@ -1069,8 +1069,53 @@ async function fakeOverlayBaseCacheKey(
return `${prefix}${suffix}`;
}
for (const variant of [GitHubVariant.DOTCOM, GitHubVariant.GHEC_DR]) {
test.serial(
`getCodeQLSource uses overlay-aware default version for a Code Scanning PR on ${variant}`,
async (t) => {
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
process.env[EnvVar.CODE_SCANNING_REF] = "refs/heads/feature-branch";
process.env[EnvVar.CODE_SCANNING_BASE_BRANCH] = "main";
sinon.stub(api, "getAutomationID").resolves("test/");
const listStub = sinon.stub(api, "listActionsCaches").resolves([
{
key: await fakeOverlayBaseCacheKey(
"javascript",
"2.20.1",
"abc-1-1",
),
},
]);
sinon
.stub(toolcache, "find")
.withArgs("CodeQL", "2.20.1")
.returns("/path/to/codeql-2.20.1");
const source = await setupCodeql.getCodeQLSource(
undefined,
overlayMatchEnabledVersions,
["javascript"],
undefined, // otherLanguagePacksReason
true,
SAMPLE_DOTCOM_API_DETAILS,
variant,
false,
createFeatures([]),
getRunnerLogger(true),
);
t.assert(listStub.calledOnce);
t.is(source.sourceType, "toolcache");
t.is(source.toolsVersion, "2.20.1");
});
},
);
}
test.serial(
"getCodeQLSource uses overlay-aware default version when requested for a PR",
"getCodeQLSource skips overlay-aware default version for a Code Scanning PR on GHES",
async (t) => {
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
@@ -1085,8 +1130,96 @@ test.serial(
]);
sinon
.stub(toolcache, "find")
.withArgs("CodeQL", "2.20.1")
.returns("/path/to/codeql-2.20.1");
.withArgs("CodeQL", "2.20.2")
.returns("/path/to/codeql-2.20.2");
const source = await setupCodeql.getCodeQLSource(
undefined,
overlayMatchEnabledVersions,
["javascript"],
undefined, // otherLanguagePacksReason
true,
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.GHES,
false,
createFeatures([]),
getRunnerLogger(true),
);
t.assert(listStub.notCalled);
t.is(source.sourceType, "toolcache");
t.is(source.toolsVersion, "2.20.2");
});
},
);
test.serial(
"getCodeQLSource skips the Actions cache when only one default version is enabled",
async (t) => {
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
process.env[EnvVar.CODE_SCANNING_REF] = "refs/heads/feature-branch";
process.env[EnvVar.CODE_SCANNING_BASE_BRANCH] = "main";
sinon.stub(api, "getAutomationID").resolves("test/");
const listStub = sinon.stub(api, "listActionsCaches").resolves([
{
key: await fakeOverlayBaseCacheKey(
"javascript",
SAMPLE_DEFAULT_CLI_VERSION.enabledVersions[0].cliVersion,
"abc-1-1",
),
},
]);
sinon
.stub(toolcache, "find")
.withArgs(
"CodeQL",
SAMPLE_DEFAULT_CLI_VERSION.enabledVersions[0].cliVersion,
)
.returns("/path/to/codeql");
const source = await setupCodeql.getCodeQLSource(
undefined,
SAMPLE_DEFAULT_CLI_VERSION,
["javascript"],
undefined, // otherLanguagePacksReason
true,
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
false,
createFeatures([]),
getRunnerLogger(true),
);
t.assert(listStub.notCalled);
t.is(source.sourceType, "toolcache");
t.is(
source.toolsVersion,
SAMPLE_DEFAULT_CLI_VERSION.enabledVersions[0].cliVersion,
);
});
},
);
test.serial(
"getCodeQLSource skips overlay-aware default version outside pull request analysis",
async (t) => {
sinon.stub(actionsUtil, "isAnalyzingPullRequest").returns(false);
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
sinon.stub(api, "getAutomationID").resolves("test/");
const listStub = sinon.stub(api, "listActionsCaches").resolves([
{
key: await fakeOverlayBaseCacheKey("javascript", "2.20.1", "abc-1-1"),
},
]);
sinon
.stub(toolcache, "find")
.withArgs("CodeQL", "2.20.2")
.returns("/path/to/codeql-2.20.2");
const source = await setupCodeql.getCodeQLSource(
undefined,
@@ -1097,19 +1230,19 @@ test.serial(
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
false,
createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]),
createFeatures([]),
getRunnerLogger(true),
);
t.assert(listStub.calledOnce);
t.assert(listStub.notCalled);
t.is(source.sourceType, "toolcache");
t.is(source.toolsVersion, "2.20.1");
t.is(source.toolsVersion, "2.20.2");
});
},
);
test.serial(
"getCodeQLSource skips overlay-aware default version when not requested",
"getCodeQLSource skips overlay-aware default version when not requested for Code Scanning",
async (t) => {
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
@@ -1136,7 +1269,7 @@ test.serial(
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
false,
createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]),
createFeatures([]),
getRunnerLogger(true),
);
@@ -1611,7 +1744,7 @@ test.serial(
);
test.serial(
"getEnabledVersionsWithOverlayBaseDatabases returns flag-enabled versions present in cache, sorted desc",
"getEnabledVersionsWithOverlayBaseDatabases returns enabled versions present in cache, sorted desc",
async (t) => {
sinon.stub(api, "getAutomationID").resolves("test/");
sinon.stub(api, "listActionsCaches").resolves([
@@ -1632,7 +1765,6 @@ test.serial(
const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases(
overlayMatchEnabledVersions,
["javascript"],
createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]),
getRunnerLogger(true),
);
t.deepEqual(result, [
@@ -1643,7 +1775,7 @@ test.serial(
);
test.serial(
"getEnabledVersionsWithOverlayBaseDatabases returns empty when no cached version is flag-enabled",
"getEnabledVersionsWithOverlayBaseDatabases returns empty when no cached version is enabled",
async (t) => {
sinon.stub(api, "getAutomationID").resolves("test/");
sinon.stub(api, "listActionsCaches").resolves([
@@ -1655,7 +1787,6 @@ test.serial(
const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases(
overlayMatchEnabledVersions,
["javascript"],
createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]),
getRunnerLogger(true),
);
t.deepEqual(result, []);
@@ -1672,7 +1803,6 @@ const noLanguagesMacro = makeMacro({
const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases(
overlayMatchEnabledVersions,
rawLanguages,
createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]),
getRunnerLogger(true),
);
t.deepEqual(result, []);
@@ -1697,7 +1827,6 @@ test.serial(
const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases(
overlayMatchEnabledVersions,
["javascript"],
createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]),
getRunnerLogger(true),
);
t.deepEqual(result, []);
@@ -1717,7 +1846,6 @@ test.serial(
const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases(
overlayMatchEnabledVersions,
["javascript"],
createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]),
getRunnerLogger(true),
);
t.deepEqual(result, [
@@ -1726,25 +1854,6 @@ test.serial(
},
);
test.serial(
"getEnabledVersionsWithOverlayBaseDatabases does not list caches when the gate is off",
async (t) => {
const listStub = sinon.stub(api, "listActionsCaches").resolves([]);
const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases(
overlayMatchEnabledVersions,
["javascript"],
createFeatures([]),
getRunnerLogger(true),
);
t.deepEqual(result, []);
t.assert(
listStub.notCalled,
"Should not list Actions caches when the gating feature flag is off.",
);
},
);
/** The CLI version that the toolcache cleanup tests download. */
const CLEANUP_CLI_VERSION = "2.21.0";
/** The bundle version that the toolcache cleanup tests download. */

View File

@@ -183,21 +183,16 @@ async function findOverridingToolsInCache(
/**
* Returns the sorted set of enabled versions that have cached overlay-base databases for the
* given languages, or an empty list if the `OverlayAnalysisMatchCodeqlVersion` feature flag is
* disabled.
* given languages.
*/
export async function getEnabledVersionsWithOverlayBaseDatabases(
defaultCliVersion: CodeQLDefaultVersionInfo,
rawLanguages: string[] | undefined,
features: FeatureEnablement,
logger: Logger,
): Promise<CodeQLVersionInfo[]> {
if (rawLanguages === undefined || rawLanguages.length === 0) {
return [];
}
if (!(await features.getValue(Feature.OverlayAnalysisMatchCodeqlVersion))) {
return [];
}
let cachedVersions: string[] | undefined;
try {
@@ -231,24 +226,30 @@ export async function getEnabledVersionsWithOverlayBaseDatabases(
/**
* Resolves the newest enabled default CLI version that has a cached overlay-base database for the
* relevant languages, if running a Code Scanning analysis for a pull request and one exists.
* Otherwise, falls back to the newest enabled default CLI version.
* relevant languages, if running a Code Scanning analysis for a pull request with multiple enabled
* default versions in a supported environment and one exists. Otherwise, falls back to the newest
* enabled default CLI version.
*/
async function resolveDefaultCliVersion(
defaultCliVersion: CodeQLDefaultVersionInfo,
rawLanguages: string[] | undefined,
useOverlayAwareDefaultCliVersion: boolean,
features: FeatureEnablement,
variant: util.GitHubVariant,
logger: Logger,
): Promise<CodeQLVersionInfo> {
if (!useOverlayAwareDefaultCliVersion || !isAnalyzingPullRequest()) {
if (
!useOverlayAwareDefaultCliVersion ||
(variant !== util.GitHubVariant.DOTCOM &&
variant !== util.GitHubVariant.GHEC_DR) ||
defaultCliVersion.enabledVersions.length === 1 ||
!isAnalyzingPullRequest()
) {
return defaultCliVersion.enabledVersions[0];
}
const overlayVersions = await getEnabledVersionsWithOverlayBaseDatabases(
defaultCliVersion,
rawLanguages,
features,
logger,
);
if (overlayVersions.length > 0) {
@@ -445,7 +446,7 @@ export async function getCodeQLSource(
defaultCliVersion,
rawLanguages,
useOverlayAwareDefaultCliVersion,
features,
variant,
logger,
);
cliVersion = version.cliVersion;
@@ -468,7 +469,7 @@ export async function getCodeQLSource(
defaultCliVersion,
rawLanguages,
useOverlayAwareDefaultCliVersion,
features,
variant,
logger,
);
cliVersion = version.cliVersion;