diff --git a/.github/workflows/__export-file-baseline-information.yml b/.github/workflows/__export-file-baseline-information.yml index f157c23f7..41fb9220f 100644 --- a/.github/workflows/__export-file-baseline-information.yml +++ b/.github/workflows/__export-file-baseline-information.yml @@ -125,5 +125,6 @@ jobs: fi done env: + CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS: false CODEQL_ACTION_SUBLANGUAGE_FILE_COVERAGE: true CODEQL_ACTION_TEST_MODE: true diff --git a/lib/analyze-action-post.js b/lib/analyze-action-post.js index c202c7219..647a56f9f 100644 --- a/lib/analyze-action-post.js +++ b/lib/analyze-action-post.js @@ -127971,6 +127971,15 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["skip_file_coverage_on_prs" /* SkipFileCoverageOnPrs */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS", + // For testing, this is not behind a CLI version check yet. However + // before rolling this out externally, we should set a minimum version here + // since current versions of the CodeQL CLI will log if baseline information + // cannot be found when interpreting results. + minimumVersion: void 0 + }, ["upload_overlay_db_to_api" /* UploadOverlayDbToApi */]: { defaultValue: false, envVar: "CODEQL_ACTION_UPLOAD_OVERLAY_DB_TO_API", @@ -128188,6 +128197,10 @@ async function getCodeQLForCmd(cmd, checkVersion) { } else if (overlayDatabaseMode === "overlay-base" /* OverlayBase */) { extraArgs.push("--overlay-base"); } + const baselineFilesOptions = config.enableFileCoverageInformation ? [ + "--calculate-language-specific-baseline", + "--sublanguage-file-coverage" + ] : ["--no-calculate-baseline"]; await runCli( cmd, [ @@ -128197,12 +128210,14 @@ async function getCodeQLForCmd(cmd, checkVersion) { "--db-cluster", config.dbLocation, `--source-root=${sourceRoot}`, - "--calculate-language-specific-baseline", + ...baselineFilesOptions, "--extractor-include-aliases", - "--sublanguage-file-coverage", ...extraArgs, ...getExtraOptionsFromEnv(["database", "init"], { - ignoringOptions: ["--overwrite"] + // Some user configs specify `--no-calculate-baseline` as an additional + // argument to `codeql database init`. Therefore ignore the baseline file + // options here to avoid specifying the same argument twice and erroring. + ignoringOptions: ["--overwrite", ...baselineFilesOptions] }) ], { stdin: externalRepositoryToken } @@ -128389,15 +128404,6 @@ ${output}` noStreamStdout: true }); }, - async databasePrintBaseline(databasePath) { - const codeqlArgs = [ - "database", - "print-baseline", - ...getExtraOptionsFromEnv(["database", "print-baseline"]), - databasePath - ]; - return await runCli(cmd, codeqlArgs); - }, async databaseCleanupCluster(config, cleanupLevel) { const cacheCleanupFlag = await codeQlVersionAtLeast( this, diff --git a/lib/analyze-action.js b/lib/analyze-action.js index f97210922..0ab72d31c 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -90723,6 +90723,15 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["skip_file_coverage_on_prs" /* SkipFileCoverageOnPrs */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS", + // For testing, this is not behind a CLI version check yet. However + // before rolling this out externally, we should set a minimum version here + // since current versions of the CodeQL CLI will log if baseline information + // cannot be found when interpreting results. + minimumVersion: void 0 + }, ["upload_overlay_db_to_api" /* UploadOverlayDbToApi */]: { defaultValue: false, envVar: "CODEQL_ACTION_UPLOAD_OVERLAY_DB_TO_API", @@ -92482,6 +92491,10 @@ async function getCodeQLForCmd(cmd, checkVersion) { } else if (overlayDatabaseMode === "overlay-base" /* OverlayBase */) { extraArgs.push("--overlay-base"); } + const baselineFilesOptions = config.enableFileCoverageInformation ? [ + "--calculate-language-specific-baseline", + "--sublanguage-file-coverage" + ] : ["--no-calculate-baseline"]; await runCli( cmd, [ @@ -92491,12 +92504,14 @@ async function getCodeQLForCmd(cmd, checkVersion) { "--db-cluster", config.dbLocation, `--source-root=${sourceRoot}`, - "--calculate-language-specific-baseline", + ...baselineFilesOptions, "--extractor-include-aliases", - "--sublanguage-file-coverage", ...extraArgs, ...getExtraOptionsFromEnv(["database", "init"], { - ignoringOptions: ["--overwrite"] + // Some user configs specify `--no-calculate-baseline` as an additional + // argument to `codeql database init`. Therefore ignore the baseline file + // options here to avoid specifying the same argument twice and erroring. + ignoringOptions: ["--overwrite", ...baselineFilesOptions] }) ], { stdin: externalRepositoryToken } @@ -92683,15 +92698,6 @@ ${output}` noStreamStdout: true }); }, - async databasePrintBaseline(databasePath) { - const codeqlArgs = [ - "database", - "print-baseline", - ...getExtraOptionsFromEnv(["database", "print-baseline"]), - databasePath - ]; - return await runCli(cmd, codeqlArgs); - }, async databaseCleanupCluster(config, cleanupLevel) { const cacheCleanupFlag = await codeQlVersionAtLeast( this, @@ -93447,10 +93453,17 @@ async function runQueries(sarifFolder, memoryFlag, threadsFlag, diffRangePackDir const endTimeInterpretResults = /* @__PURE__ */ new Date(); statusReport[`interpret_results_${language}_duration_ms`] = endTimeInterpretResults.getTime() - startTimeInterpretResults.getTime(); logger.endGroup(); - logger.info(analysisSummary); - if (qualityAnalysisSummary) { + if (analysisSummary.trim()) { + logger.info(analysisSummary); + } + if (qualityAnalysisSummary?.trim()) { logger.info(qualityAnalysisSummary); } + if (!config.enableFileCoverageInformation) { + logger.info( + "To speed up pull request analysis, file coverage information is only enabled when analyzing the default branch and protected branches." + ); + } if (await features.getValue("qa_telemetry_enabled" /* QaTelemetryEnabled */)) { const perQueryAlertCounts = getPerQueryAlertCounts(sarifFile); const perQueryAlertCountEventReport = { diff --git a/lib/autobuild-action.js b/lib/autobuild-action.js index 6d8e945cf..0a73443cb 100644 --- a/lib/autobuild-action.js +++ b/lib/autobuild-action.js @@ -87056,6 +87056,15 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["skip_file_coverage_on_prs" /* SkipFileCoverageOnPrs */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS", + // For testing, this is not behind a CLI version check yet. However + // before rolling this out externally, we should set a minimum version here + // since current versions of the CodeQL CLI will log if baseline information + // cannot be found when interpreting results. + minimumVersion: void 0 + }, ["upload_overlay_db_to_api" /* UploadOverlayDbToApi */]: { defaultValue: false, envVar: "CODEQL_ACTION_UPLOAD_OVERLAY_DB_TO_API", @@ -87582,6 +87591,10 @@ async function getCodeQLForCmd(cmd, checkVersion) { } else if (overlayDatabaseMode === "overlay-base" /* OverlayBase */) { extraArgs.push("--overlay-base"); } + const baselineFilesOptions = config.enableFileCoverageInformation ? [ + "--calculate-language-specific-baseline", + "--sublanguage-file-coverage" + ] : ["--no-calculate-baseline"]; await runCli( cmd, [ @@ -87591,12 +87604,14 @@ async function getCodeQLForCmd(cmd, checkVersion) { "--db-cluster", config.dbLocation, `--source-root=${sourceRoot}`, - "--calculate-language-specific-baseline", + ...baselineFilesOptions, "--extractor-include-aliases", - "--sublanguage-file-coverage", ...extraArgs, ...getExtraOptionsFromEnv(["database", "init"], { - ignoringOptions: ["--overwrite"] + // Some user configs specify `--no-calculate-baseline` as an additional + // argument to `codeql database init`. Therefore ignore the baseline file + // options here to avoid specifying the same argument twice and erroring. + ignoringOptions: ["--overwrite", ...baselineFilesOptions] }) ], { stdin: externalRepositoryToken } @@ -87783,15 +87798,6 @@ ${output}` noStreamStdout: true }); }, - async databasePrintBaseline(databasePath) { - const codeqlArgs = [ - "database", - "print-baseline", - ...getExtraOptionsFromEnv(["database", "print-baseline"]), - databasePath - ]; - return await runCli(cmd, codeqlArgs); - }, async databaseCleanupCluster(config, cleanupLevel) { const cacheCleanupFlag = await codeQlVersionAtLeast( this, diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 93d7288a8..0ed7f239d 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -131365,6 +131365,15 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["skip_file_coverage_on_prs" /* SkipFileCoverageOnPrs */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS", + // For testing, this is not behind a CLI version check yet. However + // before rolling this out externally, we should set a minimum version here + // since current versions of the CodeQL CLI will log if baseline information + // cannot be found when interpreting results. + minimumVersion: void 0 + }, ["upload_overlay_db_to_api" /* UploadOverlayDbToApi */]: { defaultValue: false, envVar: "CODEQL_ACTION_UPLOAD_OVERLAY_DB_TO_API", @@ -132827,6 +132836,10 @@ async function getCodeQLForCmd(cmd, checkVersion) { } else if (overlayDatabaseMode === "overlay-base" /* OverlayBase */) { extraArgs.push("--overlay-base"); } + const baselineFilesOptions = config.enableFileCoverageInformation ? [ + "--calculate-language-specific-baseline", + "--sublanguage-file-coverage" + ] : ["--no-calculate-baseline"]; await runCli( cmd, [ @@ -132836,12 +132849,14 @@ async function getCodeQLForCmd(cmd, checkVersion) { "--db-cluster", config.dbLocation, `--source-root=${sourceRoot}`, - "--calculate-language-specific-baseline", + ...baselineFilesOptions, "--extractor-include-aliases", - "--sublanguage-file-coverage", ...extraArgs, ...getExtraOptionsFromEnv(["database", "init"], { - ignoringOptions: ["--overwrite"] + // Some user configs specify `--no-calculate-baseline` as an additional + // argument to `codeql database init`. Therefore ignore the baseline file + // options here to avoid specifying the same argument twice and erroring. + ignoringOptions: ["--overwrite", ...baselineFilesOptions] }) ], { stdin: externalRepositoryToken } @@ -133028,15 +133043,6 @@ ${output}` noStreamStdout: true }); }, - async databasePrintBaseline(databasePath) { - const codeqlArgs = [ - "database", - "print-baseline", - ...getExtraOptionsFromEnv(["database", "print-baseline"]), - databasePath - ]; - return await runCli(cmd, codeqlArgs); - }, async databaseCleanupCluster(config, cleanupLevel) { const cacheCleanupFlag = await codeQlVersionAtLeast( this, diff --git a/lib/init-action.js b/lib/init-action.js index cd8d128dd..ee50500d7 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -88214,6 +88214,15 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["skip_file_coverage_on_prs" /* SkipFileCoverageOnPrs */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS", + // For testing, this is not behind a CLI version check yet. However + // before rolling this out externally, we should set a minimum version here + // since current versions of the CodeQL CLI will log if baseline information + // cannot be found when interpreting results. + minimumVersion: void 0 + }, ["upload_overlay_db_to_api" /* UploadOverlayDbToApi */]: { defaultValue: false, envVar: "CODEQL_ACTION_UPLOAD_OVERLAY_DB_TO_API", @@ -88773,7 +88782,8 @@ async function initActionState({ features, repositoryProperties, analysisKinds, - logger + logger, + enableFileCoverageInformation }, userConfig) { const languages = await getLanguages( codeql, @@ -88835,7 +88845,8 @@ async function initActionState({ extraQueryExclusions: [], overlayDatabaseMode: "none" /* None */, useOverlayDatabaseCaching: false, - repositoryProperties + repositoryProperties, + enableFileCoverageInformation }; } async function downloadCacheWithTime(trapCachingEnabled, codeQL, languages, logger) { @@ -90830,6 +90841,10 @@ async function getCodeQLForCmd(cmd, checkVersion) { } else if (overlayDatabaseMode === "overlay-base" /* OverlayBase */) { extraArgs.push("--overlay-base"); } + const baselineFilesOptions = config.enableFileCoverageInformation ? [ + "--calculate-language-specific-baseline", + "--sublanguage-file-coverage" + ] : ["--no-calculate-baseline"]; await runCli( cmd, [ @@ -90839,12 +90854,14 @@ async function getCodeQLForCmd(cmd, checkVersion) { "--db-cluster", config.dbLocation, `--source-root=${sourceRoot}`, - "--calculate-language-specific-baseline", + ...baselineFilesOptions, "--extractor-include-aliases", - "--sublanguage-file-coverage", ...extraArgs, ...getExtraOptionsFromEnv(["database", "init"], { - ignoringOptions: ["--overwrite"] + // Some user configs specify `--no-calculate-baseline` as an additional + // argument to `codeql database init`. Therefore ignore the baseline file + // options here to avoid specifying the same argument twice and erroring. + ignoringOptions: ["--overwrite", ...baselineFilesOptions] }) ], { stdin: externalRepositoryToken } @@ -91031,15 +91048,6 @@ ${output}` noStreamStdout: true }); }, - async databasePrintBaseline(databasePath) { - const codeqlArgs = [ - "database", - "print-baseline", - ...getExtraOptionsFromEnv(["database", "print-baseline"]), - databasePath - ]; - return await runCli(cmd, codeqlArgs); - }, async databaseCleanupCluster(config, cleanupLevel) { const cacheCleanupFlag = await codeQlVersionAtLeast( this, @@ -91461,6 +91469,16 @@ function cleanupDatabaseClusterDirectory(config, logger, options = {}, rmSync2 = } } } +async function getFileCoverageInformationEnabled(debugMode, repositoryNwo, features) { + return ( + // Always enable file coverage information in debug mode + debugMode || // We're most interested in speeding up PRs, and we want to keep + // submitting file coverage information for the default branch since + // it is used to populate the status page. + !isAnalyzingPullRequest() || // For now, restrict this feature to the GitHub org + repositoryNwo.owner !== "github" || !await features.getValue("skip_file_coverage_on_prs" /* SkipFileCoverageOnPrs */) + ); +} // src/status-report.ts var os5 = __toESM(require("os")); @@ -92067,6 +92085,7 @@ async function run(startedAt) { } } analysisKinds = await getAnalysisKinds(logger); + const debugMode = getOptionalInput("debug") === "true" || core13.isDebug(); config = await initConfig2(features, { analysisKinds, languagesInput: getOptionalInput("languages"), @@ -92083,7 +92102,7 @@ async function run(startedAt) { // - The `init` Action is passed `debug: true`. // - Actions step debugging is enabled (e.g. by [enabling debug logging for a rerun](https://docs.github.com/en/actions/managing-workflow-runs/re-running-workflows-and-jobs#re-running-all-the-jobs-in-a-workflow), // or by setting the `ACTIONS_STEP_DEBUG` secret to `true`). - debugMode: getOptionalInput("debug") === "true" || core13.isDebug(), + debugMode, debugArtifactName: getOptionalInput("debug-artifact-name") || DEFAULT_DEBUG_ARTIFACT_NAME, debugDatabaseName: getOptionalInput("debug-database-name") || DEFAULT_DEBUG_DATABASE_NAME, repository: repositoryNwo, @@ -92095,6 +92114,11 @@ async function run(startedAt) { apiDetails, features, repositoryProperties, + enableFileCoverageInformation: await getFileCoverageInformationEnabled( + debugMode, + repositoryNwo, + features + ), logger }); await checkInstallPython311(config.languages, codeql); diff --git a/lib/resolve-environment-action.js b/lib/resolve-environment-action.js index 9e5018d61..cc6aa521c 100644 --- a/lib/resolve-environment-action.js +++ b/lib/resolve-environment-action.js @@ -87047,6 +87047,15 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["skip_file_coverage_on_prs" /* SkipFileCoverageOnPrs */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS", + // For testing, this is not behind a CLI version check yet. However + // before rolling this out externally, we should set a minimum version here + // since current versions of the CodeQL CLI will log if baseline information + // cannot be found when interpreting results. + minimumVersion: void 0 + }, ["upload_overlay_db_to_api" /* UploadOverlayDbToApi */]: { defaultValue: false, envVar: "CODEQL_ACTION_UPLOAD_OVERLAY_DB_TO_API", @@ -87270,6 +87279,10 @@ async function getCodeQLForCmd(cmd, checkVersion) { } else if (overlayDatabaseMode === "overlay-base" /* OverlayBase */) { extraArgs.push("--overlay-base"); } + const baselineFilesOptions = config.enableFileCoverageInformation ? [ + "--calculate-language-specific-baseline", + "--sublanguage-file-coverage" + ] : ["--no-calculate-baseline"]; await runCli( cmd, [ @@ -87279,12 +87292,14 @@ async function getCodeQLForCmd(cmd, checkVersion) { "--db-cluster", config.dbLocation, `--source-root=${sourceRoot}`, - "--calculate-language-specific-baseline", + ...baselineFilesOptions, "--extractor-include-aliases", - "--sublanguage-file-coverage", ...extraArgs, ...getExtraOptionsFromEnv(["database", "init"], { - ignoringOptions: ["--overwrite"] + // Some user configs specify `--no-calculate-baseline` as an additional + // argument to `codeql database init`. Therefore ignore the baseline file + // options here to avoid specifying the same argument twice and erroring. + ignoringOptions: ["--overwrite", ...baselineFilesOptions] }) ], { stdin: externalRepositoryToken } @@ -87471,15 +87486,6 @@ ${output}` noStreamStdout: true }); }, - async databasePrintBaseline(databasePath) { - const codeqlArgs = [ - "database", - "print-baseline", - ...getExtraOptionsFromEnv(["database", "print-baseline"]), - databasePath - ]; - return await runCli(cmd, codeqlArgs); - }, async databaseCleanupCluster(config, cleanupLevel) { const cacheCleanupFlag = await codeQlVersionAtLeast( this, diff --git a/lib/setup-codeql-action.js b/lib/setup-codeql-action.js index ce8242cc6..7182336ae 100644 --- a/lib/setup-codeql-action.js +++ b/lib/setup-codeql-action.js @@ -86957,6 +86957,15 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["skip_file_coverage_on_prs" /* SkipFileCoverageOnPrs */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS", + // For testing, this is not behind a CLI version check yet. However + // before rolling this out externally, we should set a minimum version here + // since current versions of the CodeQL CLI will log if baseline information + // cannot be found when interpreting results. + minimumVersion: void 0 + }, ["upload_overlay_db_to_api" /* UploadOverlayDbToApi */]: { defaultValue: false, envVar: "CODEQL_ACTION_UPLOAD_OVERLAY_DB_TO_API", @@ -88584,6 +88593,10 @@ async function getCodeQLForCmd(cmd, checkVersion) { } else if (overlayDatabaseMode === "overlay-base" /* OverlayBase */) { extraArgs.push("--overlay-base"); } + const baselineFilesOptions = config.enableFileCoverageInformation ? [ + "--calculate-language-specific-baseline", + "--sublanguage-file-coverage" + ] : ["--no-calculate-baseline"]; await runCli( cmd, [ @@ -88593,12 +88606,14 @@ async function getCodeQLForCmd(cmd, checkVersion) { "--db-cluster", config.dbLocation, `--source-root=${sourceRoot}`, - "--calculate-language-specific-baseline", + ...baselineFilesOptions, "--extractor-include-aliases", - "--sublanguage-file-coverage", ...extraArgs, ...getExtraOptionsFromEnv(["database", "init"], { - ignoringOptions: ["--overwrite"] + // Some user configs specify `--no-calculate-baseline` as an additional + // argument to `codeql database init`. Therefore ignore the baseline file + // options here to avoid specifying the same argument twice and erroring. + ignoringOptions: ["--overwrite", ...baselineFilesOptions] }) ], { stdin: externalRepositoryToken } @@ -88785,15 +88800,6 @@ ${output}` noStreamStdout: true }); }, - async databasePrintBaseline(databasePath) { - const codeqlArgs = [ - "database", - "print-baseline", - ...getExtraOptionsFromEnv(["database", "print-baseline"]), - databasePath - ]; - return await runCli(cmd, codeqlArgs); - }, async databaseCleanupCluster(config, cleanupLevel) { const cacheCleanupFlag = await codeQlVersionAtLeast( this, diff --git a/lib/start-proxy-action-post.js b/lib/start-proxy-action-post.js index f8e266535..8e31348ce 100644 --- a/lib/start-proxy-action-post.js +++ b/lib/start-proxy-action-post.js @@ -127377,6 +127377,15 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["skip_file_coverage_on_prs" /* SkipFileCoverageOnPrs */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS", + // For testing, this is not behind a CLI version check yet. However + // before rolling this out externally, we should set a minimum version here + // since current versions of the CodeQL CLI will log if baseline information + // cannot be found when interpreting results. + minimumVersion: void 0 + }, ["upload_overlay_db_to_api" /* UploadOverlayDbToApi */]: { defaultValue: false, envVar: "CODEQL_ACTION_UPLOAD_OVERLAY_DB_TO_API", diff --git a/lib/start-proxy-action.js b/lib/start-proxy-action.js index e0aca4c39..ea6f8c96c 100644 --- a/lib/start-proxy-action.js +++ b/lib/start-proxy-action.js @@ -103926,6 +103926,15 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["skip_file_coverage_on_prs" /* SkipFileCoverageOnPrs */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS", + // For testing, this is not behind a CLI version check yet. However + // before rolling this out externally, we should set a minimum version here + // since current versions of the CodeQL CLI will log if baseline information + // cannot be found when interpreting results. + minimumVersion: void 0 + }, ["upload_overlay_db_to_api" /* UploadOverlayDbToApi */]: { defaultValue: false, envVar: "CODEQL_ACTION_UPLOAD_OVERLAY_DB_TO_API", diff --git a/lib/upload-lib.js b/lib/upload-lib.js index b06c31d8b..7f19a1a08 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -90116,6 +90116,15 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["skip_file_coverage_on_prs" /* SkipFileCoverageOnPrs */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS", + // For testing, this is not behind a CLI version check yet. However + // before rolling this out externally, we should set a minimum version here + // since current versions of the CodeQL CLI will log if baseline information + // cannot be found when interpreting results. + minimumVersion: void 0 + }, ["upload_overlay_db_to_api" /* UploadOverlayDbToApi */]: { defaultValue: false, envVar: "CODEQL_ACTION_UPLOAD_OVERLAY_DB_TO_API", @@ -91299,6 +91308,10 @@ async function getCodeQLForCmd(cmd, checkVersion) { } else if (overlayDatabaseMode === "overlay-base" /* OverlayBase */) { extraArgs.push("--overlay-base"); } + const baselineFilesOptions = config.enableFileCoverageInformation ? [ + "--calculate-language-specific-baseline", + "--sublanguage-file-coverage" + ] : ["--no-calculate-baseline"]; await runCli( cmd, [ @@ -91308,12 +91321,14 @@ async function getCodeQLForCmd(cmd, checkVersion) { "--db-cluster", config.dbLocation, `--source-root=${sourceRoot}`, - "--calculate-language-specific-baseline", + ...baselineFilesOptions, "--extractor-include-aliases", - "--sublanguage-file-coverage", ...extraArgs, ...getExtraOptionsFromEnv(["database", "init"], { - ignoringOptions: ["--overwrite"] + // Some user configs specify `--no-calculate-baseline` as an additional + // argument to `codeql database init`. Therefore ignore the baseline file + // options here to avoid specifying the same argument twice and erroring. + ignoringOptions: ["--overwrite", ...baselineFilesOptions] }) ], { stdin: externalRepositoryToken } @@ -91500,15 +91515,6 @@ ${output}` noStreamStdout: true }); }, - async databasePrintBaseline(databasePath) { - const codeqlArgs = [ - "database", - "print-baseline", - ...getExtraOptionsFromEnv(["database", "print-baseline"]), - databasePath - ]; - return await runCli(cmd, codeqlArgs); - }, async databaseCleanupCluster(config, cleanupLevel) { const cacheCleanupFlag = await codeQlVersionAtLeast( this, diff --git a/lib/upload-sarif-action-post.js b/lib/upload-sarif-action-post.js index 8b9c43a98..19eb00c41 100644 --- a/lib/upload-sarif-action-post.js +++ b/lib/upload-sarif-action-post.js @@ -127539,6 +127539,15 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["skip_file_coverage_on_prs" /* SkipFileCoverageOnPrs */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS", + // For testing, this is not behind a CLI version check yet. However + // before rolling this out externally, we should set a minimum version here + // since current versions of the CodeQL CLI will log if baseline information + // cannot be found when interpreting results. + minimumVersion: void 0 + }, ["upload_overlay_db_to_api" /* UploadOverlayDbToApi */]: { defaultValue: false, envVar: "CODEQL_ACTION_UPLOAD_OVERLAY_DB_TO_API", diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index 2c91f2c97..4b775f252 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -89911,6 +89911,15 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["skip_file_coverage_on_prs" /* SkipFileCoverageOnPrs */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS", + // For testing, this is not behind a CLI version check yet. However + // before rolling this out externally, we should set a minimum version here + // since current versions of the CodeQL CLI will log if baseline information + // cannot be found when interpreting results. + minimumVersion: void 0 + }, ["upload_overlay_db_to_api" /* UploadOverlayDbToApi */]: { defaultValue: false, envVar: "CODEQL_ACTION_UPLOAD_OVERLAY_DB_TO_API", @@ -91854,6 +91863,10 @@ async function getCodeQLForCmd(cmd, checkVersion) { } else if (overlayDatabaseMode === "overlay-base" /* OverlayBase */) { extraArgs.push("--overlay-base"); } + const baselineFilesOptions = config.enableFileCoverageInformation ? [ + "--calculate-language-specific-baseline", + "--sublanguage-file-coverage" + ] : ["--no-calculate-baseline"]; await runCli( cmd, [ @@ -91863,12 +91876,14 @@ async function getCodeQLForCmd(cmd, checkVersion) { "--db-cluster", config.dbLocation, `--source-root=${sourceRoot}`, - "--calculate-language-specific-baseline", + ...baselineFilesOptions, "--extractor-include-aliases", - "--sublanguage-file-coverage", ...extraArgs, ...getExtraOptionsFromEnv(["database", "init"], { - ignoringOptions: ["--overwrite"] + // Some user configs specify `--no-calculate-baseline` as an additional + // argument to `codeql database init`. Therefore ignore the baseline file + // options here to avoid specifying the same argument twice and erroring. + ignoringOptions: ["--overwrite", ...baselineFilesOptions] }) ], { stdin: externalRepositoryToken } @@ -92055,15 +92070,6 @@ ${output}` noStreamStdout: true }); }, - async databasePrintBaseline(databasePath) { - const codeqlArgs = [ - "database", - "print-baseline", - ...getExtraOptionsFromEnv(["database", "print-baseline"]), - databasePath - ]; - return await runCli(cmd, codeqlArgs); - }, async databaseCleanupCluster(config, cleanupLevel) { const cacheCleanupFlag = await codeQlVersionAtLeast( this, diff --git a/package-lock.json b/package-lock.json index 5624de160..68d4da28c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3792,9 +3792,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001727", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", - "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", + "version": "1.0.30001766", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz", + "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==", "dev": true, "funding": [ { @@ -3809,7 +3809,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/cbor": { "version": "10.0.9", diff --git a/pr-checks/checks/export-file-baseline-information.yml b/pr-checks/checks/export-file-baseline-information.yml index fdc352285..e45fc58ca 100644 --- a/pr-checks/checks/export-file-baseline-information.yml +++ b/pr-checks/checks/export-file-baseline-information.yml @@ -5,6 +5,7 @@ versions: ["nightly-latest"] installGo: true installDotNet: true env: + CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS: false CODEQL_ACTION_SUBLANGUAGE_FILE_COVERAGE: true steps: - uses: ./../action/init diff --git a/src/analyze.test.ts b/src/analyze.test.ts index ceabf62ba..27fe4a6f4 100644 --- a/src/analyze.test.ts +++ b/src/analyze.test.ts @@ -87,7 +87,6 @@ test("status report fields", async (t) => { ); return ""; }, - databasePrintBaseline: async () => "", }); const config = createTestConfig({ diff --git a/src/analyze.ts b/src/analyze.ts index dc631ba98..bb3841504 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -495,10 +495,18 @@ export async function runQueries( endTimeInterpretResults.getTime() - startTimeInterpretResults.getTime(); logger.endGroup(); - logger.info(analysisSummary); - if (qualityAnalysisSummary) { + if (analysisSummary.trim()) { + logger.info(analysisSummary); + } + if (qualityAnalysisSummary?.trim()) { logger.info(qualityAnalysisSummary); } + if (!config.enableFileCoverageInformation) { + logger.info( + "To speed up pull request analysis, file coverage information is only enabled when analyzing " + + "the default branch and protected branches.", + ); + } if (await features.getValue(Feature.QaTelemetryEnabled)) { // Note: QA adds the `code-quality` query suite to the `queries` input, diff --git a/src/codeql.ts b/src/codeql.ts index f70e5ffa4..8e7c2bfe2 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -186,10 +186,6 @@ export interface CodeQL { config: Config, features: FeatureEnablement, ): Promise; - /** - * Run 'codeql database print-baseline'. - */ - databasePrintBaseline(databasePath: string): Promise; /** * Run 'codeql database export-diagnostics' * @@ -493,10 +489,6 @@ export function createStubCodeQL(partialCodeql: Partial): CodeQL { partialCodeql, "databaseInterpretResults", ), - databasePrintBaseline: resolveFunction( - partialCodeql, - "databasePrintBaseline", - ), databaseExportDiagnostics: resolveFunction( partialCodeql, "databaseExportDiagnostics", @@ -628,6 +620,13 @@ async function getCodeQLForCmd( extraArgs.push("--overlay-base"); } + const baselineFilesOptions = config.enableFileCoverageInformation + ? [ + "--calculate-language-specific-baseline", + "--sublanguage-file-coverage", + ] + : ["--no-calculate-baseline"]; + await runCli( cmd, [ @@ -639,12 +638,14 @@ async function getCodeQLForCmd( "--db-cluster", config.dbLocation, `--source-root=${sourceRoot}`, - "--calculate-language-specific-baseline", + ...baselineFilesOptions, "--extractor-include-aliases", - "--sublanguage-file-coverage", ...extraArgs, ...getExtraOptionsFromEnv(["database", "init"], { - ignoringOptions: ["--overwrite"], + // Some user configs specify `--no-calculate-baseline` as an additional + // argument to `codeql database init`. Therefore ignore the baseline file + // options here to avoid specifying the same argument twice and erroring. + ignoringOptions: ["--overwrite", ...baselineFilesOptions], }), ], { stdin: externalRepositoryToken }, @@ -885,15 +886,6 @@ async function getCodeQLForCmd( noStreamStdout: true, }); }, - async databasePrintBaseline(databasePath: string): Promise { - const codeqlArgs = [ - "database", - "print-baseline", - ...getExtraOptionsFromEnv(["database", "print-baseline"]), - databasePath, - ]; - return await runCli(cmd, codeqlArgs); - }, async databaseCleanupCluster( config: Config, cleanupLevel: CleanupLevel, diff --git a/src/config-utils.test.ts b/src/config-utils.test.ts index 337eb85c5..276a7a344 100644 --- a/src/config-utils.test.ts +++ b/src/config-utils.test.ts @@ -89,6 +89,7 @@ function createTestInitConfigInputs( }, features: createFeatures([]), repositoryProperties: {}, + enableFileCoverageInformation: true, logger: getRunnerLogger(true), } satisfies configUtils.InitConfigInputs, overrides, diff --git a/src/config-utils.ts b/src/config-utils.ts index 772c187b8..a01041899 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -214,6 +214,11 @@ export interface Config { * A partial mapping from repository properties that affect us to their values. */ repositoryProperties: RepositoryProperties; + + /** + * Whether to enable file coverage information. + */ + enableFileCoverageInformation: boolean; } async function getSupportedLanguageMap( @@ -433,6 +438,7 @@ export interface InitConfigInputs { apiDetails: api.GitHubApiCombinedDetails; features: FeatureEnablement; repositoryProperties: RepositoryProperties; + enableFileCoverageInformation: boolean; analysisKinds: AnalysisKind[]; logger: Logger; } @@ -462,6 +468,7 @@ export async function initActionState( repositoryProperties, analysisKinds, logger, + enableFileCoverageInformation, }: InitConfigInputs, userConfig: UserConfig, ): Promise { @@ -542,6 +549,7 @@ export async function initActionState( overlayDatabaseMode: OverlayDatabaseMode.None, useOverlayDatabaseCaching: false, repositoryProperties, + enableFileCoverageInformation, }; } diff --git a/src/feature-flags.ts b/src/feature-flags.ts index 7ad9ecfa4..8de68a28d 100644 --- a/src/feature-flags.ts +++ b/src/feature-flags.ts @@ -70,6 +70,8 @@ export enum Feature { OverlayAnalysisSwift = "overlay_analysis_swift", PythonDefaultIsToNotExtractStdlib = "python_default_is_to_not_extract_stdlib", QaTelemetryEnabled = "qa_telemetry_enabled", + /** Note that this currently only disables baseline file coverage information. */ + SkipFileCoverageOnPrs = "skip_file_coverage_on_prs", UploadOverlayDbToApi = "upload_overlay_db_to_api", UseRepositoryProperties = "use_repository_properties", ValidateDbConfig = "validate_db_config", @@ -286,6 +288,15 @@ export const featureConfig = { legacyApi: true, minimumVersion: undefined, }, + [Feature.SkipFileCoverageOnPrs]: { + defaultValue: false, + envVar: "CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS", + // For testing, this is not behind a CLI version check yet. However + // before rolling this out externally, we should set a minimum version here + // since current versions of the CodeQL CLI will log if baseline information + // cannot be found when interpreting results. + minimumVersion: undefined, + }, [Feature.UploadOverlayDbToApi]: { defaultValue: false, envVar: "CODEQL_ACTION_UPLOAD_OVERLAY_DB_TO_API", diff --git a/src/init-action.ts b/src/init-action.ts index 8b6c200a0..0d92f46ef 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -42,6 +42,7 @@ import { checkInstallPython311, checkPacksForOverlayCompatibility, cleanupDatabaseClusterDirectory, + getFileCoverageInformationEnabled, initCodeQL, initConfig, runDatabaseInitCluster, @@ -334,6 +335,7 @@ async function run(startedAt: Date) { } analysisKinds = await getAnalysisKinds(logger); + const debugMode = getOptionalInput("debug") === "true" || core.isDebug(); config = await initConfig(features, { analysisKinds, languagesInput: getOptionalInput("languages"), @@ -350,7 +352,7 @@ async function run(startedAt: Date) { // - The `init` Action is passed `debug: true`. // - Actions step debugging is enabled (e.g. by [enabling debug logging for a rerun](https://docs.github.com/en/actions/managing-workflow-runs/re-running-workflows-and-jobs#re-running-all-the-jobs-in-a-workflow), // or by setting the `ACTIONS_STEP_DEBUG` secret to `true`). - debugMode: getOptionalInput("debug") === "true" || core.isDebug(), + debugMode, debugArtifactName: getOptionalInput("debug-artifact-name") || DEFAULT_DEBUG_ARTIFACT_NAME, debugDatabaseName: @@ -364,6 +366,11 @@ async function run(startedAt: Date) { apiDetails, features, repositoryProperties, + enableFileCoverageInformation: await getFileCoverageInformationEnabled( + debugMode, + repositoryNwo, + features, + ), logger, }); diff --git a/src/init.test.ts b/src/init.test.ts index 6640e081f..8106a78f9 100644 --- a/src/init.test.ts +++ b/src/init.test.ts @@ -2,14 +2,20 @@ import * as fs from "fs"; import path from "path"; import test, { ExecutionContext } from "ava"; +import * as sinon from "sinon"; +import * as actionsUtil from "./actions-util"; import { createStubCodeQL } from "./codeql"; +import { Feature } from "./feature-flags"; import { checkPacksForOverlayCompatibility, cleanupDatabaseClusterDirectory, + getFileCoverageInformationEnabled, } from "./init"; import { KnownLanguage } from "./languages"; +import { parseRepositoryNwo } from "./repository"; import { + createFeatures, LoggedMessage, createTestConfig, getRecordingLogger, @@ -442,3 +448,61 @@ test( expectedResult: true, }, ); + +test("file coverage information enabled when debugMode is true", async (t) => { + t.true( + await getFileCoverageInformationEnabled( + true, // debugMode + parseRepositoryNwo("github/codeql-action"), + createFeatures([Feature.SkipFileCoverageOnPrs]), + ), + ); +}); + +test("file coverage information enabled when not analyzing a pull request", async (t) => { + sinon.stub(actionsUtil, "isAnalyzingPullRequest").returns(false); + + t.true( + await getFileCoverageInformationEnabled( + false, // debugMode + parseRepositoryNwo("github/codeql-action"), + createFeatures([Feature.SkipFileCoverageOnPrs]), + ), + ); +}); + +test("file coverage information enabled when owner is not 'github'", async (t) => { + sinon.stub(actionsUtil, "isAnalyzingPullRequest").returns(true); + + t.true( + await getFileCoverageInformationEnabled( + false, // debugMode + parseRepositoryNwo("other-org/some-repo"), + createFeatures([Feature.SkipFileCoverageOnPrs]), + ), + ); +}); + +test("file coverage information enabled when feature flag is not enabled", async (t) => { + sinon.stub(actionsUtil, "isAnalyzingPullRequest").returns(true); + + t.true( + await getFileCoverageInformationEnabled( + false, // debugMode + parseRepositoryNwo("github/codeql-action"), + createFeatures([]), + ), + ); +}); + +test("file coverage information disabled when all conditions for skipping are met", async (t) => { + sinon.stub(actionsUtil, "isAnalyzingPullRequest").returns(true); + + t.false( + await getFileCoverageInformationEnabled( + false, // debugMode + parseRepositoryNwo("github/codeql-action"), + createFeatures([Feature.SkipFileCoverageOnPrs]), + ), + ); +}); diff --git a/src/init.ts b/src/init.ts index b399ef8d9..a5c8e9ec0 100644 --- a/src/init.ts +++ b/src/init.ts @@ -5,13 +5,22 @@ import * as toolrunner from "@actions/exec/lib/toolrunner"; import * as io from "@actions/io"; import * as yaml from "js-yaml"; -import { getOptionalInput, isSelfHostedRunner } from "./actions-util"; +import { + getOptionalInput, + isAnalyzingPullRequest, + isSelfHostedRunner, +} from "./actions-util"; import { GitHubApiDetails } from "./api-client"; import { CodeQL, setupCodeQL } from "./codeql"; import * as configUtils from "./config-utils"; -import { CodeQLDefaultVersionInfo, FeatureEnablement } from "./feature-flags"; +import { + CodeQLDefaultVersionInfo, + Feature, + FeatureEnablement, +} from "./feature-flags"; import { KnownLanguage, Language } from "./languages"; import { Logger, withGroupAsync } from "./logging"; +import { RepositoryNwo } from "./repository"; import { ToolsSource } from "./setup-codeql"; import { ZstdAvailability } from "./tar"; import { ToolsDownloadStatusReport } from "./tools-download"; @@ -288,3 +297,21 @@ export function cleanupDatabaseClusterDirectory( } } } + +export async function getFileCoverageInformationEnabled( + debugMode: boolean, + repositoryNwo: RepositoryNwo, + features: FeatureEnablement, +): Promise { + return ( + // Always enable file coverage information in debug mode + debugMode || + // We're most interested in speeding up PRs, and we want to keep + // submitting file coverage information for the default branch since + // it is used to populate the status page. + !isAnalyzingPullRequest() || + // For now, restrict this feature to the GitHub org + repositoryNwo.owner !== "github" || + !(await features.getValue(Feature.SkipFileCoverageOnPrs)) + ); +} diff --git a/src/testing-utils.ts b/src/testing-utils.ts index bee7d1ada..83ec88ee1 100644 --- a/src/testing-utils.ts +++ b/src/testing-utils.ts @@ -408,6 +408,7 @@ export function createTestConfig(overrides: Partial): Config { overlayDatabaseMode: OverlayDatabaseMode.None, useOverlayDatabaseCaching: false, repositoryProperties: {}, + enableFileCoverageInformation: true, } satisfies Config, overrides, );