From 57c7b0a8846ea6a4249e9adbb4c082c1eccf3233 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 17 Oct 2025 13:33:55 +0100 Subject: [PATCH] Rename `initAnalysisKinds` to `getAnalysisKinds` and cache results --- lib/init-action.js | 16 ++++++++++------ src/analyses.test.ts | 14 +++++++------- src/analyses.ts | 20 +++++++++++++++----- src/init-action.ts | 4 ++-- 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/lib/init-action.js b/lib/init-action.js index 99d76a41d..0c7936f84 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -86085,8 +86085,12 @@ async function parseAnalysisKinds(input) { new Set(components.map((component) => component)) ); } -async function initAnalysisKinds(logger) { - const analysisKinds = await parseAnalysisKinds( +var cachedAnalysisKinds; +async function getAnalysisKinds(logger, skipCache = false) { + if (!skipCache && cachedAnalysisKinds !== void 0) { + return cachedAnalysisKinds; + } + cachedAnalysisKinds = await parseAnalysisKinds( getRequiredInput("analysis-kinds") ); const qualityQueriesInput = getOptionalInput("quality-queries"); @@ -86095,10 +86099,10 @@ async function initAnalysisKinds(logger) { "The `quality-queries` input is deprecated and will be removed in a future version of the CodeQL Action. Use the `analysis-kinds` input to configure different analysis kinds instead." ); } - if (!analysisKinds.includes("code-quality" /* CodeQuality */) && qualityQueriesInput !== void 0) { - analysisKinds.push("code-quality" /* CodeQuality */); + if (!cachedAnalysisKinds.includes("code-quality" /* CodeQuality */) && qualityQueriesInput !== void 0) { + cachedAnalysisKinds.push("code-quality" /* CodeQuality */); } - return analysisKinds; + return cachedAnalysisKinds; } var codeQualityQueries = ["code-quality"]; @@ -90796,7 +90800,7 @@ async function run() { getOptionalInput("source-root") || "" ); try { - const analysisKinds = await initAnalysisKinds(logger); + const analysisKinds = await getAnalysisKinds(logger); await sendStartingStatusReport(startedAt, { analysisKinds }, logger); const codeQLDefaultVersionInfo = await features.getDefaultCliVersion( gitHubVersion.type diff --git a/src/analyses.test.ts b/src/analyses.test.ts index e48cc47d5..9178ffbd5 100644 --- a/src/analyses.test.ts +++ b/src/analyses.test.ts @@ -4,7 +4,7 @@ import * as sinon from "sinon"; import * as actionsUtil from "./actions-util"; import { AnalysisKind, - initAnalysisKinds, + getAnalysisKinds, parseAnalysisKinds, supportedAnalysisKinds, } from "./analyses"; @@ -42,28 +42,28 @@ test("Parsing analysis kinds requires at least one analysis kind", async (t) => }); }); -test("initAnalysisKinds - returns expected analysis kinds for `analysis-kinds` input", async (t) => { +test("getAnalysisKinds - returns expected analysis kinds for `analysis-kinds` input", async (t) => { const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput"); requiredInputStub .withArgs("analysis-kinds") .returns("code-scanning,code-quality"); - const result = await initAnalysisKinds(getRunnerLogger(true)); + const result = await getAnalysisKinds(getRunnerLogger(true), true); t.assert(result.includes(AnalysisKind.CodeScanning)); t.assert(result.includes(AnalysisKind.CodeQuality)); }); -test("initAnalysisKinds - includes `code-quality` when deprecated `quality-queries` input is used", async (t) => { +test("getAnalysisKinds - includes `code-quality` when deprecated `quality-queries` input is used", async (t) => { const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput"); requiredInputStub.withArgs("analysis-kinds").returns("code-scanning"); const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput"); optionalInputStub.withArgs("quality-queries").returns("code-quality"); - const result = await initAnalysisKinds(getRunnerLogger(true)); + const result = await getAnalysisKinds(getRunnerLogger(true), true); t.assert(result.includes(AnalysisKind.CodeScanning)); t.assert(result.includes(AnalysisKind.CodeQuality)); }); -test("initAnalysisKinds - throws if `analysis-kinds` input is invalid", async (t) => { +test("getAnalysisKinds - throws if `analysis-kinds` input is invalid", async (t) => { const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput"); requiredInputStub.withArgs("analysis-kinds").returns("no-such-thing"); - await t.throwsAsync(initAnalysisKinds(getRunnerLogger(true))); + await t.throwsAsync(getAnalysisKinds(getRunnerLogger(true), true)); }); diff --git a/src/analyses.ts b/src/analyses.ts index 2c5d20b11..a8d172e3b 100644 --- a/src/analyses.ts +++ b/src/analyses.ts @@ -45,19 +45,29 @@ export async function parseAnalysisKinds( ); } +// Used to avoid re-parsing the input after we have done it once. +let cachedAnalysisKinds: AnalysisKind[] | undefined; + /** * Initialises the analysis kinds for the analysis based on the `analysis-kinds` input. * This function will also use the deprecated `quality-queries` input as an indicator to enable `code-quality`. * If the `analysis-kinds` input cannot be parsed, a `ConfigurationError` is thrown. * * @param logger The logger to use. + * @param skipCache For testing, whether to ignore the cached values (default: false). + * * @returns The array of enabled analysis kinds. * @throws A `ConfigurationError` if the `analysis-kinds` input cannot be parsed. */ -export async function initAnalysisKinds( +export async function getAnalysisKinds( logger: Logger, + skipCache: boolean = false, ): Promise { - const analysisKinds = await parseAnalysisKinds( + if (!skipCache && cachedAnalysisKinds !== undefined) { + return cachedAnalysisKinds; + } + + cachedAnalysisKinds = await parseAnalysisKinds( getRequiredInput("analysis-kinds"), ); @@ -75,13 +85,13 @@ export async function initAnalysisKinds( // if an input to `quality-queries` was specified. We should remove this once // `quality-queries` is no longer used. if ( - !analysisKinds.includes(AnalysisKind.CodeQuality) && + !cachedAnalysisKinds.includes(AnalysisKind.CodeQuality) && qualityQueriesInput !== undefined ) { - analysisKinds.push(AnalysisKind.CodeQuality); + cachedAnalysisKinds.push(AnalysisKind.CodeQuality); } - return analysisKinds; + return cachedAnalysisKinds; } /** The queries to use for Code Quality analyses. */ diff --git a/src/init-action.ts b/src/init-action.ts index 8a2f72d0d..5196550e2 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -15,7 +15,7 @@ import { getTemporaryDirectory, persistInputs, } from "./actions-util"; -import { initAnalysisKinds } from "./analyses"; +import { getAnalysisKinds } from "./analyses"; import { getGitHubVersion } from "./api-client"; import { getDependencyCachingEnabled, @@ -254,7 +254,7 @@ async function run() { try { // This may throw a `ConfigurationError` before we have sent the `starting` status report. - const analysisKinds = await initAnalysisKinds(logger); + const analysisKinds = await getAnalysisKinds(logger); // Send a status report indicating that an analysis is starting. await sendStartingStatusReport(startedAt, { analysisKinds }, logger); const codeQLDefaultVersionInfo = await features.getDefaultCliVersion(