diff --git a/.github/workflows/__export-file-baseline-information.yml b/.github/workflows/__export-file-baseline-information.yml index f157c23f75..41fb9220fd 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 d0e16267ca..a7d4804875 100644 --- a/lib/analyze-action-post.js +++ b/lib/analyze-action-post.js @@ -124724,6 +124724,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", @@ -124941,6 +124950,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, [ @@ -124950,12 +124963,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 } @@ -125142,15 +125157,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 126b0f7ec9..c80deb0775 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -91287,6 +91287,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", @@ -93041,6 +93050,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, [ @@ -93050,12 +93063,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 } @@ -93242,15 +93257,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, @@ -94006,10 +94012,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 2e37724d49..e86b41e428 100644 --- a/lib/autobuild-action.js +++ b/lib/autobuild-action.js @@ -87620,6 +87620,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", @@ -88141,6 +88150,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, [ @@ -88150,12 +88163,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 } @@ -88342,15 +88357,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 272e6ee6f1..5c1de14d3f 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -128119,6 +128119,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", @@ -129576,6 +129585,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, [ @@ -129585,12 +129598,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 } @@ -129777,15 +129792,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 8dfb854c64..d50f4de685 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -88780,6 +88780,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", @@ -89334,7 +89343,8 @@ async function initActionState({ features, repositoryProperties, analysisKinds, - logger + logger, + enableFileCoverageInformation }, userConfig) { const languages = await getLanguages( codeql, @@ -89396,7 +89406,8 @@ async function initActionState({ extraQueryExclusions: [], overlayDatabaseMode: "none" /* None */, useOverlayDatabaseCaching: false, - repositoryProperties + repositoryProperties, + enableFileCoverageInformation }; } async function downloadCacheWithTime(trapCachingEnabled, codeQL, languages, logger) { @@ -91389,6 +91400,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, [ @@ -91398,12 +91413,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 } @@ -91590,15 +91607,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, @@ -92020,6 +92028,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")); @@ -92626,6 +92644,7 @@ async function run(startedAt) { } } analysisKinds = await getAnalysisKinds(logger); + const debugMode = getOptionalInput("debug") === "true" || core13.isDebug(); config = await initConfig2(features, { analysisKinds, languagesInput: getOptionalInput("languages"), @@ -92642,7 +92661,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, @@ -92654,6 +92673,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 0f6546ca92..0d30268fed 100644 --- a/lib/resolve-environment-action.js +++ b/lib/resolve-environment-action.js @@ -87611,6 +87611,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", @@ -87834,6 +87843,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, [ @@ -87843,12 +87856,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 } @@ -88035,15 +88050,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 914aad87da..69da4817b3 100644 --- a/lib/setup-codeql-action.js +++ b/lib/setup-codeql-action.js @@ -87523,6 +87523,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", @@ -89143,6 +89152,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, [ @@ -89152,12 +89165,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 } @@ -89344,15 +89359,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 6d42e77685..1f423b0dba 100644 --- a/lib/start-proxy-action-post.js +++ b/lib/start-proxy-action-post.js @@ -124132,6 +124132,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 39350b8091..a8cc0ce3c9 100644 --- a/lib/start-proxy-action.js +++ b/lib/start-proxy-action.js @@ -104438,6 +104438,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 a59f2e93f4..a41c4d41db 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -90680,6 +90680,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", @@ -91863,6 +91872,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, [ @@ -91872,12 +91885,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 } @@ -92064,15 +92079,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 c7e1156f3e..3bbc115bea 100644 --- a/lib/upload-sarif-action-post.js +++ b/lib/upload-sarif-action-post.js @@ -124294,6 +124294,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 1855fc99c4..ba69d872d4 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -90477,6 +90477,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", @@ -92413,6 +92422,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, [ @@ -92422,12 +92435,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 } @@ -92614,15 +92629,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 a4792f7fdf..a5a08c4361 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3834,9 +3834,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": [ { @@ -3851,7 +3851,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 fdc352285c..e45fc58ca3 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 ceabf62baa..27fe4a6f47 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 dc631ba98f..bb38415047 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 f70e5ffa4f..8e7c2bfe26 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 337eb85c59..276a7a344b 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 772c187b83..a010418993 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 7ad9ecfa48..8de68a28d7 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 8b6c200a05..0d92f46ef9 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 6640e081f3..8106a78f9a 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 b399ef8d9d..a5c8e9ec02 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 66a6c25fb7..a2b8a5a941 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, );