From 90d7727554572f07b95ea521dd37dc22534d1b0d Mon Sep 17 00:00:00 2001 From: Chuan-kai Lin Date: Thu, 10 Jul 2025 14:10:36 -0700 Subject: [PATCH] Overlay: check code-scanning features --- src/config-utils.test.ts | 263 ++++++++++++++++++++++++++++++++++++++- src/config-utils.ts | 39 +++++- 2 files changed, 299 insertions(+), 3 deletions(-) diff --git a/src/config-utils.test.ts b/src/config-utils.test.ts index 04bfe235d..7671f862d 100644 --- a/src/config-utils.test.ts +++ b/src/config-utils.test.ts @@ -1202,6 +1202,7 @@ interface OverlayDatabaseModeTestSetup { languages: Language[]; codeqlVersion: string; gitRoot: string | undefined; + codeScanningConfig: configUtils.UserConfig; } const defaultOverlayDatabaseModeTestSetup: OverlayDatabaseModeTestSetup = { @@ -1214,6 +1215,7 @@ const defaultOverlayDatabaseModeTestSetup: OverlayDatabaseModeTestSetup = { languages: [Language.javascript], codeqlVersion: "2.21.0", gitRoot: "/some/git/root", + codeScanningConfig: {}, }; const getOverlayDatabaseModeMacro = test.macro({ @@ -1280,6 +1282,7 @@ const getOverlayDatabaseModeMacro = test.macro({ setup.languages, tempDir, // sourceRoot setup.buildMode, + setup.codeScanningConfig, logger, ); @@ -1370,7 +1373,121 @@ test( test( getOverlayDatabaseModeMacro, - "No overlay-base database on default branch when overall feature disabled", + "Overlay-base database on default branch when feature enabled with custom analysis", + { + languages: [Language.javascript], + features: [Feature.OverlayAnalysis, Feature.OverlayAnalysisJavascript], + codeScanningConfig: { + packs: ["some-custom-pack@1.0.0"], + } as configUtils.UserConfig, + isDefaultBranch: true, + }, + { + overlayDatabaseMode: OverlayDatabaseMode.OverlayBase, + useOverlayDatabaseCaching: true, + }, +); + +test( + getOverlayDatabaseModeMacro, + "Overlay-base database on default branch when code-scanning feature enabled", + { + languages: [Language.javascript], + features: [ + Feature.OverlayAnalysis, + Feature.OverlayAnalysisCodeScanningJavascript, + ], + isDefaultBranch: true, + }, + { + overlayDatabaseMode: OverlayDatabaseMode.OverlayBase, + useOverlayDatabaseCaching: true, + }, +); + +test( + getOverlayDatabaseModeMacro, + "No overlay-base database on default branch when code-scanning feature enabled with disable-default-queries", + { + languages: [Language.javascript], + features: [ + Feature.OverlayAnalysis, + Feature.OverlayAnalysisCodeScanningJavascript, + ], + codeScanningConfig: { + "disable-default-queries": true, + } as configUtils.UserConfig, + isDefaultBranch: true, + }, + { + overlayDatabaseMode: OverlayDatabaseMode.None, + useOverlayDatabaseCaching: false, + }, +); + +test( + getOverlayDatabaseModeMacro, + "No overlay-base database on default branch when code-scanning feature enabled with packs", + { + languages: [Language.javascript], + features: [ + Feature.OverlayAnalysis, + Feature.OverlayAnalysisCodeScanningJavascript, + ], + codeScanningConfig: { + packs: ["some-custom-pack@1.0.0"], + } as configUtils.UserConfig, + isDefaultBranch: true, + }, + { + overlayDatabaseMode: OverlayDatabaseMode.None, + useOverlayDatabaseCaching: false, + }, +); + +test( + getOverlayDatabaseModeMacro, + "No overlay-base database on default branch when code-scanning feature enabled with queries", + { + languages: [Language.javascript], + features: [ + Feature.OverlayAnalysis, + Feature.OverlayAnalysisCodeScanningJavascript, + ], + codeScanningConfig: { + queries: [{ uses: "some-query.ql" }], + } as configUtils.UserConfig, + isDefaultBranch: true, + }, + { + overlayDatabaseMode: OverlayDatabaseMode.None, + useOverlayDatabaseCaching: false, + }, +); + +test( + getOverlayDatabaseModeMacro, + "No overlay-base database on default branch when code-scanning feature enabled with query-filters", + { + languages: [Language.javascript], + features: [ + Feature.OverlayAnalysis, + Feature.OverlayAnalysisCodeScanningJavascript, + ], + codeScanningConfig: { + "query-filters": [{ include: { "security-severity": "high" } }], + } as configUtils.UserConfig, + isDefaultBranch: true, + }, + { + overlayDatabaseMode: OverlayDatabaseMode.None, + useOverlayDatabaseCaching: false, + }, +); + +test( + getOverlayDatabaseModeMacro, + "No overlay-base database on default branch when only language-specific feature enabled", { languages: [Language.javascript], features: [Feature.OverlayAnalysisJavascript], @@ -1382,6 +1499,20 @@ test( }, ); +test( + getOverlayDatabaseModeMacro, + "No overlay-base database on default branch when only code-scanning feature enabled", + { + languages: [Language.javascript], + features: [Feature.OverlayAnalysisCodeScanningJavascript], + isDefaultBranch: true, + }, + { + overlayDatabaseMode: OverlayDatabaseMode.None, + useOverlayDatabaseCaching: false, + }, +); + test( getOverlayDatabaseModeMacro, "No overlay-base database on default branch when language-specific feature disabled", @@ -1412,7 +1543,121 @@ test( test( getOverlayDatabaseModeMacro, - "No overlay analysis on PR when overall feature disabled", + "Overlay analysis on PR when feature enabled with custom analysis", + { + languages: [Language.javascript], + features: [Feature.OverlayAnalysis, Feature.OverlayAnalysisJavascript], + codeScanningConfig: { + packs: ["some-custom-pack@1.0.0"], + } as configUtils.UserConfig, + isPullRequest: true, + }, + { + overlayDatabaseMode: OverlayDatabaseMode.Overlay, + useOverlayDatabaseCaching: true, + }, +); + +test( + getOverlayDatabaseModeMacro, + "Overlay analysis on PR when code-scanning feature enabled", + { + languages: [Language.javascript], + features: [ + Feature.OverlayAnalysis, + Feature.OverlayAnalysisCodeScanningJavascript, + ], + isPullRequest: true, + }, + { + overlayDatabaseMode: OverlayDatabaseMode.Overlay, + useOverlayDatabaseCaching: true, + }, +); + +test( + getOverlayDatabaseModeMacro, + "No overlay analysis on PR when code-scanning feature enabled with disable-default-queries", + { + languages: [Language.javascript], + features: [ + Feature.OverlayAnalysis, + Feature.OverlayAnalysisCodeScanningJavascript, + ], + codeScanningConfig: { + "disable-default-queries": true, + } as configUtils.UserConfig, + isPullRequest: true, + }, + { + overlayDatabaseMode: OverlayDatabaseMode.None, + useOverlayDatabaseCaching: false, + }, +); + +test( + getOverlayDatabaseModeMacro, + "No overlay analysis on PR when code-scanning feature enabled with packs", + { + languages: [Language.javascript], + features: [ + Feature.OverlayAnalysis, + Feature.OverlayAnalysisCodeScanningJavascript, + ], + codeScanningConfig: { + packs: ["some-custom-pack@1.0.0"], + } as configUtils.UserConfig, + isPullRequest: true, + }, + { + overlayDatabaseMode: OverlayDatabaseMode.None, + useOverlayDatabaseCaching: false, + }, +); + +test( + getOverlayDatabaseModeMacro, + "No overlay analysis on PR when code-scanning feature enabled with queries", + { + languages: [Language.javascript], + features: [ + Feature.OverlayAnalysis, + Feature.OverlayAnalysisCodeScanningJavascript, + ], + codeScanningConfig: { + queries: [{ uses: "some-query.ql" }], + } as configUtils.UserConfig, + isPullRequest: true, + }, + { + overlayDatabaseMode: OverlayDatabaseMode.None, + useOverlayDatabaseCaching: false, + }, +); + +test( + getOverlayDatabaseModeMacro, + "No overlay analysis on PR when code-scanning feature enabled with query-filters", + { + languages: [Language.javascript], + features: [ + Feature.OverlayAnalysis, + Feature.OverlayAnalysisCodeScanningJavascript, + ], + codeScanningConfig: { + "query-filters": [{ include: { "security-severity": "high" } }], + } as configUtils.UserConfig, + isPullRequest: true, + }, + { + overlayDatabaseMode: OverlayDatabaseMode.None, + useOverlayDatabaseCaching: false, + }, +); + +test( + getOverlayDatabaseModeMacro, + "No overlay analysis on PR when only language-specific feature enabled", { languages: [Language.javascript], features: [Feature.OverlayAnalysisJavascript], @@ -1424,6 +1669,20 @@ test( }, ); +test( + getOverlayDatabaseModeMacro, + "No overlay analysis on PR when only code-scanning feature enabled", + { + languages: [Language.javascript], + features: [Feature.OverlayAnalysisCodeScanningJavascript], + isPullRequest: true, + }, + { + overlayDatabaseMode: OverlayDatabaseMode.None, + useOverlayDatabaseCaching: false, + }, +); + test( getOverlayDatabaseModeMacro, "No overlay analysis on PR when language-specific feature disabled", diff --git a/src/config-utils.ts b/src/config-utils.ts index c9ef95bbb..0c42f671a 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -660,11 +660,25 @@ const OVERLAY_ANALYSIS_FEATURES: Record = { swift: Feature.OverlayAnalysisSwift, }; +const OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES: Record = { + actions: Feature.OverlayAnalysisCodeScanningActions, + cpp: Feature.OverlayAnalysisCodeScanningCpp, + csharp: Feature.OverlayAnalysisCodeScanningCsharp, + go: Feature.OverlayAnalysisCodeScanningGo, + java: Feature.OverlayAnalysisCodeScanningJava, + javascript: Feature.OverlayAnalysisCodeScanningJavascript, + python: Feature.OverlayAnalysisCodeScanningPython, + ruby: Feature.OverlayAnalysisCodeScanningRuby, + rust: Feature.OverlayAnalysisCodeScanningRust, + swift: Feature.OverlayAnalysisCodeScanningSwift, +}; + async function isOverlayAnalysisFeatureEnabled( repository: RepositoryNwo, features: FeatureEnablement, codeql: CodeQL, languages: Language[], + codeScanningConfig: UserConfig, ): Promise { // TODO: Remove the repository owner check once support for overlay analysis // stabilizes, and no more backward-incompatible changes are expected. @@ -674,14 +688,34 @@ async function isOverlayAnalysisFeatureEnabled( if (!(await features.getValue(Feature.OverlayAnalysis, codeql))) { return false; } + let enableForCodeScanningOnly = false; for (const language of languages) { const feature = OVERLAY_ANALYSIS_FEATURES[language]; if (feature && (await features.getValue(feature, codeql))) { continue; } - // TODO: Add code-scanning feature checks here + const codeScanningFeature = + OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES[language]; + if ( + codeScanningFeature && + (await features.getValue(codeScanningFeature, codeql)) + ) { + enableForCodeScanningOnly = true; + continue; + } return false; } + 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 ( + codeScanningConfig["disable-default-queries"] !== true && + codeScanningConfig.packs === undefined && + codeScanningConfig.queries === undefined && + codeScanningConfig["query-filters"] === undefined + ); + } return true; } @@ -713,6 +747,7 @@ export async function getOverlayDatabaseMode( languages: Language[], sourceRoot: string, buildMode: BuildMode | undefined, + codeScanningConfig: UserConfig, logger: Logger, ): Promise<{ overlayDatabaseMode: OverlayDatabaseMode; @@ -740,6 +775,7 @@ export async function getOverlayDatabaseMode( features, codeql, languages, + codeScanningConfig, ) ) { if (isAnalyzingPullRequest()) { @@ -1015,6 +1051,7 @@ export async function initConfig(inputs: InitConfigInputs): Promise { config.languages, inputs.sourceRoot, config.buildMode, + generateCodeScanningConfig(userConfig, augmentationProperties), logger, ); logger.info(