From 9267d8d51e8b42a6a4d4fd944280c2f9cdc5335c Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 11 Feb 2026 19:48:06 +0000 Subject: [PATCH 01/13] Add `csra` analysis kind --- lib/analyze-action-post.js | 1 + lib/analyze-action.js | 18 +++++++++++++++++- lib/autobuild-action.js | 1 + lib/init-action-post.js | 1 + lib/init-action.js | 1 + lib/resolve-environment-action.js | 1 + lib/setup-codeql-action.js | 1 + lib/start-proxy-action-post.js | 1 + lib/start-proxy-action.js | 1 + lib/upload-lib.js | 16 +++++++++++++++- lib/upload-sarif-action-post.js | 1 + lib/upload-sarif-action.js | 18 +++++++++++++++++- src/analyses.ts | 20 +++++++++++++++++++- 13 files changed, 77 insertions(+), 4 deletions(-) diff --git a/lib/analyze-action-post.js b/lib/analyze-action-post.js index d097d992d3..bceaf258f3 100644 --- a/lib/analyze-action-post.js +++ b/lib/analyze-action-post.js @@ -161224,6 +161224,7 @@ var path3 = __toESM(require("path")); var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { AnalysisKind2["CodeScanning"] = "code-scanning"; AnalysisKind2["CodeQuality"] = "code-quality"; + AnalysisKind2["CSRA"] = "csra"; return AnalysisKind2; })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); diff --git a/lib/analyze-action.js b/lib/analyze-action.js index c0288403bf..ec649abd59 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -106485,6 +106485,7 @@ function fixCodeQualityCategory(logger, category) { var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { AnalysisKind2["CodeScanning"] = "code-scanning"; AnalysisKind2["CodeQuality"] = "code-quality"; + AnalysisKind2["CSRA"] = "csra"; return AnalysisKind2; })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); @@ -106507,15 +106508,30 @@ var CodeQuality = { fixCategory: fixCodeQualityCategory, sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" }; +var CSRA = { + kind: "csra" /* CSRA */, + name: "csra", + target: "PUT /repos/:owner/:repo/code-scanning/risk-assessment" /* CSRA */, + sarifExtension: ".csra.sarif", + sarifPredicate: (name) => name.endsWith(CSRA.sarifExtension), + fixCategory: fixCodeQualityCategory, + sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_" +}; function getAnalysisConfig(kind) { switch (kind) { case "code-scanning" /* CodeScanning */: return CodeScanning; case "code-quality" /* CodeQuality */: return CodeQuality; + case "csra" /* CSRA */: + return CSRA; } } -var SarifScanOrder = [CodeQuality, CodeScanning]; +var SarifScanOrder = [ + CSRA, + CodeQuality, + CodeScanning +]; // src/analyze.ts var fs12 = __toESM(require("fs")); diff --git a/lib/autobuild-action.js b/lib/autobuild-action.js index 416cc22720..9aa58f4170 100644 --- a/lib/autobuild-action.js +++ b/lib/autobuild-action.js @@ -103629,6 +103629,7 @@ var path4 = __toESM(require("path")); var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { AnalysisKind2["CodeScanning"] = "code-scanning"; AnalysisKind2["CodeQuality"] = "code-quality"; + AnalysisKind2["CSRA"] = "csra"; return AnalysisKind2; })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 44e368f8a4..122494401a 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -164545,6 +164545,7 @@ var path6 = __toESM(require("path")); var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { AnalysisKind2["CodeScanning"] = "code-scanning"; AnalysisKind2["CodeQuality"] = "code-quality"; + AnalysisKind2["CSRA"] = "csra"; return AnalysisKind2; })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); diff --git a/lib/init-action.js b/lib/init-action.js index 8607b23914..1dcae20054 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -103833,6 +103833,7 @@ function isAnalyzingPullRequest() { var AnalysisKind = /* @__PURE__ */ ((AnalysisKind3) => { AnalysisKind3["CodeScanning"] = "code-scanning"; AnalysisKind3["CodeQuality"] = "code-quality"; + AnalysisKind3["CSRA"] = "csra"; return AnalysisKind3; })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); diff --git a/lib/resolve-environment-action.js b/lib/resolve-environment-action.js index a841072511..d2c4da143b 100644 --- a/lib/resolve-environment-action.js +++ b/lib/resolve-environment-action.js @@ -103628,6 +103628,7 @@ var path3 = __toESM(require("path")); var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { AnalysisKind2["CodeScanning"] = "code-scanning"; AnalysisKind2["CodeQuality"] = "code-quality"; + AnalysisKind2["CSRA"] = "csra"; return AnalysisKind2; })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); diff --git a/lib/setup-codeql-action.js b/lib/setup-codeql-action.js index c01ec64f56..ddc06f431d 100644 --- a/lib/setup-codeql-action.js +++ b/lib/setup-codeql-action.js @@ -104553,6 +104553,7 @@ function wrapCliConfigurationError(cliError) { var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { AnalysisKind2["CodeScanning"] = "code-scanning"; AnalysisKind2["CodeQuality"] = "code-quality"; + AnalysisKind2["CSRA"] = "csra"; return AnalysisKind2; })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); diff --git a/lib/start-proxy-action-post.js b/lib/start-proxy-action-post.js index c29841a85b..adccec31bc 100644 --- a/lib/start-proxy-action-post.js +++ b/lib/start-proxy-action-post.js @@ -160859,6 +160859,7 @@ var path = __toESM(require("path")); var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { AnalysisKind2["CodeScanning"] = "code-scanning"; AnalysisKind2["CodeQuality"] = "code-quality"; + AnalysisKind2["CSRA"] = "csra"; return AnalysisKind2; })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); diff --git a/lib/start-proxy-action.js b/lib/start-proxy-action.js index 072924405e..7baced5b4b 100644 --- a/lib/start-proxy-action.js +++ b/lib/start-proxy-action.js @@ -121161,6 +121161,7 @@ var core9 = __toESM(require_core()); var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { AnalysisKind2["CodeScanning"] = "code-scanning"; AnalysisKind2["CodeQuality"] = "code-quality"; + AnalysisKind2["CSRA"] = "csra"; return AnalysisKind2; })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); diff --git a/lib/upload-lib.js b/lib/upload-lib.js index 0fa50e3967..4b38eb22d9 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -106141,6 +106141,7 @@ function fixCodeQualityCategory(logger, category) { var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { AnalysisKind2["CodeScanning"] = "code-scanning"; AnalysisKind2["CodeQuality"] = "code-quality"; + AnalysisKind2["CSRA"] = "csra"; return AnalysisKind2; })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); @@ -106162,7 +106163,20 @@ var CodeQuality = { fixCategory: fixCodeQualityCategory, sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" }; -var SarifScanOrder = [CodeQuality, CodeScanning]; +var CSRA = { + kind: "csra" /* CSRA */, + name: "csra", + target: "PUT /repos/:owner/:repo/code-scanning/risk-assessment" /* CSRA */, + sarifExtension: ".csra.sarif", + sarifPredicate: (name) => name.endsWith(CSRA.sarifExtension), + fixCategory: fixCodeQualityCategory, + sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_" +}; +var SarifScanOrder = [ + CSRA, + CodeQuality, + CodeScanning +]; // src/api-client.ts var core5 = __toESM(require_core()); diff --git a/lib/upload-sarif-action-post.js b/lib/upload-sarif-action-post.js index a733e8c04b..04f5016943 100644 --- a/lib/upload-sarif-action-post.js +++ b/lib/upload-sarif-action-post.js @@ -160866,6 +160866,7 @@ var io5 = __toESM(require_io()); var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { AnalysisKind2["CodeScanning"] = "code-scanning"; AnalysisKind2["CodeQuality"] = "code-quality"; + AnalysisKind2["CSRA"] = "csra"; return AnalysisKind2; })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index edc7840847..6d33fb587e 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -106179,6 +106179,7 @@ function fixCodeQualityCategory(logger, category) { var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { AnalysisKind2["CodeScanning"] = "code-scanning"; AnalysisKind2["CodeQuality"] = "code-quality"; + AnalysisKind2["CSRA"] = "csra"; return AnalysisKind2; })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); @@ -106200,15 +106201,30 @@ var CodeQuality = { fixCategory: fixCodeQualityCategory, sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" }; +var CSRA = { + kind: "csra" /* CSRA */, + name: "csra", + target: "PUT /repos/:owner/:repo/code-scanning/risk-assessment" /* CSRA */, + sarifExtension: ".csra.sarif", + sarifPredicate: (name) => name.endsWith(CSRA.sarifExtension), + fixCategory: fixCodeQualityCategory, + sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_" +}; function getAnalysisConfig(kind) { switch (kind) { case "code-scanning" /* CodeScanning */: return CodeScanning; case "code-quality" /* CodeQuality */: return CodeQuality; + case "csra" /* CSRA */: + return CSRA; } } -var SarifScanOrder = [CodeQuality, CodeScanning]; +var SarifScanOrder = [ + CSRA, + CodeQuality, + CodeScanning +]; // src/api-client.ts var core5 = __toESM(require_core()); diff --git a/src/analyses.ts b/src/analyses.ts index 4f91ab07c0..33aa68f564 100644 --- a/src/analyses.ts +++ b/src/analyses.ts @@ -9,6 +9,7 @@ import { ConfigurationError } from "./util"; export enum AnalysisKind { CodeScanning = "code-scanning", CodeQuality = "code-quality", + CSRA = "csra", } // Exported for testing. A set of all known analysis kinds. @@ -101,6 +102,7 @@ export const codeQualityQueries: string[] = ["code-quality"]; enum SARIF_UPLOAD_ENDPOINT { CODE_SCANNING = "PUT /repos/:owner/:repo/code-scanning/analysis", CODE_QUALITY = "PUT /repos/:owner/:repo/code-quality/analysis", + CSRA = "PUT /repos/:owner/:repo/code-scanning/risk-assessment", } // Represents configurations for different analysis kinds. @@ -146,6 +148,16 @@ export const CodeQuality: AnalysisConfig = { sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_", }; +export const CSRA: AnalysisConfig = { + kind: AnalysisKind.CSRA, + name: "csra", + target: SARIF_UPLOAD_ENDPOINT.CSRA, + sarifExtension: ".csra.sarif", + sarifPredicate: (name) => name.endsWith(CSRA.sarifExtension), + fixCategory: fixCodeQualityCategory, + sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_", +}; + /** * Gets the `AnalysisConfig` corresponding to `kind`. * @param kind The analysis kind to get the `AnalysisConfig` for. @@ -160,6 +172,8 @@ export function getAnalysisConfig(kind: AnalysisKind): AnalysisConfig { return CodeScanning; case AnalysisKind.CodeQuality: return CodeQuality; + case AnalysisKind.CSRA: + return CSRA; } } @@ -167,4 +181,8 @@ export function getAnalysisConfig(kind: AnalysisKind): AnalysisConfig { // we want to scan a folder containing SARIF files in an order that finds the more // specific extensions first. This constant defines an array in the order of analyis // configurations with more specific extensions to less specific extensions. -export const SarifScanOrder = [CodeQuality, CodeScanning]; +export const SarifScanOrder: AnalysisConfig[] = [ + CSRA, + CodeQuality, + CodeScanning, +]; From 5b3261bcbf50d677ad985c371e13611679173bd0 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 11 Feb 2026 20:14:37 +0000 Subject: [PATCH 02/13] Enforce that only compatible kinds can be enabled concurrently --- lib/init-action.js | 22 +++++++++++++++++++--- src/analyses.test.ts | 34 ++++++++++++++++++++++++++++++++++ src/analyses.ts | 30 +++++++++++++++++++++++++++--- 3 files changed, 80 insertions(+), 6 deletions(-) diff --git a/lib/init-action.js b/lib/init-action.js index 1dcae20054..6bf9880a5b 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -103836,6 +103836,11 @@ var AnalysisKind = /* @__PURE__ */ ((AnalysisKind3) => { AnalysisKind3["CSRA"] = "csra"; return AnalysisKind3; })(AnalysisKind || {}); +var compatibilityMatrix = { + ["code-scanning" /* CodeScanning */]: /* @__PURE__ */ new Set(["code-quality" /* CodeQuality */]), + ["code-quality" /* CodeQuality */]: /* @__PURE__ */ new Set(["code-scanning" /* CodeScanning */]), + ["csra" /* CSRA */]: /* @__PURE__ */ new Set() +}; var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); async function parseAnalysisKinds(input) { const components = input.split(","); @@ -103858,7 +103863,7 @@ async function getAnalysisKinds(logger, skipCache = false) { if (!skipCache && cachedAnalysisKinds !== void 0) { return cachedAnalysisKinds; } - cachedAnalysisKinds = await parseAnalysisKinds( + const analysisKinds = await parseAnalysisKinds( getRequiredInput("analysis-kinds") ); const qualityQueriesInput = getOptionalInput("quality-queries"); @@ -103867,9 +103872,20 @@ async function getAnalysisKinds(logger, skipCache = false) { "The `quality-queries` input is deprecated and will be removed in a future version of the CodeQL Action. Use the `analysis-kinds` input to configure different analysis kinds instead." ); } - if (!cachedAnalysisKinds.includes("code-quality" /* CodeQuality */) && qualityQueriesInput !== void 0) { - cachedAnalysisKinds.push("code-quality" /* CodeQuality */); + if (!analysisKinds.includes("code-quality" /* CodeQuality */) && qualityQueriesInput !== void 0) { + analysisKinds.push("code-quality" /* CodeQuality */); + } + for (const analysisKind of analysisKinds) { + for (const otherAnalysisKind of analysisKinds) { + if (analysisKind === otherAnalysisKind) continue; + if (!compatibilityMatrix[analysisKind].has(otherAnalysisKind)) { + throw new ConfigurationError( + `${otherAnalysisKind} cannot be enabled at the same time as ${analysisKind}` + ); + } + } } + cachedAnalysisKinds = analysisKinds; return cachedAnalysisKinds; } var codeQualityQueries = ["code-quality"]; diff --git a/src/analyses.test.ts b/src/analyses.test.ts index 9178ffbd5a..d3cd584d0c 100644 --- a/src/analyses.test.ts +++ b/src/analyses.test.ts @@ -4,6 +4,7 @@ import * as sinon from "sinon"; import * as actionsUtil from "./actions-util"; import { AnalysisKind, + compatibilityMatrix, getAnalysisKinds, parseAnalysisKinds, supportedAnalysisKinds, @@ -67,3 +68,36 @@ test("getAnalysisKinds - throws if `analysis-kinds` input is invalid", async (t) requiredInputStub.withArgs("analysis-kinds").returns("no-such-thing"); await t.throwsAsync(getAnalysisKinds(getRunnerLogger(true), true)); }); + +// Test the compatibility matrix by looping through all analysis kinds. +const analysisKinds = Object.values(AnalysisKind); +for (let i = 0; i < analysisKinds.length; i++) { + const analysisKind = analysisKinds[i]; + + for (let j = i + 1; j < analysisKinds.length; j++) { + const otherAnalysis = analysisKinds[j]; + + if (analysisKind === otherAnalysis) continue; + if (compatibilityMatrix[analysisKind].has(otherAnalysis)) { + test(`getAnalysisKinds - allows ${analysisKind} with ${otherAnalysis}`, async (t) => { + const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput"); + requiredInputStub + .withArgs("analysis-kinds") + .returns([analysisKind, otherAnalysis].join(",")); + const result = await getAnalysisKinds(getRunnerLogger(true), true); + t.is(result.length, 2); + }); + } else { + test(`getAnalysisKinds - throws if ${analysisKind} is enabled with ${otherAnalysis}`, async (t) => { + const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput"); + requiredInputStub + .withArgs("analysis-kinds") + .returns([analysisKind, otherAnalysis].join(",")); + await t.throwsAsync(getAnalysisKinds(getRunnerLogger(true), true), { + instanceOf: ConfigurationError, + message: `${otherAnalysis} cannot be enabled at the same time as ${analysisKind}`, + }); + }); + } + } +} diff --git a/src/analyses.ts b/src/analyses.ts index 33aa68f564..522d3aee84 100644 --- a/src/analyses.ts +++ b/src/analyses.ts @@ -12,6 +12,15 @@ export enum AnalysisKind { CSRA = "csra", } +export type CompatibilityMatrix = Record>; + +/** A mapping from analysis kinds to other analysis kinds which can be enabled concurrently. */ +export const compatibilityMatrix: CompatibilityMatrix = { + [AnalysisKind.CodeScanning]: new Set([AnalysisKind.CodeQuality]), + [AnalysisKind.CodeQuality]: new Set([AnalysisKind.CodeScanning]), + [AnalysisKind.CSRA]: new Set(), +}; + // Exported for testing. A set of all known analysis kinds. export const supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); @@ -68,7 +77,7 @@ export async function getAnalysisKinds( return cachedAnalysisKinds; } - cachedAnalysisKinds = await parseAnalysisKinds( + const analysisKinds = await parseAnalysisKinds( getRequiredInput("analysis-kinds"), ); @@ -86,12 +95,27 @@ export async function getAnalysisKinds( // if an input to `quality-queries` was specified. We should remove this once // `quality-queries` is no longer used. if ( - !cachedAnalysisKinds.includes(AnalysisKind.CodeQuality) && + !analysisKinds.includes(AnalysisKind.CodeQuality) && qualityQueriesInput !== undefined ) { - cachedAnalysisKinds.push(AnalysisKind.CodeQuality); + analysisKinds.push(AnalysisKind.CodeQuality); + } + + // Check that all enabled analysis kinds are compatible with each other. + for (const analysisKind of analysisKinds) { + for (const otherAnalysisKind of analysisKinds) { + if (analysisKind === otherAnalysisKind) continue; + + if (!compatibilityMatrix[analysisKind].has(otherAnalysisKind)) { + throw new ConfigurationError( + `${otherAnalysisKind} cannot be enabled at the same time as ${analysisKind}`, + ); + } + } } + // Cache the analysis kinds and return them. + cachedAnalysisKinds = analysisKinds; return cachedAnalysisKinds; } From 5132eb53f286efeb5a0ab86e0ecc0ff8920107ec Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 11 Feb 2026 22:10:55 +0000 Subject: [PATCH 03/13] Fix `CodeScanning` config's `sarifPredicate` and add test --- lib/analyze-action.js | 2 +- lib/init-action-post.js | 11 ++++++++++- lib/upload-lib.js | 2 +- lib/upload-sarif-action.js | 2 +- src/analyses.test.ts | 16 ++++++++++++++++ src/analyses.ts | 3 ++- 6 files changed, 31 insertions(+), 5 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index ec649abd59..8ddcd0ed02 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -106495,7 +106495,7 @@ var CodeScanning = { name: "code scanning", target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, sarifExtension: ".sarif", - sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name), + sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name) && !CSRA.sarifPredicate(name), fixCategory: (_, category) => category, sentinelPrefix: "CODEQL_UPLOAD_SARIF_" }; diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 122494401a..51286a9164 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -164554,7 +164554,7 @@ var CodeScanning = { name: "code scanning", target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, sarifExtension: ".sarif", - sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name), + sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name) && !CSRA.sarifPredicate(name), fixCategory: (_2, category) => category, sentinelPrefix: "CODEQL_UPLOAD_SARIF_" }; @@ -164567,6 +164567,15 @@ var CodeQuality = { fixCategory: fixCodeQualityCategory, sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" }; +var CSRA = { + kind: "csra" /* CSRA */, + name: "csra", + target: "PUT /repos/:owner/:repo/code-scanning/risk-assessment" /* CSRA */, + sarifExtension: ".csra.sarif", + sarifPredicate: (name) => name.endsWith(CSRA.sarifExtension), + fixCategory: fixCodeQualityCategory, + sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_" +}; // src/config/db-config.ts var jsonschema = __toESM(require_lib2()); diff --git a/lib/upload-lib.js b/lib/upload-lib.js index 4b38eb22d9..a4166a3593 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -106150,7 +106150,7 @@ var CodeScanning = { name: "code scanning", target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, sarifExtension: ".sarif", - sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name), + sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name) && !CSRA.sarifPredicate(name), fixCategory: (_, category) => category, sentinelPrefix: "CODEQL_UPLOAD_SARIF_" }; diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index 6d33fb587e..8057d09097 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -106188,7 +106188,7 @@ var CodeScanning = { name: "code scanning", target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, sarifExtension: ".sarif", - sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name), + sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name) && !CSRA.sarifPredicate(name), fixCategory: (_, category) => category, sentinelPrefix: "CODEQL_UPLOAD_SARIF_" }; diff --git a/src/analyses.test.ts b/src/analyses.test.ts index d3cd584d0c..3e0fb74bc3 100644 --- a/src/analyses.test.ts +++ b/src/analyses.test.ts @@ -4,7 +4,9 @@ import * as sinon from "sinon"; import * as actionsUtil from "./actions-util"; import { AnalysisKind, + CodeScanning, compatibilityMatrix, + getAnalysisConfig, getAnalysisKinds, parseAnalysisKinds, supportedAnalysisKinds, @@ -12,6 +14,7 @@ import { import { getRunnerLogger } from "./logging"; import { setupTests } from "./testing-utils"; import { ConfigurationError } from "./util"; +import path from "path"; setupTests(test); @@ -101,3 +104,16 @@ for (let i = 0; i < analysisKinds.length; i++) { } } } + +test("Code Scanning configuration does not accept other SARIF extensions", (t) => { + for (const analysisKind of supportedAnalysisKinds) { + if (analysisKind === AnalysisKind.CodeScanning) continue; + + const analysis = getAnalysisConfig(analysisKind); + const sarifPath = path.join("path", "to", `file${analysis.sarifExtension}`); + + // The Code Scanning configuration's `sarifPredicate` should not accept a path which + // ends in a different configuration's `sarifExtension`. + t.false(CodeScanning.sarifPredicate(sarifPath)); + } +}); diff --git a/src/analyses.ts b/src/analyses.ts index 522d3aee84..714917b91f 100644 --- a/src/analyses.ts +++ b/src/analyses.ts @@ -156,7 +156,8 @@ export const CodeScanning: AnalysisConfig = { sarifExtension: ".sarif", sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && - !CodeQuality.sarifPredicate(name), + !CodeQuality.sarifPredicate(name) && + !CSRA.sarifPredicate(name), fixCategory: (_, category) => category, sentinelPrefix: "CODEQL_UPLOAD_SARIF_", }; From 406bbfcef143cd98ac5732d7ef8d582eb97ae6a0 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 11 Feb 2026 22:11:17 +0000 Subject: [PATCH 04/13] Update `upload-lib` tests for CSRA --- src/upload-lib.test.ts | 80 ++++++++++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 23 deletions(-) diff --git a/src/upload-lib.test.ts b/src/upload-lib.test.ts index 7a5be6382f..5accb871a2 100644 --- a/src/upload-lib.test.ts +++ b/src/upload-lib.test.ts @@ -128,11 +128,21 @@ test("finding SARIF files", async (t) => { "file", ); - // add some `.quality.sarif` files that should be ignored, unless we look for them specifically - fs.writeFileSync(path.join(tmpDir, "a.quality.sarif"), ""); - fs.writeFileSync(path.join(tmpDir, "dir1", "b.quality.sarif"), ""); + // add some non-Code Scanning files that should be ignored, unless we look for them specifically + for (const analysisKind of analyses.supportedAnalysisKinds) { + if (analysisKind === AnalysisKind.CodeScanning) continue; - const expectedSarifFiles = [ + const analysis = analyses.getAnalysisConfig(analysisKind); + + fs.writeFileSync(path.join(tmpDir, `a${analysis.sarifExtension}`), ""); + fs.writeFileSync( + path.join(tmpDir, "dir1", `b${analysis.sarifExtension}`), + "", + ); + } + + const expectedSarifFiles: Partial> = {}; + expectedSarifFiles[AnalysisKind.CodeScanning] = [ path.join(tmpDir, "a.sarif"), path.join(tmpDir, "b.sarif"), path.join(tmpDir, "dir1", "d.sarif"), @@ -143,18 +153,24 @@ test("finding SARIF files", async (t) => { CodeScanning.sarifPredicate, ); - t.deepEqual(sarifFiles, expectedSarifFiles); + t.deepEqual(sarifFiles, expectedSarifFiles[AnalysisKind.CodeScanning]); - const expectedQualitySarifFiles = [ - path.join(tmpDir, "a.quality.sarif"), - path.join(tmpDir, "dir1", "b.quality.sarif"), - ]; - const qualitySarifFiles = uploadLib.findSarifFilesInDir( - tmpDir, - CodeQuality.sarifPredicate, - ); + for (const analysisKind of analyses.supportedAnalysisKinds) { + if (analysisKind === AnalysisKind.CodeScanning) continue; + + const analysis = analyses.getAnalysisConfig(analysisKind); - t.deepEqual(qualitySarifFiles, expectedQualitySarifFiles); + expectedSarifFiles[analysisKind] = [ + path.join(tmpDir, `a${analysis.sarifExtension}`), + path.join(tmpDir, "dir1", `b${analysis.sarifExtension}`), + ]; + const foundSarifFiles = uploadLib.findSarifFilesInDir( + tmpDir, + analysis.sarifPredicate, + ); + + t.deepEqual(foundSarifFiles, expectedSarifFiles[analysisKind]); + } const groupedSarifFiles = await uploadLib.getGroupedSarifFilePaths( getRunnerLogger(true), @@ -162,16 +178,31 @@ test("finding SARIF files", async (t) => { ); t.not(groupedSarifFiles, undefined); - t.not(groupedSarifFiles[AnalysisKind.CodeScanning], undefined); - t.not(groupedSarifFiles[AnalysisKind.CodeQuality], undefined); - t.deepEqual( - groupedSarifFiles[AnalysisKind.CodeScanning], - expectedSarifFiles, - ); - t.deepEqual( - groupedSarifFiles[AnalysisKind.CodeQuality], - expectedQualitySarifFiles, + for (const analysisKind of analyses.supportedAnalysisKinds) { + t.not(groupedSarifFiles[analysisKind], undefined); + t.deepEqual( + groupedSarifFiles[analysisKind], + expectedSarifFiles[analysisKind], + ); + } + }); +}); + +test("getGroupedSarifFilePaths - CSRA", async (t) => { + await withTmpDir(async (tmpDir) => { + const sarifPath = path.join(tmpDir, "a.csra.sarif"); + fs.writeFileSync(sarifPath, ""); + + const groupedSarifFiles = await uploadLib.getGroupedSarifFilePaths( + getRunnerLogger(true), + sarifPath, ); + + t.not(groupedSarifFiles, undefined); + t.is(groupedSarifFiles[AnalysisKind.CodeScanning], undefined); + t.is(groupedSarifFiles[AnalysisKind.CodeQuality], undefined); + t.not(groupedSarifFiles[AnalysisKind.CSRA], undefined); + t.deepEqual(groupedSarifFiles[AnalysisKind.CSRA], [sarifPath]); }); }); @@ -188,6 +219,7 @@ test("getGroupedSarifFilePaths - Code Quality file", async (t) => { t.not(groupedSarifFiles, undefined); t.is(groupedSarifFiles[AnalysisKind.CodeScanning], undefined); t.not(groupedSarifFiles[AnalysisKind.CodeQuality], undefined); + t.is(groupedSarifFiles[AnalysisKind.CSRA], undefined); t.deepEqual(groupedSarifFiles[AnalysisKind.CodeQuality], [sarifPath]); }); }); @@ -205,6 +237,7 @@ test("getGroupedSarifFilePaths - Code Scanning file", async (t) => { t.not(groupedSarifFiles, undefined); t.not(groupedSarifFiles[AnalysisKind.CodeScanning], undefined); t.is(groupedSarifFiles[AnalysisKind.CodeQuality], undefined); + t.is(groupedSarifFiles[AnalysisKind.CSRA], undefined); t.deepEqual(groupedSarifFiles[AnalysisKind.CodeScanning], [sarifPath]); }); }); @@ -222,6 +255,7 @@ test("getGroupedSarifFilePaths - Other file", async (t) => { t.not(groupedSarifFiles, undefined); t.not(groupedSarifFiles[AnalysisKind.CodeScanning], undefined); t.is(groupedSarifFiles[AnalysisKind.CodeQuality], undefined); + t.is(groupedSarifFiles[AnalysisKind.CSRA], undefined); t.deepEqual(groupedSarifFiles[AnalysisKind.CodeScanning], [sarifPath]); }); }); From 8cc4d2539be9c0611c322315a28ec4ec6b4e1284 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 11 Feb 2026 22:14:39 +0000 Subject: [PATCH 05/13] Remove redundant analysis kind check --- lib/analyze-action.js | 5 +---- src/analyze.ts | 9 +++------ 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 8ddcd0ed02..8b8a7932ee 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -110546,10 +110546,7 @@ async function runQueries(sarifFolder, memoryFlag, threadsFlag, diffRangePackDir return statusReport; async function runInterpretResultsFor(analysis, language, queries, enableDebugLogging) { logger.info(`Interpreting ${analysis.name} results for ${language}`); - let category = automationDetailsId; - if (analysis.kind === "code-quality" /* CodeQuality */) { - category = analysis.fixCategory(logger, automationDetailsId); - } + const category = analysis.fixCategory(logger, automationDetailsId); const sarifFile = path12.join( sarifFolder, addSarifExtension(analysis, language) diff --git a/src/analyze.ts b/src/analyze.ts index bb38415047..352efd9756 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -549,12 +549,9 @@ export async function runQueries( ): Promise<{ summary: string; sarifFile: string }> { logger.info(`Interpreting ${analysis.name} results for ${language}`); - // If this is a Code Quality analysis, correct the category to one - // accepted by the Code Quality backend. - let category = automationDetailsId; - if (analysis.kind === analyses.AnalysisKind.CodeQuality) { - category = analysis.fixCategory(logger, automationDetailsId); - } + // Apply the analysis configuration's `fixCategory` function to adjust the category if needed. + // This is a no-op for Code Scanning. + const category = analysis.fixCategory(logger, automationDetailsId); const sarifFile = path.join( sarifFolder, From 6a17f4e25875a628d745e764fd91be895e66294e Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 11 Feb 2026 22:28:03 +0000 Subject: [PATCH 06/13] Update `getPrimaryAnalysis*` and add test --- lib/analyze-action.js | 5 ++++- src/analyses.test.ts | 3 ++- src/config-utils.test.ts | 21 ++++++++++++++++++++- src/config-utils.ts | 24 +++++++++++------------- 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 8b8a7932ee..798cdada2f 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -108432,10 +108432,13 @@ function isCodeQualityEnabled(config) { return config.analysisKinds.includes("code-quality" /* CodeQuality */); } function getPrimaryAnalysisKind(config) { + if (config.analysisKinds.length === 1) { + return config.analysisKinds[0]; + } return isCodeScanningEnabled(config) ? "code-scanning" /* CodeScanning */ : "code-quality" /* CodeQuality */; } function getPrimaryAnalysisConfig(config) { - return getPrimaryAnalysisKind(config) === "code-scanning" /* CodeScanning */ ? CodeScanning : CodeQuality; + return getAnalysisConfig(getPrimaryAnalysisKind(config)); } // src/setup-codeql.ts diff --git a/src/analyses.test.ts b/src/analyses.test.ts index 3e0fb74bc3..b4a24f4ff3 100644 --- a/src/analyses.test.ts +++ b/src/analyses.test.ts @@ -1,3 +1,5 @@ +import path from "path"; + import test from "ava"; import * as sinon from "sinon"; @@ -14,7 +16,6 @@ import { import { getRunnerLogger } from "./logging"; import { setupTests } from "./testing-utils"; import { ConfigurationError } from "./util"; -import path from "path"; setupTests(test); diff --git a/src/config-utils.test.ts b/src/config-utils.test.ts index 276a7a344b..d0583f1674 100644 --- a/src/config-utils.test.ts +++ b/src/config-utils.test.ts @@ -7,7 +7,7 @@ import * as yaml from "js-yaml"; import * as sinon from "sinon"; import * as actionsUtil from "./actions-util"; -import { AnalysisKind } from "./analyses"; +import { AnalysisKind, supportedAnalysisKinds } from "./analyses"; import * as api from "./api-client"; import { CachingKind } from "./caching-utils"; import { createStubCodeQL } from "./codeql"; @@ -1829,3 +1829,22 @@ test("hasActionsWorkflows doesn't throw if workflows folder doesn't exist", asyn t.notThrows(() => configUtils.hasActionsWorkflows(tmpDir)); }); }); + +test("getPrimaryAnalysisConfig - single analysis kind", (t) => { + // If only one analysis kind is configured, we expect to get the matching configuration. + for (const analysisKind of supportedAnalysisKinds) { + const singleKind = createTestConfig({ analysisKinds: [analysisKind] }); + t.is(configUtils.getPrimaryAnalysisConfig(singleKind).kind, analysisKind); + } +}); + +test("getPrimaryAnalysisConfig - Code Scanning + Code Quality", (t) => { + // For CS+CQ, we expect to get the Code Scanning configuration. + const codeScanningAndCodeQuality = createTestConfig({ + analysisKinds: [AnalysisKind.CodeScanning, AnalysisKind.CodeQuality], + }); + t.is( + configUtils.getPrimaryAnalysisConfig(codeScanningAndCodeQuality).kind, + AnalysisKind.CodeScanning, + ); +}); diff --git a/src/config-utils.ts b/src/config-utils.ts index e52070b47f..c35bad33bd 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -12,9 +12,8 @@ import { import { AnalysisConfig, AnalysisKind, - CodeQuality, codeQualityQueries, - CodeScanning, + getAnalysisConfig, } from "./analyses"; import * as api from "./api-client"; import { CachingKind, getCachingKind } from "./caching-utils"; @@ -1389,28 +1388,27 @@ export function isCodeQualityEnabled(config: Config): boolean { } /** - * Returns the primary analysis kind that the Action is initialised with. This is - * always `AnalysisKind.CodeScanning` unless `AnalysisKind.CodeScanning` is not enabled. + * Returns the primary analysis kind that the Action is initialised with. If there is only + * one analysis kind, then that is returned. * - * @returns Returns `AnalysisKind.CodeScanning` if `AnalysisKind.CodeScanning` is enabled; - * otherwise `AnalysisKind.CodeQuality`. + * The special case is Code Scanning + Code Quality, which can be enabled at the same time. + * In that case, this function returns Code Scanning. */ function getPrimaryAnalysisKind(config: Config): AnalysisKind { + if (config.analysisKinds.length === 1) { + return config.analysisKinds[0]; + } + return isCodeScanningEnabled(config) ? AnalysisKind.CodeScanning : AnalysisKind.CodeQuality; } /** - * Returns the primary analysis configuration that the Action is initialised with. This is - * always `CodeScanning` unless `CodeScanning` is not enabled. - * - * @returns Returns `CodeScanning` if `AnalysisKind.CodeScanning` is enabled; otherwise `CodeQuality`. + * Returns the primary analysis configuration that the Action is initialised with. */ export function getPrimaryAnalysisConfig(config: Config): AnalysisConfig { - return getPrimaryAnalysisKind(config) === AnalysisKind.CodeScanning - ? CodeScanning - : CodeQuality; + return getAnalysisConfig(getPrimaryAnalysisKind(config)); } /** Logs the Git version as a telemetry diagnostic. */ From 2de76b6faa8d19e7e5625b329dd551fcb7c07cd8 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 11 Feb 2026 22:41:32 +0000 Subject: [PATCH 07/13] Update PR check for `csra` --- ...ality-queries.yml => __analysis-kinds.yml} | 42 +++++++++++-------- ...quality-queries.yml => analysis-kinds.yml} | 34 ++++++++------- 2 files changed, 43 insertions(+), 33 deletions(-) rename .github/workflows/{__quality-queries.yml => __analysis-kinds.yml} (84%) rename pr-checks/checks/{quality-queries.yml => analysis-kinds.yml} (75%) diff --git a/.github/workflows/__quality-queries.yml b/.github/workflows/__analysis-kinds.yml similarity index 84% rename from .github/workflows/__quality-queries.yml rename to .github/workflows/__analysis-kinds.yml index fdbe0e812a..a4f21d510f 100644 --- a/.github/workflows/__quality-queries.yml +++ b/.github/workflows/__analysis-kinds.yml @@ -3,7 +3,7 @@ # pr-checks/sync.sh # to regenerate this file. -name: PR Check - Quality queries input +name: PR Check - Analysis kinds env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GO111MODULE: auto @@ -29,9 +29,9 @@ defaults: shell: bash concurrency: cancel-in-progress: ${{ github.event_name == 'pull_request' || false }} - group: quality-queries-${{github.ref}} + group: analysis-kinds-${{github.ref}} jobs: - quality-queries: + analysis-kinds: strategy: fail-fast: false matrix: @@ -45,6 +45,9 @@ jobs: - os: ubuntu-latest version: linked analysis-kinds: code-scanning,code-quality + - os: ubuntu-latest + version: linked + analysis-kinds: csra - os: ubuntu-latest version: nightly-latest analysis-kinds: code-scanning @@ -54,7 +57,10 @@ jobs: - os: ubuntu-latest version: nightly-latest analysis-kinds: code-scanning,code-quality - name: Quality queries input + - os: ubuntu-latest + version: nightly-latest + analysis-kinds: csra + name: Analysis kinds if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read @@ -81,30 +87,24 @@ jobs: output: ${{ runner.temp }}/results upload-database: false post-processed-sarif-path: ${{ runner.temp }}/post-processed - - name: Upload security SARIF - if: contains(matrix.analysis-kinds, 'code-scanning') - uses: actions/upload-artifact@v6 - with: - name: | - quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.sarif.json - path: ${{ runner.temp }}/results/javascript.sarif - retention-days: 7 - - name: Upload quality SARIF - if: contains(matrix.analysis-kinds, 'code-quality') + + - name: Upload SARIF files uses: actions/upload-artifact@v6 with: name: | - quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.quality.sarif.json - path: ${{ runner.temp }}/results/javascript.quality.sarif + analysis-kinds-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }} + path: ${{ runner.temp }}/results/*.sarif retention-days: 7 + - name: Upload post-processed SARIF uses: actions/upload-artifact@v6 with: name: | - post-processed-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.sarif.json + post-processed-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }} path: ${{ runner.temp }}/post-processed retention-days: 7 if-no-files-found: error + - name: Check quality query does not appear in security SARIF if: contains(matrix.analysis-kinds, 'code-scanning') uses: actions/github-script@v8 @@ -121,6 +121,14 @@ jobs: EXPECT_PRESENT: 'true' with: script: ${{ env.CHECK_SCRIPT }} + - name: Check quality query does not appear in CSRA SARIF + if: contains(matrix.analysis-kinds, 'csra') + uses: actions/github-script@v8 + env: + SARIF_PATH: ${{ runner.temp }}/results/javascript.csra.sarif + EXPECT_PRESENT: 'false' + with: + script: ${{ env.CHECK_SCRIPT }} env: CHECK_SCRIPT: | const fs = require('fs'); diff --git a/pr-checks/checks/quality-queries.yml b/pr-checks/checks/analysis-kinds.yml similarity index 75% rename from pr-checks/checks/quality-queries.yml rename to pr-checks/checks/analysis-kinds.yml index 353abbb774..86344eeb21 100644 --- a/pr-checks/checks/quality-queries.yml +++ b/pr-checks/checks/analysis-kinds.yml @@ -1,7 +1,7 @@ -name: "Quality queries input" -description: "Tests that queries specified in the quality-queries input are used." +name: "Analysis kinds" +description: "Tests basic functionality for different `analysis-kinds` inputs." versions: ["linked", "nightly-latest"] -analysisKinds: ["code-scanning", "code-quality", "code-scanning,code-quality"] +analysisKinds: ["code-scanning", "code-quality", "code-scanning,code-quality", "csra"] env: CHECK_SCRIPT: | const fs = require('fs'); @@ -37,30 +37,24 @@ steps: output: "${{ runner.temp }}/results" upload-database: false post-processed-sarif-path: "${{ runner.temp }}/post-processed" - - name: Upload security SARIF - if: contains(matrix.analysis-kinds, 'code-scanning') - uses: actions/upload-artifact@v6 - with: - name: | - quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.sarif.json - path: "${{ runner.temp }}/results/javascript.sarif" - retention-days: 7 - - name: Upload quality SARIF - if: contains(matrix.analysis-kinds, 'code-quality') + + - name: Upload SARIF files uses: actions/upload-artifact@v6 with: name: | - quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.quality.sarif.json - path: "${{ runner.temp }}/results/javascript.quality.sarif" + analysis-kinds-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }} + path: "${{ runner.temp }}/results/*.sarif" retention-days: 7 + - name: Upload post-processed SARIF uses: actions/upload-artifact@v6 with: name: | - post-processed-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.sarif.json + post-processed-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }} path: "${{ runner.temp }}/post-processed" retention-days: 7 if-no-files-found: error + - name: Check quality query does not appear in security SARIF if: contains(matrix.analysis-kinds, 'code-scanning') uses: actions/github-script@v8 @@ -77,3 +71,11 @@ steps: EXPECT_PRESENT: "true" with: script: ${{ env.CHECK_SCRIPT }} + - name: Check quality query does not appear in CSRA SARIF + if: contains(matrix.analysis-kinds, 'csra') + uses: actions/github-script@v8 + env: + SARIF_PATH: "${{ runner.temp }}/results/javascript.csra.sarif" + EXPECT_PRESENT: "false" + with: + script: ${{ env.CHECK_SCRIPT }} From db9346285d6fe8d74481f8dbee03302c163e566a Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 11 Feb 2026 23:06:54 +0000 Subject: [PATCH 08/13] Add `csra` case to `addSarifExtension` test --- src/analyze.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/analyze.test.ts b/src/analyze.test.ts index 27fe4a6f47..c5aec6e4fe 100644 --- a/src/analyze.test.ts +++ b/src/analyze.test.ts @@ -4,7 +4,7 @@ import * as path from "path"; import test from "ava"; import * as sinon from "sinon"; -import { CodeQuality, CodeScanning } from "./analyses"; +import { CodeQuality, CodeScanning, CSRA } from "./analyses"; import { runQueries, defaultSuites, @@ -155,5 +155,6 @@ test("addSarifExtension", (t) => { addSarifExtension(CodeQuality, language), `${language}.quality.sarif`, ); + t.is(addSarifExtension(CSRA, language), `${language}.csra.sarif`); } }); From cbb92e7ff669385e3de54725992d15f43f10a5db Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 11 Feb 2026 23:40:55 +0000 Subject: [PATCH 09/13] Type the upload payload object --- src/upload-lib.test.ts | 11 ++++++++++- src/upload-lib.ts | 7 ++++--- src/upload-lib/types.ts | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 src/upload-lib/types.ts diff --git a/src/upload-lib.test.ts b/src/upload-lib.test.ts index 5accb871a2..5b6c0db5f2 100644 --- a/src/upload-lib.test.ts +++ b/src/upload-lib.test.ts @@ -12,6 +12,7 @@ import * as api from "./api-client"; import { getRunnerLogger, Logger } from "./logging"; import { setupTests } from "./testing-utils"; import * as uploadLib from "./upload-lib"; +import { UploadPayload } from "./upload-lib/types"; import { GitHubVariant, initializeEnvironment, withTmpDir } from "./util"; setupTests(test); @@ -909,7 +910,15 @@ function createMockSarif(id?: string, tool?: string) { function uploadPayloadFixtures(analysis: analyses.AnalysisConfig) { const mockData = { - payload: { sarif: "base64data", commit_sha: "abc123" }, + payload: { + commit_oid: "abc123", + ref: "ref", + sarif: "base64data", + workflow_run_id: 1, + workflow_run_attempt: 1, + checkout_uri: "uri", + tool_names: ["codeql"], + } satisfies UploadPayload, owner: "test-owner", repo: "test-repo", response: { diff --git a/src/upload-lib.ts b/src/upload-lib.ts index ac02745207..85208b7b4b 100644 --- a/src/upload-lib.ts +++ b/src/upload-lib.ts @@ -21,6 +21,7 @@ import * as gitUtils from "./git-utils"; import { initCodeQL } from "./init"; import { Logger } from "./logging"; import { getRepositoryNwo, RepositoryNwo } from "./repository"; +import { UploadPayload } from "./upload-lib/types"; import * as util from "./util"; import { ConfigurationError, @@ -326,7 +327,7 @@ function getAutomationID( * This is exported for testing purposes only. */ export async function uploadPayload( - payload: any, + payload: UploadPayload, repositoryNwo: RepositoryNwo, logger: Logger, analysis: analyses.AnalysisConfig, @@ -618,8 +619,8 @@ export function buildPayload( environment: string | undefined, toolNames: string[], mergeBaseCommitOid: string | undefined, -) { - const payloadObj = { +): UploadPayload { + const payloadObj: UploadPayload = { commit_oid: commitOid, ref, analysis_key: analysisKey, diff --git a/src/upload-lib/types.ts b/src/upload-lib/types.ts new file mode 100644 index 0000000000..b861075573 --- /dev/null +++ b/src/upload-lib/types.ts @@ -0,0 +1,15 @@ +export interface UploadPayload { + commit_oid: string; + ref: string; + analysis_key?: string; + analysis_name?: string; + sarif: string; + workflow_run_id: number; + workflow_run_attempt: number; + checkout_uri: string; + environment?: string; + started_at?: string; + tool_names: string[]; + base_ref?: string; + base_sha?: string; +} From 0cfcceb4b8d171a552bd69887d490f6a4d3bf594 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 11 Feb 2026 23:45:34 +0000 Subject: [PATCH 10/13] Add `transformPayload` to `AnalysisConfig` --- lib/analyze-action.js | 35 ++++++++++++++++++++--------------- lib/init-action-post.js | 35 ++++++++++++++++++++--------------- lib/upload-lib.js | 35 ++++++++++++++++++++--------------- lib/upload-sarif-action.js | 35 ++++++++++++++++++++--------------- src/analyses.ts | 6 ++++++ src/upload-lib.ts | 26 ++++++++++++++------------ 6 files changed, 100 insertions(+), 72 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 798cdada2f..be8cca241a 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -106497,7 +106497,8 @@ var CodeScanning = { sarifExtension: ".sarif", sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name) && !CSRA.sarifPredicate(name), fixCategory: (_, category) => category, - sentinelPrefix: "CODEQL_UPLOAD_SARIF_" + sentinelPrefix: "CODEQL_UPLOAD_SARIF_", + transformPayload: (payload) => payload }; var CodeQuality = { kind: "code-quality" /* CodeQuality */, @@ -106506,7 +106507,8 @@ var CodeQuality = { sarifExtension: ".quality.sarif", sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension), fixCategory: fixCodeQualityCategory, - sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" + sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_", + transformPayload: (payload) => payload }; var CSRA = { kind: "csra" /* CSRA */, @@ -106515,7 +106517,8 @@ var CSRA = { sarifExtension: ".csra.sarif", sarifPredicate: (name) => name.endsWith(CSRA.sarifExtension), fixCategory: fixCodeQualityCategory, - sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_" + sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_", + transformPayload: (payload) => payload }; function getAnalysisConfig(kind) { switch (kind) { @@ -112534,18 +112537,20 @@ async function uploadPostProcessedFiles(logger, checkoutPath, uploadTarget, post logger.debug(`Compressing serialized SARIF`); const zippedSarif = import_zlib.default.gzipSync(sarifPayload).toString("base64"); const checkoutURI = url.pathToFileURL(checkoutPath).href; - const payload = buildPayload( - await getCommitOid(checkoutPath), - await getRef(), - postProcessingResults.analysisKey, - getRequiredEnvParam("GITHUB_WORKFLOW"), - zippedSarif, - getWorkflowRunID(), - getWorkflowRunAttempt(), - checkoutURI, - postProcessingResults.environment, - toolNames, - await determineBaseBranchHeadCommitOid() + const payload = uploadTarget.transformPayload( + buildPayload( + await getCommitOid(checkoutPath), + await getRef(), + postProcessingResults.analysisKey, + getRequiredEnvParam("GITHUB_WORKFLOW"), + zippedSarif, + getWorkflowRunID(), + getWorkflowRunAttempt(), + checkoutURI, + postProcessingResults.environment, + toolNames, + await determineBaseBranchHeadCommitOid() + ) ); const rawUploadSizeBytes = sarifPayload.length; logger.debug(`Raw upload size: ${rawUploadSizeBytes} bytes`); diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 51286a9164..c6a1591580 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -164556,7 +164556,8 @@ var CodeScanning = { sarifExtension: ".sarif", sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name) && !CSRA.sarifPredicate(name), fixCategory: (_2, category) => category, - sentinelPrefix: "CODEQL_UPLOAD_SARIF_" + sentinelPrefix: "CODEQL_UPLOAD_SARIF_", + transformPayload: (payload) => payload }; var CodeQuality = { kind: "code-quality" /* CodeQuality */, @@ -164565,7 +164566,8 @@ var CodeQuality = { sarifExtension: ".quality.sarif", sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension), fixCategory: fixCodeQualityCategory, - sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" + sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_", + transformPayload: (payload) => payload }; var CSRA = { kind: "csra" /* CSRA */, @@ -164574,7 +164576,8 @@ var CSRA = { sarifExtension: ".csra.sarif", sarifPredicate: (name) => name.endsWith(CSRA.sarifExtension), fixCategory: fixCodeQualityCategory, - sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_" + sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_", + transformPayload: (payload) => payload }; // src/config/db-config.ts @@ -169141,18 +169144,20 @@ async function uploadPostProcessedFiles(logger, checkoutPath, uploadTarget, post logger.debug(`Compressing serialized SARIF`); const zippedSarif = import_zlib.default.gzipSync(sarifPayload).toString("base64"); const checkoutURI = url.pathToFileURL(checkoutPath).href; - const payload = buildPayload( - await getCommitOid(checkoutPath), - await getRef(), - postProcessingResults.analysisKey, - getRequiredEnvParam("GITHUB_WORKFLOW"), - zippedSarif, - getWorkflowRunID(), - getWorkflowRunAttempt(), - checkoutURI, - postProcessingResults.environment, - toolNames, - await determineBaseBranchHeadCommitOid() + const payload = uploadTarget.transformPayload( + buildPayload( + await getCommitOid(checkoutPath), + await getRef(), + postProcessingResults.analysisKey, + getRequiredEnvParam("GITHUB_WORKFLOW"), + zippedSarif, + getWorkflowRunID(), + getWorkflowRunAttempt(), + checkoutURI, + postProcessingResults.environment, + toolNames, + await determineBaseBranchHeadCommitOid() + ) ); const rawUploadSizeBytes = sarifPayload.length; logger.debug(`Raw upload size: ${rawUploadSizeBytes} bytes`); diff --git a/lib/upload-lib.js b/lib/upload-lib.js index a4166a3593..ed56953baf 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -106152,7 +106152,8 @@ var CodeScanning = { sarifExtension: ".sarif", sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name) && !CSRA.sarifPredicate(name), fixCategory: (_, category) => category, - sentinelPrefix: "CODEQL_UPLOAD_SARIF_" + sentinelPrefix: "CODEQL_UPLOAD_SARIF_", + transformPayload: (payload) => payload }; var CodeQuality = { kind: "code-quality" /* CodeQuality */, @@ -106161,7 +106162,8 @@ var CodeQuality = { sarifExtension: ".quality.sarif", sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension), fixCategory: fixCodeQualityCategory, - sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" + sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_", + transformPayload: (payload) => payload }; var CSRA = { kind: "csra" /* CSRA */, @@ -106170,7 +106172,8 @@ var CSRA = { sarifExtension: ".csra.sarif", sarifPredicate: (name) => name.endsWith(CSRA.sarifExtension), fixCategory: fixCodeQualityCategory, - sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_" + sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_", + transformPayload: (payload) => payload }; var SarifScanOrder = [ CSRA, @@ -110461,18 +110464,20 @@ async function uploadPostProcessedFiles(logger, checkoutPath, uploadTarget, post logger.debug(`Compressing serialized SARIF`); const zippedSarif = import_zlib.default.gzipSync(sarifPayload).toString("base64"); const checkoutURI = url.pathToFileURL(checkoutPath).href; - const payload = buildPayload( - await getCommitOid(checkoutPath), - await getRef(), - postProcessingResults.analysisKey, - getRequiredEnvParam("GITHUB_WORKFLOW"), - zippedSarif, - getWorkflowRunID(), - getWorkflowRunAttempt(), - checkoutURI, - postProcessingResults.environment, - toolNames, - await determineBaseBranchHeadCommitOid() + const payload = uploadTarget.transformPayload( + buildPayload( + await getCommitOid(checkoutPath), + await getRef(), + postProcessingResults.analysisKey, + getRequiredEnvParam("GITHUB_WORKFLOW"), + zippedSarif, + getWorkflowRunID(), + getWorkflowRunAttempt(), + checkoutURI, + postProcessingResults.environment, + toolNames, + await determineBaseBranchHeadCommitOid() + ) ); const rawUploadSizeBytes = sarifPayload.length; logger.debug(`Raw upload size: ${rawUploadSizeBytes} bytes`); diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index 8057d09097..14cef27381 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -106190,7 +106190,8 @@ var CodeScanning = { sarifExtension: ".sarif", sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name) && !CSRA.sarifPredicate(name), fixCategory: (_, category) => category, - sentinelPrefix: "CODEQL_UPLOAD_SARIF_" + sentinelPrefix: "CODEQL_UPLOAD_SARIF_", + transformPayload: (payload) => payload }; var CodeQuality = { kind: "code-quality" /* CodeQuality */, @@ -106199,7 +106200,8 @@ var CodeQuality = { sarifExtension: ".quality.sarif", sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension), fixCategory: fixCodeQualityCategory, - sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" + sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_", + transformPayload: (payload) => payload }; var CSRA = { kind: "csra" /* CSRA */, @@ -106208,7 +106210,8 @@ var CSRA = { sarifExtension: ".csra.sarif", sarifPredicate: (name) => name.endsWith(CSRA.sarifExtension), fixCategory: fixCodeQualityCategory, - sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_" + sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_", + transformPayload: (payload) => payload }; function getAnalysisConfig(kind) { switch (kind) { @@ -110971,18 +110974,20 @@ async function uploadPostProcessedFiles(logger, checkoutPath, uploadTarget, post logger.debug(`Compressing serialized SARIF`); const zippedSarif = import_zlib.default.gzipSync(sarifPayload).toString("base64"); const checkoutURI = url.pathToFileURL(checkoutPath).href; - const payload = buildPayload( - await getCommitOid(checkoutPath), - await getRef(), - postProcessingResults.analysisKey, - getRequiredEnvParam("GITHUB_WORKFLOW"), - zippedSarif, - getWorkflowRunID(), - getWorkflowRunAttempt(), - checkoutURI, - postProcessingResults.environment, - toolNames, - await determineBaseBranchHeadCommitOid() + const payload = uploadTarget.transformPayload( + buildPayload( + await getCommitOid(checkoutPath), + await getRef(), + postProcessingResults.analysisKey, + getRequiredEnvParam("GITHUB_WORKFLOW"), + zippedSarif, + getWorkflowRunID(), + getWorkflowRunAttempt(), + checkoutURI, + postProcessingResults.environment, + toolNames, + await determineBaseBranchHeadCommitOid() + ) ); const rawUploadSizeBytes = sarifPayload.length; logger.debug(`Raw upload size: ${rawUploadSizeBytes} bytes`); diff --git a/src/analyses.ts b/src/analyses.ts index 714917b91f..39486cab9d 100644 --- a/src/analyses.ts +++ b/src/analyses.ts @@ -4,6 +4,7 @@ import { getRequiredInput, } from "./actions-util"; import { Logger } from "./logging"; +import { UploadPayload } from "./upload-lib/types"; import { ConfigurationError } from "./util"; export enum AnalysisKind { @@ -146,6 +147,8 @@ export interface AnalysisConfig { fixCategory: (logger: Logger, category?: string) => string | undefined; /** A prefix for environment variables used to track the uniqueness of SARIF uploads. */ sentinelPrefix: string; + /** Transforms the upload payload in an analysis-specific way. */ + transformPayload: (payload: UploadPayload) => UploadPayload; } // Represents the Code Scanning analysis configuration. @@ -160,6 +163,7 @@ export const CodeScanning: AnalysisConfig = { !CSRA.sarifPredicate(name), fixCategory: (_, category) => category, sentinelPrefix: "CODEQL_UPLOAD_SARIF_", + transformPayload: (payload) => payload, }; // Represents the Code Quality analysis configuration. @@ -171,6 +175,7 @@ export const CodeQuality: AnalysisConfig = { sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension), fixCategory: fixCodeQualityCategory, sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_", + transformPayload: (payload) => payload, }; export const CSRA: AnalysisConfig = { @@ -181,6 +186,7 @@ export const CSRA: AnalysisConfig = { sarifPredicate: (name) => name.endsWith(CSRA.sarifExtension), fixCategory: fixCodeQualityCategory, sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_", + transformPayload: (payload) => payload, }; /** diff --git a/src/upload-lib.ts b/src/upload-lib.ts index 85208b7b4b..f5c6366abd 100644 --- a/src/upload-lib.ts +++ b/src/upload-lib.ts @@ -848,18 +848,20 @@ export async function uploadPostProcessedFiles( const zippedSarif = zlib.gzipSync(sarifPayload).toString("base64"); const checkoutURI = url.pathToFileURL(checkoutPath).href; - const payload = buildPayload( - await gitUtils.getCommitOid(checkoutPath), - await gitUtils.getRef(), - postProcessingResults.analysisKey, - util.getRequiredEnvParam("GITHUB_WORKFLOW"), - zippedSarif, - actionsUtil.getWorkflowRunID(), - actionsUtil.getWorkflowRunAttempt(), - checkoutURI, - postProcessingResults.environment, - toolNames, - await gitUtils.determineBaseBranchHeadCommitOid(), + const payload = uploadTarget.transformPayload( + buildPayload( + await gitUtils.getCommitOid(checkoutPath), + await gitUtils.getRef(), + postProcessingResults.analysisKey, + util.getRequiredEnvParam("GITHUB_WORKFLOW"), + zippedSarif, + actionsUtil.getWorkflowRunID(), + actionsUtil.getWorkflowRunAttempt(), + checkoutURI, + postProcessingResults.environment, + toolNames, + await gitUtils.determineBaseBranchHeadCommitOid(), + ), ); // Log some useful debug info about the info From c48cd247df861d9ba3bc6d36ab6cbc5c386f47fc Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 11 Feb 2026 23:51:07 +0000 Subject: [PATCH 11/13] Add `assessment_id` to CSRA payload --- .github/workflows/__analysis-kinds.yml | 1 + lib/analyze-action.js | 6 +++++- lib/init-action-post.js | 6 +++++- lib/upload-lib.js | 6 +++++- lib/upload-sarif-action.js | 6 +++++- pr-checks/checks/analysis-kinds.yml | 1 + src/analyses.ts | 15 ++++++++++++--- src/upload-lib/types.ts | 4 ++++ 8 files changed, 38 insertions(+), 7 deletions(-) diff --git a/.github/workflows/__analysis-kinds.yml b/.github/workflows/__analysis-kinds.yml index a4f21d510f..b36a0bceb3 100644 --- a/.github/workflows/__analysis-kinds.yml +++ b/.github/workflows/__analysis-kinds.yml @@ -130,6 +130,7 @@ jobs: with: script: ${{ env.CHECK_SCRIPT }} env: + CODEQL_ACTION_CSRA_ASSESSMENT_ID: 1 CHECK_SCRIPT: | const fs = require('fs'); diff --git a/lib/analyze-action.js b/lib/analyze-action.js index be8cca241a..b220970550 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -106510,6 +106510,10 @@ var CodeQuality = { sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_", transformPayload: (payload) => payload }; +function addAssessmentId(payload) { + const assessmentId = getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"); + return { ...payload, assessment_id: assessmentId }; +} var CSRA = { kind: "csra" /* CSRA */, name: "csra", @@ -106518,7 +106522,7 @@ var CSRA = { sarifPredicate: (name) => name.endsWith(CSRA.sarifExtension), fixCategory: fixCodeQualityCategory, sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_", - transformPayload: (payload) => payload + transformPayload: addAssessmentId }; function getAnalysisConfig(kind) { switch (kind) { diff --git a/lib/init-action-post.js b/lib/init-action-post.js index c6a1591580..45b490f7f2 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -164569,6 +164569,10 @@ var CodeQuality = { sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_", transformPayload: (payload) => payload }; +function addAssessmentId(payload) { + const assessmentId = getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"); + return { ...payload, assessment_id: assessmentId }; +} var CSRA = { kind: "csra" /* CSRA */, name: "csra", @@ -164577,7 +164581,7 @@ var CSRA = { sarifPredicate: (name) => name.endsWith(CSRA.sarifExtension), fixCategory: fixCodeQualityCategory, sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_", - transformPayload: (payload) => payload + transformPayload: addAssessmentId }; // src/config/db-config.ts diff --git a/lib/upload-lib.js b/lib/upload-lib.js index ed56953baf..550606b157 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -106165,6 +106165,10 @@ var CodeQuality = { sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_", transformPayload: (payload) => payload }; +function addAssessmentId(payload) { + const assessmentId = getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"); + return { ...payload, assessment_id: assessmentId }; +} var CSRA = { kind: "csra" /* CSRA */, name: "csra", @@ -106173,7 +106177,7 @@ var CSRA = { sarifPredicate: (name) => name.endsWith(CSRA.sarifExtension), fixCategory: fixCodeQualityCategory, sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_", - transformPayload: (payload) => payload + transformPayload: addAssessmentId }; var SarifScanOrder = [ CSRA, diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index 14cef27381..b50d9322a2 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -106203,6 +106203,10 @@ var CodeQuality = { sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_", transformPayload: (payload) => payload }; +function addAssessmentId(payload) { + const assessmentId = getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"); + return { ...payload, assessment_id: assessmentId }; +} var CSRA = { kind: "csra" /* CSRA */, name: "csra", @@ -106211,7 +106215,7 @@ var CSRA = { sarifPredicate: (name) => name.endsWith(CSRA.sarifExtension), fixCategory: fixCodeQualityCategory, sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_", - transformPayload: (payload) => payload + transformPayload: addAssessmentId }; function getAnalysisConfig(kind) { switch (kind) { diff --git a/pr-checks/checks/analysis-kinds.yml b/pr-checks/checks/analysis-kinds.yml index 86344eeb21..18483e6e1b 100644 --- a/pr-checks/checks/analysis-kinds.yml +++ b/pr-checks/checks/analysis-kinds.yml @@ -3,6 +3,7 @@ description: "Tests basic functionality for different `analysis-kinds` inputs." versions: ["linked", "nightly-latest"] analysisKinds: ["code-scanning", "code-quality", "code-scanning,code-quality", "csra"] env: + CODEQL_ACTION_CSRA_ASSESSMENT_ID: 1 CHECK_SCRIPT: | const fs = require('fs'); diff --git a/src/analyses.ts b/src/analyses.ts index 39486cab9d..dd60c54ede 100644 --- a/src/analyses.ts +++ b/src/analyses.ts @@ -4,8 +4,8 @@ import { getRequiredInput, } from "./actions-util"; import { Logger } from "./logging"; -import { UploadPayload } from "./upload-lib/types"; -import { ConfigurationError } from "./util"; +import { AssessmentPayload, UploadPayload } from "./upload-lib/types"; +import { ConfigurationError, getRequiredEnvParam } from "./util"; export enum AnalysisKind { CodeScanning = "code-scanning", @@ -178,6 +178,15 @@ export const CodeQuality: AnalysisConfig = { transformPayload: (payload) => payload, }; +/** + * Retrieves the CSRA assessment id from an environment variable and adds it to the payload. + * @param payload The base payload. + */ +function addAssessmentId(payload: UploadPayload): AssessmentPayload { + const assessmentId = getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"); + return { ...payload, assessment_id: assessmentId }; +} + export const CSRA: AnalysisConfig = { kind: AnalysisKind.CSRA, name: "csra", @@ -186,7 +195,7 @@ export const CSRA: AnalysisConfig = { sarifPredicate: (name) => name.endsWith(CSRA.sarifExtension), fixCategory: fixCodeQualityCategory, sentinelPrefix: "CODEQL_UPLOAD_CSRA_SARIF_", - transformPayload: (payload) => payload, + transformPayload: addAssessmentId, }; /** diff --git a/src/upload-lib/types.ts b/src/upload-lib/types.ts index b861075573..8a6c274508 100644 --- a/src/upload-lib/types.ts +++ b/src/upload-lib/types.ts @@ -13,3 +13,7 @@ export interface UploadPayload { base_ref?: string; base_sha?: string; } + +export interface AssessmentPayload extends UploadPayload { + assessment_id: string; +} From da67096c6fa6d294a2ef9d1e1d381ca62aff7d9a Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 12 Feb 2026 00:10:42 +0000 Subject: [PATCH 12/13] Change `assessment_id` to be a number --- lib/analyze-action.js | 5 ++++- lib/init-action-post.js | 5 ++++- lib/upload-lib.js | 5 ++++- lib/upload-sarif-action.js | 5 ++++- src/analyses.ts | 5 ++++- src/upload-lib/types.ts | 2 +- 6 files changed, 21 insertions(+), 6 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index b220970550..248b2547be 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -106511,7 +106511,10 @@ var CodeQuality = { transformPayload: (payload) => payload }; function addAssessmentId(payload) { - const assessmentId = getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"); + const assessmentId = parseInt( + getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"), + 10 + ); return { ...payload, assessment_id: assessmentId }; } var CSRA = { diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 45b490f7f2..7a2299e72b 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -164570,7 +164570,10 @@ var CodeQuality = { transformPayload: (payload) => payload }; function addAssessmentId(payload) { - const assessmentId = getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"); + const assessmentId = parseInt( + getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"), + 10 + ); return { ...payload, assessment_id: assessmentId }; } var CSRA = { diff --git a/lib/upload-lib.js b/lib/upload-lib.js index 550606b157..9cd6a38fcd 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -106166,7 +106166,10 @@ var CodeQuality = { transformPayload: (payload) => payload }; function addAssessmentId(payload) { - const assessmentId = getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"); + const assessmentId = parseInt( + getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"), + 10 + ); return { ...payload, assessment_id: assessmentId }; } var CSRA = { diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index b50d9322a2..0a77cdfd04 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -106204,7 +106204,10 @@ var CodeQuality = { transformPayload: (payload) => payload }; function addAssessmentId(payload) { - const assessmentId = getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"); + const assessmentId = parseInt( + getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"), + 10 + ); return { ...payload, assessment_id: assessmentId }; } var CSRA = { diff --git a/src/analyses.ts b/src/analyses.ts index dd60c54ede..9f2b2bbf3f 100644 --- a/src/analyses.ts +++ b/src/analyses.ts @@ -183,7 +183,10 @@ export const CodeQuality: AnalysisConfig = { * @param payload The base payload. */ function addAssessmentId(payload: UploadPayload): AssessmentPayload { - const assessmentId = getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"); + const assessmentId = parseInt( + getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"), + 10, + ); return { ...payload, assessment_id: assessmentId }; } diff --git a/src/upload-lib/types.ts b/src/upload-lib/types.ts index 8a6c274508..d04ed1c6b2 100644 --- a/src/upload-lib/types.ts +++ b/src/upload-lib/types.ts @@ -15,5 +15,5 @@ export interface UploadPayload { } export interface AssessmentPayload extends UploadPayload { - assessment_id: string; + assessment_id: number; } From 2adcb6464ed1599265239c021cb981d575008218 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 12 Feb 2026 00:13:22 +0000 Subject: [PATCH 13/13] Add `BasePayload` type and derive `AssessmentPayload` from it --- lib/analyze-action.js | 2 +- lib/init-action-post.js | 2 +- lib/upload-lib.js | 2 +- lib/upload-sarif-action.js | 2 +- src/analyses.ts | 10 +++++++--- src/upload-lib.ts | 4 ++-- src/upload-lib/types.ts | 9 ++++++--- 7 files changed, 19 insertions(+), 12 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 248b2547be..a22217bb28 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -106515,7 +106515,7 @@ function addAssessmentId(payload) { getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"), 10 ); - return { ...payload, assessment_id: assessmentId }; + return { sarif: payload.sarif, assessment_id: assessmentId }; } var CSRA = { kind: "csra" /* CSRA */, diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 7a2299e72b..e19a9678c3 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -164574,7 +164574,7 @@ function addAssessmentId(payload) { getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"), 10 ); - return { ...payload, assessment_id: assessmentId }; + return { sarif: payload.sarif, assessment_id: assessmentId }; } var CSRA = { kind: "csra" /* CSRA */, diff --git a/lib/upload-lib.js b/lib/upload-lib.js index 9cd6a38fcd..53c52c2198 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -106170,7 +106170,7 @@ function addAssessmentId(payload) { getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"), 10 ); - return { ...payload, assessment_id: assessmentId }; + return { sarif: payload.sarif, assessment_id: assessmentId }; } var CSRA = { kind: "csra" /* CSRA */, diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index 0a77cdfd04..c8994877d0 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -106208,7 +106208,7 @@ function addAssessmentId(payload) { getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"), 10 ); - return { ...payload, assessment_id: assessmentId }; + return { sarif: payload.sarif, assessment_id: assessmentId }; } var CSRA = { kind: "csra" /* CSRA */, diff --git a/src/analyses.ts b/src/analyses.ts index 9f2b2bbf3f..ce7f101582 100644 --- a/src/analyses.ts +++ b/src/analyses.ts @@ -4,7 +4,11 @@ import { getRequiredInput, } from "./actions-util"; import { Logger } from "./logging"; -import { AssessmentPayload, UploadPayload } from "./upload-lib/types"; +import { + AssessmentPayload, + BasePayload, + UploadPayload, +} from "./upload-lib/types"; import { ConfigurationError, getRequiredEnvParam } from "./util"; export enum AnalysisKind { @@ -148,7 +152,7 @@ export interface AnalysisConfig { /** A prefix for environment variables used to track the uniqueness of SARIF uploads. */ sentinelPrefix: string; /** Transforms the upload payload in an analysis-specific way. */ - transformPayload: (payload: UploadPayload) => UploadPayload; + transformPayload: (payload: UploadPayload) => BasePayload; } // Represents the Code Scanning analysis configuration. @@ -187,7 +191,7 @@ function addAssessmentId(payload: UploadPayload): AssessmentPayload { getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"), 10, ); - return { ...payload, assessment_id: assessmentId }; + return { sarif: payload.sarif, assessment_id: assessmentId }; } export const CSRA: AnalysisConfig = { diff --git a/src/upload-lib.ts b/src/upload-lib.ts index f5c6366abd..43039c596f 100644 --- a/src/upload-lib.ts +++ b/src/upload-lib.ts @@ -21,7 +21,7 @@ import * as gitUtils from "./git-utils"; import { initCodeQL } from "./init"; import { Logger } from "./logging"; import { getRepositoryNwo, RepositoryNwo } from "./repository"; -import { UploadPayload } from "./upload-lib/types"; +import { BasePayload, UploadPayload } from "./upload-lib/types"; import * as util from "./util"; import { ConfigurationError, @@ -327,7 +327,7 @@ function getAutomationID( * This is exported for testing purposes only. */ export async function uploadPayload( - payload: UploadPayload, + payload: BasePayload, repositoryNwo: RepositoryNwo, logger: Logger, analysis: analyses.AnalysisConfig, diff --git a/src/upload-lib/types.ts b/src/upload-lib/types.ts index d04ed1c6b2..64480a4fc4 100644 --- a/src/upload-lib/types.ts +++ b/src/upload-lib/types.ts @@ -1,9 +1,12 @@ -export interface UploadPayload { +export interface BasePayload { + sarif: string; +} + +export interface UploadPayload extends BasePayload { commit_oid: string; ref: string; analysis_key?: string; analysis_name?: string; - sarif: string; workflow_run_id: number; workflow_run_attempt: number; checkout_uri: string; @@ -14,6 +17,6 @@ export interface UploadPayload { base_sha?: string; } -export interface AssessmentPayload extends UploadPayload { +export interface AssessmentPayload extends BasePayload { assessment_id: number; }