diff --git a/lib/entry-points.js b/lib/entry-points.js index d5e64717a0..b6728397f6 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -172084,16 +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_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */]: { - defaultValue: false, - envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION_DRY_RUN", - minimumVersion: void 0 - }, ["overlay_analysis_min_disk_8_gb" /* OverlayAnalysisMinDisk8Gb */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MIN_DISK_8_GB", @@ -176283,17 +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 []; } - const isEnabled = await features.getValue( - "overlay_analysis_match_codeql_version" /* OverlayAnalysisMatchCodeqlVersion */ - ); - const isDryRun = !isEnabled && await features.getValue("overlay_analysis_match_codeql_version_dry_run" /* OverlayAnalysisMatchCodeqlVersionDryRun */); - if (!isEnabled && !isDryRun) { - return []; - } let cachedVersions; try { cachedVersions = await getCodeQlVersionsForOverlayBaseDatabases( @@ -176310,46 +176293,17 @@ async function getEnabledVersionsWithOverlayBaseDatabases(defaultCliVersion, raw return []; } const cachedVersionsSet = new Set(cachedVersions); - const overlayVersions = defaultCliVersion.enabledVersions.filter( + return defaultCliVersion.enabledVersions.filter( (v) => cachedVersionsSet.has(v.cliVersion) ); - if (overlayVersions.length === 0) { - return []; - } - const isCachedVersionDifferent = overlayVersions[0].cliVersion !== defaultCliVersion.enabledVersions[0].cliVersion; - if (isCachedVersionDifferent) { - addNoLanguageDiagnostic( - void 0, - makeTelemetryDiagnostic( - "codeql-action/overlay-aware-default-codeql-version", - "Overlay-aware default CodeQL version selection", - { - cachedVersions, - enabledVersions: defaultCliVersion.enabledVersions.map( - (v) => v.cliVersion - ), - isDryRun, - overlayAwareVersion: overlayVersions[0].cliVersion - } - ) - ); - } - if (isDryRun) { - logger2.debug( - `Overlay-aware default CodeQL version selection is running in dry-run mode. Would have used version ${overlayVersions[0].cliVersion}.` - ); - return []; - } - 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) { @@ -176456,7 +176410,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, othe defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, - features, + variant, logger2 ); cliVersion2 = version.cliVersion; @@ -176476,7 +176430,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, othe defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, - features, + variant, logger2 ); cliVersion2 = version.cliVersion; diff --git a/src/feature-flags.ts b/src/feature-flags.ts index f74d0bd250..fcb2bbc9d3 100644 --- a/src/feature-flags.ts +++ b/src/feature-flags.ts @@ -113,19 +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", - /** - * Like `OverlayAnalysisMatchCodeqlVersion`, but only logs a diagnostic with the version that - * would have been chosen instead of actually changing the default CodeQL CLI version. - * `OverlayAnalysisMatchCodeqlVersion` overrides this flag. - */ - OverlayAnalysisMatchCodeqlVersionDryRun = "overlay_analysis_match_codeql_version_dry_run", /** * Lowers the overlay minimum available disk space to 8 GB. The lowest enabled limit wins; if * none are enabled, the default applies. @@ -384,16 +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.OverlayAnalysisMatchCodeqlVersionDryRun]: { - defaultValue: false, - envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION_DRY_RUN", - minimumVersion: undefined, - }, [Feature.OverlayAnalysisMinDisk8Gb]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MIN_DISK_8_GB", diff --git a/src/setup-codeql.test.ts b/src/setup-codeql.test.ts index 6bdb29f462..a120d6ebd0 100644 --- a/src/setup-codeql.test.ts +++ b/src/setup-codeql.test.ts @@ -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,8 @@ 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, @@ -1095,21 +1140,109 @@ test.serial( 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([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, + SAMPLE_DEFAULT_CLI_VERSION.enabledVersions[0].cliVersion, + ); }); }, ); test.serial( - "getCodeQLSource skips overlay-aware default version when not requested", + "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, + overlayMatchEnabledVersions, + ["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, "2.20.2"); + }); + }, +); + +test.serial( + "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,78 +1854,6 @@ test.serial( }, ); -test.serial( - "getEnabledVersionsWithOverlayBaseDatabases does not list caches when both gates are 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 both gating feature flags are off.", - ); - }, -); - -test.serial( - "getEnabledVersionsWithOverlayBaseDatabases dry-run returns empty but lists caches", - async (t) => { - sinon.stub(api, "getAutomationID").resolves("test/"); - const listStub = sinon.stub(api, "listActionsCaches").resolves([ - { - key: await fakeOverlayBaseCacheKey("javascript", "2.20.1", "abc-1-1"), - }, - ]); - - const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases( - overlayMatchEnabledVersions, - ["javascript"], - createFeatures([Feature.OverlayAnalysisMatchCodeqlVersionDryRun]), - getRunnerLogger(true), - ); - t.deepEqual( - result, - [], - "Dry-run should return an empty list so the caller falls back.", - ); - t.assert( - listStub.calledOnce, - "Dry-run should still list Actions caches to populate the diagnostic.", - ); - }, -); - -test.serial( - "getEnabledVersionsWithOverlayBaseDatabases match flag wins over dry-run", - async (t) => { - sinon.stub(api, "getAutomationID").resolves("test/"); - sinon.stub(api, "listActionsCaches").resolves([ - { - key: await fakeOverlayBaseCacheKey("javascript", "2.20.1", "abc-1-1"), - }, - ]); - - const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases( - overlayMatchEnabledVersions, - ["javascript"], - createFeatures([ - Feature.OverlayAnalysisMatchCodeqlVersion, - Feature.OverlayAnalysisMatchCodeqlVersionDryRun, - ]), - getRunnerLogger(true), - ); - t.deepEqual(result, [ - { cliVersion: "2.20.1", tagName: "codeql-bundle-v2.20.1" }, - ]); - }, -); - /** 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. */ diff --git a/src/setup-codeql.ts b/src/setup-codeql.ts index 07666d6302..cece0dcd22 100644 --- a/src/setup-codeql.ts +++ b/src/setup-codeql.ts @@ -183,29 +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 neither the `OverlayAnalysisMatchCodeqlVersion` nor the - * `OverlayAnalysisMatchCodeqlVersionDryRun` feature flag is enabled. When only the dry-run flag - * is enabled, this performs the lookup and emits a telemetry diagnostic with the version that - * would have been chosen, but still returns an empty list so the caller falls back. + * given languages. */ export async function getEnabledVersionsWithOverlayBaseDatabases( defaultCliVersion: CodeQLDefaultVersionInfo, rawLanguages: string[] | undefined, - features: FeatureEnablement, logger: Logger, ): Promise { if (rawLanguages === undefined || rawLanguages.length === 0) { return []; } - const isEnabled = await features.getValue( - Feature.OverlayAnalysisMatchCodeqlVersion, - ); - const isDryRun = - !isEnabled && - (await features.getValue(Feature.OverlayAnalysisMatchCodeqlVersionDryRun)); - if (!isEnabled && !isDryRun) { - return []; - } let cachedVersions: string[] | undefined; try { @@ -226,66 +213,37 @@ export async function getEnabledVersionsWithOverlayBaseDatabases( } const cachedVersionsSet = new Set(cachedVersions); - const overlayVersions = defaultCliVersion.enabledVersions.filter((v) => + return defaultCliVersion.enabledVersions.filter((v) => cachedVersionsSet.has(v.cliVersion), ); - - if (overlayVersions.length === 0) { - return []; - } - - const isCachedVersionDifferent = - overlayVersions[0].cliVersion !== - defaultCliVersion.enabledVersions[0].cliVersion; - - if (isCachedVersionDifferent) { - addNoLanguageDiagnostic( - undefined, - makeTelemetryDiagnostic( - "codeql-action/overlay-aware-default-codeql-version", - "Overlay-aware default CodeQL version selection", - { - cachedVersions, - enabledVersions: defaultCliVersion.enabledVersions.map( - (v) => v.cliVersion, - ), - isDryRun, - overlayAwareVersion: overlayVersions[0].cliVersion, - }, - ), - ); - } - - if (isDryRun) { - logger.debug( - `Overlay-aware default CodeQL version selection is running in dry-run mode. Would have used version ${overlayVersions[0].cliVersion}.`, - ); - return []; - } - - return overlayVersions; } /** * 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 { - 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) { @@ -482,7 +440,7 @@ export async function getCodeQLSource( defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, - features, + variant, logger, ); cliVersion = version.cliVersion; @@ -505,7 +463,7 @@ export async function getCodeQLSource( defaultCliVersion, rawLanguages, useOverlayAwareDefaultCliVersion, - features, + variant, logger, ); cliVersion = version.cliVersion;