From 2a8731cc0636c612147a349ccc88166bd482a9e1 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 27 Jul 2026 13:10:34 +0100 Subject: [PATCH 1/3] Move `config-file` computation after determining the `analysisKinds` --- lib/entry-points.js | 10 +++++----- src/init-action.ts | 13 +++++++------ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 528f258a87..c522b43c4a 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -160750,11 +160750,6 @@ async function run3(actionState) { logger.info(`Job run UUID is ${jobRunUuid}.`); core21.exportVariable("JOB_RUN_UUID" /* JOB_RUN_UUID */, jobRunUuid); core21.exportVariable("CODEQL_ACTION_INIT_HAS_RUN" /* INIT_ACTION_HAS_RUN */, "true"); - const actionStateWithFeatures = { ...actionState, features }; - configFile = await getConfigFileInput( - actionStateWithFeatures, - repositoryProperties - ); sourceRoot = path24.resolve( getRequiredEnvParam("GITHUB_WORKSPACE"), getOptionalInput("source-root") || "" @@ -160767,6 +160762,11 @@ async function run3(actionState) { `Failed to parse analysis kinds for 'starting' status report: ${getErrorMessage(err)}` ); } + const actionStateWithFeatures = { ...actionState, features }; + configFile = await getConfigFileInput( + actionStateWithFeatures, + repositoryProperties + ); await sendStartingStatusReport(startedAt, { analysisKinds }, logger); if (process.env["CODEQL_ACTION_SETUP_CODEQL_HAS_RUN" /* SETUP_CODEQL_ACTION_HAS_RUN */] === "true") { throw new ConfigurationError( diff --git a/src/init-action.ts b/src/init-action.ts index c7837c6eed..ec7983b76c 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -262,12 +262,6 @@ async function run( core.exportVariable(EnvVar.INIT_ACTION_HAS_RUN, "true"); - const actionStateWithFeatures = { ...actionState, features }; - configFile = await getConfigFileInput( - actionStateWithFeatures, - repositoryProperties, - ); - // path.resolve() respects the intended semantics of source-root. If // source-root is relative, it is relative to the GITHUB_WORKSPACE. If // source-root is absolute, it is used as given. @@ -290,6 +284,13 @@ async function run( ); } + // Compute the value of the `config-file` input. + const actionStateWithFeatures = { ...actionState, features }; + configFile = await getConfigFileInput( + actionStateWithFeatures, + repositoryProperties, + ); + // Send a status report indicating that an analysis is starting. await sendStartingStatusReport(startedAt, { analysisKinds }, logger); From 8289a49271cbb335d374e7e2e7a50c1576be0afe Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 27 Jul 2026 13:23:39 +0100 Subject: [PATCH 2/3] Ignore repository property for unsupported analysis kinds --- lib/entry-points.js | 8 +++++--- src/config/file.test.ts | 39 ++++++++++++++++++++++++++++++++++----- src/config/file.ts | 16 +++++++++++++++- src/init-action.ts | 1 + 4 files changed, 55 insertions(+), 9 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index c522b43c4a..5904ad07ae 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -148495,14 +148495,15 @@ async function getConfigFileInput({ logger, actions, features -}, repositoryProperties) { +}, repositoryProperties, analysisKinds) { const input = actions.getOptionalInput("config-file"); if (input !== void 0) { logger.info(`Using configuration file input from workflow: ${input}`); return input; } const propertyValue = repositoryProperties["github-codeql-config-file" /* CONFIG_FILE */]; - if (propertyValue !== void 0 && propertyValue.trim().length > 0) { + const analysisKindSupported = analysisKinds === void 0 || analysisKinds.includes("code-scanning" /* CodeScanning */) && analysisKinds.length === 1; + if (analysisKindSupported && propertyValue !== void 0 && propertyValue.trim().length > 0) { const useRepositoryProperty = await features.getValue( "config_file_repository_property" /* ConfigFileRepositoryProperty */ ); @@ -160765,7 +160766,8 @@ async function run3(actionState) { const actionStateWithFeatures = { ...actionState, features }; configFile = await getConfigFileInput( actionStateWithFeatures, - repositoryProperties + repositoryProperties, + analysisKinds ); await sendStartingStatusReport(startedAt, { analysisKinds }, logger); if (process.env["CODEQL_ACTION_SETUP_CODEQL_HAS_RUN" /* SETUP_CODEQL_ACTION_HAS_RUN */] === "true") { diff --git a/src/config/file.test.ts b/src/config/file.test.ts index 22e2f795f8..17ac21d565 100644 --- a/src/config/file.test.ts +++ b/src/config/file.test.ts @@ -2,6 +2,7 @@ import * as github from "@actions/github"; import test from "ava"; import sinon from "sinon"; +import { AnalysisKind } from "../analyses"; import * as api from "../api-client"; import { RegistryProxyVars } from "../environment"; import { Feature } from "../feature-flags"; @@ -18,7 +19,7 @@ setupTests(test); test("getConfigFileInput returns undefined by default", async (t) => { await callee(getConfigFileInput) - .withArgs({}) + .withArgs({}, undefined) .withFeatures([Feature.ConfigFileRepositoryProperty]) .passes(t.is, undefined); }); @@ -40,7 +41,7 @@ test("getConfigFileInput returns input value", async (t) => { .withArgs("config-file") .returns(testInput); }) - .withArgs(repositoryProperties) + .withArgs(repositoryProperties, undefined) .logs(t, "Using configuration file input from workflow") .passes(t.is, testInput); }); @@ -49,16 +50,44 @@ test("getConfigFileInput returns repository property value", async (t) => { // Since there is no direct input, we should use the repository property. await callee(getConfigFileInput) .withFeatures([Feature.ConfigFileRepositoryProperty]) - .withArgs(repositoryProperties) + .withArgs(repositoryProperties, undefined) .logs(t, "Using configuration file input from repository property") .passes(t.is, repositoryProperties[RepositoryPropertyName.CONFIG_FILE]); }); +test("getConfigFileInput returns repository property value for Code Scanning", async (t) => { + // Since there is no direct input, we should use the repository property. + await callee(getConfigFileInput) + .withFeatures([Feature.ConfigFileRepositoryProperty]) + .withArgs(repositoryProperties, [AnalysisKind.CodeScanning]) + .logs(t, "Using configuration file input from repository property") + .passes(t.is, repositoryProperties[RepositoryPropertyName.CONFIG_FILE]); +}); + +test("getConfigFileInput ignores repository property for other analysis kinds", async (t) => { + const unsupportedCases = [ + [AnalysisKind.CodeQuality], + [AnalysisKind.RiskAssessment], + [AnalysisKind.CodeScanning, AnalysisKind.CodeQuality], + ]; + + const target = callee(getConfigFileInput).withFeatures([ + Feature.ConfigFileRepositoryProperty, + ]); + + for (const unsupportedCase of unsupportedCases) { + // Since the analysis kind is unsupported, we should ignore the repository property. + await target + .withArgs(repositoryProperties, unsupportedCase) + .passes(t.is, undefined); + } +}); + test("getConfigFileInput ignores empty repository property value", async (t) => { // Since the repository property value is an empty/whitespace string, we should ignore it. await callee(getConfigFileInput) .withFeatures([Feature.ConfigFileRepositoryProperty]) - .withArgs({ [RepositoryPropertyName.CONFIG_FILE]: " " }) + .withArgs({ [RepositoryPropertyName.CONFIG_FILE]: " " }, undefined) .passes(t.is, undefined); }); @@ -66,7 +95,7 @@ test("getConfigFileInput ignores repository property value when FF is off", asyn // Since the FF is off, we should ignore the repository property value. await callee(getConfigFileInput) .withFeatures([]) - .withArgs(repositoryProperties) + .withArgs(repositoryProperties, undefined) .notLogs(t, "Using configuration file input from repository property") .logs( t, diff --git a/src/config/file.ts b/src/config/file.ts index 8cb7bc3a11..9858328e11 100644 --- a/src/config/file.ts +++ b/src/config/file.ts @@ -1,4 +1,5 @@ import { ActionState } from "../action-common"; +import { AnalysisKind } from "../analyses"; import * as api from "../api-client"; import * as errorMessages from "../error-messages"; import { Feature } from "../feature-flags"; @@ -34,6 +35,7 @@ export async function getConfigFileInput( features, }: ActionState<["Logger", "Actions", "FeatureFlags"]>, repositoryProperties: Partial, + analysisKinds: AnalysisKind[] | undefined, ): Promise { const input = actions.getOptionalInput("config-file"); @@ -45,7 +47,19 @@ export async function getConfigFileInput( const propertyValue = repositoryProperties[RepositoryPropertyName.CONFIG_FILE]; - if (propertyValue !== undefined && propertyValue.trim().length > 0) { + // Only allow the repository property to be used for standard Code Scanning analyses, + // since we don't currently support some customisation options for Code Quality. + // We don't expect customisations for Risk Assessments either. + const analysisKindSupported = + analysisKinds === undefined || + (analysisKinds.includes(AnalysisKind.CodeScanning) && + analysisKinds.length === 1); + + if ( + analysisKindSupported && + propertyValue !== undefined && + propertyValue.trim().length > 0 + ) { // Only use the repository property value if the FF is enabled. const useRepositoryProperty = await features.getValue( Feature.ConfigFileRepositoryProperty, diff --git a/src/init-action.ts b/src/init-action.ts index ec7983b76c..4b52ba6ec6 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -289,6 +289,7 @@ async function run( configFile = await getConfigFileInput( actionStateWithFeatures, repositoryProperties, + analysisKinds, ); // Send a status report indicating that an analysis is starting. From 2d4c474c2ca5ea2965b9e53fabb7b67b0100016c Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 28 Jul 2026 12:02:41 +0100 Subject: [PATCH 3/3] Log `!analysisKindSupported` case --- lib/entry-points.js | 8 ++++++-- src/config/file.test.ts | 4 ++++ src/config/file.ts | 12 ++++++------ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 5904ad07ae..46c44a8183 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -148503,15 +148503,19 @@ async function getConfigFileInput({ } const propertyValue = repositoryProperties["github-codeql-config-file" /* CONFIG_FILE */]; const analysisKindSupported = analysisKinds === void 0 || analysisKinds.includes("code-scanning" /* CodeScanning */) && analysisKinds.length === 1; - if (analysisKindSupported && propertyValue !== void 0 && propertyValue.trim().length > 0) { + if (propertyValue !== void 0 && propertyValue.trim().length > 0) { const useRepositoryProperty = await features.getValue( "config_file_repository_property" /* ConfigFileRepositoryProperty */ ); - if (useRepositoryProperty) { + if (analysisKindSupported && useRepositoryProperty) { logger.info( `Using configuration file input from repository property: ${propertyValue}` ); return propertyValue; + } else if (!analysisKindSupported) { + logger.info( + "Ignoring configuration file input from repository property, because it is unsupported for the current analysis kind." + ); } else { logger.info( "Ignoring configuration file input from repository property, because the corresponding feature flag is disabled." diff --git a/src/config/file.test.ts b/src/config/file.test.ts index 17ac21d565..0833ad3d06 100644 --- a/src/config/file.test.ts +++ b/src/config/file.test.ts @@ -79,6 +79,10 @@ test("getConfigFileInput ignores repository property for other analysis kinds", // Since the analysis kind is unsupported, we should ignore the repository property. await target .withArgs(repositoryProperties, unsupportedCase) + .logs( + t, + "Ignoring configuration file input from repository property, because it is unsupported for the current analysis kind.", + ) .passes(t.is, undefined); } }); diff --git a/src/config/file.ts b/src/config/file.ts index 9858328e11..be0e415a38 100644 --- a/src/config/file.ts +++ b/src/config/file.ts @@ -55,21 +55,21 @@ export async function getConfigFileInput( (analysisKinds.includes(AnalysisKind.CodeScanning) && analysisKinds.length === 1); - if ( - analysisKindSupported && - propertyValue !== undefined && - propertyValue.trim().length > 0 - ) { + if (propertyValue !== undefined && propertyValue.trim().length > 0) { // Only use the repository property value if the FF is enabled. const useRepositoryProperty = await features.getValue( Feature.ConfigFileRepositoryProperty, ); - if (useRepositoryProperty) { + if (analysisKindSupported && useRepositoryProperty) { logger.info( `Using configuration file input from repository property: ${propertyValue}`, ); return propertyValue; + } else if (!analysisKindSupported) { + logger.info( + "Ignoring configuration file input from repository property, because it is unsupported for the current analysis kind.", + ); } else { logger.info( "Ignoring configuration file input from repository property, because the corresponding feature flag is disabled.",