diff --git a/lib/analyze-action-post.js b/lib/analyze-action-post.js index 7fd5d7df08..f7af12f0b5 100644 --- a/lib/analyze-action-post.js +++ b/lib/analyze-action-post.js @@ -119134,6 +119134,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT", minimumVersion: void 0 }, + ["analyze_use_new_upload" /* AnalyzeUseNewUpload */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_ANALYZE_USE_NEW_UPLOAD", + minimumVersion: void 0 + }, ["cleanup_trap_caches" /* CleanupTrapCaches */]: { defaultValue: false, envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES", diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 8b936b19d2..ebf4b507ea 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -89986,6 +89986,11 @@ async function asyncSome(array, predicate) { const results = await Promise.all(array.map(predicate)); return results.some((result) => result); } +function unsafeEntriesInvariant(object) { + return Object.entries(object).filter( + ([_, val2]) => val2 !== void 0 + ); +} // src/actions-util.ts var pkg = require_package(); @@ -90223,6 +90228,15 @@ var CodeQuality = { fixCategory: fixCodeQualityCategory, sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" }; +function getAnalysisConfig(kind) { + switch (kind) { + case "code-scanning" /* CodeScanning */: + return CodeScanning; + case "code-quality" /* CodeQuality */: + return CodeQuality; + } +} +var SarifScanOrder = [CodeQuality, CodeScanning]; // src/analyze.ts var fs15 = __toESM(require("fs")); @@ -91112,6 +91126,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT", minimumVersion: void 0 }, + ["analyze_use_new_upload" /* AnalyzeUseNewUpload */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_ANALYZE_USE_NEW_UPLOAD", + minimumVersion: void 0 + }, ["cleanup_trap_caches" /* CleanupTrapCaches */]: { defaultValue: false, envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES", @@ -95736,6 +95755,54 @@ function getSarifFilePaths(sarifPath, isSarif) { } return sarifFiles; } +async function getGroupedSarifFilePaths(logger, sarifPath) { + const stats = fs18.statSync(sarifPath, { throwIfNoEntry: false }); + if (stats === void 0) { + throw new ConfigurationError(`Path does not exist: ${sarifPath}`); + } + const results = {}; + if (stats.isDirectory()) { + let unassignedSarifFiles = findSarifFilesInDir( + sarifPath, + (name) => path18.extname(name) === ".sarif" + ); + logger.debug( + `Found the following .sarif files in ${sarifPath}: ${unassignedSarifFiles.join(", ")}` + ); + for (const analysisConfig of SarifScanOrder) { + const filesForCurrentAnalysis = unassignedSarifFiles.filter( + analysisConfig.sarifPredicate + ); + if (filesForCurrentAnalysis.length > 0) { + logger.debug( + `The following SARIF files are for ${analysisConfig.name}: ${filesForCurrentAnalysis.join(", ")}` + ); + unassignedSarifFiles = unassignedSarifFiles.filter( + (name) => !analysisConfig.sarifPredicate(name) + ); + results[analysisConfig.kind] = filesForCurrentAnalysis; + } else { + logger.debug(`Found no SARIF files for ${analysisConfig.name}`); + } + } + if (unassignedSarifFiles.length !== 0) { + logger.warning( + `Found files in ${sarifPath} which do not belong to any analysis: ${unassignedSarifFiles.join(", ")}` + ); + } + } else { + for (const analysisConfig of SarifScanOrder) { + if (analysisConfig.kind === "code-scanning" /* CodeScanning */ || analysisConfig.sarifPredicate(sarifPath)) { + logger.debug( + `Using '${sarifPath}' as a SARIF file for ${analysisConfig.name}.` + ); + results[analysisConfig.kind] = [sarifPath]; + break; + } + } + } + return results; +} function countResultsInSarif(sarif) { let numResults = 0; const parsedSarif = JSON.parse(sarif); @@ -96092,6 +96159,29 @@ function filterAlertsByDiffRange(logger, sarif) { return sarif; } +// src/upload-sarif.ts +async function uploadSarif(logger, features, checkoutPath, sarifPath, category) { + const sarifGroups = await getGroupedSarifFilePaths( + logger, + sarifPath + ); + const uploadResults = {}; + for (const [analysisKind, sarifFiles] of unsafeEntriesInvariant( + sarifGroups + )) { + const analysisConfig = getAnalysisConfig(analysisKind); + uploadResults[analysisKind] = await uploadSpecifiedFiles( + sarifFiles, + checkoutPath, + category, + features, + logger, + analysisConfig + ); + } + return uploadResults; +} + // src/analyze-action.ts async function sendStatusReport2(startedAt, config, stats, error2, trapCacheUploadTime, dbCreationTimings, didUploadTrapCaches, trapCacheCleanup, dependencyCacheResults, logger) { const status = getActionsStatus(error2, stats?.analyze_failure_language); @@ -96185,7 +96275,7 @@ async function runAutobuildIfLegacyGoWorkflow(config, logger) { } async function run() { const startedAt = /* @__PURE__ */ new Date(); - let uploadResult = void 0; + let uploadResults = void 0; let runStats = void 0; let config = void 0; let trapCacheCleanupTelemetry = void 0; @@ -96288,28 +96378,50 @@ async function run() { core14.setOutput("sarif-output", import_path4.default.resolve(outputDir)); const uploadInput = getOptionalInput("upload"); if (runStats && getUploadValue(uploadInput) === "always") { - if (isCodeScanningEnabled(config)) { - uploadResult = await uploadFiles( - outputDir, - getRequiredInput("checkout_path"), - getOptionalInput("category"), - features, + const checkoutPath = getRequiredInput("checkout_path"); + const category = getOptionalInput("category"); + if (await features.getValue("analyze_use_new_upload" /* AnalyzeUseNewUpload */)) { + uploadResults = await uploadSarif( logger, - CodeScanning + features, + checkoutPath, + outputDir, + category + ); + } else { + uploadResults = {}; + if (isCodeScanningEnabled(config)) { + uploadResults["code-scanning" /* CodeScanning */] = await uploadFiles( + outputDir, + checkoutPath, + category, + features, + logger, + CodeScanning + ); + } + if (isCodeQualityEnabled(config)) { + uploadResults["code-quality" /* CodeQuality */] = await uploadFiles( + outputDir, + checkoutPath, + category, + features, + logger, + CodeQuality + ); + } + } + if (uploadResults["code-scanning" /* CodeScanning */] !== void 0) { + core14.setOutput( + "sarif-id", + uploadResults["code-scanning" /* CodeScanning */].sarifID ); - core14.setOutput("sarif-id", uploadResult.sarifID); } - if (isCodeQualityEnabled(config)) { - const analysis = CodeQuality; - const qualityUploadResult = await uploadFiles( - outputDir, - getRequiredInput("checkout_path"), - getOptionalInput("category"), - features, - logger, - analysis + if (uploadResults["code-quality" /* CodeQuality */] !== void 0) { + core14.setOutput( + "quality-sarif-id", + uploadResults["code-quality" /* CodeQuality */].sarifID ); - core14.setOutput("quality-sarif-id", qualityUploadResult.sarifID); } } else { logger.info("Not uploading results"); @@ -96337,10 +96449,10 @@ async function run() { } if (isInTestMode()) { logger.debug("In test mode. Waiting for processing is disabled."); - } else if (uploadResult !== void 0 && getRequiredInput("wait-for-processing") === "true") { + } else if (uploadResults?.["code-scanning" /* CodeScanning */] !== void 0 && getRequiredInput("wait-for-processing") === "true") { await waitForProcessing( getRepositoryNwo(), - uploadResult.sarifID, + uploadResults["code-scanning" /* CodeScanning */].sarifID, getActionsLogger() ); } @@ -96369,13 +96481,13 @@ async function run() { ); return; } - if (runStats && uploadResult) { + if (runStats !== void 0 && uploadResults?.["code-scanning" /* CodeScanning */] !== void 0) { await sendStatusReport2( startedAt, config, { ...runStats, - ...uploadResult.statusReport + ...uploadResults["code-scanning" /* CodeScanning */].statusReport }, void 0, trapCacheUploadTime, @@ -96385,7 +96497,7 @@ async function run() { dependencyCacheResults, logger ); - } else if (runStats) { + } else if (runStats !== void 0) { await sendStatusReport2( startedAt, config, diff --git a/lib/autobuild-action.js b/lib/autobuild-action.js index f2aa1ddffb..a6aaf21db4 100644 --- a/lib/autobuild-action.js +++ b/lib/autobuild-action.js @@ -79887,6 +79887,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT", minimumVersion: void 0 }, + ["analyze_use_new_upload" /* AnalyzeUseNewUpload */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_ANALYZE_USE_NEW_UPLOAD", + minimumVersion: void 0 + }, ["cleanup_trap_caches" /* CleanupTrapCaches */]: { defaultValue: false, envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES", diff --git a/lib/init-action-post.js b/lib/init-action-post.js index b2de76f433..bcdf136182 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -129250,6 +129250,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT", minimumVersion: void 0 }, + ["analyze_use_new_upload" /* AnalyzeUseNewUpload */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_ANALYZE_USE_NEW_UPLOAD", + minimumVersion: void 0 + }, ["cleanup_trap_caches" /* CleanupTrapCaches */]: { defaultValue: false, envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES", diff --git a/lib/init-action.js b/lib/init-action.js index 18e350024c..fb022d7c35 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -88552,6 +88552,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT", minimumVersion: void 0 }, + ["analyze_use_new_upload" /* AnalyzeUseNewUpload */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_ANALYZE_USE_NEW_UPLOAD", + minimumVersion: void 0 + }, ["cleanup_trap_caches" /* CleanupTrapCaches */]: { defaultValue: false, envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES", diff --git a/lib/resolve-environment-action.js b/lib/resolve-environment-action.js index e0474b9a5c..4538b0e356 100644 --- a/lib/resolve-environment-action.js +++ b/lib/resolve-environment-action.js @@ -79878,6 +79878,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT", minimumVersion: void 0 }, + ["analyze_use_new_upload" /* AnalyzeUseNewUpload */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_ANALYZE_USE_NEW_UPLOAD", + minimumVersion: void 0 + }, ["cleanup_trap_caches" /* CleanupTrapCaches */]: { defaultValue: false, envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES", diff --git a/lib/setup-codeql-action.js b/lib/setup-codeql-action.js index 37fc43ec6d..c915edc0eb 100644 --- a/lib/setup-codeql-action.js +++ b/lib/setup-codeql-action.js @@ -86357,6 +86357,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT", minimumVersion: void 0 }, + ["analyze_use_new_upload" /* AnalyzeUseNewUpload */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_ANALYZE_USE_NEW_UPLOAD", + minimumVersion: void 0 + }, ["cleanup_trap_caches" /* CleanupTrapCaches */]: { defaultValue: false, envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES", diff --git a/lib/start-proxy-action-post.js b/lib/start-proxy-action-post.js index b224695c4b..8b75462569 100644 --- a/lib/start-proxy-action-post.js +++ b/lib/start-proxy-action-post.js @@ -118540,6 +118540,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT", minimumVersion: void 0 }, + ["analyze_use_new_upload" /* AnalyzeUseNewUpload */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_ANALYZE_USE_NEW_UPLOAD", + minimumVersion: void 0 + }, ["cleanup_trap_caches" /* CleanupTrapCaches */]: { defaultValue: false, envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES", diff --git a/lib/start-proxy-action.js b/lib/start-proxy-action.js index dc17468b85..99e294ab1c 100644 --- a/lib/start-proxy-action.js +++ b/lib/start-proxy-action.js @@ -96669,6 +96669,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT", minimumVersion: void 0 }, + ["analyze_use_new_upload" /* AnalyzeUseNewUpload */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_ANALYZE_USE_NEW_UPLOAD", + minimumVersion: void 0 + }, ["cleanup_trap_caches" /* CleanupTrapCaches */]: { defaultValue: false, envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES", diff --git a/lib/upload-lib.js b/lib/upload-lib.js index a952f35ab4..2497ae3a6f 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -89349,6 +89349,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT", minimumVersion: void 0 }, + ["analyze_use_new_upload" /* AnalyzeUseNewUpload */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_ANALYZE_USE_NEW_UPLOAD", + minimumVersion: void 0 + }, ["cleanup_trap_caches" /* CleanupTrapCaches */]: { defaultValue: false, envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES", diff --git a/lib/upload-sarif-action-post.js b/lib/upload-sarif-action-post.js index 17777d3b8f..ea287ce37c 100644 --- a/lib/upload-sarif-action-post.js +++ b/lib/upload-sarif-action-post.js @@ -118706,6 +118706,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT", minimumVersion: void 0 }, + ["analyze_use_new_upload" /* AnalyzeUseNewUpload */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_ANALYZE_USE_NEW_UPLOAD", + minimumVersion: void 0 + }, ["cleanup_trap_caches" /* CleanupTrapCaches */]: { defaultValue: false, envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES", diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index 9596cc4512..e47be5b0e2 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -89300,6 +89300,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT", minimumVersion: void 0 }, + ["analyze_use_new_upload" /* AnalyzeUseNewUpload */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_ANALYZE_USE_NEW_UPLOAD", + minimumVersion: void 0 + }, ["cleanup_trap_caches" /* CleanupTrapCaches */]: { defaultValue: false, envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES", diff --git a/src/analyze-action.ts b/src/analyze-action.ts index 3d0fb1c89e..b6aa05ebec 100644 --- a/src/analyze-action.ts +++ b/src/analyze-action.ts @@ -52,6 +52,7 @@ import { } from "./trap-caching"; import * as uploadLib from "./upload-lib"; import { UploadResult } from "./upload-lib"; +import { uploadSarif } from "./upload-sarif"; import * as util from "./util"; interface AnalysisStatusReport @@ -211,7 +212,9 @@ async function runAutobuildIfLegacyGoWorkflow(config: Config, logger: Logger) { async function run() { const startedAt = new Date(); - let uploadResult: UploadResult | undefined = undefined; + let uploadResults: + | Partial> + | undefined = undefined; let runStats: QueriesStatusReport | undefined = undefined; let config: Config | undefined = undefined; let trapCacheCleanupTelemetry: TrapCacheCleanupStatusReport | undefined = @@ -343,29 +346,58 @@ async function run() { core.setOutput("sarif-output", path.resolve(outputDir)); const uploadInput = actionsUtil.getOptionalInput("upload"); if (runStats && actionsUtil.getUploadValue(uploadInput) === "always") { - if (isCodeScanningEnabled(config)) { - uploadResult = await uploadLib.uploadFiles( - outputDir, - actionsUtil.getRequiredInput("checkout_path"), - actionsUtil.getOptionalInput("category"), - features, + const checkoutPath = actionsUtil.getRequiredInput("checkout_path"); + const category = actionsUtil.getOptionalInput("category"); + + if (await features.getValue(Feature.AnalyzeUseNewUpload)) { + uploadResults = await uploadSarif( logger, - analyses.CodeScanning, + features, + checkoutPath, + outputDir, + category, ); - core.setOutput("sarif-id", uploadResult.sarifID); + } else { + uploadResults = {}; + + if (isCodeScanningEnabled(config)) { + uploadResults[analyses.AnalysisKind.CodeScanning] = + await uploadLib.uploadFiles( + outputDir, + checkoutPath, + category, + features, + logger, + analyses.CodeScanning, + ); + } + + if (isCodeQualityEnabled(config)) { + uploadResults[analyses.AnalysisKind.CodeQuality] = + await uploadLib.uploadFiles( + outputDir, + checkoutPath, + category, + features, + logger, + analyses.CodeQuality, + ); + } } - if (isCodeQualityEnabled(config)) { - const analysis = analyses.CodeQuality; - const qualityUploadResult = await uploadLib.uploadFiles( - outputDir, - actionsUtil.getRequiredInput("checkout_path"), - actionsUtil.getOptionalInput("category"), - features, - logger, - analysis, + // Set the SARIF id outputs only if we have results for them, to avoid + // having keys with empty values in the action output. + if (uploadResults[analyses.AnalysisKind.CodeScanning] !== undefined) { + core.setOutput( + "sarif-id", + uploadResults[analyses.AnalysisKind.CodeScanning].sarifID, + ); + } + if (uploadResults[analyses.AnalysisKind.CodeQuality] !== undefined) { + core.setOutput( + "quality-sarif-id", + uploadResults[analyses.AnalysisKind.CodeQuality].sarifID, ); - core.setOutput("quality-sarif-id", qualityUploadResult.sarifID); } } else { logger.info("Not uploading results"); @@ -408,12 +440,12 @@ async function run() { if (util.isInTestMode()) { logger.debug("In test mode. Waiting for processing is disabled."); } else if ( - uploadResult !== undefined && + uploadResults?.[analyses.AnalysisKind.CodeScanning] !== undefined && actionsUtil.getRequiredInput("wait-for-processing") === "true" ) { await uploadLib.waitForProcessing( getRepositoryNwo(), - uploadResult.sarifID, + uploadResults[analyses.AnalysisKind.CodeScanning].sarifID, getActionsLogger(), ); } @@ -450,13 +482,16 @@ async function run() { return; } - if (runStats && uploadResult) { + if ( + runStats !== undefined && + uploadResults?.[analyses.AnalysisKind.CodeScanning] !== undefined + ) { await sendStatusReport( startedAt, config, { ...runStats, - ...uploadResult.statusReport, + ...uploadResults[analyses.AnalysisKind.CodeScanning].statusReport, }, undefined, trapCacheUploadTime, @@ -466,7 +501,7 @@ async function run() { dependencyCacheResults, logger, ); - } else if (runStats) { + } else if (runStats !== undefined) { await sendStatusReport( startedAt, config, diff --git a/src/feature-flags.ts b/src/feature-flags.ts index 334769913a..bf7f7d3d4f 100644 --- a/src/feature-flags.ts +++ b/src/feature-flags.ts @@ -44,6 +44,7 @@ export interface FeatureEnablement { */ export enum Feature { AllowToolcacheInput = "allow_toolcache_input", + AnalyzeUseNewUpload = "analyze_use_new_upload", CleanupTrapCaches = "cleanup_trap_caches", CppDependencyInstallation = "cpp_dependency_installation_enabled", DiffInformedQueries = "diff_informed_queries", @@ -116,6 +117,11 @@ export const featureConfig: Record< envVar: "CODEQL_ACTION_ALLOW_TOOLCACHE_INPUT", minimumVersion: undefined, }, + [Feature.AnalyzeUseNewUpload]: { + defaultValue: false, + envVar: "CODEQL_ACTION_ANALYZE_USE_NEW_UPLOAD", + minimumVersion: undefined, + }, [Feature.CleanupTrapCaches]: { defaultValue: false, envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES",