From 434df8e95c159402af7f3c50877a30d53e715837 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 28 Aug 2025 16:34:33 +0100 Subject: [PATCH 01/25] Update checks to use `analysis-kinds` instead of `quality-queries` --- .github/workflows/__quality-queries.yml | 2 +- .github/workflows/__upload-quality-sarif.yml | 2 +- pr-checks/checks/quality-queries.yml | 2 +- pr-checks/checks/upload-quality-sarif.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/__quality-queries.yml b/.github/workflows/__quality-queries.yml index 1260241cb2..1578d4c7ab 100644 --- a/.github/workflows/__quality-queries.yml +++ b/.github/workflows/__quality-queries.yml @@ -61,7 +61,7 @@ jobs: - uses: ./../action/init with: languages: javascript - quality-queries: code-quality + analysis-kinds: code-scanning,code-quality tools: ${{ steps.prepare-test.outputs.tools-url }} - uses: ./../action/analyze with: diff --git a/.github/workflows/__upload-quality-sarif.yml b/.github/workflows/__upload-quality-sarif.yml index d122d40861..2332aff841 100644 --- a/.github/workflows/__upload-quality-sarif.yml +++ b/.github/workflows/__upload-quality-sarif.yml @@ -73,7 +73,7 @@ jobs: languages: cpp,csharp,java,javascript,python config-file: ${{ github.repository }}/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{ github.sha }} - quality-queries: code-quality + analysis-kinds: code-scanning,code-quality - name: Build code shell: bash run: ./build.sh diff --git a/pr-checks/checks/quality-queries.yml b/pr-checks/checks/quality-queries.yml index 6cf07e2474..3f4ff3b1bf 100644 --- a/pr-checks/checks/quality-queries.yml +++ b/pr-checks/checks/quality-queries.yml @@ -29,7 +29,7 @@ steps: - uses: ./../action/init with: languages: javascript - quality-queries: code-quality + analysis-kinds: code-scanning,code-quality tools: ${{ steps.prepare-test.outputs.tools-url }} - uses: ./../action/analyze with: diff --git a/pr-checks/checks/upload-quality-sarif.yml b/pr-checks/checks/upload-quality-sarif.yml index 019654fa6e..02d2cc5636 100644 --- a/pr-checks/checks/upload-quality-sarif.yml +++ b/pr-checks/checks/upload-quality-sarif.yml @@ -8,7 +8,7 @@ steps: tools: ${{ steps.prepare-test.outputs.tools-url }} languages: cpp,csharp,java,javascript,python config-file: ${{ github.repository }}/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{ github.sha }} - quality-queries: code-quality + analysis-kinds: code-scanning,code-quality - name: Build code shell: bash run: ./build.sh From 85a4853504727c23e00dda24d21fe1d791a57d11 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 28 Aug 2025 16:36:26 +0100 Subject: [PATCH 02/25] Add utility function to check if code scanning is enabled --- src/config-utils.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/config-utils.ts b/src/config-utils.ts index 66e50e74d0..d751149db3 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -1509,6 +1509,13 @@ export function appendExtraQueryExclusions( return augmentedConfig; } +/** + * Returns `true` if Code Scanning analysis is enabled, or `false` if not. + */ +export function isCodeScanningEnabled(config: Config): boolean { + return config.analysisKinds.includes(AnalysisKind.CodeScanning); +} + /** * Returns `true` if Code Quality analysis is enabled, or `false` if not. */ From ca7dd4ad38a24686d92482cf29370bd6ec1fb3b3 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 28 Aug 2025 16:47:33 +0100 Subject: [PATCH 03/25] Move `UploadTarget` definitions to `analyses.ts` --- lib/analyze-action.js | 36 ++++++++++++------------ lib/init-action-post.js | 24 ++++++++-------- lib/upload-lib.js | 51 +++++++++++++--------------------- lib/upload-sarif-action.js | 40 +++++++++++++------------- src/analyses.ts | 31 +++++++++++++++++++++ src/analyze-action.ts | 5 ++-- src/init-action-post-helper.ts | 3 +- src/upload-lib.test.ts | 7 +++-- src/upload-lib.ts | 40 ++++---------------------- src/upload-sarif-action.ts | 7 +++-- 10 files changed, 119 insertions(+), 125 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 12628f9bd2..fba60d03bc 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -90113,12 +90113,6 @@ function fixCodeQualityCategory(logger, category) { return category; } -// src/analyze.ts -var fs15 = __toESM(require("fs")); -var path16 = __toESM(require("path")); -var import_perf_hooks2 = require("perf_hooks"); -var io5 = __toESM(require_io()); - // src/analyses.ts var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { AnalysisKind2["CodeScanning"] = "code-scanning"; @@ -90127,6 +90121,24 @@ var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); var codeQualityQueries = ["code-quality"]; +var CodeScanningTarget = { + name: "code scanning", + target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, + sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), + sentinelPrefix: "CODEQL_UPLOAD_SARIF_" +}; +var CodeQualityTarget = { + name: "code quality", + target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, + sarifPredicate: (name) => name.endsWith(".quality.sarif"), + sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" +}; + +// src/analyze.ts +var fs15 = __toESM(require("fs")); +var path16 = __toESM(require("path")); +var import_perf_hooks2 = require("perf_hooks"); +var io5 = __toESM(require_io()); // src/api-client.ts var core5 = __toESM(require_core()); @@ -95498,18 +95510,6 @@ function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, wo } return payloadObj; } -var CodeScanningTarget = { - name: "code scanning", - target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, - sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), - sentinelPrefix: "CODEQL_UPLOAD_SARIF_" -}; -var CodeQualityTarget = { - name: "code quality", - target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, - sarifPredicate: (name) => name.endsWith(".quality.sarif"), - sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" -}; async function uploadFiles(inputSarifPath, checkoutPath, category, features, logger, uploadTarget) { const sarifPaths = getSarifFilePaths( inputSarifPath, diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 2751c1ec80..31547af741 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -128754,6 +128754,18 @@ var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { return AnalysisKind2; })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); +var CodeScanningTarget = { + name: "code scanning", + target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, + sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), + sentinelPrefix: "CODEQL_UPLOAD_SARIF_" +}; +var CodeQualityTarget = { + name: "code quality", + target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, + sarifPredicate: (name) => name.endsWith(".quality.sarif"), + sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" +}; // src/caching-utils.ts var core6 = __toESM(require_core()); @@ -132980,18 +132992,6 @@ function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, wo } return payloadObj; } -var CodeScanningTarget = { - name: "code scanning", - target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, - sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), - sentinelPrefix: "CODEQL_UPLOAD_SARIF_" -}; -var CodeQualityTarget = { - name: "code quality", - target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, - sarifPredicate: (name) => name.endsWith(".quality.sarif"), - sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" -}; async function uploadFiles(inputSarifPath, checkoutPath, category, features, logger, uploadTarget) { const sarifPaths = getSarifFilePaths( inputSarifPath, diff --git a/lib/upload-lib.js b/lib/upload-lib.js index b23e8262ee..d18597ef87 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -84778,10 +84778,7 @@ var require_sarif_schema_2_1_0 = __commonJS({ // src/upload-lib.ts var upload_lib_exports = {}; __export(upload_lib_exports, { - CodeQualityTarget: () => CodeQualityTarget, - CodeScanningTarget: () => CodeScanningTarget, InvalidSarifUploadError: () => InvalidSarifUploadError, - SARIF_UPLOAD_ENDPOINT: () => SARIF_UPLOAD_ENDPOINT, buildPayload: () => buildPayload, findSarifFilesInDir: () => findSarifFilesInDir, getSarifFilePaths: () => getSarifFilePaths, @@ -88493,6 +88490,26 @@ async function runTool(cmd, args = [], opts = {}) { return stdout; } +// src/analyses.ts +var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { + AnalysisKind2["CodeScanning"] = "code-scanning"; + AnalysisKind2["CodeQuality"] = "code-quality"; + return AnalysisKind2; +})(AnalysisKind || {}); +var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); +var CodeScanningTarget = { + name: "code scanning", + target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, + sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), + sentinelPrefix: "CODEQL_UPLOAD_SARIF_" +}; +var CodeQualityTarget = { + name: "code quality", + target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, + sarifPredicate: (name) => name.endsWith(".quality.sarif"), + sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" +}; + // src/api-client.ts var core5 = __toESM(require_core()); var githubUtils = __toESM(require_utils4()); @@ -88877,14 +88894,6 @@ var fs7 = __toESM(require("fs")); var path9 = __toESM(require("path")); var semver4 = __toESM(require_semver2()); -// src/analyses.ts -var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { - AnalysisKind2["CodeScanning"] = "code-scanning"; - AnalysisKind2["CodeQuality"] = "code-quality"; - return AnalysisKind2; -})(AnalysisKind || {}); -var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); - // src/caching-utils.ts var core6 = __toESM(require_core()); @@ -92203,11 +92212,6 @@ function getAutomationID(category, analysis_key, environment) { } return computeAutomationID(analysis_key, environment); } -var SARIF_UPLOAD_ENDPOINT = /* @__PURE__ */ ((SARIF_UPLOAD_ENDPOINT2) => { - SARIF_UPLOAD_ENDPOINT2["CODE_SCANNING"] = "PUT /repos/:owner/:repo/code-scanning/analysis"; - SARIF_UPLOAD_ENDPOINT2["CODE_QUALITY"] = "PUT /repos/:owner/:repo/code-quality/analysis"; - return SARIF_UPLOAD_ENDPOINT2; -})(SARIF_UPLOAD_ENDPOINT || {}); async function uploadPayload(payload, repositoryNwo, logger, target) { logger.info("Uploading results"); if (isInTestMode()) { @@ -92376,18 +92380,6 @@ function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, wo } return payloadObj; } -var CodeScanningTarget = { - name: "code scanning", - target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, - sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), - sentinelPrefix: "CODEQL_UPLOAD_SARIF_" -}; -var CodeQualityTarget = { - name: "code quality", - target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, - sarifPredicate: (name) => name.endsWith(".quality.sarif"), - sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" -}; async function uploadFiles(inputSarifPath, checkoutPath, category, features, logger, uploadTarget) { const sarifPaths = getSarifFilePaths( inputSarifPath, @@ -92630,10 +92622,7 @@ function filterAlertsByDiffRange(logger, sarif) { } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { - CodeQualityTarget, - CodeScanningTarget, InvalidSarifUploadError, - SARIF_UPLOAD_ENDPOINT, buildPayload, findSarifFilesInDir, getSarifFilePaths, diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index 6665c2ac51..91eec037a2 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -88718,6 +88718,26 @@ function fixCodeQualityCategory(logger, category) { return category; } +// src/analyses.ts +var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { + AnalysisKind2["CodeScanning"] = "code-scanning"; + AnalysisKind2["CodeQuality"] = "code-quality"; + return AnalysisKind2; +})(AnalysisKind || {}); +var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); +var CodeScanningTarget = { + name: "code scanning", + target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, + sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), + sentinelPrefix: "CODEQL_UPLOAD_SARIF_" +}; +var CodeQualityTarget = { + name: "code quality", + target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, + sarifPredicate: (name) => name.endsWith(".quality.sarif"), + sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" +}; + // src/api-client.ts var core5 = __toESM(require_core()); var githubUtils = __toESM(require_utils4()); @@ -89585,14 +89605,6 @@ var fs8 = __toESM(require("fs")); var path10 = __toESM(require("path")); var semver4 = __toESM(require_semver2()); -// src/analyses.ts -var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { - AnalysisKind2["CodeScanning"] = "code-scanning"; - AnalysisKind2["CodeQuality"] = "code-quality"; - return AnalysisKind2; -})(AnalysisKind || {}); -var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); - // src/caching-utils.ts var core8 = __toESM(require_core()); @@ -93053,18 +93065,6 @@ function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, wo } return payloadObj; } -var CodeScanningTarget = { - name: "code scanning", - target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, - sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), - sentinelPrefix: "CODEQL_UPLOAD_SARIF_" -}; -var CodeQualityTarget = { - name: "code quality", - target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, - sarifPredicate: (name) => name.endsWith(".quality.sarif"), - sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" -}; async function uploadFiles(inputSarifPath, checkoutPath, category, features, logger, uploadTarget) { const sarifPaths = getSarifFilePaths( inputSarifPath, diff --git a/src/analyses.ts b/src/analyses.ts index e80cdfb20e..0d8e164458 100644 --- a/src/analyses.ts +++ b/src/analyses.ts @@ -41,3 +41,34 @@ export async function parseAnalysisKinds( /** The queries to use for Code Quality analyses. */ export const codeQualityQueries: string[] = ["code-quality"]; + +// Enumerates API endpoints that accept SARIF files. +export enum SARIF_UPLOAD_ENDPOINT { + CODE_SCANNING = "PUT /repos/:owner/:repo/code-scanning/analysis", + CODE_QUALITY = "PUT /repos/:owner/:repo/code-quality/analysis", +} + +// Represents configurations for different services that we can upload SARIF to. +export interface UploadTarget { + name: string; + target: SARIF_UPLOAD_ENDPOINT; + sarifPredicate: (name: string) => boolean; + sentinelPrefix: string; +} + +// Represents the Code Scanning upload target. +export const CodeScanningTarget: UploadTarget = { + name: "code scanning", + target: SARIF_UPLOAD_ENDPOINT.CODE_SCANNING, + sarifPredicate: (name) => + name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), + sentinelPrefix: "CODEQL_UPLOAD_SARIF_", +}; + +// Represents the Code Quality upload target. +export const CodeQualityTarget: UploadTarget = { + name: "code quality", + target: SARIF_UPLOAD_ENDPOINT.CODE_QUALITY, + sarifPredicate: (name) => name.endsWith(".quality.sarif"), + sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_", +}; diff --git a/src/analyze-action.ts b/src/analyze-action.ts index 87af6fcca7..24da7e8765 100644 --- a/src/analyze-action.ts +++ b/src/analyze-action.ts @@ -5,6 +5,7 @@ import { performance } from "perf_hooks"; import * as core from "@actions/core"; import * as actionsUtil from "./actions-util"; +import * as analyses from "./analyses"; import { CodeQLAnalysisError, dbIsFinalized, @@ -332,7 +333,7 @@ async function run() { actionsUtil.getOptionalInput("category"), features, logger, - uploadLib.CodeScanningTarget, + analyses.CodeScanningTarget, ); core.setOutput("sarif-id", uploadResult.sarifID); @@ -346,7 +347,7 @@ async function run() { ), features, logger, - uploadLib.CodeQualityTarget, + analyses.CodeQualityTarget, ); core.setOutput("quality-sarif-id", qualityUploadResult.sarifID); } diff --git a/src/init-action-post-helper.ts b/src/init-action-post-helper.ts index b04e62c290..16822aa49a 100644 --- a/src/init-action-post-helper.ts +++ b/src/init-action-post-helper.ts @@ -4,6 +4,7 @@ import * as core from "@actions/core"; import * as github from "@actions/github"; import * as actionsUtil from "./actions-util"; +import { CodeScanningTarget } from "./analyses"; import { getApiClient } from "./api-client"; import { CodeQL, getCodeQL } from "./codeql"; import { Config } from "./config-utils"; @@ -104,7 +105,7 @@ async function maybeUploadFailedSarif( category, features, logger, - uploadLib.CodeScanningTarget, + CodeScanningTarget, ); await uploadLib.waitForProcessing( repositoryNwo, diff --git a/src/upload-lib.test.ts b/src/upload-lib.test.ts index 96f132b210..9848d9a711 100644 --- a/src/upload-lib.test.ts +++ b/src/upload-lib.test.ts @@ -3,6 +3,7 @@ import * as path from "path"; import test from "ava"; +import { CodeQualityTarget, CodeScanningTarget } from "./analyses"; import { getRunnerLogger, Logger } from "./logging"; import { setupTests } from "./testing-utils"; import * as uploadLib from "./upload-lib"; @@ -128,7 +129,7 @@ test("finding SARIF files", async (t) => { const sarifFiles = uploadLib.findSarifFilesInDir( tmpDir, - uploadLib.CodeScanningTarget.sarifPredicate, + CodeScanningTarget.sarifPredicate, ); t.deepEqual(sarifFiles, [ @@ -140,7 +141,7 @@ test("finding SARIF files", async (t) => { const qualitySarifFiles = uploadLib.findSarifFilesInDir( tmpDir, - uploadLib.CodeQualityTarget.sarifPredicate, + CodeQualityTarget.sarifPredicate, ); t.deepEqual(qualitySarifFiles, [ @@ -335,7 +336,7 @@ test("validateUniqueCategory with different prefixes", (t) => { t.notThrows(() => uploadLib.validateUniqueCategory( createMockSarif(), - uploadLib.CodeQualityTarget.sentinelPrefix, + CodeQualityTarget.sentinelPrefix, ), ); }); diff --git a/src/upload-lib.ts b/src/upload-lib.ts index e87dad839f..d21797903a 100644 --- a/src/upload-lib.ts +++ b/src/upload-lib.ts @@ -8,6 +8,7 @@ import { OctokitResponse } from "@octokit/types"; import * as jsonschema from "jsonschema"; import * as actionsUtil from "./actions-util"; +import * as analyses from "./analyses"; import * as api from "./api-client"; import { getGitHubVersion, wrapApiConfigurationError } from "./api-client"; import { CodeQL, getCodeQL } from "./codeql"; @@ -345,19 +346,13 @@ function getAutomationID( return api.computeAutomationID(analysis_key, environment); } -// Enumerates API endpoints that accept SARIF files. -export enum SARIF_UPLOAD_ENDPOINT { - CODE_SCANNING = "PUT /repos/:owner/:repo/code-scanning/analysis", - CODE_QUALITY = "PUT /repos/:owner/:repo/code-quality/analysis", -} - // Upload the given payload. // If the request fails then this will retry a small number of times. async function uploadPayload( payload: any, repositoryNwo: RepositoryNwo, logger: Logger, - target: SARIF_UPLOAD_ENDPOINT, + target: analyses.SARIF_UPLOAD_ENDPOINT, ): Promise { logger.info("Uploading results"); @@ -616,31 +611,6 @@ export function buildPayload( return payloadObj; } -// Represents configurations for different services that we can upload SARIF to. -export interface UploadTarget { - name: string; - target: SARIF_UPLOAD_ENDPOINT; - sarifPredicate: (name: string) => boolean; - sentinelPrefix: string; -} - -// Represents the Code Scanning upload target. -export const CodeScanningTarget: UploadTarget = { - name: "code scanning", - target: SARIF_UPLOAD_ENDPOINT.CODE_SCANNING, - sarifPredicate: (name) => - name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), - sentinelPrefix: "CODEQL_UPLOAD_SARIF_", -}; - -// Represents the Code Quality upload target. -export const CodeQualityTarget: UploadTarget = { - name: "code quality", - target: SARIF_UPLOAD_ENDPOINT.CODE_QUALITY, - sarifPredicate: (name) => name.endsWith(".quality.sarif"), - sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_", -}; - /** * Uploads a single SARIF file or a directory of SARIF files depending on what `inputSarifPath` refers * to. @@ -651,7 +621,7 @@ export async function uploadFiles( category: string | undefined, features: FeatureEnablement, logger: Logger, - uploadTarget: UploadTarget, + uploadTarget: analyses.UploadTarget, ): Promise { const sarifPaths = getSarifFilePaths( inputSarifPath, @@ -677,7 +647,7 @@ export async function uploadSpecifiedFiles( category: string | undefined, features: FeatureEnablement, logger: Logger, - uploadTarget: UploadTarget = CodeScanningTarget, + uploadTarget: analyses.UploadTarget = analyses.CodeScanningTarget, ): Promise { logger.startGroup(`Uploading ${uploadTarget.name} results`); logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`); @@ -943,7 +913,7 @@ function handleProcessingResultForUnsuccessfulExecution( export function validateUniqueCategory( sarif: SarifFile, - sentinelPrefix: string = CodeScanningTarget.sentinelPrefix, + sentinelPrefix: string = analyses.CodeScanningTarget.sentinelPrefix, ): void { // duplicate categories are allowed in the same sarif file // but not across multiple sarif files diff --git a/src/upload-sarif-action.ts b/src/upload-sarif-action.ts index 25e884ea0f..e18d96b14d 100644 --- a/src/upload-sarif-action.ts +++ b/src/upload-sarif-action.ts @@ -4,6 +4,7 @@ import * as core from "@actions/core"; import * as actionsUtil from "./actions-util"; import { getActionVersion, getTemporaryDirectory } from "./actions-util"; +import * as analyses from "./analyses"; import { getGitHubVersion } from "./api-client"; import { Features } from "./feature-flags"; import { Logger, getActionsLogger } from "./logging"; @@ -95,7 +96,7 @@ async function run() { category, features, logger, - upload_lib.CodeScanningTarget, + analyses.CodeScanningTarget, ); core.setOutput("sarif-id", uploadResult.sarifID); @@ -105,7 +106,7 @@ async function run() { if (fs.lstatSync(sarifPath).isDirectory()) { const qualitySarifFiles = upload_lib.findSarifFilesInDir( sarifPath, - upload_lib.CodeQualityTarget.sarifPredicate, + analyses.CodeQualityTarget.sarifPredicate, ); if (qualitySarifFiles.length !== 0) { @@ -115,7 +116,7 @@ async function run() { actionsUtil.fixCodeQualityCategory(logger, category), features, logger, - upload_lib.CodeQualityTarget, + analyses.CodeQualityTarget, ); } } From 01627081ffd3fbffe8f62eb8f9c0f683aa6d28e4 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 28 Aug 2025 16:53:34 +0100 Subject: [PATCH 04/25] Rename `UploadTarget` to `AnalysisConfig` --- lib/analyze-action.js | 14 +++++++------- lib/init-action-post.js | 12 ++++++------ lib/upload-lib.js | 10 +++++----- lib/upload-sarif-action.js | 16 ++++++++-------- src/analyses.ts | 14 +++++++------- src/analyze-action.ts | 4 ++-- src/init-action-post-helper.ts | 4 ++-- src/upload-lib.test.ts | 8 ++++---- src/upload-lib.ts | 6 +++--- src/upload-sarif-action.ts | 6 +++--- 10 files changed, 47 insertions(+), 47 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index fba60d03bc..af61a40bae 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -90121,13 +90121,13 @@ var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); var codeQualityQueries = ["code-quality"]; -var CodeScanningTarget = { +var CodeScanning = { name: "code scanning", target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, - sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), + sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQuality.sarifPredicate(name), sentinelPrefix: "CODEQL_UPLOAD_SARIF_" }; -var CodeQualityTarget = { +var CodeQuality = { name: "code quality", target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, sarifPredicate: (name) => name.endsWith(".quality.sarif"), @@ -95524,7 +95524,7 @@ async function uploadFiles(inputSarifPath, checkoutPath, category, features, log uploadTarget ); } -async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanningTarget) { +async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanning) { logger.startGroup(`Uploading ${uploadTarget.name} results`); logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`); const gitHubVersion = await getGitHubVersion(); @@ -95695,7 +95695,7 @@ function handleProcessingResultForUnsuccessfulExecution(response, status, logger assertNever(status); } } -function validateUniqueCategory(sarif, sentinelPrefix = CodeScanningTarget.sentinelPrefix) { +function validateUniqueCategory(sarif, sentinelPrefix = CodeScanning.sentinelPrefix) { const categories = {}; for (const run2 of sarif.runs) { const id = run2?.automationDetails?.id; @@ -95951,7 +95951,7 @@ async function run() { getOptionalInput("category"), features, logger, - CodeScanningTarget + CodeScanning ); core14.setOutput("sarif-id", uploadResult.sarifID); if (isCodeQualityEnabled(config)) { @@ -95964,7 +95964,7 @@ async function run() { ), features, logger, - CodeQualityTarget + CodeQuality ); core14.setOutput("quality-sarif-id", qualityUploadResult.sarifID); } diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 31547af741..2320d55f0c 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -128754,13 +128754,13 @@ var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { return AnalysisKind2; })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); -var CodeScanningTarget = { +var CodeScanning = { name: "code scanning", target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, - sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), + sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQuality.sarifPredicate(name), sentinelPrefix: "CODEQL_UPLOAD_SARIF_" }; -var CodeQualityTarget = { +var CodeQuality = { name: "code quality", target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, sarifPredicate: (name) => name.endsWith(".quality.sarif"), @@ -133006,7 +133006,7 @@ async function uploadFiles(inputSarifPath, checkoutPath, category, features, log uploadTarget ); } -async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanningTarget) { +async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanning) { logger.startGroup(`Uploading ${uploadTarget.name} results`); logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`); const gitHubVersion = await getGitHubVersion(); @@ -133177,7 +133177,7 @@ function handleProcessingResultForUnsuccessfulExecution(response, status, logger assertNever(status); } } -function validateUniqueCategory(sarif, sentinelPrefix = CodeScanningTarget.sentinelPrefix) { +function validateUniqueCategory(sarif, sentinelPrefix = CodeScanning.sentinelPrefix) { const categories = {}; for (const run2 of sarif.runs) { const id = run2?.automationDetails?.id; @@ -133402,7 +133402,7 @@ async function maybeUploadFailedSarif(config, repositoryNwo, features, logger) { category, features, logger, - CodeScanningTarget + CodeScanning ); await waitForProcessing( repositoryNwo, diff --git a/lib/upload-lib.js b/lib/upload-lib.js index d18597ef87..64ac6a9de1 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -88497,13 +88497,13 @@ var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { return AnalysisKind2; })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); -var CodeScanningTarget = { +var CodeScanning = { name: "code scanning", target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, - sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), + sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQuality.sarifPredicate(name), sentinelPrefix: "CODEQL_UPLOAD_SARIF_" }; -var CodeQualityTarget = { +var CodeQuality = { name: "code quality", target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, sarifPredicate: (name) => name.endsWith(".quality.sarif"), @@ -92394,7 +92394,7 @@ async function uploadFiles(inputSarifPath, checkoutPath, category, features, log uploadTarget ); } -async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanningTarget) { +async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanning) { logger.startGroup(`Uploading ${uploadTarget.name} results`); logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`); const gitHubVersion = await getGitHubVersion(); @@ -92565,7 +92565,7 @@ function handleProcessingResultForUnsuccessfulExecution(response, status, logger assertNever(status); } } -function validateUniqueCategory(sarif, sentinelPrefix = CodeScanningTarget.sentinelPrefix) { +function validateUniqueCategory(sarif, sentinelPrefix = CodeScanning.sentinelPrefix) { const categories = {}; for (const run of sarif.runs) { const id = run?.automationDetails?.id; diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index 91eec037a2..dd2f38edc7 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -88725,13 +88725,13 @@ var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { return AnalysisKind2; })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); -var CodeScanningTarget = { +var CodeScanning = { name: "code scanning", target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, - sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), + sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQuality.sarifPredicate(name), sentinelPrefix: "CODEQL_UPLOAD_SARIF_" }; -var CodeQualityTarget = { +var CodeQuality = { name: "code quality", target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, sarifPredicate: (name) => name.endsWith(".quality.sarif"), @@ -93079,7 +93079,7 @@ async function uploadFiles(inputSarifPath, checkoutPath, category, features, log uploadTarget ); } -async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanningTarget) { +async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanning) { logger.startGroup(`Uploading ${uploadTarget.name} results`); logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`); const gitHubVersion = await getGitHubVersion(); @@ -93250,7 +93250,7 @@ function handleProcessingResultForUnsuccessfulExecution(response, status, logger assertNever(status); } } -function validateUniqueCategory(sarif, sentinelPrefix = CodeScanningTarget.sentinelPrefix) { +function validateUniqueCategory(sarif, sentinelPrefix = CodeScanning.sentinelPrefix) { const categories = {}; for (const run2 of sarif.runs) { const id = run2?.automationDetails?.id; @@ -93359,13 +93359,13 @@ async function run() { category, features, logger, - CodeScanningTarget + CodeScanning ); core13.setOutput("sarif-id", uploadResult.sarifID); if (fs15.lstatSync(sarifPath).isDirectory()) { const qualitySarifFiles = findSarifFilesInDir( sarifPath, - CodeQualityTarget.sarifPredicate + CodeQuality.sarifPredicate ); if (qualitySarifFiles.length !== 0) { await uploadSpecifiedFiles( @@ -93374,7 +93374,7 @@ async function run() { fixCodeQualityCategory(logger, category), features, logger, - CodeQualityTarget + CodeQuality ); } } diff --git a/src/analyses.ts b/src/analyses.ts index 0d8e164458..71c50b824a 100644 --- a/src/analyses.ts +++ b/src/analyses.ts @@ -48,25 +48,25 @@ export enum SARIF_UPLOAD_ENDPOINT { CODE_QUALITY = "PUT /repos/:owner/:repo/code-quality/analysis", } -// Represents configurations for different services that we can upload SARIF to. -export interface UploadTarget { +// Represents configurations for different analysis kinds. +export interface AnalysisConfig { name: string; target: SARIF_UPLOAD_ENDPOINT; sarifPredicate: (name: string) => boolean; sentinelPrefix: string; } -// Represents the Code Scanning upload target. -export const CodeScanningTarget: UploadTarget = { +// Represents the Code Scanning analysis configuration. +export const CodeScanning: AnalysisConfig = { name: "code scanning", target: SARIF_UPLOAD_ENDPOINT.CODE_SCANNING, sarifPredicate: (name) => - name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), + name.endsWith(".sarif") && !CodeQuality.sarifPredicate(name), sentinelPrefix: "CODEQL_UPLOAD_SARIF_", }; -// Represents the Code Quality upload target. -export const CodeQualityTarget: UploadTarget = { +// Represents the Code Quality analysis configuration. +export const CodeQuality: AnalysisConfig = { name: "code quality", target: SARIF_UPLOAD_ENDPOINT.CODE_QUALITY, sarifPredicate: (name) => name.endsWith(".quality.sarif"), diff --git a/src/analyze-action.ts b/src/analyze-action.ts index 24da7e8765..c949e3d4d7 100644 --- a/src/analyze-action.ts +++ b/src/analyze-action.ts @@ -333,7 +333,7 @@ async function run() { actionsUtil.getOptionalInput("category"), features, logger, - analyses.CodeScanningTarget, + analyses.CodeScanning, ); core.setOutput("sarif-id", uploadResult.sarifID); @@ -347,7 +347,7 @@ async function run() { ), features, logger, - analyses.CodeQualityTarget, + analyses.CodeQuality, ); core.setOutput("quality-sarif-id", qualityUploadResult.sarifID); } diff --git a/src/init-action-post-helper.ts b/src/init-action-post-helper.ts index 16822aa49a..0d21bd3b66 100644 --- a/src/init-action-post-helper.ts +++ b/src/init-action-post-helper.ts @@ -4,7 +4,7 @@ import * as core from "@actions/core"; import * as github from "@actions/github"; import * as actionsUtil from "./actions-util"; -import { CodeScanningTarget } from "./analyses"; +import { CodeScanning } from "./analyses"; import { getApiClient } from "./api-client"; import { CodeQL, getCodeQL } from "./codeql"; import { Config } from "./config-utils"; @@ -105,7 +105,7 @@ async function maybeUploadFailedSarif( category, features, logger, - CodeScanningTarget, + CodeScanning, ); await uploadLib.waitForProcessing( repositoryNwo, diff --git a/src/upload-lib.test.ts b/src/upload-lib.test.ts index 9848d9a711..3e463b9441 100644 --- a/src/upload-lib.test.ts +++ b/src/upload-lib.test.ts @@ -3,7 +3,7 @@ import * as path from "path"; import test from "ava"; -import { CodeQualityTarget, CodeScanningTarget } from "./analyses"; +import { CodeQuality, CodeScanning } from "./analyses"; import { getRunnerLogger, Logger } from "./logging"; import { setupTests } from "./testing-utils"; import * as uploadLib from "./upload-lib"; @@ -129,7 +129,7 @@ test("finding SARIF files", async (t) => { const sarifFiles = uploadLib.findSarifFilesInDir( tmpDir, - CodeScanningTarget.sarifPredicate, + CodeScanning.sarifPredicate, ); t.deepEqual(sarifFiles, [ @@ -141,7 +141,7 @@ test("finding SARIF files", async (t) => { const qualitySarifFiles = uploadLib.findSarifFilesInDir( tmpDir, - CodeQualityTarget.sarifPredicate, + CodeQuality.sarifPredicate, ); t.deepEqual(qualitySarifFiles, [ @@ -336,7 +336,7 @@ test("validateUniqueCategory with different prefixes", (t) => { t.notThrows(() => uploadLib.validateUniqueCategory( createMockSarif(), - CodeQualityTarget.sentinelPrefix, + CodeQuality.sentinelPrefix, ), ); }); diff --git a/src/upload-lib.ts b/src/upload-lib.ts index d21797903a..cd11b8e3f7 100644 --- a/src/upload-lib.ts +++ b/src/upload-lib.ts @@ -621,7 +621,7 @@ export async function uploadFiles( category: string | undefined, features: FeatureEnablement, logger: Logger, - uploadTarget: analyses.UploadTarget, + uploadTarget: analyses.AnalysisConfig, ): Promise { const sarifPaths = getSarifFilePaths( inputSarifPath, @@ -647,7 +647,7 @@ export async function uploadSpecifiedFiles( category: string | undefined, features: FeatureEnablement, logger: Logger, - uploadTarget: analyses.UploadTarget = analyses.CodeScanningTarget, + uploadTarget: analyses.AnalysisConfig = analyses.CodeScanning, ): Promise { logger.startGroup(`Uploading ${uploadTarget.name} results`); logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`); @@ -913,7 +913,7 @@ function handleProcessingResultForUnsuccessfulExecution( export function validateUniqueCategory( sarif: SarifFile, - sentinelPrefix: string = analyses.CodeScanningTarget.sentinelPrefix, + sentinelPrefix: string = analyses.CodeScanning.sentinelPrefix, ): void { // duplicate categories are allowed in the same sarif file // but not across multiple sarif files diff --git a/src/upload-sarif-action.ts b/src/upload-sarif-action.ts index e18d96b14d..a193e242a6 100644 --- a/src/upload-sarif-action.ts +++ b/src/upload-sarif-action.ts @@ -96,7 +96,7 @@ async function run() { category, features, logger, - analyses.CodeScanningTarget, + analyses.CodeScanning, ); core.setOutput("sarif-id", uploadResult.sarifID); @@ -106,7 +106,7 @@ async function run() { if (fs.lstatSync(sarifPath).isDirectory()) { const qualitySarifFiles = upload_lib.findSarifFilesInDir( sarifPath, - analyses.CodeQualityTarget.sarifPredicate, + analyses.CodeQuality.sarifPredicate, ); if (qualitySarifFiles.length !== 0) { @@ -116,7 +116,7 @@ async function run() { actionsUtil.fixCodeQualityCategory(logger, category), features, logger, - analyses.CodeQualityTarget, + analyses.CodeQuality, ); } } From cb8f28fbf763a6383f1515a57aea66a4331b2416 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 28 Aug 2025 16:58:28 +0100 Subject: [PATCH 05/25] Add `kind` property to `AnalysisConfig` and documentation --- 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 | 9 +++++++++ 5 files changed, 17 insertions(+) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index af61a40bae..36b972483a 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -90122,12 +90122,14 @@ var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); var codeQualityQueries = ["code-quality"]; var CodeScanning = { + kind: "code-scanning" /* CodeScanning */, name: "code scanning", target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQuality.sarifPredicate(name), sentinelPrefix: "CODEQL_UPLOAD_SARIF_" }; var CodeQuality = { + kind: "code-quality" /* CodeQuality */, name: "code quality", target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, sarifPredicate: (name) => name.endsWith(".quality.sarif"), diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 2320d55f0c..e4f20853a0 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -128755,12 +128755,14 @@ var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); var CodeScanning = { + kind: "code-scanning" /* CodeScanning */, name: "code scanning", target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQuality.sarifPredicate(name), sentinelPrefix: "CODEQL_UPLOAD_SARIF_" }; var CodeQuality = { + kind: "code-quality" /* CodeQuality */, name: "code quality", target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, sarifPredicate: (name) => name.endsWith(".quality.sarif"), diff --git a/lib/upload-lib.js b/lib/upload-lib.js index 64ac6a9de1..fedf0454f5 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -88498,12 +88498,14 @@ var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); var CodeScanning = { + kind: "code-scanning" /* CodeScanning */, name: "code scanning", target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQuality.sarifPredicate(name), sentinelPrefix: "CODEQL_UPLOAD_SARIF_" }; var CodeQuality = { + kind: "code-quality" /* CodeQuality */, name: "code quality", target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, sarifPredicate: (name) => name.endsWith(".quality.sarif"), diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index dd2f38edc7..d3047dd99f 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -88726,12 +88726,14 @@ var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); var CodeScanning = { + kind: "code-scanning" /* CodeScanning */, name: "code scanning", target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQuality.sarifPredicate(name), sentinelPrefix: "CODEQL_UPLOAD_SARIF_" }; var CodeQuality = { + kind: "code-quality" /* CodeQuality */, name: "code quality", target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, sarifPredicate: (name) => name.endsWith(".quality.sarif"), diff --git a/src/analyses.ts b/src/analyses.ts index 71c50b824a..9a5d1e831c 100644 --- a/src/analyses.ts +++ b/src/analyses.ts @@ -50,14 +50,22 @@ export enum SARIF_UPLOAD_ENDPOINT { // Represents configurations for different analysis kinds. export interface AnalysisConfig { + /** The analysis kind the configuration is for. */ + kind: AnalysisKind; + /** A display friendly name for logs. */ name: string; + /** The API endpoint to upload SARIF files to. */ target: SARIF_UPLOAD_ENDPOINT; + /** A predicate on filenames to decide whether a SARIF file + * belongs to this kind of analysis. */ sarifPredicate: (name: string) => boolean; + /** A prefix for environment variables used to track the uniqueness of SARIF uploads. */ sentinelPrefix: string; } // Represents the Code Scanning analysis configuration. export const CodeScanning: AnalysisConfig = { + kind: AnalysisKind.CodeScanning, name: "code scanning", target: SARIF_UPLOAD_ENDPOINT.CODE_SCANNING, sarifPredicate: (name) => @@ -67,6 +75,7 @@ export const CodeScanning: AnalysisConfig = { // Represents the Code Quality analysis configuration. export const CodeQuality: AnalysisConfig = { + kind: AnalysisKind.CodeQuality, name: "code quality", target: SARIF_UPLOAD_ENDPOINT.CODE_QUALITY, sarifPredicate: (name) => name.endsWith(".quality.sarif"), From e4ffe6f3e5fd5e3777b08846347a9c2c184734a3 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 28 Aug 2025 17:01:22 +0100 Subject: [PATCH 06/25] Only specify queries for `run-queries` if both analysis kinds are enabled --- lib/analyze-action.js | 5 ++++- src/analyze.ts | 13 ++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 36b972483a..cb0fe5ce54 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -91615,6 +91615,9 @@ function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { } return augmentedConfig; } +function isCodeScanningEnabled(config) { + return config.analysisKinds.includes("code-scanning" /* CodeScanning */); +} function isCodeQualityEnabled(config) { return config.analysisKinds.includes("code-quality" /* CodeQuality */); } @@ -93597,7 +93600,7 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, try { const sarifFile = path16.join(sarifFolder, `${language}.sarif`); const queries = []; - if (isCodeQualityEnabled(config)) { + if (isCodeQualityEnabled(config) && isCodeScanningEnabled(config)) { queries.push(getGeneratedSuitePath(config, language)); for (const qualityQuery of codeQualityQueries) { queries.push(resolveQuerySuiteAlias(language, qualityQuery)); diff --git a/src/analyze.ts b/src/analyze.ts index a8ab5ca91d..ad9f61401a 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -654,8 +654,19 @@ export async function runQueries( try { const sarifFile = path.join(sarifFolder, `${language}.sarif`); + // This should be empty to run only the query suite that was generated when + // the database was initialised. const queries: string[] = []; - if (configUtils.isCodeQualityEnabled(config)) { + + // If both Code Scanning and Code Quality analyses are enabled, the database + // is initialised for Code Scanning. To avoid duplicate work, we want to run + // queries for both analyses at the same time. To do this, we invoke `run-queries` + // once with the generated query suite for Code Scanning + the fixed + // query suite for Code Quality. + if ( + configUtils.isCodeQualityEnabled(config) && + configUtils.isCodeScanningEnabled(config) + ) { queries.push(util.getGeneratedSuitePath(config, language)); for (const qualityQuery of analyses.codeQualityQueries) { queries.push(resolveQuerySuiteAlias(language, qualityQuery)); From ff57bbf22c32f59014565cd404e2262b1279a2de Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 28 Aug 2025 17:15:26 +0100 Subject: [PATCH 07/25] Handle different permutations of analysis kinds in `analyze` action --- lib/analyze-action.js | 31 ++++++++++++++++--------- src/analyze.ts | 53 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 62 insertions(+), 22 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index cb0fe5ce54..a08333b86a 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -93598,7 +93598,7 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, const sarifRunPropertyFlag = incrementalMode.length > 0 ? `--sarif-run-property=incrementalMode=${incrementalMode.join(",")}` : void 0; for (const language of config.languages) { try { - const sarifFile = path16.join(sarifFolder, `${language}.sarif`); + const sarifFile = isCodeScanningEnabled(config) ? path16.join(sarifFolder, `${language}.sarif`) : path16.join(sarifFolder, `${language}.quality.sarif`); const queries = []; if (isCodeQualityEnabled(config) && isCodeScanningEnabled(config)) { queries.push(getGeneratedSuitePath(config, language)); @@ -93612,17 +93612,24 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, await codeql.databaseRunQueries(databasePath, queryFlags, queries); logger.debug(`Finished running queries for ${language}.`); statusReport[`analyze_builtin_queries_${language}_duration_ms`] = (/* @__PURE__ */ new Date()).getTime() - startTimeRunQueries; - logger.startGroup(`Interpreting results for ${language}`); const startTimeInterpretResults = /* @__PURE__ */ new Date(); - const analysisSummary = await runInterpretResults( - language, - void 0, - sarifFile, - config.debugMode, - automationDetailsId - ); + let analysisSummary; + if (isCodeScanningEnabled(config) || isCodeQualityEnabled(config)) { + logger.startGroup(`Interpreting results for ${language}`); + let category = automationDetailsId; + if (isCodeQualityEnabled(config)) { + category = fixCodeQualityCategory(logger, automationDetailsId); + } + analysisSummary = await runInterpretResults( + language, + void 0, + sarifFile, + config.debugMode, + category + ); + } let qualityAnalysisSummary; - if (isCodeQualityEnabled(config)) { + if (isCodeQualityEnabled(config) && isCodeScanningEnabled(config)) { logger.info(`Interpreting quality results for ${language}`); const qualityCategory = fixCodeQualityCategory( logger, @@ -93645,7 +93652,9 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, const endTimeInterpretResults = /* @__PURE__ */ new Date(); statusReport[`interpret_results_${language}_duration_ms`] = endTimeInterpretResults.getTime() - startTimeInterpretResults.getTime(); logger.endGroup(); - logger.info(analysisSummary); + if (analysisSummary) { + logger.info(analysisSummary); + } if (qualityAnalysisSummary) { logger.info(qualityAnalysisSummary); } diff --git a/src/analyze.ts b/src/analyze.ts index ad9f61401a..a7f224353d 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -652,7 +652,11 @@ export async function runQueries( for (const language of config.languages) { try { - const sarifFile = path.join(sarifFolder, `${language}.sarif`); + // If Code Scanning is enabled, then the main SARIF file is always the Code Scanning one. + // Otherwise, only Code Quality is enabled, and the main SARIF file is the Code Quality one. + const sarifFile = configUtils.isCodeScanningEnabled(config) + ? path.join(sarifFolder, `${language}.sarif`) + : path.join(sarifFolder, `${language}.quality.sarif`); // This should be empty to run only the query suite that was generated when // the database was initialised. @@ -687,18 +691,43 @@ export async function runQueries( statusReport[`analyze_builtin_queries_${language}_duration_ms`] = new Date().getTime() - startTimeRunQueries; - logger.startGroup(`Interpreting results for ${language}`); const startTimeInterpretResults = new Date(); - const analysisSummary = await runInterpretResults( - language, - undefined, - sarifFile, - config.debugMode, - automationDetailsId, - ); + // If only one analysis kind is enabled, then the database is initialised for the + // respective set of queries. Therefore, running `interpret-results` produces the + // SARIF file we want for the one enabled analysis kind. + let analysisSummary: string | undefined; + if ( + configUtils.isCodeScanningEnabled(config) || + configUtils.isCodeQualityEnabled(config) + ) { + logger.startGroup(`Interpreting 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 (configUtils.isCodeQualityEnabled(config)) { + category = fixCodeQualityCategory(logger, automationDetailsId); + } + + analysisSummary = await runInterpretResults( + language, + undefined, + sarifFile, + config.debugMode, + category, + ); + } + + // This case is only needed if Code Quality is enabled in addition to Code Scanning. + // In this case, we will have run queries for both analysis kinds. The previous call to + // `interpret-results` will have produced a SARIF file for Code Scanning and we now + // need to produce an additional SARIF file for Code Quality. let qualityAnalysisSummary: string | undefined; - if (configUtils.isCodeQualityEnabled(config)) { + if ( + configUtils.isCodeQualityEnabled(config) && + configUtils.isCodeScanningEnabled(config) + ) { logger.info(`Interpreting quality results for ${language}`); const qualityCategory = fixCodeQualityCategory( logger, @@ -722,8 +751,10 @@ export async function runQueries( statusReport[`interpret_results_${language}_duration_ms`] = endTimeInterpretResults.getTime() - startTimeInterpretResults.getTime(); logger.endGroup(); - logger.info(analysisSummary); + if (analysisSummary) { + logger.info(analysisSummary); + } if (qualityAnalysisSummary) { logger.info(qualityAnalysisSummary); } From 6d2d2042ffc6535b891bb2f6558c89359784b73c Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 28 Aug 2025 17:57:17 +0100 Subject: [PATCH 08/25] Add note for `getPerQueryAlertCounts` --- src/analyze.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/analyze.ts b/src/analyze.ts index a7f224353d..82f470d013 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -760,6 +760,8 @@ export async function runQueries( } if (await features.getValue(Feature.QaTelemetryEnabled)) { + // Note: QA adds the `code-quality` query suite to the `queries` input, + // so this is fine since there is no `.quality.sarif`. const perQueryAlertCounts = getPerQueryAlertCounts(sarifFile); const perQueryAlertCountEventReport: EventReport = { From 04bb07498c7dd2ae10edf2cfbba3c2cb8adb5a26 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 1 Sep 2025 13:54:00 +0100 Subject: [PATCH 09/25] Add `sarifExtension` field to `AnalysisConfig` --- lib/analyze-action.js | 6 ++++-- lib/init-action-post.js | 6 ++++-- lib/upload-lib.js | 6 ++++-- lib/upload-sarif-action.js | 6 ++++-- src/analyses.ts | 9 +++++++-- 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index a08333b86a..a781dbc419 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -90125,14 +90125,16 @@ var CodeScanning = { kind: "code-scanning" /* CodeScanning */, name: "code scanning", target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, - sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQuality.sarifPredicate(name), + sarifExtension: ".sarif", + sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name), sentinelPrefix: "CODEQL_UPLOAD_SARIF_" }; var CodeQuality = { kind: "code-quality" /* CodeQuality */, name: "code quality", target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, - sarifPredicate: (name) => name.endsWith(".quality.sarif"), + sarifExtension: ".quality.sarif", + sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension), sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" }; diff --git a/lib/init-action-post.js b/lib/init-action-post.js index e4f20853a0..490414bdbb 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -128758,14 +128758,16 @@ var CodeScanning = { kind: "code-scanning" /* CodeScanning */, name: "code scanning", target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, - sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQuality.sarifPredicate(name), + sarifExtension: ".sarif", + sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name), sentinelPrefix: "CODEQL_UPLOAD_SARIF_" }; var CodeQuality = { kind: "code-quality" /* CodeQuality */, name: "code quality", target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, - sarifPredicate: (name) => name.endsWith(".quality.sarif"), + sarifExtension: ".quality.sarif", + sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension), sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" }; diff --git a/lib/upload-lib.js b/lib/upload-lib.js index fedf0454f5..e13493f1fd 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -88501,14 +88501,16 @@ var CodeScanning = { kind: "code-scanning" /* CodeScanning */, name: "code scanning", target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, - sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQuality.sarifPredicate(name), + sarifExtension: ".sarif", + sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name), sentinelPrefix: "CODEQL_UPLOAD_SARIF_" }; var CodeQuality = { kind: "code-quality" /* CodeQuality */, name: "code quality", target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, - sarifPredicate: (name) => name.endsWith(".quality.sarif"), + sarifExtension: ".quality.sarif", + sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension), sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" }; diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index d3047dd99f..980ef151fa 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -88729,14 +88729,16 @@ var CodeScanning = { kind: "code-scanning" /* CodeScanning */, name: "code scanning", target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, - sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQuality.sarifPredicate(name), + sarifExtension: ".sarif", + sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name), sentinelPrefix: "CODEQL_UPLOAD_SARIF_" }; var CodeQuality = { kind: "code-quality" /* CodeQuality */, name: "code quality", target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, - sarifPredicate: (name) => name.endsWith(".quality.sarif"), + sarifExtension: ".quality.sarif", + sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension), sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" }; diff --git a/src/analyses.ts b/src/analyses.ts index 9a5d1e831c..8d8cd1d616 100644 --- a/src/analyses.ts +++ b/src/analyses.ts @@ -56,6 +56,8 @@ export interface AnalysisConfig { name: string; /** The API endpoint to upload SARIF files to. */ target: SARIF_UPLOAD_ENDPOINT; + /** The file extension for SARIF files generated by this kind of analysis. */ + sarifExtension: string; /** A predicate on filenames to decide whether a SARIF file * belongs to this kind of analysis. */ sarifPredicate: (name: string) => boolean; @@ -68,8 +70,10 @@ export const CodeScanning: AnalysisConfig = { kind: AnalysisKind.CodeScanning, name: "code scanning", target: SARIF_UPLOAD_ENDPOINT.CODE_SCANNING, + sarifExtension: ".sarif", sarifPredicate: (name) => - name.endsWith(".sarif") && !CodeQuality.sarifPredicate(name), + name.endsWith(CodeScanning.sarifExtension) && + !CodeQuality.sarifPredicate(name), sentinelPrefix: "CODEQL_UPLOAD_SARIF_", }; @@ -78,6 +82,7 @@ export const CodeQuality: AnalysisConfig = { kind: AnalysisKind.CodeQuality, name: "code quality", target: SARIF_UPLOAD_ENDPOINT.CODE_QUALITY, - sarifPredicate: (name) => name.endsWith(".quality.sarif"), + sarifExtension: ".quality.sarif", + sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension), sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_", }; From 8ea50b8f82c81b039d02832d932359e102f65989 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 1 Sep 2025 14:10:25 +0100 Subject: [PATCH 10/25] Add and use helpers for determining analysis config the DB is initialised with --- lib/analyze-action.js | 25 +++++++++++++++++++++---- src/analyze.ts | 29 +++++++++++++++++++++++------ src/config-utils.ts | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 76 insertions(+), 11 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index a781dbc419..9f00316aaa 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -91623,6 +91623,12 @@ function isCodeScanningEnabled(config) { function isCodeQualityEnabled(config) { return config.analysisKinds.includes("code-quality" /* CodeQuality */); } +function getDbAnalysisKind(config) { + return isCodeScanningEnabled(config) ? "code-scanning" /* CodeScanning */ : "code-quality" /* CodeQuality */; +} +function getDbAnalysisConfig(config) { + return getDbAnalysisKind(config) === "code-scanning" /* CodeScanning */ ? CodeScanning : CodeQuality; +} // src/setup-codeql.ts var fs12 = __toESM(require("fs")); @@ -93579,6 +93585,9 @@ function resolveQuerySuiteAlias(language, maybeSuite) { } return maybeSuite; } +function addSarifExtension(analysis, base) { + return `${base}.${analysis.sarifExtension}`; +} async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, diffRangePackDir, automationDetailsId, codeql, config, logger, features) { const statusReport = {}; const queryFlags = [memoryFlag, threadsFlag]; @@ -93598,9 +93607,13 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, incrementalMode.push("overlay"); } const sarifRunPropertyFlag = incrementalMode.length > 0 ? `--sarif-run-property=incrementalMode=${incrementalMode.join(",")}` : void 0; + const dbAnalysisConfig = getDbAnalysisConfig(config); for (const language of config.languages) { try { - const sarifFile = isCodeScanningEnabled(config) ? path16.join(sarifFolder, `${language}.sarif`) : path16.join(sarifFolder, `${language}.quality.sarif`); + const sarifFile = path16.join( + sarifFolder, + addSarifExtension(dbAnalysisConfig, language) + ); const queries = []; if (isCodeQualityEnabled(config) && isCodeScanningEnabled(config)) { queries.push(getGeneratedSuitePath(config, language)); @@ -93617,7 +93630,9 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, const startTimeInterpretResults = /* @__PURE__ */ new Date(); let analysisSummary; if (isCodeScanningEnabled(config) || isCodeQualityEnabled(config)) { - logger.startGroup(`Interpreting results for ${language}`); + logger.startGroup( + `Interpreting ${dbAnalysisConfig.name} results for ${language}` + ); let category = automationDetailsId; if (isCodeQualityEnabled(config)) { category = fixCodeQualityCategory(logger, automationDetailsId); @@ -93632,14 +93647,16 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, } let qualityAnalysisSummary; if (isCodeQualityEnabled(config) && isCodeScanningEnabled(config)) { - logger.info(`Interpreting quality results for ${language}`); + logger.info( + `Interpreting ${CodeQuality.name} results for ${language}` + ); const qualityCategory = fixCodeQualityCategory( logger, automationDetailsId ); const qualitySarifFile = path16.join( sarifFolder, - `${language}.quality.sarif` + addSarifExtension(CodeQuality, language) ); qualityAnalysisSummary = await runInterpretResults( language, diff --git a/src/analyze.ts b/src/analyze.ts index 82f470d013..ef15d08839 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -608,6 +608,16 @@ export function resolveQuerySuiteAlias( return maybeSuite; } +/** + * Adds the appropriate file extension for the given analysis configuration to the given base filename. + */ +export function addSarifExtension( + analysis: analyses.AnalysisConfig, + base: string, +): string { + return `${base}.${analysis.sarifExtension}`; +} + // Runs queries and creates sarif files in the given folder export async function runQueries( sarifFolder: string, @@ -650,13 +660,16 @@ export async function runQueries( ? `--sarif-run-property=incrementalMode=${incrementalMode.join(",")}` : undefined; + const dbAnalysisConfig = configUtils.getDbAnalysisConfig(config); + for (const language of config.languages) { try { // If Code Scanning is enabled, then the main SARIF file is always the Code Scanning one. // Otherwise, only Code Quality is enabled, and the main SARIF file is the Code Quality one. - const sarifFile = configUtils.isCodeScanningEnabled(config) - ? path.join(sarifFolder, `${language}.sarif`) - : path.join(sarifFolder, `${language}.quality.sarif`); + const sarifFile = path.join( + sarifFolder, + addSarifExtension(dbAnalysisConfig, language), + ); // This should be empty to run only the query suite that was generated when // the database was initialised. @@ -701,7 +714,9 @@ export async function runQueries( configUtils.isCodeScanningEnabled(config) || configUtils.isCodeQualityEnabled(config) ) { - logger.startGroup(`Interpreting results for ${language}`); + logger.startGroup( + `Interpreting ${dbAnalysisConfig.name} results for ${language}`, + ); // If this is a Code Quality analysis, correct the category to one // accepted by the Code Quality backend. @@ -728,14 +743,16 @@ export async function runQueries( configUtils.isCodeQualityEnabled(config) && configUtils.isCodeScanningEnabled(config) ) { - logger.info(`Interpreting quality results for ${language}`); + logger.info( + `Interpreting ${analyses.CodeQuality.name} results for ${language}`, + ); const qualityCategory = fixCodeQualityCategory( logger, automationDetailsId, ); const qualitySarifFile = path.join( sarifFolder, - `${language}.quality.sarif`, + addSarifExtension(analyses.CodeQuality, language), ); qualityAnalysisSummary = await runInterpretResults( language, diff --git a/src/config-utils.ts b/src/config-utils.ts index d751149db3..0fcc87bd64 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -6,7 +6,13 @@ import * as yaml from "js-yaml"; import * as semver from "semver"; import { isAnalyzingPullRequest } from "./actions-util"; -import { AnalysisKind, parseAnalysisKinds } from "./analyses"; +import { + AnalysisConfig, + AnalysisKind, + CodeQuality, + CodeScanning, + parseAnalysisKinds, +} from "./analyses"; import * as api from "./api-client"; import { CachingKind, getCachingKind } from "./caching-utils"; import { type CodeQL } from "./codeql"; @@ -1522,3 +1528,28 @@ export function isCodeScanningEnabled(config: Config): boolean { export function isCodeQualityEnabled(config: Config): boolean { return config.analysisKinds.includes(AnalysisKind.CodeQuality); } + +/** + * Returns the analysis kind for which the database is initialised. This is + * always `AnalysisKind.CodeScanning` unless `AnalysisKind.CodeScanning` is not enabled. + * + * @returns Returns `AnalysisKind.CodeScanning` if `AnalysisKind.CodeScanning` is enabled; + * otherwise `AnalysisKind.CodeQuality`. + */ +export function getDbAnalysisKind(config: Config): AnalysisKind { + return isCodeScanningEnabled(config) + ? AnalysisKind.CodeScanning + : AnalysisKind.CodeQuality; +} + +/** + * Returns the analysis configuration for which the database is initialised. This is + * always `CodeScanning` unless `CodeScanning` is not enabled. + * + * @returns Returns `CodeScanning` if `AnalysisKind.CodeScanning` is enabled; otherwise `CodeQuality`. + */ +export function getDbAnalysisConfig(config: Config): AnalysisConfig { + return getDbAnalysisKind(config) === AnalysisKind.CodeScanning + ? CodeScanning + : CodeQuality; +} From 244e04cc4a97a920e5fa5c217495842320fc6381 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 1 Sep 2025 14:56:04 +0100 Subject: [PATCH 11/25] Add test with `analysisKindsInput: code-quality` --- src/config-utils.test.ts | 41 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/config-utils.test.ts b/src/config-utils.test.ts index c78ba6a33d..3feb0e96c1 100644 --- a/src/config-utils.test.ts +++ b/src/config-utils.test.ts @@ -171,6 +171,47 @@ test("load empty config", async (t) => { }); }); +test("load code quality config", async (t) => { + return await withTmpDir(async (tempDir) => { + const logger = getRunnerLogger(true); + const languages = "actions"; + + const codeql = createStubCodeQL({ + async betterResolveLanguages() { + return { + extractors: { + actions: [{ extractor_root: "" }], + }, + }; + }, + }); + + const config = await configUtils.initConfig( + createTestInitConfigInputs({ + analysisKindsInput: "code-quality", + languagesInput: languages, + repository: { owner: "github", repo: "example" }, + tempDir, + codeql, + logger, + }), + ); + + t.deepEqual( + config, + await configUtils.getDefaultConfig( + createTestInitConfigInputs({ + analysisKindsInput: "code-quality", + languagesInput: languages, + tempDir, + codeql, + logger, + }), + ), + ); + }); +}); + test("loading config saves config", async (t) => { return await withTmpDir(async (tempDir) => { const logger = getRunnerLogger(true); From 811aef84cb139f8e0a7a5886e73b2da1aee21c99 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 1 Sep 2025 15:14:57 +0100 Subject: [PATCH 12/25] Move `isDefined` from `start-proxy` to `util` --- lib/start-proxy-action.js | 6 +++--- src/start-proxy.ts | 11 +---------- src/util.ts | 9 +++++++++ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/start-proxy-action.js b/lib/start-proxy-action.js index 5881cacead..9670648c8e 100644 --- a/lib/start-proxy-action.js +++ b/lib/start-proxy-action.js @@ -47753,6 +47753,9 @@ async function delay(milliseconds, opts) { function getErrorMessage(error2) { return error2 instanceof Error ? error2.message : String(error2); } +function isDefined(value) { + return value !== void 0 && value !== null; +} // src/actions-util.ts var pkg = require_package(); @@ -47825,9 +47828,6 @@ var LANGUAGE_TO_REGISTRY_TYPE = { rust: "cargo_registry", go: "goproxy_server" }; -function isDefined(value) { - return value !== void 0 && value !== null; -} function getCredentials(logger, registrySecrets, registriesCredentials, languageString) { const language = languageString ? parseLanguage(languageString) : void 0; const registryTypeForLanguage = language ? LANGUAGE_TO_REGISTRY_TYPE[language] : void 0; diff --git a/src/start-proxy.ts b/src/start-proxy.ts index d74884bfd4..08da182918 100644 --- a/src/start-proxy.ts +++ b/src/start-proxy.ts @@ -2,7 +2,7 @@ import * as core from "@actions/core"; import { KnownLanguage } from "./languages"; import { Logger } from "./logging"; -import { ConfigurationError } from "./util"; +import { ConfigurationError, isDefined } from "./util"; export type Credential = { type: string; @@ -65,15 +65,6 @@ const LANGUAGE_TO_REGISTRY_TYPE: Partial> = { go: "goproxy_server", } as const; -/** - * Checks that `value` is neither `undefined` nor `null`. - * @param value The value to test. - * @returns Narrows the type of `value` to exclude `undefined` and `null`. - */ -function isDefined(value: T | null | undefined): value is T { - return value !== undefined && value !== null; -} - // getCredentials returns registry credentials from action inputs. // It prefers `registries_credentials` over `registry_secrets`. // If neither is set, it returns an empty array. diff --git a/src/util.ts b/src/util.ts index 1ac24ad124..5ef037636f 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1278,3 +1278,12 @@ export async function asyncSome( const results = await Promise.all(array.map(predicate)); return results.some((result) => result); } + +/** + * Checks that `value` is neither `undefined` nor `null`. + * @param value The value to test. + * @returns Narrows the type of `value` to exclude `undefined` and `null`. + */ +export function isDefined(value: T | null | undefined): value is T { + return value !== undefined && value !== null; +} From 01fe6a1120018276d76e0b980e4887bf8a830895 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 1 Sep 2025 15:59:51 +0100 Subject: [PATCH 13/25] Override query configuration for Code Quality only analyses --- lib/analyze-action-post.js | 50 +++++++++++++------------- lib/analyze-action.js | 36 +++++++++---------- lib/autobuild-action.js | 36 +++++++++---------- lib/init-action-post.js | 50 +++++++++++++------------- lib/init-action.js | 60 +++++++++++++++++++++---------- lib/resolve-environment-action.js | 36 +++++++++---------- lib/start-proxy-action-post.js | 50 +++++++++++++------------- lib/upload-lib.js | 36 +++++++++---------- lib/upload-sarif-action-post.js | 50 +++++++++++++------------- lib/upload-sarif-action.js | 36 +++++++++---------- src/config-utils.test.ts | 42 +++++++++++++++------- src/config-utils.ts | 38 ++++++++++++++++++++ 12 files changed, 300 insertions(+), 220 deletions(-) diff --git a/lib/analyze-action-post.js b/lib/analyze-action-post.js index 5398605d40..3a10dad154 100644 --- a/lib/analyze-action-post.js +++ b/lib/analyze-action-post.js @@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -31821,14 +31821,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -31839,7 +31839,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); @@ -102910,7 +102910,7 @@ var require_dist_node16 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -102918,7 +102918,7 @@ var require_dist_node16 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -102928,12 +102928,12 @@ var require_dist_node16 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push(encodeValue(operator, value2, isKeyOperator(operator) ? key : "")); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -102941,12 +102941,12 @@ var require_dist_node16 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -102961,7 +102961,7 @@ var require_dist_node16 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 9f00316aaa..65e6befe3d 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -37670,14 +37670,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -37688,7 +37688,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); diff --git a/lib/autobuild-action.js b/lib/autobuild-action.js index 931f34583c..bfab5e3375 100644 --- a/lib/autobuild-action.js +++ b/lib/autobuild-action.js @@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -31821,14 +31821,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -31839,7 +31839,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 490414bdbb..558d20426c 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context3, operator, key, modifier) { var value = context3[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context3, operator, key, modifier) { var value = context3[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -37670,14 +37670,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -37688,7 +37688,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); @@ -108759,7 +108759,7 @@ var require_dist_node16 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -108767,7 +108767,7 @@ var require_dist_node16 = __commonJS({ } function getValues(context3, operator, key, modifier) { var value = context3[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -108777,12 +108777,12 @@ var require_dist_node16 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push(encodeValue(operator, value2, isKeyOperator(operator) ? key : "")); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -108790,12 +108790,12 @@ var require_dist_node16 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -108810,7 +108810,7 @@ var require_dist_node16 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { diff --git a/lib/init-action.js b/lib/init-action.js index c7db9fb5f1..367504727a 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -22196,7 +22196,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -22204,7 +22204,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -22216,14 +22216,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -22231,12 +22231,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -22251,7 +22251,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -22936,7 +22936,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -22944,7 +22944,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -22956,14 +22956,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -22971,12 +22971,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -22991,7 +22991,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -37670,14 +37670,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -37688,7 +37688,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); @@ -85778,6 +85778,9 @@ async function asyncSome(array, predicate) { const results = await Promise.all(array.map(predicate)); return results.some((result) => result); } +function isDefined(value) { + return value !== void 0 && value !== null; +} // src/actions-util.ts var pkg = require_package(); @@ -86167,6 +86170,7 @@ async function parseAnalysisKinds(input) { new Set(components.map((component) => component)) ); } +var codeQualityQueries = ["code-quality"]; // src/feature-flags.ts var fs7 = __toESM(require("fs")); @@ -87578,6 +87582,9 @@ function dbLocationOrDefault(dbLocation, tempDir) { function userConfigFromActionPath(tempDir) { return path10.resolve(tempDir, "user-config-from-action.yml"); } +function hasQueryCustomisation(userConfig) { + return isDefined(userConfig["disable-default-queries"]) || isDefined(userConfig.queries) || isDefined(userConfig["query-filters"]); +} async function initConfig(inputs) { const { logger, tempDir } = inputs; if (inputs.configInput) { @@ -87603,6 +87610,20 @@ async function initConfig(inputs) { ); } const config = await initActionState(inputs, userConfig); + if (!isCodeScanningEnabled(config)) { + if (hasQueryCustomisation(config.computedConfig)) { + logger.warning( + "Query customizations will be ignored, because only `code-quality` analysis is enabled." + ); + } + const queries = codeQualityQueries.map((v) => ({ uses: v })); + config.originalUserInput["disable-default-queries"] = true; + config.originalUserInput.queries = queries; + config.originalUserInput["query-filters"] = []; + config.computedConfig["disable-default-queries"] = true; + config.computedConfig.queries = queries; + config.computedConfig["query-filters"] = []; + } const { overlayDatabaseMode, useOverlayDatabaseCaching } = await getOverlayDatabaseMode( inputs.codeql, inputs.repository, @@ -87836,6 +87857,9 @@ function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { } return augmentedConfig; } +function isCodeScanningEnabled(config) { + return config.analysisKinds.includes("code-scanning" /* CodeScanning */); +} // src/dependency-caching.ts var os2 = __toESM(require("os")); diff --git a/lib/resolve-environment-action.js b/lib/resolve-environment-action.js index eb4c0b59f6..976a012f65 100644 --- a/lib/resolve-environment-action.js +++ b/lib/resolve-environment-action.js @@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -31821,14 +31821,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -31839,7 +31839,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); diff --git a/lib/start-proxy-action-post.js b/lib/start-proxy-action-post.js index 5083c32fdd..b85291f996 100644 --- a/lib/start-proxy-action-post.js +++ b/lib/start-proxy-action-post.js @@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -31821,14 +31821,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -31839,7 +31839,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); @@ -101570,7 +101570,7 @@ var require_dist_node16 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -101578,7 +101578,7 @@ var require_dist_node16 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -101588,12 +101588,12 @@ var require_dist_node16 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push(encodeValue(operator, value2, isKeyOperator(operator) ? key : "")); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -101601,12 +101601,12 @@ var require_dist_node16 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -101621,7 +101621,7 @@ var require_dist_node16 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { diff --git a/lib/upload-lib.js b/lib/upload-lib.js index e13493f1fd..b3acaa33d8 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -21585,7 +21585,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21593,7 +21593,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21605,14 +21605,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21620,12 +21620,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21640,7 +21640,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -22325,7 +22325,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -22333,7 +22333,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -22345,14 +22345,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -22360,12 +22360,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -22380,7 +22380,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -38967,14 +38967,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -38985,7 +38985,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); diff --git a/lib/upload-sarif-action-post.js b/lib/upload-sarif-action-post.js index a704d103e7..503f515c31 100644 --- a/lib/upload-sarif-action-post.js +++ b/lib/upload-sarif-action-post.js @@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -35658,14 +35658,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -35676,7 +35676,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); @@ -95692,7 +95692,7 @@ var require_dist_node16 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -95700,7 +95700,7 @@ var require_dist_node16 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -95710,12 +95710,12 @@ var require_dist_node16 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push(encodeValue(operator, value2, isKeyOperator(operator) ? key : "")); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -95723,12 +95723,12 @@ var require_dist_node16 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -95743,7 +95743,7 @@ var require_dist_node16 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index 980ef151fa..6d5a9c8f7a 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -37670,14 +37670,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -37688,7 +37688,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); diff --git a/src/config-utils.test.ts b/src/config-utils.test.ts index 3feb0e96c1..d42a5e2091 100644 --- a/src/config-utils.test.ts +++ b/src/config-utils.test.ts @@ -197,18 +197,36 @@ test("load code quality config", async (t) => { }), ); - t.deepEqual( - config, - await configUtils.getDefaultConfig( - createTestInitConfigInputs({ - analysisKindsInput: "code-quality", - languagesInput: languages, - tempDir, - codeql, - logger, - }), - ), - ); + const userConfig: configUtils.UserConfig = { + "disable-default-queries": true, + queries: [{ uses: "code-quality" }], + "query-filters": [], + }; + + // And the config we expect it to result in + const expectedConfig: configUtils.Config = { + analysisKinds: [AnalysisKind.CodeQuality], + languages: [KnownLanguage.actions], + buildMode: undefined, + // This gets set because we only have `AnalysisKind.CodeQuality` + originalUserInput: userConfig, + computedConfig: userConfig, + tempDir, + codeQLCmd: codeql.getPath(), + gitHubVersion: githubVersion, + dbLocation: path.resolve(tempDir, "codeql_databases"), + debugMode: false, + debugArtifactName: "", + debugDatabaseName: "", + trapCaches: {}, + trapCacheDownloadTime: 0, + dependencyCachingEnabled: CachingKind.None, + extraQueryExclusions: [], + overlayDatabaseMode: OverlayDatabaseMode.None, + useOverlayDatabaseCaching: false, + }; + + t.deepEqual(config, expectedConfig); }); }); diff --git a/src/config-utils.ts b/src/config-utils.ts index 0fcc87bd64..6e99bb7372 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -10,6 +10,7 @@ import { AnalysisConfig, AnalysisKind, CodeQuality, + codeQualityQueries, CodeScanning, parseAnalysisKinds, } from "./analyses"; @@ -34,6 +35,7 @@ import { BuildMode, codeQlVersionAtLeast, cloneObject, + isDefined, } from "./util"; // Property names from the user-supplied config file. @@ -1080,6 +1082,19 @@ function userConfigFromActionPath(tempDir: string): string { return path.resolve(tempDir, "user-config-from-action.yml"); } +/** + * Checks whether the given `UserConfig` contains any query customisations. + * + * @returns Returns `true` if the `UserConfig` customises which queries are run. + */ +function hasQueryCustomisation(userConfig: UserConfig): boolean { + return ( + isDefined(userConfig["disable-default-queries"]) || + isDefined(userConfig.queries) || + isDefined(userConfig["query-filters"]) + ); +} + /** * Load and return the config. * @@ -1116,6 +1131,29 @@ export async function initConfig(inputs: InitConfigInputs): Promise { const config = await initActionState(inputs, userConfig); + // If Code Scanning analysis is disabled, then we initialise the database for Code Quality. + // That entails disabling the default queries and only running quality queries. + if (!isCodeScanningEnabled(config)) { + // Warn if any query customisations are present in the computed configuration. + if (hasQueryCustomisation(config.computedConfig)) { + logger.warning( + "Query customizations will be ignored, because only `code-quality` analysis is enabled.", + ); + } + + const queries = codeQualityQueries.map((v) => ({ uses: v })); + + // Set the query customisation options for Code Quality only analysis. + config.originalUserInput["disable-default-queries"] = true; + config.originalUserInput.queries = queries; + config.originalUserInput["query-filters"] = []; + + // Update the computed configuration for the call to `getOverlayDatabaseMode`. + config.computedConfig["disable-default-queries"] = true; + config.computedConfig.queries = queries; + config.computedConfig["query-filters"] = []; + } + // The choice of overlay database mode depends on the selection of languages // and queries, which in turn depends on the user config and the augmentation // properties. So we need to calculate the overlay database mode after the From 86275f6e9a11cb69e98fd5dafd4dc3e6c87c25a7 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 1 Sep 2025 16:11:03 +0100 Subject: [PATCH 14/25] Fix `addSarifExtension` and add tests --- lib/analyze-action.js | 2 +- src/analyze.test.ts | 12 ++++++++++++ src/analyze.ts | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 65e6befe3d..482c573b83 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -93586,7 +93586,7 @@ function resolveQuerySuiteAlias(language, maybeSuite) { return maybeSuite; } function addSarifExtension(analysis, base) { - return `${base}.${analysis.sarifExtension}`; + return `${base}${analysis.sarifExtension}`; } async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, diffRangePackDir, automationDetailsId, codeql, config, logger, features) { const statusReport = {}; diff --git a/src/analyze.test.ts b/src/analyze.test.ts index e957b73843..305d41d241 100644 --- a/src/analyze.test.ts +++ b/src/analyze.test.ts @@ -5,11 +5,13 @@ import test from "ava"; import * as sinon from "sinon"; import * as actionsUtil from "./actions-util"; +import { CodeQuality, CodeScanning } from "./analyses"; import { exportedForTesting, runQueries, defaultSuites, resolveQuerySuiteAlias, + addSarifExtension, } from "./analyze"; import { createStubCodeQL } from "./codeql"; import { Feature } from "./feature-flags"; @@ -348,3 +350,13 @@ test("resolveQuerySuiteAlias", (t) => { t.deepEqual(resolveQuerySuiteAlias(KnownLanguage.go, name), name); } }); + +test("addSarifExtension", (t) => { + for (const language of Object.values(KnownLanguage)) { + t.deepEqual(addSarifExtension(CodeScanning, language), `${language}.sarif`); + t.deepEqual( + addSarifExtension(CodeQuality, language), + `${language}.quality.sarif`, + ); + } +}); diff --git a/src/analyze.ts b/src/analyze.ts index ef15d08839..f4ebdffa9d 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -615,7 +615,7 @@ export function addSarifExtension( analysis: analyses.AnalysisConfig, base: string, ): string { - return `${base}.${analysis.sarifExtension}`; + return `${base}${analysis.sarifExtension}`; } // Runs queries and creates sarif files in the given folder From 7baedbc3b8af7961a84479192b0499be0cd72e7e Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 1 Sep 2025 16:44:31 +0100 Subject: [PATCH 15/25] Check if Code Scanning is enabled before uploading Code Scanning SARIF --- lib/analyze-action.js | 20 +++++++++++--------- src/analyze-action.ts | 27 +++++++++++++++++---------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 482c573b83..c73256b981 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -95978,15 +95978,17 @@ async function run() { core14.setOutput("sarif-output", import_path4.default.resolve(outputDir)); const uploadInput = getOptionalInput("upload"); if (runStats && getUploadValue(uploadInput) === "always") { - uploadResult = await uploadFiles( - outputDir, - getRequiredInput("checkout_path"), - getOptionalInput("category"), - features, - logger, - CodeScanning - ); - core14.setOutput("sarif-id", uploadResult.sarifID); + if (isCodeScanningEnabled(config)) { + uploadResult = await uploadFiles( + outputDir, + getRequiredInput("checkout_path"), + getOptionalInput("category"), + features, + logger, + CodeScanning + ); + core14.setOutput("sarif-id", uploadResult.sarifID); + } if (isCodeQualityEnabled(config)) { const qualityUploadResult = await uploadFiles( outputDir, diff --git a/src/analyze-action.ts b/src/analyze-action.ts index c949e3d4d7..f93072d723 100644 --- a/src/analyze-action.ts +++ b/src/analyze-action.ts @@ -19,7 +19,12 @@ import { getApiDetails, getGitHubVersion } from "./api-client"; import { runAutobuild } from "./autobuild"; import { getTotalCacheSize, shouldStoreCache } from "./caching-utils"; import { getCodeQL } from "./codeql"; -import { Config, getConfig, isCodeQualityEnabled } from "./config-utils"; +import { + Config, + getConfig, + isCodeQualityEnabled, + isCodeScanningEnabled, +} from "./config-utils"; import { uploadDatabases } from "./database-upload"; import { uploadDependencyCaches } from "./dependency-caching"; import { getDiffInformedAnalysisBranches } from "./diff-informed-analysis-utils"; @@ -327,15 +332,17 @@ async function run() { core.setOutput("sarif-output", path.resolve(outputDir)); const uploadInput = actionsUtil.getOptionalInput("upload"); if (runStats && actionsUtil.getUploadValue(uploadInput) === "always") { - uploadResult = await uploadLib.uploadFiles( - outputDir, - actionsUtil.getRequiredInput("checkout_path"), - actionsUtil.getOptionalInput("category"), - features, - logger, - analyses.CodeScanning, - ); - core.setOutput("sarif-id", uploadResult.sarifID); + if (isCodeScanningEnabled(config)) { + uploadResult = await uploadLib.uploadFiles( + outputDir, + actionsUtil.getRequiredInput("checkout_path"), + actionsUtil.getOptionalInput("category"), + features, + logger, + analyses.CodeScanning, + ); + core.setOutput("sarif-id", uploadResult.sarifID); + } if (isCodeQualityEnabled(config)) { const qualityUploadResult = await uploadLib.uploadFiles( From 3ee9287c7a0dd4982d0eb5e8f663893f1f70c26d Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 2 Sep 2025 08:45:16 +0100 Subject: [PATCH 16/25] Update condition and comment for CQ-only config --- lib/init-action.js | 6 +++--- src/config-utils.ts | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/init-action.js b/lib/init-action.js index 367504727a..80acb0820f 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -87610,7 +87610,7 @@ async function initConfig(inputs) { ); } const config = await initActionState(inputs, userConfig); - if (!isCodeScanningEnabled(config)) { + if (config.analysisKinds.length === 1 && isCodeQualityEnabled(config)) { if (hasQueryCustomisation(config.computedConfig)) { logger.warning( "Query customizations will be ignored, because only `code-quality` analysis is enabled." @@ -87857,8 +87857,8 @@ function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { } return augmentedConfig; } -function isCodeScanningEnabled(config) { - return config.analysisKinds.includes("code-scanning" /* CodeScanning */); +function isCodeQualityEnabled(config) { + return config.analysisKinds.includes("code-quality" /* CodeQuality */); } // src/dependency-caching.ts diff --git a/src/config-utils.ts b/src/config-utils.ts index 6e99bb7372..a66e63e13b 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -1131,9 +1131,10 @@ export async function initConfig(inputs: InitConfigInputs): Promise { const config = await initActionState(inputs, userConfig); - // If Code Scanning analysis is disabled, then we initialise the database for Code Quality. - // That entails disabling the default queries and only running quality queries. - if (!isCodeScanningEnabled(config)) { + // If Code Quality analysis is the only enabled analysis kind, then we will initialise + // the database for Code Quality. That entails disabling the default queries and only + // running quality queries. We do not currently support query customisations in that case. + if (config.analysisKinds.length === 1 && isCodeQualityEnabled(config)) { // Warn if any query customisations are present in the computed configuration. if (hasQueryCustomisation(config.computedConfig)) { logger.warning( From 51d74ac81c96d2ae0667521957d5a00873dbef49 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 2 Sep 2025 08:51:55 +0100 Subject: [PATCH 17/25] Remove default arguments from `uploadSpecifiedFiles` and `validateUniqueCategory` --- lib/analyze-action.js | 4 +- lib/init-action-post.js | 4 +- lib/upload-lib.js | 36 ++----- lib/upload-sarif-action.js | 4 +- src/upload-lib.test.ts | 215 ++++++++++++++++++++++++++++++------- src/upload-lib.ts | 4 +- 6 files changed, 195 insertions(+), 72 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index c73256b981..c7fa77f579 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -95557,7 +95557,7 @@ async function uploadFiles(inputSarifPath, checkoutPath, category, features, log uploadTarget ); } -async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanning) { +async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget) { logger.startGroup(`Uploading ${uploadTarget.name} results`); logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`); const gitHubVersion = await getGitHubVersion(); @@ -95728,7 +95728,7 @@ function handleProcessingResultForUnsuccessfulExecution(response, status, logger assertNever(status); } } -function validateUniqueCategory(sarif, sentinelPrefix = CodeScanning.sentinelPrefix) { +function validateUniqueCategory(sarif, sentinelPrefix) { const categories = {}; for (const run2 of sarif.runs) { const id = run2?.automationDetails?.id; diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 558d20426c..be33782791 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -133010,7 +133010,7 @@ async function uploadFiles(inputSarifPath, checkoutPath, category, features, log uploadTarget ); } -async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanning) { +async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget) { logger.startGroup(`Uploading ${uploadTarget.name} results`); logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`); const gitHubVersion = await getGitHubVersion(); @@ -133181,7 +133181,7 @@ function handleProcessingResultForUnsuccessfulExecution(response, status, logger assertNever(status); } } -function validateUniqueCategory(sarif, sentinelPrefix = CodeScanning.sentinelPrefix) { +function validateUniqueCategory(sarif, sentinelPrefix) { const categories = {}; for (const run2 of sarif.runs) { const id = run2?.automationDetails?.id; diff --git a/lib/upload-lib.js b/lib/upload-lib.js index b3acaa33d8..2483ea10e7 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -88490,30 +88490,6 @@ async function runTool(cmd, args = [], opts = {}) { return stdout; } -// src/analyses.ts -var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { - AnalysisKind2["CodeScanning"] = "code-scanning"; - AnalysisKind2["CodeQuality"] = "code-quality"; - return AnalysisKind2; -})(AnalysisKind || {}); -var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); -var CodeScanning = { - kind: "code-scanning" /* 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), - sentinelPrefix: "CODEQL_UPLOAD_SARIF_" -}; -var CodeQuality = { - kind: "code-quality" /* CodeQuality */, - name: "code quality", - target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, - sarifExtension: ".quality.sarif", - sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension), - sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" -}; - // src/api-client.ts var core5 = __toESM(require_core()); var githubUtils = __toESM(require_utils4()); @@ -88898,6 +88874,14 @@ var fs7 = __toESM(require("fs")); var path9 = __toESM(require("path")); var semver4 = __toESM(require_semver2()); +// src/analyses.ts +var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { + AnalysisKind2["CodeScanning"] = "code-scanning"; + AnalysisKind2["CodeQuality"] = "code-quality"; + return AnalysisKind2; +})(AnalysisKind || {}); +var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); + // src/caching-utils.ts var core6 = __toESM(require_core()); @@ -92398,7 +92382,7 @@ async function uploadFiles(inputSarifPath, checkoutPath, category, features, log uploadTarget ); } -async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanning) { +async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget) { logger.startGroup(`Uploading ${uploadTarget.name} results`); logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`); const gitHubVersion = await getGitHubVersion(); @@ -92569,7 +92553,7 @@ function handleProcessingResultForUnsuccessfulExecution(response, status, logger assertNever(status); } } -function validateUniqueCategory(sarif, sentinelPrefix = CodeScanning.sentinelPrefix) { +function validateUniqueCategory(sarif, sentinelPrefix) { const categories = {}; for (const run of sarif.runs) { const id = run?.automationDetails?.id; diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index 6d5a9c8f7a..7fed9664be 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -93083,7 +93083,7 @@ async function uploadFiles(inputSarifPath, checkoutPath, category, features, log uploadTarget ); } -async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanning) { +async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget) { logger.startGroup(`Uploading ${uploadTarget.name} results`); logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`); const gitHubVersion = await getGitHubVersion(); @@ -93254,7 +93254,7 @@ function handleProcessingResultForUnsuccessfulExecution(response, status, logger assertNever(status); } } -function validateUniqueCategory(sarif, sentinelPrefix = CodeScanning.sentinelPrefix) { +function validateUniqueCategory(sarif, sentinelPrefix) { const categories = {}; for (const run2 of sarif.runs) { const id = run2?.automationDetails?.id; diff --git a/src/upload-lib.test.ts b/src/upload-lib.test.ts index 3e463b9441..bfa5e9844c 100644 --- a/src/upload-lib.test.ts +++ b/src/upload-lib.test.ts @@ -212,109 +212,237 @@ test("populateRunAutomationDetails", (t) => { }); test("validateUniqueCategory when empty", (t) => { - t.notThrows(() => uploadLib.validateUniqueCategory(createMockSarif())); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif())); + t.notThrows(() => + uploadLib.validateUniqueCategory( + createMockSarif(), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif(), + CodeScanning.sentinelPrefix, + ), + ); }); test("validateUniqueCategory for automation details id", (t) => { - t.notThrows(() => uploadLib.validateUniqueCategory(createMockSarif("abc"))); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc"))); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("AbC"))); + t.notThrows(() => + uploadLib.validateUniqueCategory( + createMockSarif("abc"), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif("abc"), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif("AbC"), + CodeScanning.sentinelPrefix, + ), + ); - t.notThrows(() => uploadLib.validateUniqueCategory(createMockSarif("def"))); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("def"))); + t.notThrows(() => + uploadLib.validateUniqueCategory( + createMockSarif("def"), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif("def"), + CodeScanning.sentinelPrefix, + ), + ); // Our category sanitization is not perfect. Here are some examples // of where we see false clashes t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif("abc/def")), + uploadLib.validateUniqueCategory( + createMockSarif("abc/def"), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif("abc@def"), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif("abc_def"), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif("abc def"), + CodeScanning.sentinelPrefix, + ), ); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc@def"))); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc_def"))); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc def"))); // this one is fine t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif("abc_ def")), + uploadLib.validateUniqueCategory( + createMockSarif("abc_ def"), + CodeScanning.sentinelPrefix, + ), ); }); test("validateUniqueCategory for tool name", (t) => { t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "abc"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "abc"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "AbC")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "AbC"), + CodeScanning.sentinelPrefix, + ), ); t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "def")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "def"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "def")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "def"), + CodeScanning.sentinelPrefix, + ), ); // Our category sanitization is not perfect. Here are some examples // of where we see false clashes t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc/def")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "abc/def"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc@def")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "abc@def"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc_def")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "abc_def"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc def")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "abc def"), + CodeScanning.sentinelPrefix, + ), ); // this one is fine t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif("abc_ def")), + uploadLib.validateUniqueCategory( + createMockSarif("abc_ def"), + CodeScanning.sentinelPrefix, + ), ); }); test("validateUniqueCategory for automation details id and tool name", (t) => { t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif("abc", "abc")), + uploadLib.validateUniqueCategory( + createMockSarif("abc", "abc"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif("abc", "abc")), + uploadLib.validateUniqueCategory( + createMockSarif("abc", "abc"), + CodeScanning.sentinelPrefix, + ), ); t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif("abc_", "def")), + uploadLib.validateUniqueCategory( + createMockSarif("abc_", "def"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif("abc_", "def")), + uploadLib.validateUniqueCategory( + createMockSarif("abc_", "def"), + CodeScanning.sentinelPrefix, + ), ); t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif("ghi", "_jkl")), + uploadLib.validateUniqueCategory( + createMockSarif("ghi", "_jkl"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif("ghi", "_jkl")), + uploadLib.validateUniqueCategory( + createMockSarif("ghi", "_jkl"), + CodeScanning.sentinelPrefix, + ), ); // Our category sanitization is not perfect. Here are some examples // of where we see false clashes - t.notThrows(() => uploadLib.validateUniqueCategory(createMockSarif("abc"))); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc", "_"))); + t.notThrows(() => + uploadLib.validateUniqueCategory( + createMockSarif("abc"), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif("abc", "_"), + CodeScanning.sentinelPrefix, + ), + ); t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif("abc", "def__")), + uploadLib.validateUniqueCategory( + createMockSarif("abc", "def__"), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif("abc_def"), + CodeScanning.sentinelPrefix, + ), ); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc_def"))); t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif("mno_", "pqr")), + uploadLib.validateUniqueCategory( + createMockSarif("mno_", "pqr"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif("mno", "_pqr")), + uploadLib.validateUniqueCategory( + createMockSarif("mno", "_pqr"), + CodeScanning.sentinelPrefix, + ), ); }); @@ -324,15 +452,26 @@ test("validateUniqueCategory for multiple runs", (t) => { // duplicate categories are allowed within the same sarif file const multiSarif = { runs: [sarif1.runs[0], sarif1.runs[0], sarif2.runs[0]] }; - t.notThrows(() => uploadLib.validateUniqueCategory(multiSarif)); + t.notThrows(() => + uploadLib.validateUniqueCategory(multiSarif, CodeScanning.sentinelPrefix), + ); // should throw if there are duplicate categories in separate validations - t.throws(() => uploadLib.validateUniqueCategory(sarif1)); - t.throws(() => uploadLib.validateUniqueCategory(sarif2)); + t.throws(() => + uploadLib.validateUniqueCategory(sarif1, CodeScanning.sentinelPrefix), + ); + t.throws(() => + uploadLib.validateUniqueCategory(sarif2, CodeScanning.sentinelPrefix), + ); }); test("validateUniqueCategory with different prefixes", (t) => { - t.notThrows(() => uploadLib.validateUniqueCategory(createMockSarif())); + t.notThrows(() => + uploadLib.validateUniqueCategory( + createMockSarif(), + CodeScanning.sentinelPrefix, + ), + ); t.notThrows(() => uploadLib.validateUniqueCategory( createMockSarif(), diff --git a/src/upload-lib.ts b/src/upload-lib.ts index cd11b8e3f7..8939e16944 100644 --- a/src/upload-lib.ts +++ b/src/upload-lib.ts @@ -647,7 +647,7 @@ export async function uploadSpecifiedFiles( category: string | undefined, features: FeatureEnablement, logger: Logger, - uploadTarget: analyses.AnalysisConfig = analyses.CodeScanning, + uploadTarget: analyses.AnalysisConfig, ): Promise { logger.startGroup(`Uploading ${uploadTarget.name} results`); logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`); @@ -913,7 +913,7 @@ function handleProcessingResultForUnsuccessfulExecution( export function validateUniqueCategory( sarif: SarifFile, - sentinelPrefix: string = analyses.CodeScanning.sentinelPrefix, + sentinelPrefix: string, ): void { // duplicate categories are allowed in the same sarif file // but not across multiple sarif files From f4fca705906ad1da7ffa833c67db6c7b840b8abc Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 2 Sep 2025 12:27:58 +0100 Subject: [PATCH 18/25] Do not mutate `originalUserInput` --- lib/init-action.js | 3 --- src/config-utils.test.ts | 14 ++++++-------- src/config-utils.ts | 5 ----- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/lib/init-action.js b/lib/init-action.js index 80acb0820f..381d2061ef 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -87617,9 +87617,6 @@ async function initConfig(inputs) { ); } const queries = codeQualityQueries.map((v) => ({ uses: v })); - config.originalUserInput["disable-default-queries"] = true; - config.originalUserInput.queries = queries; - config.originalUserInput["query-filters"] = []; config.computedConfig["disable-default-queries"] = true; config.computedConfig.queries = queries; config.computedConfig["query-filters"] = []; diff --git a/src/config-utils.test.ts b/src/config-utils.test.ts index d42a5e2091..9526a4b8a9 100644 --- a/src/config-utils.test.ts +++ b/src/config-utils.test.ts @@ -197,20 +197,18 @@ test("load code quality config", async (t) => { }), ); - const userConfig: configUtils.UserConfig = { - "disable-default-queries": true, - queries: [{ uses: "code-quality" }], - "query-filters": [], - }; - // And the config we expect it to result in const expectedConfig: configUtils.Config = { analysisKinds: [AnalysisKind.CodeQuality], languages: [KnownLanguage.actions], buildMode: undefined, + originalUserInput: {}, // This gets set because we only have `AnalysisKind.CodeQuality` - originalUserInput: userConfig, - computedConfig: userConfig, + computedConfig: { + "disable-default-queries": true, + queries: [{ uses: "code-quality" }], + "query-filters": [], + }, tempDir, codeQLCmd: codeql.getPath(), gitHubVersion: githubVersion, diff --git a/src/config-utils.ts b/src/config-utils.ts index a66e63e13b..1041ad5146 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -1145,11 +1145,6 @@ export async function initConfig(inputs: InitConfigInputs): Promise { const queries = codeQualityQueries.map((v) => ({ uses: v })); // Set the query customisation options for Code Quality only analysis. - config.originalUserInput["disable-default-queries"] = true; - config.originalUserInput.queries = queries; - config.originalUserInput["query-filters"] = []; - - // Update the computed configuration for the call to `getOverlayDatabaseMode`. config.computedConfig["disable-default-queries"] = true; config.computedConfig.queries = queries; config.computedConfig["query-filters"] = []; From ae2df706294002e7c3fddd882c61a3ea7ac3ab32 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 4 Sep 2025 12:03:24 +0100 Subject: [PATCH 19/25] Make code that builds the list of queries for `run-queries` more robust in the event of future changes --- lib/analyze-action.js | 8 +++++--- src/analyze.ts | 21 ++++++++++----------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index c7fa77f579..65a522dfea 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -93615,10 +93615,12 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, addSarifExtension(dbAnalysisConfig, language) ); const queries = []; - if (isCodeQualityEnabled(config) && isCodeScanningEnabled(config)) { + if (config.analysisKinds.length > 1) { queries.push(getGeneratedSuitePath(config, language)); - for (const qualityQuery of codeQualityQueries) { - queries.push(resolveQuerySuiteAlias(language, qualityQuery)); + if (isCodeQualityEnabled(config)) { + for (const qualityQuery of codeQualityQueries) { + queries.push(resolveQuerySuiteAlias(language, qualityQuery)); + } } } logger.startGroup(`Running queries for ${language}`); diff --git a/src/analyze.ts b/src/analyze.ts index f4ebdffa9d..31c809e725 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -675,18 +675,17 @@ export async function runQueries( // the database was initialised. const queries: string[] = []; - // If both Code Scanning and Code Quality analyses are enabled, the database - // is initialised for Code Scanning. To avoid duplicate work, we want to run - // queries for both analyses at the same time. To do this, we invoke `run-queries` - // once with the generated query suite for Code Scanning + the fixed - // query suite for Code Quality. - if ( - configUtils.isCodeQualityEnabled(config) && - configUtils.isCodeScanningEnabled(config) - ) { + // If multiple analysis kinds are enabled, the database is initialised for Code Scanning. + // To avoid duplicate work, we want to run queries for all analyses at the same time. + // To do this, we invoke `run-queries` once with the generated query suite that was created + // when the database was initialised + the queries for other analysis kinds. + if (config.analysisKinds.length > 1) { queries.push(util.getGeneratedSuitePath(config, language)); - for (const qualityQuery of analyses.codeQualityQueries) { - queries.push(resolveQuerySuiteAlias(language, qualityQuery)); + + if (configUtils.isCodeQualityEnabled(config)) { + for (const qualityQuery of analyses.codeQualityQueries) { + queries.push(resolveQuerySuiteAlias(language, qualityQuery)); + } } } From d08e9a2e041f33e595e36c918f135cfb43c94acf Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 4 Sep 2025 12:14:12 +0100 Subject: [PATCH 20/25] Make conditions for `interpret-results` more robust --- lib/analyze-action.js | 37 +++++++++++++--------------- src/analyze.ts | 56 ++++++++++++++++++------------------------- 2 files changed, 39 insertions(+), 54 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 65a522dfea..4d54f824dd 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -93629,26 +93629,23 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, await codeql.databaseRunQueries(databasePath, queryFlags, queries); logger.debug(`Finished running queries for ${language}.`); statusReport[`analyze_builtin_queries_${language}_duration_ms`] = (/* @__PURE__ */ new Date()).getTime() - startTimeRunQueries; - const startTimeInterpretResults = /* @__PURE__ */ new Date(); - let analysisSummary; - if (isCodeScanningEnabled(config) || isCodeQualityEnabled(config)) { - logger.startGroup( - `Interpreting ${dbAnalysisConfig.name} results for ${language}` - ); - let category = automationDetailsId; - if (isCodeQualityEnabled(config)) { - category = fixCodeQualityCategory(logger, automationDetailsId); - } - analysisSummary = await runInterpretResults( - language, - void 0, - sarifFile, - config.debugMode, - category - ); + logger.startGroup( + `Interpreting ${dbAnalysisConfig.name} results for ${language}` + ); + let category = automationDetailsId; + if (dbAnalysisConfig.kind === "code-quality" /* CodeQuality */) { + category = fixCodeQualityCategory(logger, automationDetailsId); } + const startTimeInterpretResults = /* @__PURE__ */ new Date(); + const analysisSummary = await runInterpretResults( + language, + void 0, + sarifFile, + config.debugMode, + category + ); let qualityAnalysisSummary; - if (isCodeQualityEnabled(config) && isCodeScanningEnabled(config)) { + if (config.analysisKinds.length > 1 && isCodeQualityEnabled(config)) { logger.info( `Interpreting ${CodeQuality.name} results for ${language}` ); @@ -93673,9 +93670,7 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, const endTimeInterpretResults = /* @__PURE__ */ new Date(); statusReport[`interpret_results_${language}_duration_ms`] = endTimeInterpretResults.getTime() - startTimeInterpretResults.getTime(); logger.endGroup(); - if (analysisSummary) { - logger.info(analysisSummary); - } + logger.info(analysisSummary); if (qualityAnalysisSummary) { logger.info(qualityAnalysisSummary); } diff --git a/src/analyze.ts b/src/analyze.ts index 31c809e725..e7a7cab8a5 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -703,44 +703,36 @@ export async function runQueries( statusReport[`analyze_builtin_queries_${language}_duration_ms`] = new Date().getTime() - startTimeRunQueries; - const startTimeInterpretResults = new Date(); - - // If only one analysis kind is enabled, then the database is initialised for the - // respective set of queries. Therefore, running `interpret-results` produces the - // SARIF file we want for the one enabled analysis kind. - let analysisSummary: string | undefined; - if ( - configUtils.isCodeScanningEnabled(config) || - configUtils.isCodeQualityEnabled(config) - ) { - logger.startGroup( - `Interpreting ${dbAnalysisConfig.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 (configUtils.isCodeQualityEnabled(config)) { - category = fixCodeQualityCategory(logger, automationDetailsId); - } + // There is always at least one analysis kind enabled. Running `interpret-results` + // produces the SARIF file for the analysis kind that the database was initialised with. + logger.startGroup( + `Interpreting ${dbAnalysisConfig.name} results for ${language}`, + ); - analysisSummary = await runInterpretResults( - language, - undefined, - sarifFile, - config.debugMode, - category, - ); + // If this is a Code Quality analysis, correct the category to one + // accepted by the Code Quality backend. + let category = automationDetailsId; + if (dbAnalysisConfig.kind === analyses.AnalysisKind.CodeQuality) { + category = fixCodeQualityCategory(logger, automationDetailsId); } - // This case is only needed if Code Quality is enabled in addition to Code Scanning. + const startTimeInterpretResults = new Date(); + const analysisSummary = await runInterpretResults( + language, + undefined, + sarifFile, + config.debugMode, + category, + ); + + // This case is only needed if Code Quality is not the sole analysis kind. // In this case, we will have run queries for both analysis kinds. The previous call to // `interpret-results` will have produced a SARIF file for Code Scanning and we now // need to produce an additional SARIF file for Code Quality. let qualityAnalysisSummary: string | undefined; if ( - configUtils.isCodeQualityEnabled(config) && - configUtils.isCodeScanningEnabled(config) + config.analysisKinds.length > 1 && + configUtils.isCodeQualityEnabled(config) ) { logger.info( `Interpreting ${analyses.CodeQuality.name} results for ${language}`, @@ -768,9 +760,7 @@ export async function runQueries( endTimeInterpretResults.getTime() - startTimeInterpretResults.getTime(); logger.endGroup(); - if (analysisSummary) { - logger.info(analysisSummary); - } + logger.info(analysisSummary); if (qualityAnalysisSummary) { logger.info(qualityAnalysisSummary); } From 38f1a701791c22c7bcf5f7e3b288424a7e991f62 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 4 Sep 2025 12:25:50 +0100 Subject: [PATCH 21/25] Add `runInterpretResultsFor` to de-duplicate code for `interpret-results` --- lib/analyze-action.js | 56 ++++++++++++++--------------- src/analyze.ts | 82 ++++++++++++++++++++++--------------------- 2 files changed, 68 insertions(+), 70 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 4d54f824dd..660d2a794a 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -93610,10 +93610,6 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, const dbAnalysisConfig = getDbAnalysisConfig(config); for (const language of config.languages) { try { - const sarifFile = path16.join( - sarifFolder, - addSarifExtension(dbAnalysisConfig, language) - ); const queries = []; if (config.analysisKinds.length > 1) { queries.push(getGeneratedSuitePath(config, language)); @@ -93629,43 +93625,24 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, await codeql.databaseRunQueries(databasePath, queryFlags, queries); logger.debug(`Finished running queries for ${language}.`); statusReport[`analyze_builtin_queries_${language}_duration_ms`] = (/* @__PURE__ */ new Date()).getTime() - startTimeRunQueries; - logger.startGroup( - `Interpreting ${dbAnalysisConfig.name} results for ${language}` - ); - let category = automationDetailsId; - if (dbAnalysisConfig.kind === "code-quality" /* CodeQuality */) { - category = fixCodeQualityCategory(logger, automationDetailsId); - } const startTimeInterpretResults = /* @__PURE__ */ new Date(); - const analysisSummary = await runInterpretResults( + const { summary: analysisSummary, sarifFile } = await runInterpretResultsFor( + dbAnalysisConfig, language, void 0, - sarifFile, - config.debugMode, - category + config.debugMode ); let qualityAnalysisSummary; if (config.analysisKinds.length > 1 && isCodeQualityEnabled(config)) { - logger.info( - `Interpreting ${CodeQuality.name} results for ${language}` - ); - const qualityCategory = fixCodeQualityCategory( - logger, - automationDetailsId - ); - const qualitySarifFile = path16.join( - sarifFolder, - addSarifExtension(CodeQuality, language) - ); - qualityAnalysisSummary = await runInterpretResults( + const qualityResult = await runInterpretResultsFor( + CodeQuality, language, codeQualityQueries.map( (i) => resolveQuerySuiteAlias(language, i) ), - qualitySarifFile, - config.debugMode, - qualityCategory + config.debugMode ); + qualityAnalysisSummary = qualityResult.summary; } const endTimeInterpretResults = /* @__PURE__ */ new Date(); statusReport[`interpret_results_${language}_duration_ms`] = endTimeInterpretResults.getTime() - startTimeInterpretResults.getTime(); @@ -93701,6 +93678,25 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, } } return statusReport; + async function runInterpretResultsFor(analysis, language, queries, enableDebugLogging) { + logger.info(`Interpreting ${analysis.name} results for ${language}`); + let category = automationDetailsId; + if (dbAnalysisConfig.kind === "code-quality" /* CodeQuality */) { + category = fixCodeQualityCategory(logger, automationDetailsId); + } + const sarifFile = path16.join( + sarifFolder, + addSarifExtension(analysis, language) + ); + const summary = await runInterpretResults( + language, + queries, + sarifFile, + enableDebugLogging, + category + ); + return { summary, sarifFile }; + } async function runInterpretResults(language, queries, sarifFile, enableDebugLogging, category) { const databasePath = getCodeQLDatabasePath(config, language); return await codeql.databaseInterpretResults( diff --git a/src/analyze.ts b/src/analyze.ts index e7a7cab8a5..3c82845b06 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -664,13 +664,6 @@ export async function runQueries( for (const language of config.languages) { try { - // If Code Scanning is enabled, then the main SARIF file is always the Code Scanning one. - // Otherwise, only Code Quality is enabled, and the main SARIF file is the Code Quality one. - const sarifFile = path.join( - sarifFolder, - addSarifExtension(dbAnalysisConfig, language), - ); - // This should be empty to run only the query suite that was generated when // the database was initialised. const queries: string[] = []; @@ -705,28 +698,17 @@ export async function runQueries( // There is always at least one analysis kind enabled. Running `interpret-results` // produces the SARIF file for the analysis kind that the database was initialised with. - logger.startGroup( - `Interpreting ${dbAnalysisConfig.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 (dbAnalysisConfig.kind === analyses.AnalysisKind.CodeQuality) { - category = fixCodeQualityCategory(logger, automationDetailsId); - } - const startTimeInterpretResults = new Date(); - const analysisSummary = await runInterpretResults( - language, - undefined, - sarifFile, - config.debugMode, - category, - ); + const { summary: analysisSummary, sarifFile } = + await runInterpretResultsFor( + dbAnalysisConfig, + language, + undefined, + config.debugMode, + ); // This case is only needed if Code Quality is not the sole analysis kind. - // In this case, we will have run queries for both analysis kinds. The previous call to + // In this case, we will have run queries for all analysis kinds. The previous call to // `interpret-results` will have produced a SARIF file for Code Scanning and we now // need to produce an additional SARIF file for Code Quality. let qualityAnalysisSummary: string | undefined; @@ -734,26 +716,15 @@ export async function runQueries( config.analysisKinds.length > 1 && configUtils.isCodeQualityEnabled(config) ) { - logger.info( - `Interpreting ${analyses.CodeQuality.name} results for ${language}`, - ); - const qualityCategory = fixCodeQualityCategory( - logger, - automationDetailsId, - ); - const qualitySarifFile = path.join( - sarifFolder, - addSarifExtension(analyses.CodeQuality, language), - ); - qualityAnalysisSummary = await runInterpretResults( + const qualityResult = await runInterpretResultsFor( + analyses.CodeQuality, language, analyses.codeQualityQueries.map((i) => resolveQuerySuiteAlias(language, i), ), - qualitySarifFile, config.debugMode, - qualityCategory, ); + qualityAnalysisSummary = qualityResult.summary; } const endTimeInterpretResults = new Date(); statusReport[`interpret_results_${language}_duration_ms`] = @@ -798,6 +769,37 @@ export async function runQueries( return statusReport; + async function runInterpretResultsFor( + analysis: analyses.AnalysisConfig, + language: Language, + queries: string[] | undefined, + enableDebugLogging: boolean, + ): 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 (dbAnalysisConfig.kind === analyses.AnalysisKind.CodeQuality) { + category = fixCodeQualityCategory(logger, automationDetailsId); + } + + const sarifFile = path.join( + sarifFolder, + addSarifExtension(analysis, language), + ); + + const summary = await runInterpretResults( + language, + queries, + sarifFile, + enableDebugLogging, + category, + ); + + return { summary, sarifFile }; + } + async function runInterpretResults( language: Language, queries: string[] | undefined, From 6d0bcea69900def54838ca8a688b0dca11516b38 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 5 Sep 2025 12:35:53 +0100 Subject: [PATCH 22/25] Matrix over `analysis-kinds` in `quality-queries` check --- .github/workflows/__quality-queries.yml | 48 ++++++++++++++++++++++++- pr-checks/checks/quality-queries.yml | 7 +++- pr-checks/sync.py | 12 +++++++ 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/.github/workflows/__quality-queries.yml b/.github/workflows/__quality-queries.yml index 1578d4c7ab..8b74c1c7f4 100644 --- a/.github/workflows/__quality-queries.yml +++ b/.github/workflows/__quality-queries.yml @@ -32,16 +32,58 @@ jobs: include: - os: ubuntu-latest version: linked + analysis-kinds: code-scanning + - os: ubuntu-latest + version: linked + analysis-kinds: code-quality + - os: ubuntu-latest + version: linked + analysis-kinds: code-scanning,code-quality + - os: macos-latest + version: linked + analysis-kinds: code-scanning - os: macos-latest version: linked + analysis-kinds: code-quality + - os: macos-latest + version: linked + analysis-kinds: code-scanning,code-quality + - os: windows-latest + version: linked + analysis-kinds: code-scanning + - os: windows-latest + version: linked + analysis-kinds: code-quality - os: windows-latest version: linked + analysis-kinds: code-scanning,code-quality - os: ubuntu-latest version: nightly-latest + analysis-kinds: code-scanning + - os: ubuntu-latest + version: nightly-latest + analysis-kinds: code-quality + - os: ubuntu-latest + version: nightly-latest + analysis-kinds: code-scanning,code-quality + - os: macos-latest + version: nightly-latest + analysis-kinds: code-scanning - os: macos-latest version: nightly-latest + analysis-kinds: code-quality + - os: macos-latest + version: nightly-latest + analysis-kinds: code-scanning,code-quality + - os: windows-latest + version: nightly-latest + analysis-kinds: code-scanning + - os: windows-latest + version: nightly-latest + analysis-kinds: code-quality - os: windows-latest version: nightly-latest + analysis-kinds: code-scanning,code-quality name: Quality queries input permissions: contents: read @@ -61,25 +103,28 @@ jobs: - uses: ./../action/init with: languages: javascript - analysis-kinds: code-scanning,code-quality + analysis-kinds: ${{ matrix.analysis-kinds }} tools: ${{ steps.prepare-test.outputs.tools-url }} - uses: ./../action/analyze with: output: ${{ runner.temp }}/results upload-database: false - name: Upload security SARIF + if: contains(matrix.analysis-kinds, 'code-scanning') uses: actions/upload-artifact@v4 with: name: quality-queries-${{ matrix.os }}-${{ matrix.version }}.sarif.json path: ${{ runner.temp }}/results/javascript.sarif retention-days: 7 - name: Upload quality SARIF + if: contains(matrix.analysis-kinds, 'code-quality') uses: actions/upload-artifact@v4 with: name: quality-queries-${{ matrix.os }}-${{ matrix.version }}.quality.sarif.json path: ${{ runner.temp }}/results/javascript.quality.sarif retention-days: 7 - name: Check quality query does not appear in security SARIF + if: contains(matrix.analysis-kinds, 'code-scanning') uses: actions/github-script@v7 env: SARIF_PATH: ${{ runner.temp }}/results/javascript.sarif @@ -87,6 +132,7 @@ jobs: with: script: ${{ env.CHECK_SCRIPT }} - name: Check quality query appears in quality SARIF + if: contains(matrix.analysis-kinds, 'code-quality') uses: actions/github-script@v7 env: SARIF_PATH: ${{ runner.temp }}/results/javascript.quality.sarif diff --git a/pr-checks/checks/quality-queries.yml b/pr-checks/checks/quality-queries.yml index 3f4ff3b1bf..618f8e4cf8 100644 --- a/pr-checks/checks/quality-queries.yml +++ b/pr-checks/checks/quality-queries.yml @@ -1,6 +1,7 @@ name: "Quality queries input" description: "Tests that queries specified in the quality-queries input are used." versions: ["linked", "nightly-latest"] +analysisKinds: ["code-scanning", "code-quality", "code-scanning,code-quality"] env: CHECK_SCRIPT: | const fs = require('fs'); @@ -29,25 +30,28 @@ steps: - uses: ./../action/init with: languages: javascript - analysis-kinds: code-scanning,code-quality + analysis-kinds: ${{ matrix.analysis-kinds }} tools: ${{ steps.prepare-test.outputs.tools-url }} - uses: ./../action/analyze with: output: "${{ runner.temp }}/results" upload-database: false - name: Upload security SARIF + if: contains(matrix.analysis-kinds, 'code-scanning') uses: actions/upload-artifact@v4 with: name: quality-queries-${{ matrix.os }}-${{ matrix.version }}.sarif.json path: "${{ runner.temp }}/results/javascript.sarif" retention-days: 7 - name: Upload quality SARIF + if: contains(matrix.analysis-kinds, 'code-quality') uses: actions/upload-artifact@v4 with: name: quality-queries-${{ matrix.os }}-${{ matrix.version }}.quality.sarif.json path: "${{ runner.temp }}/results/javascript.quality.sarif" retention-days: 7 - name: Check quality query does not appear in security SARIF + if: contains(matrix.analysis-kinds, 'code-scanning') uses: actions/github-script@v7 env: SARIF_PATH: "${{ runner.temp }}/results/javascript.sarif" @@ -55,6 +59,7 @@ steps: with: script: ${{ env.CHECK_SCRIPT }} - name: Check quality query appears in quality SARIF + if: contains(matrix.analysis-kinds, 'code-quality') uses: actions/github-script@v7 env: SARIF_PATH: "${{ runner.temp }}/results/javascript.quality.sarif" diff --git a/pr-checks/sync.py b/pr-checks/sync.py index beaa943985..6d23cafab5 100755 --- a/pr-checks/sync.py +++ b/pr-checks/sync.py @@ -102,6 +102,18 @@ def writeHeader(checkStream): if checkSpecification.get('useAllPlatformBundle'): useAllPlatformBundle = checkSpecification['useAllPlatformBundle'] + + if 'analysisKinds' in checkSpecification: + newMatrix = [] + for matrixInclude in matrix: + for analysisKind in checkSpecification.get('analysisKinds'): + newMatrix.append( + matrixInclude | + { 'analysis-kinds': analysisKind } + ) + matrix = newMatrix + + # Construct the workflow steps needed for this check. steps = [ { 'name': 'Check out repository', From 5d822f13cd473db57ac1a4717f727d4792e77da2 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 5 Sep 2025 12:39:34 +0100 Subject: [PATCH 23/25] Rename `getDbAnalysisKind` and `getDbAnalysisConfig` --- lib/analyze-action.js | 8 ++++---- src/analyze.ts | 2 +- src/config-utils.ts | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 660d2a794a..709a1546f3 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -91623,11 +91623,11 @@ function isCodeScanningEnabled(config) { function isCodeQualityEnabled(config) { return config.analysisKinds.includes("code-quality" /* CodeQuality */); } -function getDbAnalysisKind(config) { +function getPrimaryAnalysisKind(config) { return isCodeScanningEnabled(config) ? "code-scanning" /* CodeScanning */ : "code-quality" /* CodeQuality */; } -function getDbAnalysisConfig(config) { - return getDbAnalysisKind(config) === "code-scanning" /* CodeScanning */ ? CodeScanning : CodeQuality; +function getPrimaryAnalysisConfig(config) { + return getPrimaryAnalysisKind(config) === "code-scanning" /* CodeScanning */ ? CodeScanning : CodeQuality; } // src/setup-codeql.ts @@ -93607,7 +93607,7 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, incrementalMode.push("overlay"); } const sarifRunPropertyFlag = incrementalMode.length > 0 ? `--sarif-run-property=incrementalMode=${incrementalMode.join(",")}` : void 0; - const dbAnalysisConfig = getDbAnalysisConfig(config); + const dbAnalysisConfig = getPrimaryAnalysisConfig(config); for (const language of config.languages) { try { const queries = []; diff --git a/src/analyze.ts b/src/analyze.ts index 3c82845b06..153b00a1f4 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -660,7 +660,7 @@ export async function runQueries( ? `--sarif-run-property=incrementalMode=${incrementalMode.join(",")}` : undefined; - const dbAnalysisConfig = configUtils.getDbAnalysisConfig(config); + const dbAnalysisConfig = configUtils.getPrimaryAnalysisConfig(config); for (const language of config.languages) { try { diff --git a/src/config-utils.ts b/src/config-utils.ts index 1041ad5146..626cd4b49a 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -1564,26 +1564,26 @@ export function isCodeQualityEnabled(config: Config): boolean { } /** - * Returns the analysis kind for which the database is initialised. This is + * Returns the primary analysis kind that the Action is initialised with. This is * always `AnalysisKind.CodeScanning` unless `AnalysisKind.CodeScanning` is not enabled. * * @returns Returns `AnalysisKind.CodeScanning` if `AnalysisKind.CodeScanning` is enabled; * otherwise `AnalysisKind.CodeQuality`. */ -export function getDbAnalysisKind(config: Config): AnalysisKind { +export function getPrimaryAnalysisKind(config: Config): AnalysisKind { return isCodeScanningEnabled(config) ? AnalysisKind.CodeScanning : AnalysisKind.CodeQuality; } /** - * Returns the analysis configuration for which the database is initialised. This is + * 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`. */ -export function getDbAnalysisConfig(config: Config): AnalysisConfig { - return getDbAnalysisKind(config) === AnalysisKind.CodeScanning +export function getPrimaryAnalysisConfig(config: Config): AnalysisConfig { + return getPrimaryAnalysisKind(config) === AnalysisKind.CodeScanning ? CodeScanning : CodeQuality; } From 918e792ec9cc69f7161a0e2aa77727fa0c285daf Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 5 Sep 2025 12:44:30 +0100 Subject: [PATCH 24/25] Throw an error if query customisations are enabled for a `code-quality`-only analysis --- lib/init-action.js | 4 ++-- src/config-utils.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/init-action.js b/lib/init-action.js index 381d2061ef..e76379f64a 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -87612,8 +87612,8 @@ async function initConfig(inputs) { const config = await initActionState(inputs, userConfig); if (config.analysisKinds.length === 1 && isCodeQualityEnabled(config)) { if (hasQueryCustomisation(config.computedConfig)) { - logger.warning( - "Query customizations will be ignored, because only `code-quality` analysis is enabled." + throw new ConfigurationError( + "Query customizations are unsupported, because only `code-quality` analysis is enabled." ); } const queries = codeQualityQueries.map((v) => ({ uses: v })); diff --git a/src/config-utils.ts b/src/config-utils.ts index 626cd4b49a..16144398f3 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -1137,8 +1137,8 @@ export async function initConfig(inputs: InitConfigInputs): Promise { if (config.analysisKinds.length === 1 && isCodeQualityEnabled(config)) { // Warn if any query customisations are present in the computed configuration. if (hasQueryCustomisation(config.computedConfig)) { - logger.warning( - "Query customizations will be ignored, because only `code-quality` analysis is enabled.", + throw new ConfigurationError( + "Query customizations are unsupported, because only `code-quality` analysis is enabled.", ); } From e75b5d33734ec23fcc2297acb6944c7715798f04 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 5 Sep 2025 14:27:28 +0100 Subject: [PATCH 25/25] Fix: Include `matrix.analysis-kinds` in artifact names --- .github/workflows/__quality-queries.yml | 6 ++++-- pr-checks/checks/quality-queries.yml | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/__quality-queries.yml b/.github/workflows/__quality-queries.yml index 8b74c1c7f4..bbd5decf78 100644 --- a/.github/workflows/__quality-queries.yml +++ b/.github/workflows/__quality-queries.yml @@ -113,14 +113,16 @@ jobs: if: contains(matrix.analysis-kinds, 'code-scanning') uses: actions/upload-artifact@v4 with: - name: quality-queries-${{ matrix.os }}-${{ matrix.version }}.sarif.json + 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') uses: actions/upload-artifact@v4 with: - name: quality-queries-${{ matrix.os }}-${{ matrix.version }}.quality.sarif.json + name: | + quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.quality.sarif.json path: ${{ runner.temp }}/results/javascript.quality.sarif retention-days: 7 - name: Check quality query does not appear in security SARIF diff --git a/pr-checks/checks/quality-queries.yml b/pr-checks/checks/quality-queries.yml index 618f8e4cf8..9eb578171e 100644 --- a/pr-checks/checks/quality-queries.yml +++ b/pr-checks/checks/quality-queries.yml @@ -40,14 +40,16 @@ steps: if: contains(matrix.analysis-kinds, 'code-scanning') uses: actions/upload-artifact@v4 with: - name: quality-queries-${{ matrix.os }}-${{ matrix.version }}.sarif.json + 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') uses: actions/upload-artifact@v4 with: - name: quality-queries-${{ matrix.os }}-${{ matrix.version }}.quality.sarif.json + name: | + quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.quality.sarif.json path: "${{ runner.temp }}/results/javascript.quality.sarif" retention-days: 7 - name: Check quality query does not appear in security SARIF