From fb605661cd22014d06850f0b6c10e456b9a0f7f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20San=20Jos=C3=A9?= Date: Fri, 29 May 2026 13:18:17 +0200 Subject: [PATCH] Missing files --- src/config/resolve-tools-input.test.ts | 149 +++++++++++++++++++++++++ src/config/resolve-tools-input.ts | 50 +++++++++ 2 files changed, 199 insertions(+) create mode 100644 src/config/resolve-tools-input.test.ts create mode 100644 src/config/resolve-tools-input.ts diff --git a/src/config/resolve-tools-input.test.ts b/src/config/resolve-tools-input.test.ts new file mode 100644 index 000000000..92e86a3c7 --- /dev/null +++ b/src/config/resolve-tools-input.test.ts @@ -0,0 +1,149 @@ +import test from "ava"; + +import { resolveToolsInput } from "../config/resolve-tools-input"; +import { RepositoryPropertyName } from "../feature-flags/properties"; +import type { RepositoryProperties } from "../feature-flags/properties"; +import { + getRecordingLogger, + LoggedMessage, + setupTests, +} from "../testing-utils"; + +setupTests(test); + +test("resolveToolsInput returns undefined when no tools input or repository property is set", (t) => { + const loggedMessages: LoggedMessage[] = []; + const logger = getRecordingLogger(loggedMessages); + + const result = resolveToolsInput(undefined, true, {}, logger); + + t.is(result, undefined); + t.is(loggedMessages.length, 0); +}); + +test("resolveToolsInput returns workflow input when only workflow input is provided", (t) => { + const loggedMessages: LoggedMessage[] = []; + const logger = getRecordingLogger(loggedMessages); + + const result = resolveToolsInput("latest", true, {}, logger); + + t.is(result, "latest"); + t.is(loggedMessages.length, 1); + t.is( + loggedMessages[0].message, + "Setting tools: latest based on workflow input.", + ); +}); + +test("resolveToolsInput returns repository property when only repository property is provided", (t) => { + const loggedMessages: LoggedMessage[] = []; + const logger = getRecordingLogger(loggedMessages); + + const repositoryProperties: RepositoryProperties = { + [RepositoryPropertyName.TOOLS]: "toolcache", + }; + const result = resolveToolsInput( + undefined, + true, + repositoryProperties, + logger, + ); + + t.is(result, "toolcache"); + t.is(loggedMessages.length, 1); + t.is( + loggedMessages[0].message, + "Setting tools: toolcache based on the 'github-codeql-tools' repository property.", + ); +}); + +test("resolveToolsInput prioritizes workflow input over repository property", (t) => { + const loggedMessages: LoggedMessage[] = []; + const logger = getRecordingLogger(loggedMessages); + + const repositoryProperties: RepositoryProperties = { + [RepositoryPropertyName.TOOLS]: "toolcache", + }; + const result = resolveToolsInput( + "nightly", + true, + repositoryProperties, + logger, + ); + + t.is(result, "nightly"); + t.is(loggedMessages.length, 1); + t.is( + loggedMessages[0].message, + "Setting tools: nightly based on workflow input.", + ); +}); + +test("resolveToolsInput treats empty string workflow input as not set", (t) => { + const loggedMessages: LoggedMessage[] = []; + const logger = getRecordingLogger(loggedMessages); + + const repositoryProperties: RepositoryProperties = { + [RepositoryPropertyName.TOOLS]: "toolcache", + }; + const result = resolveToolsInput("", true, repositoryProperties, logger); + + t.is(result, "toolcache"); + t.is(loggedMessages.length, 1); + t.is( + loggedMessages[0].message, + "Setting tools: toolcache based on the 'github-codeql-tools' repository property.", + ); +}); + +test("resolveToolsInput returns undefined when repository property is undefined", (t) => { + const loggedMessages: LoggedMessage[] = []; + const logger = getRecordingLogger(loggedMessages); + + const repositoryProperties: RepositoryProperties = { + [RepositoryPropertyName.TOOLS]: undefined, + }; + const result = resolveToolsInput( + undefined, + true, + repositoryProperties, + logger, + ); + + t.is(result, undefined); + t.is(loggedMessages.length, 0); +}); + +test("resolveToolsInput ignores repository property when fallback is disabled", (t) => { + const loggedMessages: LoggedMessage[] = []; + const logger = getRecordingLogger(loggedMessages); + + const repositoryProperties: RepositoryProperties = { + [RepositoryPropertyName.TOOLS]: "toolcache", + }; + const result = resolveToolsInput( + undefined, + false, + repositoryProperties, + logger, + ); + + t.is(result, undefined); + t.is(loggedMessages.length, 1); + const fallbackDisabledMessage = String(loggedMessages[0].message); + t.true( + /Ignoring 'github-codeql-tools' repository property because it is only supported for dynamic workflows\./.test( + fallbackDisabledMessage, + ), + ); +}); + +test("resolveToolsInput does not log when fallback is disabled and repository property is not set", (t) => { + const loggedMessages: LoggedMessage[] = []; + const logger = getRecordingLogger(loggedMessages); + + const result = resolveToolsInput(undefined, false, {}, logger); + + t.is(result, undefined); + t.is(loggedMessages.length, 0); +}); diff --git a/src/config/resolve-tools-input.ts b/src/config/resolve-tools-input.ts new file mode 100644 index 000000000..24af52874 --- /dev/null +++ b/src/config/resolve-tools-input.ts @@ -0,0 +1,50 @@ +import { + RepositoryProperties, + RepositoryPropertyName, +} from "../feature-flags/properties"; +import { Logger } from "../logging"; + +/** + * Resolves the effective tools input by combining the workflow input and repository properties. + * The explicit `tools` workflow input takes precedence. If none is provided, + * falls back to the repository property (if set and enabled for this workflow). + * + * @param toolsWorkflowInput - The value of the `tools` workflow input, if provided. + * @param allowRepositoryPropertyFallback - Whether the repository property fallback is enabled. + * @param repositoryProperties - The parsed repository properties. + * @param logger - Logger for outputting resolution messages. + * @returns The effective tools input value. + */ +export function resolveToolsInput( + toolsWorkflowInput: string | undefined, + allowRepositoryPropertyFallback: boolean, + repositoryProperties: RepositoryProperties, + logger: Logger, +): string | undefined { + if (toolsWorkflowInput) { + logger.info( + `Setting tools: ${toolsWorkflowInput} based on workflow input.`, + ); + return toolsWorkflowInput; + } + + const toolsPropertyValue = repositoryProperties[RepositoryPropertyName.TOOLS]; + + if (!allowRepositoryPropertyFallback) { + if (toolsPropertyValue) { + logger.info( + `No explicit tools input was provided. Ignoring '${RepositoryPropertyName.TOOLS}' repository property because it is only supported for dynamic workflows.`, + ); + } + return undefined; + } + + if (toolsPropertyValue) { + logger.info( + `Setting tools: ${toolsPropertyValue} based on the '${RepositoryPropertyName.TOOLS}' repository property.`, + ); + return toolsPropertyValue; + } + + return undefined; +}