From 5909f491f01cb1148d0a84f97b2a874387f5b8bf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Mar 2026 17:17:35 +0000 Subject: [PATCH 1/6] Initial plan From e74c1eea4ad969f004d29f62cb2a379983918272 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Mar 2026 17:30:23 +0000 Subject: [PATCH 2/6] Add github-codeql-tools repository property support for tools input Co-authored-by: oscarsj <1410188+oscarsj@users.noreply.github.com> Agent-Logs-Url: https://github.com/github/codeql-action/sessions/24ef386a-5e4a-4630-b138-747d6c5729da --- lib/analyze-action-post.js | 1 + lib/analyze-action.js | 44 +++++++---- lib/autobuild-action.js | 1 + lib/init-action-post.js | 44 +++++++---- lib/init-action.js | 56 +++++++++----- lib/resolve-environment-action.js | 1 + lib/setup-codeql-action.js | 44 +++++++---- lib/start-proxy-action-post.js | 1 + lib/start-proxy-action.js | 1 + lib/upload-lib.js | 44 +++++++---- lib/upload-sarif-action-post.js | 1 + lib/upload-sarif-action.js | 44 +++++++---- src/codeql.ts | 2 + src/feature-flags/properties.test.ts | 21 ++++++ src/feature-flags/properties.ts | 4 + src/init-action.ts | 15 +++- src/init.ts | 2 + src/setup-codeql.test.ts | 109 +++++++++++++++++++++++++++ src/setup-codeql.ts | 33 ++++++-- 19 files changed, 372 insertions(+), 96 deletions(-) diff --git a/lib/analyze-action-post.js b/lib/analyze-action-post.js index b501469f5e..fc411ec94e 100644 --- a/lib/analyze-action-post.js +++ b/lib/analyze-action-post.js @@ -162033,6 +162033,7 @@ var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; RepositoryPropertyName2["FILE_COVERAGE_ON_PRS"] = "github-codeql-file-coverage-on-prs"; + RepositoryPropertyName2["TOOLS"] = "github-codeql-tools"; return RepositoryPropertyName2; })(RepositoryPropertyName || {}); var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 7f7f4fbe88..592c059dd9 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -107537,6 +107537,7 @@ var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; RepositoryPropertyName2["FILE_COVERAGE_ON_PRS"] = "github-codeql-file-coverage-on-prs"; + RepositoryPropertyName2["TOOLS"] = "github-codeql-tools"; return RepositoryPropertyName2; })(RepositoryPropertyName || {}); var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( @@ -109491,7 +109492,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { +async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty = false) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -109559,11 +109560,17 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian const allowToolcacheValueFF = await features.getValue( "allow_toolcache_input" /* AllowToolcacheInput */ ); - const allowToolcacheValue = allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); + const allowToolcacheValue = toolsInputFromRepositoryProperty || allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); if (allowToolcacheValue) { - logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` - ); + if (toolsInputFromRepositoryProperty) { + logger.info( + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.` + ); + } else { + logger.info( + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` + ); + } latestToolcacheVersion = getLatestToolcacheVersion(logger); if (latestToolcacheVersion) { cliVersion2 = latestToolcacheVersion; @@ -109571,9 +109578,15 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian } if (latestToolcacheVersion === void 0) { if (allowToolcacheValue) { - logger.info( - `Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...` - ); + if (toolsInputFromRepositoryProperty) { + logger.info( + `Found no CodeQL CLI in the toolcache, ignoring the 'github-codeql-tools' repository property...` + ); + } else { + logger.info( + `Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...` + ); + } } else { if (allowToolcacheValueFF) { logger.warning( @@ -109796,7 +109809,7 @@ function getCanonicalToolcacheVersion(cliVersion2, bundleVersion2, logger) { } return cliVersion2; } -async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { if (!await isBinaryAccessible("tar", logger)) { throw new ConfigurationError( "Could not find tar in PATH, so unable to extract CodeQL bundle." @@ -109810,7 +109823,8 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau variant, zstdAvailability.available, features, - logger + logger, + toolsInputFromRepositoryProperty ); let codeqlFolder; let toolsVersion = source.toolsVersion; @@ -109966,7 +109980,7 @@ var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion, toolsInputFromRepositoryProperty = false) { try { const { codeqlFolder, @@ -109981,7 +109995,8 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV variant, defaultCliVersion, features, - logger + logger, + toolsInputFromRepositoryProperty ); logger.debug( `Bundle download status report: ${JSON.stringify( @@ -112679,7 +112694,7 @@ var core14 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); var github2 = __toESM(require_github()); var io6 = __toESM(require_io()); -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -112695,7 +112710,8 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe defaultCliVersion, features, logger, - true + true, + toolsInputFromRepositoryProperty ); await codeql.printVersion(); logger.endGroup(); diff --git a/lib/autobuild-action.js b/lib/autobuild-action.js index 42d955963e..eabf92cff0 100644 --- a/lib/autobuild-action.js +++ b/lib/autobuild-action.js @@ -104089,6 +104089,7 @@ var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; RepositoryPropertyName2["FILE_COVERAGE_ON_PRS"] = "github-codeql-file-coverage-on-prs"; + RepositoryPropertyName2["TOOLS"] = "github-codeql-tools"; return RepositoryPropertyName2; })(RepositoryPropertyName || {}); var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 27cb1e9b40..4897dc4669 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -165431,6 +165431,7 @@ var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; RepositoryPropertyName2["FILE_COVERAGE_ON_PRS"] = "github-codeql-file-coverage-on-prs"; + RepositoryPropertyName2["TOOLS"] = "github-codeql-tools"; return RepositoryPropertyName2; })(RepositoryPropertyName || {}); var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( @@ -167044,7 +167045,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { +async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty = false) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -167112,11 +167113,17 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian const allowToolcacheValueFF = await features.getValue( "allow_toolcache_input" /* AllowToolcacheInput */ ); - const allowToolcacheValue = allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); + const allowToolcacheValue = toolsInputFromRepositoryProperty || allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); if (allowToolcacheValue) { - logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` - ); + if (toolsInputFromRepositoryProperty) { + logger.info( + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.` + ); + } else { + logger.info( + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` + ); + } latestToolcacheVersion = getLatestToolcacheVersion(logger); if (latestToolcacheVersion) { cliVersion2 = latestToolcacheVersion; @@ -167124,9 +167131,15 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian } if (latestToolcacheVersion === void 0) { if (allowToolcacheValue) { - logger.info( - `Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...` - ); + if (toolsInputFromRepositoryProperty) { + logger.info( + `Found no CodeQL CLI in the toolcache, ignoring the 'github-codeql-tools' repository property...` + ); + } else { + logger.info( + `Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...` + ); + } } else { if (allowToolcacheValueFF) { logger.warning( @@ -167349,7 +167362,7 @@ function getCanonicalToolcacheVersion(cliVersion2, bundleVersion2, logger) { } return cliVersion2; } -async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { if (!await isBinaryAccessible("tar", logger)) { throw new ConfigurationError( "Could not find tar in PATH, so unable to extract CodeQL bundle." @@ -167363,7 +167376,8 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau variant, zstdAvailability.available, features, - logger + logger, + toolsInputFromRepositoryProperty ); let codeqlFolder; let toolsVersion = source.toolsVersion; @@ -167486,7 +167500,7 @@ var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion, toolsInputFromRepositoryProperty = false) { try { const { codeqlFolder, @@ -167501,7 +167515,8 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV variant, defaultCliVersion, features, - logger + logger, + toolsInputFromRepositoryProperty ); logger.debug( `Bundle download status report: ${JSON.stringify( @@ -169756,7 +169771,7 @@ var core14 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); var github2 = __toESM(require_github()); var io6 = __toESM(require_io()); -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -169772,7 +169787,8 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe defaultCliVersion, features, logger, - true + true, + toolsInputFromRepositoryProperty ); await codeql.printVersion(); logger.endGroup(); diff --git a/lib/init-action.js b/lib/init-action.js index 625562ed91..98f1a259ea 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -104710,6 +104710,7 @@ var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; RepositoryPropertyName2["FILE_COVERAGE_ON_PRS"] = "github-codeql-file-coverage-on-prs"; + RepositoryPropertyName2["TOOLS"] = "github-codeql-tools"; return RepositoryPropertyName2; })(RepositoryPropertyName || {}); function isString2(value) { @@ -104727,7 +104728,8 @@ var booleanProperty = { var repositoryPropertyParsers = { ["github-codeql-disable-overlay" /* DISABLE_OVERLAY */]: booleanProperty, ["github-codeql-extra-queries" /* EXTRA_QUERIES */]: stringProperty, - ["github-codeql-file-coverage-on-prs" /* FILE_COVERAGE_ON_PRS */]: booleanProperty + ["github-codeql-file-coverage-on-prs" /* FILE_COVERAGE_ON_PRS */]: booleanProperty, + ["github-codeql-tools" /* TOOLS */]: stringProperty }; async function loadPropertiesFromApi(logger, repositoryNwo) { try { @@ -108177,7 +108179,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { +async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty = false) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -108245,11 +108247,17 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian const allowToolcacheValueFF = await features.getValue( "allow_toolcache_input" /* AllowToolcacheInput */ ); - const allowToolcacheValue = allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); + const allowToolcacheValue = toolsInputFromRepositoryProperty || allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); if (allowToolcacheValue) { - logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` - ); + if (toolsInputFromRepositoryProperty) { + logger.info( + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.` + ); + } else { + logger.info( + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` + ); + } latestToolcacheVersion = getLatestToolcacheVersion(logger); if (latestToolcacheVersion) { cliVersion2 = latestToolcacheVersion; @@ -108257,9 +108265,15 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian } if (latestToolcacheVersion === void 0) { if (allowToolcacheValue) { - logger.info( - `Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...` - ); + if (toolsInputFromRepositoryProperty) { + logger.info( + `Found no CodeQL CLI in the toolcache, ignoring the 'github-codeql-tools' repository property...` + ); + } else { + logger.info( + `Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...` + ); + } } else { if (allowToolcacheValueFF) { logger.warning( @@ -108482,7 +108496,7 @@ function getCanonicalToolcacheVersion(cliVersion2, bundleVersion2, logger) { } return cliVersion2; } -async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { if (!await isBinaryAccessible("tar", logger)) { throw new ConfigurationError( "Could not find tar in PATH, so unable to extract CodeQL bundle." @@ -108496,7 +108510,8 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau variant, zstdAvailability.available, features, - logger + logger, + toolsInputFromRepositoryProperty ); let codeqlFolder; let toolsVersion = source.toolsVersion; @@ -108641,7 +108656,7 @@ var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion, toolsInputFromRepositoryProperty = false) { try { const { codeqlFolder, @@ -108656,7 +108671,8 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV variant, defaultCliVersion, features, - logger + logger, + toolsInputFromRepositoryProperty ); logger.debug( `Bundle download status report: ${JSON.stringify( @@ -109244,7 +109260,7 @@ async function getJobRunUuidSarifOptions(codeql) { } // src/init.ts -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -109260,7 +109276,8 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe defaultCliVersion, features, logger, - true + true, + toolsInputFromRepositoryProperty ); await codeql.printVersion(); logger.endGroup(); @@ -110042,14 +110059,19 @@ async function run(startedAt) { gitHubVersion.type ); toolsFeatureFlagsValid = codeQLDefaultVersionInfo.toolsFeatureFlagsValid; + const toolsWorkflowInput = getOptionalInput("tools"); + const toolsPropertyValue = repositoryPropertiesResult.orElse({})["github-codeql-tools" /* TOOLS */]; + const effectiveToolsInput = toolsWorkflowInput ?? toolsPropertyValue; + const toolsInputFromRepositoryProperty = toolsWorkflowInput === void 0 && toolsPropertyValue !== void 0; const initCodeQLResult = await initCodeQL( - getOptionalInput("tools"), + effectiveToolsInput, apiDetails, getTemporaryDirectory(), gitHubVersion.type, codeQLDefaultVersionInfo, features, - logger + logger, + toolsInputFromRepositoryProperty ); codeql = initCodeQLResult.codeql; toolsDownloadStatusReport = initCodeQLResult.toolsDownloadStatusReport; diff --git a/lib/resolve-environment-action.js b/lib/resolve-environment-action.js index df13d019d4..f4abd56335 100644 --- a/lib/resolve-environment-action.js +++ b/lib/resolve-environment-action.js @@ -104088,6 +104088,7 @@ var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; RepositoryPropertyName2["FILE_COVERAGE_ON_PRS"] = "github-codeql-file-coverage-on-prs"; + RepositoryPropertyName2["TOOLS"] = "github-codeql-tools"; return RepositoryPropertyName2; })(RepositoryPropertyName || {}); var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( diff --git a/lib/setup-codeql-action.js b/lib/setup-codeql-action.js index e710db4911..90052f7930 100644 --- a/lib/setup-codeql-action.js +++ b/lib/setup-codeql-action.js @@ -105069,6 +105069,7 @@ var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; RepositoryPropertyName2["FILE_COVERAGE_ON_PRS"] = "github-codeql-file-coverage-on-prs"; + RepositoryPropertyName2["TOOLS"] = "github-codeql-tools"; return RepositoryPropertyName2; })(RepositoryPropertyName || {}); var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( @@ -105658,7 +105659,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { +async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty = false) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -105726,11 +105727,17 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian const allowToolcacheValueFF = await features.getValue( "allow_toolcache_input" /* AllowToolcacheInput */ ); - const allowToolcacheValue = allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); + const allowToolcacheValue = toolsInputFromRepositoryProperty || allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); if (allowToolcacheValue) { - logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` - ); + if (toolsInputFromRepositoryProperty) { + logger.info( + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.` + ); + } else { + logger.info( + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` + ); + } latestToolcacheVersion = getLatestToolcacheVersion(logger); if (latestToolcacheVersion) { cliVersion2 = latestToolcacheVersion; @@ -105738,9 +105745,15 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian } if (latestToolcacheVersion === void 0) { if (allowToolcacheValue) { - logger.info( - `Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...` - ); + if (toolsInputFromRepositoryProperty) { + logger.info( + `Found no CodeQL CLI in the toolcache, ignoring the 'github-codeql-tools' repository property...` + ); + } else { + logger.info( + `Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...` + ); + } } else { if (allowToolcacheValueFF) { logger.warning( @@ -105963,7 +105976,7 @@ function getCanonicalToolcacheVersion(cliVersion2, bundleVersion2, logger) { } return cliVersion2; } -async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { if (!await isBinaryAccessible("tar", logger)) { throw new ConfigurationError( "Could not find tar in PATH, so unable to extract CodeQL bundle." @@ -105977,7 +105990,8 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau variant, zstdAvailability.available, features, - logger + logger, + toolsInputFromRepositoryProperty ); let codeqlFolder; let toolsVersion = source.toolsVersion; @@ -106100,7 +106114,7 @@ var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion, toolsInputFromRepositoryProperty = false) { try { const { codeqlFolder, @@ -106115,7 +106129,8 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV variant, defaultCliVersion, features, - logger + logger, + toolsInputFromRepositoryProperty ); logger.debug( `Bundle download status report: ${JSON.stringify( @@ -106703,7 +106718,7 @@ async function getJobRunUuidSarifOptions(codeql) { } // src/init.ts -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -106719,7 +106734,8 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe defaultCliVersion, features, logger, - true + true, + toolsInputFromRepositoryProperty ); await codeql.printVersion(); logger.endGroup(); diff --git a/lib/start-proxy-action-post.js b/lib/start-proxy-action-post.js index 0160eecbd9..af44aea8b9 100644 --- a/lib/start-proxy-action-post.js +++ b/lib/start-proxy-action-post.js @@ -161668,6 +161668,7 @@ var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; RepositoryPropertyName2["FILE_COVERAGE_ON_PRS"] = "github-codeql-file-coverage-on-prs"; + RepositoryPropertyName2["TOOLS"] = "github-codeql-tools"; return RepositoryPropertyName2; })(RepositoryPropertyName || {}); var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( diff --git a/lib/start-proxy-action.js b/lib/start-proxy-action.js index a1b8a027f8..4a26b93a71 100644 --- a/lib/start-proxy-action.js +++ b/lib/start-proxy-action.js @@ -121774,6 +121774,7 @@ var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; RepositoryPropertyName2["FILE_COVERAGE_ON_PRS"] = "github-codeql-file-coverage-on-prs"; + RepositoryPropertyName2["TOOLS"] = "github-codeql-tools"; return RepositoryPropertyName2; })(RepositoryPropertyName || {}); var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( diff --git a/lib/upload-lib.js b/lib/upload-lib.js index 485021d43d..5f119603d4 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -107132,6 +107132,7 @@ var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; RepositoryPropertyName2["FILE_COVERAGE_ON_PRS"] = "github-codeql-file-coverage-on-prs"; + RepositoryPropertyName2["TOOLS"] = "github-codeql-tools"; return RepositoryPropertyName2; })(RepositoryPropertyName || {}); var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( @@ -108347,7 +108348,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { +async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty = false) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -108415,11 +108416,17 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian const allowToolcacheValueFF = await features.getValue( "allow_toolcache_input" /* AllowToolcacheInput */ ); - const allowToolcacheValue = allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); + const allowToolcacheValue = toolsInputFromRepositoryProperty || allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); if (allowToolcacheValue) { - logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` - ); + if (toolsInputFromRepositoryProperty) { + logger.info( + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.` + ); + } else { + logger.info( + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` + ); + } latestToolcacheVersion = getLatestToolcacheVersion(logger); if (latestToolcacheVersion) { cliVersion2 = latestToolcacheVersion; @@ -108427,9 +108434,15 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian } if (latestToolcacheVersion === void 0) { if (allowToolcacheValue) { - logger.info( - `Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...` - ); + if (toolsInputFromRepositoryProperty) { + logger.info( + `Found no CodeQL CLI in the toolcache, ignoring the 'github-codeql-tools' repository property...` + ); + } else { + logger.info( + `Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...` + ); + } } else { if (allowToolcacheValueFF) { logger.warning( @@ -108652,7 +108665,7 @@ function getCanonicalToolcacheVersion(cliVersion2, bundleVersion2, logger) { } return cliVersion2; } -async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { if (!await isBinaryAccessible("tar", logger)) { throw new ConfigurationError( "Could not find tar in PATH, so unable to extract CodeQL bundle." @@ -108666,7 +108679,8 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau variant, zstdAvailability.available, features, - logger + logger, + toolsInputFromRepositoryProperty ); let codeqlFolder; let toolsVersion = source.toolsVersion; @@ -108789,7 +108803,7 @@ var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion, toolsInputFromRepositoryProperty = false) { try { const { codeqlFolder, @@ -108804,7 +108818,8 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV variant, defaultCliVersion, features, - logger + logger, + toolsInputFromRepositoryProperty ); logger.debug( `Bundle download status report: ${JSON.stringify( @@ -110524,7 +110539,7 @@ var core12 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); var github2 = __toESM(require_github()); var io5 = __toESM(require_io()); -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -110540,7 +110555,8 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe defaultCliVersion, features, logger, - true + true, + toolsInputFromRepositoryProperty ); await codeql.printVersion(); logger.endGroup(); diff --git a/lib/upload-sarif-action-post.js b/lib/upload-sarif-action-post.js index 74a5b57fd9..a8f4d79cc1 100644 --- a/lib/upload-sarif-action-post.js +++ b/lib/upload-sarif-action-post.js @@ -161820,6 +161820,7 @@ var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; RepositoryPropertyName2["FILE_COVERAGE_ON_PRS"] = "github-codeql-file-coverage-on-prs"; + RepositoryPropertyName2["TOOLS"] = "github-codeql-tools"; return RepositoryPropertyName2; })(RepositoryPropertyName || {}); var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index 484025f829..9042fe0c10 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -107858,6 +107858,7 @@ var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; RepositoryPropertyName2["FILE_COVERAGE_ON_PRS"] = "github-codeql-file-coverage-on-prs"; + RepositoryPropertyName2["TOOLS"] = "github-codeql-tools"; return RepositoryPropertyName2; })(RepositoryPropertyName || {}); var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( @@ -109009,7 +109010,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger) { +async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty = false) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -109077,11 +109078,17 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian const allowToolcacheValueFF = await features.getValue( "allow_toolcache_input" /* AllowToolcacheInput */ ); - const allowToolcacheValue = allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); + const allowToolcacheValue = toolsInputFromRepositoryProperty || allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); if (allowToolcacheValue) { - logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` - ); + if (toolsInputFromRepositoryProperty) { + logger.info( + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.` + ); + } else { + logger.info( + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` + ); + } latestToolcacheVersion = getLatestToolcacheVersion(logger); if (latestToolcacheVersion) { cliVersion2 = latestToolcacheVersion; @@ -109089,9 +109096,15 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian } if (latestToolcacheVersion === void 0) { if (allowToolcacheValue) { - logger.info( - `Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...` - ); + if (toolsInputFromRepositoryProperty) { + logger.info( + `Found no CodeQL CLI in the toolcache, ignoring the 'github-codeql-tools' repository property...` + ); + } else { + logger.info( + `Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...` + ); + } } else { if (allowToolcacheValueFF) { logger.warning( @@ -109314,7 +109327,7 @@ function getCanonicalToolcacheVersion(cliVersion2, bundleVersion2, logger) { } return cliVersion2; } -async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { if (!await isBinaryAccessible("tar", logger)) { throw new ConfigurationError( "Could not find tar in PATH, so unable to extract CodeQL bundle." @@ -109328,7 +109341,8 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau variant, zstdAvailability.available, features, - logger + logger, + toolsInputFromRepositoryProperty ); let codeqlFolder; let toolsVersion = source.toolsVersion; @@ -109451,7 +109465,7 @@ var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion, toolsInputFromRepositoryProperty = false) { try { const { codeqlFolder, @@ -109466,7 +109480,8 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV variant, defaultCliVersion, features, - logger + logger, + toolsInputFromRepositoryProperty ); logger.debug( `Bundle download status report: ${JSON.stringify( @@ -111186,7 +111201,7 @@ var core13 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); var github2 = __toESM(require_github()); var io5 = __toESM(require_io()); -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -111202,7 +111217,8 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe defaultCliVersion, features, logger, - true + true, + toolsInputFromRepositoryProperty ); await codeql.printVersion(); logger.endGroup(); diff --git a/src/codeql.ts b/src/codeql.ts index ee2773c01b..dad77466d6 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -323,6 +323,7 @@ export async function setupCodeQL( features: FeatureEnablement, logger: Logger, checkVersion: boolean, + toolsInputFromRepositoryProperty = false, ): Promise<{ codeql: CodeQL; toolsDownloadStatusReport?: ToolsDownloadStatusReport; @@ -345,6 +346,7 @@ export async function setupCodeQL( defaultCliVersion, features, logger, + toolsInputFromRepositoryProperty, ); logger.debug( diff --git a/src/feature-flags/properties.test.ts b/src/feature-flags/properties.test.ts index 2676c2dcda..912535efdc 100644 --- a/src/feature-flags/properties.test.ts +++ b/src/feature-flags/properties.test.ts @@ -90,6 +90,27 @@ test.serial("loadPropertiesFromApi loads known properties", async (t) => { t.deepEqual(response, { "github-codeql-extra-queries": "+queries" }); }); +test.serial( + "loadPropertiesFromApi loads github-codeql-tools property", + async (t) => { + sinon.stub(api, "getRepositoryProperties").resolves({ + headers: {}, + status: 200, + url: "", + data: [ + { property_name: "github-codeql-tools", value: "toolcache" }, + ] satisfies properties.GitHubPropertiesResponse, + }); + const logger = getRunnerLogger(true); + const mockRepositoryNwo = parseRepositoryNwo("owner/repo"); + const response = await properties.loadPropertiesFromApi( + logger, + mockRepositoryNwo, + ); + t.deepEqual(response, { "github-codeql-tools": "toolcache" }); + }, +); + test.serial("loadPropertiesFromApi parses true boolean property", async (t) => { sinon.stub(api, "getRepositoryProperties").resolves({ headers: {}, diff --git a/src/feature-flags/properties.ts b/src/feature-flags/properties.ts index 12ba280bec..4fb929b53f 100644 --- a/src/feature-flags/properties.ts +++ b/src/feature-flags/properties.ts @@ -13,6 +13,7 @@ export enum RepositoryPropertyName { DISABLE_OVERLAY = "github-codeql-disable-overlay", EXTRA_QUERIES = "github-codeql-extra-queries", FILE_COVERAGE_ON_PRS = "github-codeql-file-coverage-on-prs", + TOOLS = "github-codeql-tools", } /** Parsed types of the known repository properties. */ @@ -20,6 +21,7 @@ export type AllRepositoryProperties = { [RepositoryPropertyName.DISABLE_OVERLAY]: boolean; [RepositoryPropertyName.EXTRA_QUERIES]: string; [RepositoryPropertyName.FILE_COVERAGE_ON_PRS]: boolean; + [RepositoryPropertyName.TOOLS]: string; }; /** Parsed repository properties. */ @@ -30,6 +32,7 @@ export type RepositoryPropertyApiType = { [RepositoryPropertyName.DISABLE_OVERLAY]: string; [RepositoryPropertyName.EXTRA_QUERIES]: string; [RepositoryPropertyName.FILE_COVERAGE_ON_PRS]: string; + [RepositoryPropertyName.TOOLS]: string; }; /** The type of functions which take the `value` from the API and try to convert it to the type we want. */ @@ -77,6 +80,7 @@ const repositoryPropertyParsers: { [RepositoryPropertyName.DISABLE_OVERLAY]: booleanProperty, [RepositoryPropertyName.EXTRA_QUERIES]: stringProperty, [RepositoryPropertyName.FILE_COVERAGE_ON_PRS]: booleanProperty, + [RepositoryPropertyName.TOOLS]: stringProperty, }; /** diff --git a/src/init-action.ts b/src/init-action.ts index 6fe89165bd..ce705d3dd7 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -42,6 +42,7 @@ import { Feature, FeatureEnablement, initFeatures } from "./feature-flags"; import { loadPropertiesFromApi, RepositoryProperties, + RepositoryPropertyName, } from "./feature-flags/properties"; import { checkInstallPython311, @@ -297,14 +298,26 @@ async function run(startedAt: Date) { gitHubVersion.type, ); toolsFeatureFlagsValid = codeQLDefaultVersionInfo.toolsFeatureFlagsValid; + + // Determine the effective tools input. + // The explicit `tools` workflow input takes precedence. If none is provided, + // fall back to the 'github-codeql-tools' repository property (if set). + const toolsWorkflowInput = getOptionalInput("tools"); + const toolsPropertyValue: string | undefined = + repositoryPropertiesResult.orElse({})[RepositoryPropertyName.TOOLS]; + const effectiveToolsInput = toolsWorkflowInput ?? toolsPropertyValue; + const toolsInputFromRepositoryProperty = + toolsWorkflowInput === undefined && toolsPropertyValue !== undefined; + const initCodeQLResult = await initCodeQL( - getOptionalInput("tools"), + effectiveToolsInput, apiDetails, getTemporaryDirectory(), gitHubVersion.type, codeQLDefaultVersionInfo, features, logger, + toolsInputFromRepositoryProperty, ); codeql = initCodeQLResult.codeql; toolsDownloadStatusReport = initCodeQLResult.toolsDownloadStatusReport; diff --git a/src/init.ts b/src/init.ts index 8e3fa21a4a..376425861c 100644 --- a/src/init.ts +++ b/src/init.ts @@ -41,6 +41,7 @@ export async function initCodeQL( defaultCliVersion: CodeQLDefaultVersionInfo, features: FeatureEnablement, logger: Logger, + toolsInputFromRepositoryProperty = false, ): Promise<{ codeql: CodeQL; toolsDownloadStatusReport?: ToolsDownloadStatusReport; @@ -64,6 +65,7 @@ export async function initCodeQL( features, logger, true, + toolsInputFromRepositoryProperty, ); await codeql.printVersion(); logger.endGroup(); diff --git a/src/setup-codeql.test.ts b/src/setup-codeql.test.ts index 555352bd21..4c249fcfb6 100644 --- a/src/setup-codeql.test.ts +++ b/src/setup-codeql.test.ts @@ -565,6 +565,115 @@ test.serial( [`Ignoring 'tools: toolcache' because the feature is not enabled.`], ); +test.serial( + "getCodeQLSource correctly returns latest version from toolcache when set via repository property", + async (t) => { + const loggedMessages: LoggedMessage[] = []; + const logger = getRecordingLogger(loggedMessages); + const features = createFeatures([]); + + const latestToolcacheVersion = "3.2.1"; + const latestVersionPath = "/path/to/latest"; + const testVersions = ["2.3.1", latestToolcacheVersion, "1.2.3"]; + const findAllVersionsStub = sinon + .stub(toolcache, "findAllVersions") + .returns(testVersions); + const findStub = sinon.stub(toolcache, "find"); + findStub + .withArgs("CodeQL", latestToolcacheVersion) + .returns(latestVersionPath); + + await withTmpDir(async (tmpDir) => { + // Note: GITHUB_EVENT_NAME is not "dynamic", and the feature flag is not enabled. + // The repository property should bypass these restrictions. + setupActionsVars(tmpDir, tmpDir, { GITHUB_EVENT_NAME: "pull_request" }); + + const source = await setupCodeql.getCodeQLSource( + "toolcache", + SAMPLE_DEFAULT_CLI_VERSION, + SAMPLE_DOTCOM_API_DETAILS, + GitHubVariant.DOTCOM, + false, + features, + logger, + true, // toolsInputFromRepositoryProperty + ); + + t.assert( + findAllVersionsStub.calledOnceWith("CodeQL"), + `toolcache.findAllVersions("CodeQL") wasn't called`, + ); + t.assert( + findStub.calledOnceWith("CodeQL", latestToolcacheVersion), + `toolcache.find("CodeQL", ${latestToolcacheVersion}) wasn't called`, + ); + + t.is(source.sourceType, "toolcache"); + t.is(source.toolsVersion, latestToolcacheVersion); + + const expectedMessages: string[] = [ + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.`, + `CLI version ${latestToolcacheVersion} is the latest version in the toolcache.`, + `Using CodeQL CLI version ${latestToolcacheVersion} from toolcache at ${latestVersionPath}`, + ]; + for (const expectedMessage of expectedMessages) { + t.assert( + loggedMessages.some( + (msg) => + typeof msg.message === "string" && + msg.message.includes(expectedMessage), + ), + `Expected '${expectedMessage}' in the logger output, but didn't find it in:\n ${loggedMessages.map((m) => ` - '${m.message}'`).join("\n")}`, + ); + } + }); + }, +); + +test.serial( + "getCodeQLSource falls back to downloading CLI if toolcache is empty when set via repository property", + async (t) => { + const loggedMessages: LoggedMessage[] = []; + const logger = getRecordingLogger(loggedMessages); + const features = createFeatures([]); + + sinon.stub(toolcache, "findAllVersions").returns([]); + + await withTmpDir(async (tmpDir) => { + setupActionsVars(tmpDir, tmpDir, { GITHUB_EVENT_NAME: "pull_request" }); + + const source = await setupCodeql.getCodeQLSource( + "toolcache", + SAMPLE_DEFAULT_CLI_VERSION, + SAMPLE_DOTCOM_API_DETAILS, + GitHubVariant.DOTCOM, + false, + features, + logger, + true, // toolsInputFromRepositoryProperty + ); + + t.is(source.sourceType, "download"); + t.is(source.toolsVersion, SAMPLE_DEFAULT_CLI_VERSION.cliVersion); + + const expectedMessages: string[] = [ + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.`, + `Found no CodeQL CLI in the toolcache, ignoring the 'github-codeql-tools' repository property...`, + ]; + for (const expectedMessage of expectedMessages) { + t.assert( + loggedMessages.some( + (msg) => + typeof msg.message === "string" && + msg.message.includes(expectedMessage), + ), + `Expected '${expectedMessage}' in the logger output, but didn't find it in:\n ${loggedMessages.map((m) => ` - '${m.message}'`).join("\n")}`, + ); + } + }); + }, +); + test.serial( 'tryGetTagNameFromUrl extracts the right tag name for a repo name containing "codeql-bundle"', (t) => { diff --git a/src/setup-codeql.ts b/src/setup-codeql.ts index 4ca3302f95..6c0ecf4e8c 100644 --- a/src/setup-codeql.ts +++ b/src/setup-codeql.ts @@ -286,6 +286,7 @@ export async function getCodeQLSource( tarSupportsZstd: boolean, features: FeatureEnablement, logger: Logger, + toolsInputFromRepositoryProperty = false, ): Promise { // If there is an explicit `tools` input, it's not one of the reserved values, and it doesn't appear // to point to a URL, then we assume it is a local path and use the CLI from there. @@ -401,19 +402,27 @@ export async function getCodeQLSource( // We only allow `toolsInput === "toolcache"` for `dynamic` events. In general, using `toolsInput === "toolcache"` // can lead to alert wobble and so it shouldn't be used for an analysis where results are intended to be uploaded. - // We also allow this in test mode. + // We also allow this in test mode, and when the value was set via a repository property (in which case the + // organization admin has explicitly opted in to this behavior). const allowToolcacheValueFF = await features.getValue( Feature.AllowToolcacheInput, ); const allowToolcacheValue = - allowToolcacheValueFF && (isDynamicWorkflow() || util.isInTestMode()); + toolsInputFromRepositoryProperty || + (allowToolcacheValueFF && (isDynamicWorkflow() || util.isInTestMode())); if (allowToolcacheValue) { // If `toolsInput === "toolcache"`, try to find the latest version of the CLI that's available in the toolcache // and use that. We perform this check here since we can set `cliVersion` directly and don't want to default to // the linked version. - logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.`, - ); + if (toolsInputFromRepositoryProperty) { + logger.info( + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.`, + ); + } else { + logger.info( + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.`, + ); + } latestToolcacheVersion = getLatestToolcacheVersion(logger); if (latestToolcacheVersion) { @@ -423,9 +432,15 @@ export async function getCodeQLSource( if (latestToolcacheVersion === undefined) { if (allowToolcacheValue) { - logger.info( - `Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...`, - ); + if (toolsInputFromRepositoryProperty) { + logger.info( + `Found no CodeQL CLI in the toolcache, ignoring the 'github-codeql-tools' repository property...`, + ); + } else { + logger.info( + `Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...`, + ); + } } else { if (allowToolcacheValueFF) { logger.warning( @@ -793,6 +808,7 @@ export async function setupCodeQLBundle( defaultCliVersion: CodeQLDefaultVersionInfo, features: FeatureEnablement, logger: Logger, + toolsInputFromRepositoryProperty = false, ): Promise { if (!(await util.isBinaryAccessible("tar", logger))) { throw new util.ConfigurationError( @@ -809,6 +825,7 @@ export async function setupCodeQLBundle( zstdAvailability.available, features, logger, + toolsInputFromRepositoryProperty, ); let codeqlFolder: string; From 020856ca4e4f8bd905d8627cbc659ccf9a3c6ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20San=20Jos=C3=A9?= Date: Tue, 14 Apr 2026 15:10:54 +0200 Subject: [PATCH 3/6] Address comments on the PR --- src/actions-util.ts | 29 ++++++++++++++ src/codeql.ts | 2 +- src/feature-flags/properties.test.ts | 27 +++---------- src/init-action.ts | 18 ++++++--- src/init.ts | 2 +- src/setup-codeql-action.ts | 30 ++++++++++++++- src/setup-codeql.test.ts | 16 ++++++-- src/setup-codeql.ts | 57 ++++++++++++++++------------ 8 files changed, 121 insertions(+), 60 deletions(-) diff --git a/src/actions-util.ts b/src/actions-util.ts index e1a7adb8f0..296b196151 100644 --- a/src/actions-util.ts +++ b/src/actions-util.ts @@ -46,6 +46,35 @@ export const getOptionalInput = function (name: string): string | undefined { return value.length > 0 ? value : undefined; }; +/** + * Resolves the effective tools input by combining workflow input and repository properties. + * The explicit `tools` workflow input takes precedence. If none is provided, + * fall back to the repository property (if set). + * + * @param repositoryProperties - The loaded repository properties object + * @param toolsPropertyName - The name of the tools property to look up + * @returns An object containing the effective tools input and whether it came from repository property + */ +export function resolveToolsInput( + repositoryProperties: Record, + toolsPropertyName: string, +): { + effectiveToolsInput: string | undefined; + toolsInputFromRepositoryProperty: boolean; +} { + const toolsWorkflowInput = getOptionalInput("tools"); + const toolsPropertyValue: string | undefined = + repositoryProperties[toolsPropertyName]; + const effectiveToolsInput = toolsWorkflowInput ?? toolsPropertyValue; + const toolsInputFromRepositoryProperty = + toolsWorkflowInput === undefined && toolsPropertyValue !== undefined; + + return { + effectiveToolsInput, + toolsInputFromRepositoryProperty, + }; +} + export function getTemporaryDirectory(): string { const value = process.env["CODEQL_ACTION_TEMP"]; return value !== undefined && value !== "" diff --git a/src/codeql.ts b/src/codeql.ts index dad77466d6..4978de66f8 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -323,7 +323,7 @@ export async function setupCodeQL( features: FeatureEnablement, logger: Logger, checkVersion: boolean, - toolsInputFromRepositoryProperty = false, + toolsInputFromRepositoryProperty: boolean, ): Promise<{ codeql: CodeQL; toolsDownloadStatusReport?: ToolsDownloadStatusReport; diff --git a/src/feature-flags/properties.test.ts b/src/feature-flags/properties.test.ts index 912535efdc..2bb9e10e4f 100644 --- a/src/feature-flags/properties.test.ts +++ b/src/feature-flags/properties.test.ts @@ -78,6 +78,7 @@ test.serial("loadPropertiesFromApi loads known properties", async (t) => { url: "", data: [ { property_name: "github-codeql-extra-queries", value: "+queries" }, + { property_name: "github-codeql-tools", value: "toolcache" }, { property_name: "unknown-property", value: "something" }, ] satisfies properties.GitHubPropertiesResponse, }); @@ -87,30 +88,12 @@ test.serial("loadPropertiesFromApi loads known properties", async (t) => { logger, mockRepositoryNwo, ); - t.deepEqual(response, { "github-codeql-extra-queries": "+queries" }); + t.deepEqual(response, { + "github-codeql-extra-queries": "+queries", + "github-codeql-tools": "toolcache", + }); }); -test.serial( - "loadPropertiesFromApi loads github-codeql-tools property", - async (t) => { - sinon.stub(api, "getRepositoryProperties").resolves({ - headers: {}, - status: 200, - url: "", - data: [ - { property_name: "github-codeql-tools", value: "toolcache" }, - ] satisfies properties.GitHubPropertiesResponse, - }); - const logger = getRunnerLogger(true); - const mockRepositoryNwo = parseRepositoryNwo("owner/repo"); - const response = await properties.loadPropertiesFromApi( - logger, - mockRepositoryNwo, - ); - t.deepEqual(response, { "github-codeql-tools": "toolcache" }); - }, -); - test.serial("loadPropertiesFromApi parses true boolean property", async (t) => { sinon.stub(api, "getRepositoryProperties").resolves({ headers: {}, diff --git a/src/init-action.ts b/src/init-action.ts index ce705d3dd7..9a878363e7 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -15,6 +15,7 @@ import { getRequiredInput, getTemporaryDirectory, persistInputs, + resolveToolsInput, } from "./actions-util"; import { AnalysisKind, getAnalysisKinds } from "./analyses"; import { getGitHubVersion, GitHubApiCombinedDetails } from "./api-client"; @@ -141,6 +142,7 @@ async function sendCompletedStatusReport( toolsFeatureFlagsValid: boolean | undefined, toolsSource: ToolsSource, toolsVersion: string, + effectiveToolsInput: string | undefined, overlayBaseDatabaseStats: OverlayBaseDatabaseDownloadStats | undefined, dependencyCachingResults: DependencyCacheRestoreStatusReport | undefined, logger: Logger, @@ -165,7 +167,7 @@ async function sendCompletedStatusReport( const initStatusReport: InitStatusReport = { ...statusReportBase, - tools_input: getOptionalInput("tools") || "", + tools_input: effectiveToolsInput || "", tools_resolved_version: toolsVersion, tools_source: toolsSource || ToolsSource.Unknown, workflow_languages: workflowLanguages || "", @@ -220,6 +222,7 @@ async function run(startedAt: Date) { let toolsSource: ToolsSource; let toolsVersion: string; let zstdAvailability: ZstdAvailability | undefined; + let effectiveToolsInput: string | undefined; try { initializeEnvironment(getActionVersion()); @@ -302,12 +305,13 @@ async function run(startedAt: Date) { // Determine the effective tools input. // The explicit `tools` workflow input takes precedence. If none is provided, // fall back to the 'github-codeql-tools' repository property (if set). - const toolsWorkflowInput = getOptionalInput("tools"); - const toolsPropertyValue: string | undefined = - repositoryPropertiesResult.orElse({})[RepositoryPropertyName.TOOLS]; - const effectiveToolsInput = toolsWorkflowInput ?? toolsPropertyValue; + const resolvedToolsInput = resolveToolsInput( + repositoryPropertiesResult.orElse({}), + RepositoryPropertyName.TOOLS, + ); + effectiveToolsInput = resolvedToolsInput.effectiveToolsInput; const toolsInputFromRepositoryProperty = - toolsWorkflowInput === undefined && toolsPropertyValue !== undefined; + resolvedToolsInput.toolsInputFromRepositoryProperty; const initCodeQLResult = await initCodeQL( effectiveToolsInput, @@ -791,6 +795,7 @@ async function run(startedAt: Date) { toolsFeatureFlagsValid, toolsSource, toolsVersion, + effectiveToolsInput, overlayBaseDatabaseStats, dependencyCachingStatus, logger, @@ -808,6 +813,7 @@ async function run(startedAt: Date) { toolsFeatureFlagsValid, toolsSource, toolsVersion, + effectiveToolsInput, overlayBaseDatabaseStats, dependencyCachingStatus, logger, diff --git a/src/init.ts b/src/init.ts index 376425861c..6519ec361e 100644 --- a/src/init.ts +++ b/src/init.ts @@ -41,7 +41,7 @@ export async function initCodeQL( defaultCliVersion: CodeQLDefaultVersionInfo, features: FeatureEnablement, logger: Logger, - toolsInputFromRepositoryProperty = false, + toolsInputFromRepositoryProperty: boolean, ): Promise<{ codeql: CodeQL; toolsDownloadStatusReport?: ToolsDownloadStatusReport; diff --git a/src/setup-codeql-action.ts b/src/setup-codeql-action.ts index bd504f3fd3..619da8959f 100644 --- a/src/setup-codeql-action.ts +++ b/src/setup-codeql-action.ts @@ -6,11 +6,16 @@ import { getOptionalInput, getRequiredInput, getTemporaryDirectory, + resolveToolsInput, } from "./actions-util"; import { getGitHubVersion } from "./api-client"; import { CodeQL } from "./codeql"; import { EnvVar } from "./environment"; import { initFeatures } from "./feature-flags"; +import { + loadPropertiesFromApi, + RepositoryPropertyName, +} from "./feature-flags/properties"; import { initCodeQL } from "./init"; import { getActionsLogger, Logger } from "./logging"; import { getRepositoryNwo } from "./repository"; @@ -46,6 +51,7 @@ async function sendCompletedStatusReport( toolsFeatureFlagsValid: boolean | undefined, toolsSource: ToolsSource, toolsVersion: string, + effectiveToolsInput: string | undefined, logger: Logger, error?: Error, ): Promise { @@ -66,7 +72,7 @@ async function sendCompletedStatusReport( const initStatusReport: InitStatusReport = { ...statusReportBase, - tools_input: getOptionalInput("tools") || "", + tools_input: effectiveToolsInput || "", tools_resolved_version: toolsVersion, tools_source: toolsSource || ToolsSource.Unknown, workflow_languages: "", @@ -97,6 +103,7 @@ async function run(startedAt: Date): Promise { let toolsFeatureFlagsValid: boolean | undefined; let toolsSource: ToolsSource; let toolsVersion: string; + let effectiveToolsInput: string | undefined; try { initializeEnvironment(getActionVersion()); @@ -121,6 +128,11 @@ async function run(startedAt: Date): Promise { logger, ); + const repositoryPropertiesResult = await loadPropertiesFromApi( + logger, + repositoryNwo, + ); + const jobRunUuid = uuidV4(); logger.info(`Job run UUID is ${jobRunUuid}.`); core.exportVariable(EnvVar.JOB_RUN_UUID, jobRunUuid); @@ -140,14 +152,27 @@ async function run(startedAt: Date): Promise { gitHubVersion.type, ); toolsFeatureFlagsValid = codeQLDefaultVersionInfo.toolsFeatureFlagsValid; + + // Determine the effective tools input. + // The explicit `tools` workflow input takes precedence. If none is provided, + // fall back to the 'github-codeql-tools' repository property (if set). + const resolvedToolsInput = resolveToolsInput( + repositoryPropertiesResult, + RepositoryPropertyName.TOOLS, + ); + effectiveToolsInput = resolvedToolsInput.effectiveToolsInput; + const toolsInputFromRepositoryProperty = + resolvedToolsInput.toolsInputFromRepositoryProperty; + const initCodeQLResult = await initCodeQL( - getOptionalInput("tools"), + effectiveToolsInput, apiDetails, getTemporaryDirectory(), gitHubVersion.type, codeQLDefaultVersionInfo, features, logger, + toolsInputFromRepositoryProperty, ); codeql = initCodeQLResult.codeql; toolsDownloadStatusReport = initCodeQLResult.toolsDownloadStatusReport; @@ -183,6 +208,7 @@ async function run(startedAt: Date): Promise { toolsFeatureFlagsValid, toolsSource, toolsVersion, + effectiveToolsInput, logger, ); } diff --git a/src/setup-codeql.test.ts b/src/setup-codeql.test.ts index 4c249fcfb6..72a53cbcbc 100644 --- a/src/setup-codeql.test.ts +++ b/src/setup-codeql.test.ts @@ -8,6 +8,7 @@ import * as sinon from "sinon"; import * as actionsUtil from "./actions-util"; import * as api from "./api-client"; import { Feature, FeatureEnablement } from "./feature-flags"; +import { RepositoryPropertyName } from "./feature-flags/properties"; import { getRunnerLogger } from "./logging"; import * as setupCodeql from "./setup-codeql"; import * as tar from "./tar"; @@ -112,6 +113,7 @@ test.serial( false, features, getRunnerLogger(true), + false, ); t.is(source.sourceType, "download"); @@ -135,6 +137,7 @@ test.serial( false, features, getRunnerLogger(true), + false, ); t.is(source.toolsVersion, LINKED_CLI_VERSION.cliVersion); @@ -160,6 +163,7 @@ test.serial( false, features, logger, + false, ); // First, ensure that the CLI version is the linked version, so that backwards @@ -213,6 +217,7 @@ test.serial( SAMPLE_DEFAULT_CLI_VERSION, features, logger, + false, ); // Basic sanity check that the version we got back is indeed @@ -268,6 +273,7 @@ test.serial( SAMPLE_DEFAULT_CLI_VERSION, features, logger, + false, ); // Basic sanity check that the version we got back is indeed the version that the @@ -322,6 +328,7 @@ test.serial( false, features, logger, + false, ); // Check that the `CodeQLToolsSource` object matches our expectations. @@ -383,6 +390,7 @@ test.serial( false, features, logger, + false, ); // Check that the `CodeQLToolsSource` object matches our expectations. @@ -437,6 +445,7 @@ test.serial( false, features, logger, + false, ); // Check that the toolcache functions were called with the expected arguments @@ -504,6 +513,7 @@ const toolcacheInputFallbackMacro = test.macro({ false, features, logger, + false, ); // Check that the toolcache functions were called with the expected arguments @@ -612,7 +622,7 @@ test.serial( t.is(source.toolsVersion, latestToolcacheVersion); const expectedMessages: string[] = [ - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.`, + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the '${RepositoryPropertyName.TOOLS}' repository property.`, `CLI version ${latestToolcacheVersion} is the latest version in the toolcache.`, `Using CodeQL CLI version ${latestToolcacheVersion} from toolcache at ${latestVersionPath}`, ]; @@ -657,8 +667,8 @@ test.serial( t.is(source.toolsVersion, SAMPLE_DEFAULT_CLI_VERSION.cliVersion); const expectedMessages: string[] = [ - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.`, - `Found no CodeQL CLI in the toolcache, ignoring the 'github-codeql-tools' repository property...`, + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the '${RepositoryPropertyName.TOOLS}' repository property.`, + `Found no CodeQL CLI in the toolcache, ignoring the '${RepositoryPropertyName.TOOLS}' repository property...`, ]; for (const expectedMessage of expectedMessages) { t.assert( diff --git a/src/setup-codeql.ts b/src/setup-codeql.ts index 6c0ecf4e8c..b564161aa2 100644 --- a/src/setup-codeql.ts +++ b/src/setup-codeql.ts @@ -17,6 +17,7 @@ import { Feature, FeatureEnablement, } from "./feature-flags"; +import { RepositoryPropertyName } from "./feature-flags/properties"; import { Logger } from "./logging"; import * as tar from "./tar"; import { @@ -264,6 +265,24 @@ async function findOverridingToolsInCache( return undefined; } +/** + * Creates a user-friendly description of the tools input origin for log messages. + * + * @param toolsInput The tools input value + * @param toolsInputFromRepositoryProperty Whether the tools input came from repository property + * @returns A description like "'tools: toolcache'" or "the 'github-codeql-tools' repository property" + */ +function getToolsInputOriginDescription( + toolsInput: string | undefined, + toolsInputFromRepositoryProperty: boolean, +): string { + if (toolsInputFromRepositoryProperty) { + return `the '${RepositoryPropertyName.TOOLS}' repository property`; + } else { + return `'tools: ${toolsInput}'`; + } +} + /** * Determines where the CodeQL CLI we want to use comes from. This can be from a local file, * the Actions toolcache, or a download. @@ -286,7 +305,7 @@ export async function getCodeQLSource( tarSupportsZstd: boolean, features: FeatureEnablement, logger: Logger, - toolsInputFromRepositoryProperty = false, + toolsInputFromRepositoryProperty: boolean, ): Promise { // If there is an explicit `tools` input, it's not one of the reserved values, and it doesn't appear // to point to a URL, then we assume it is a local path and use the CLI from there. @@ -361,7 +380,7 @@ export async function getCodeQLSource( ); } else { logger.info( - `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.`, + `Using the latest CodeQL CLI nightly, as requested by ${getToolsInputOriginDescription(toolsInput, toolsInputFromRepositoryProperty)}.`, ); } toolsInput = await getNightlyToolsUrl(logger); @@ -386,7 +405,7 @@ export async function getCodeQLSource( tagName = defaults.bundleVersion; logger.info( - `'tools: ${toolsInput}' was requested, so using CodeQL version ${cliVersion}, the version shipped with the Action.`, + `${getToolsInputOriginDescription(toolsInput, toolsInputFromRepositoryProperty)} was requested, so using CodeQL version ${cliVersion}, the version shipped with the Action.`, ); if (toolsInput === "latest") { @@ -414,15 +433,9 @@ export async function getCodeQLSource( // If `toolsInput === "toolcache"`, try to find the latest version of the CLI that's available in the toolcache // and use that. We perform this check here since we can set `cliVersion` directly and don't want to default to // the linked version. - if (toolsInputFromRepositoryProperty) { - logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.`, - ); - } else { - logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.`, - ); - } + logger.info( + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by ${getToolsInputOriginDescription(toolsInput, toolsInputFromRepositoryProperty)}.`, + ); latestToolcacheVersion = getLatestToolcacheVersion(logger); if (latestToolcacheVersion) { @@ -432,23 +445,17 @@ export async function getCodeQLSource( if (latestToolcacheVersion === undefined) { if (allowToolcacheValue) { - if (toolsInputFromRepositoryProperty) { - logger.info( - `Found no CodeQL CLI in the toolcache, ignoring the 'github-codeql-tools' repository property...`, - ); - } else { - logger.info( - `Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...`, - ); - } + logger.info( + `Found no CodeQL CLI in the toolcache, ignoring ${getToolsInputOriginDescription(toolsInput, toolsInputFromRepositoryProperty)}...`, + ); } else { if (allowToolcacheValueFF) { logger.warning( - `Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.`, + `Ignoring ${getToolsInputOriginDescription(toolsInput, toolsInputFromRepositoryProperty)} because the workflow was not triggered dynamically.`, ); } else { - logger.info( - `Ignoring 'tools: ${toolsInput}' because the feature is not enabled.`, + logger.warning( + `Ignoring ${getToolsInputOriginDescription(toolsInput, toolsInputFromRepositoryProperty)} because the feature is not enabled.`, ); } } @@ -808,7 +815,7 @@ export async function setupCodeQLBundle( defaultCliVersion: CodeQLDefaultVersionInfo, features: FeatureEnablement, logger: Logger, - toolsInputFromRepositoryProperty = false, + toolsInputFromRepositoryProperty: boolean, ): Promise { if (!(await util.isBinaryAccessible("tar", logger))) { throw new util.ConfigurationError( From 3b0b845f42e6f4bf53a8a3f17fe0fa58e9e5d571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20San=20Jos=C3=A9?= Date: Tue, 14 Apr 2026 18:35:27 +0200 Subject: [PATCH 4/6] Some more suggestions from CR --- src/setup-codeql.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/setup-codeql.ts b/src/setup-codeql.ts index b564161aa2..8222f96e2a 100644 --- a/src/setup-codeql.ts +++ b/src/setup-codeql.ts @@ -427,8 +427,10 @@ export async function getCodeQLSource( Feature.AllowToolcacheInput, ); const allowToolcacheValue = - toolsInputFromRepositoryProperty || - (allowToolcacheValueFF && (isDynamicWorkflow() || util.isInTestMode())); + allowToolcacheValueFF && + (toolsInputFromRepositoryProperty || + isDynamicWorkflow() || + util.isInTestMode()); if (allowToolcacheValue) { // If `toolsInput === "toolcache"`, try to find the latest version of the CLI that's available in the toolcache // and use that. We perform this check here since we can set `cliVersion` directly and don't want to default to From 8c412539478fdadbde2b6512a4b323fd9a6d6e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20San=20Jos=C3=A9?= Date: Wed, 15 Apr 2026 11:45:57 +0200 Subject: [PATCH 5/6] Changes from CR --- CHANGELOG.md | 2 +- lib/analyze-action.js | 46 +++++---- lib/init-action-post.js | 46 +++++---- lib/init-action.js | 55 +++++++---- lib/setup-codeql-action.js | 191 ++++++++++++++++++++++++++++++------- lib/upload-lib.js | 46 +++++---- lib/upload-sarif-action.js | 46 +++++---- src/actions-util.ts | 27 +++--- src/codeql.ts | 2 - src/init-action.ts | 7 +- src/init.ts | 2 - src/setup-codeql-action.ts | 7 +- src/setup-codeql.test.ts | 15 +-- src/setup-codeql.ts | 64 ++++++------- src/upload-lib.ts | 23 ++++- 15 files changed, 376 insertions(+), 203 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d94f28e616..4ab7938f6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th ## [UNRELEASED] -No user facing changes. +- Organizations can now create a custom repository property with the name `github-codeql-tools` to control the CodeQL CLI tools input at the repository level. When this property is set to a valid tools input value (such as `"toolcache"`, `"latest"`, or a specific version), it will override the default tools configuration for that repository. This allows organization administrators to standardize CodeQL CLI versions across repositories or enable toolcache usage on repositories where it would otherwise be restricted. For more information on creating custom repository properties, see [Managing custom properties for repositories in your organization](https://docs.github.com/en/organizations/managing-organization-settings/managing-custom-properties-for-repositories-in-your-organization). ## 4.34.1 - 20 Mar 2026 diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 592c059dd9..24494ac487 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -109538,7 +109538,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ); } else { logger.info( - `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` + `Using the latest CodeQL CLI nightly, as requested.` ); } toolsInput = await getNightlyToolsUrl(logger); @@ -109560,15 +109560,16 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian const allowToolcacheValueFF = await features.getValue( "allow_toolcache_input" /* AllowToolcacheInput */ ); - const allowToolcacheValue = toolsInputFromRepositoryProperty || allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); + const allowToolcacheValue = toolsInputFromRepositoryProperty || // Repository properties bypass all restrictions + allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); if (allowToolcacheValue) { if (toolsInputFromRepositoryProperty) { logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.` + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the '${"github-codeql-tools" /* TOOLS */}' repository property.` ); } else { logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested.` ); } latestToolcacheVersion = getLatestToolcacheVersion(logger); @@ -109580,7 +109581,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian if (allowToolcacheValue) { if (toolsInputFromRepositoryProperty) { logger.info( - `Found no CodeQL CLI in the toolcache, ignoring the 'github-codeql-tools' repository property...` + `Found no CodeQL CLI in the toolcache, ignoring the '${"github-codeql-tools" /* TOOLS */}' repository property...` ); } else { logger.info( @@ -109593,7 +109594,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian `Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.` ); } else { - logger.info( + logger.warning( `Ignoring 'tools: ${toolsInput}' because the feature is not enabled.` ); } @@ -109980,7 +109981,7 @@ var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion, toolsInputFromRepositoryProperty = false) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { try { const { codeqlFolder, @@ -109995,8 +109996,7 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV variant, defaultCliVersion, features, - logger, - toolsInputFromRepositoryProperty + logger ); logger.debug( `Bundle download status report: ${JSON.stringify( @@ -112694,7 +112694,7 @@ var core14 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); var github2 = __toESM(require_github()); var io6 = __toESM(require_io()); -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -112710,8 +112710,7 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe defaultCliVersion, features, logger, - true, - toolsInputFromRepositoryProperty + true ); await codeql.printVersion(); logger.endGroup(); @@ -113248,20 +113247,33 @@ async function waitForProcessing(repositoryNwo, sarifID, logger, options = { ); break; } + if (!response) { + logger.warning( + "Unable to check analysis status due to missing response. It should still be processed in the background." + ); + break; + } const status = response.data.processing_status; logger.info(`Analysis upload status is ${status}.`); if (status === "pending") { logger.debug("Analysis processing is still pending..."); } else if (options.isUnsuccessfulExecution) { - handleProcessingResultForUnsuccessfulExecution( - response, - status, - logger - ); + if (response) { + handleProcessingResultForUnsuccessfulExecution( + response, + status, + logger + ); + } break; } else if (status === "complete") { break; } else if (status === "failed") { + if (!response) { + throw new Error( + "Code Scanning could not process the submitted SARIF file: Unable to retrieve error details." + ); + } const message = `Code Scanning could not process the submitted SARIF file: ${response.data.errors}`; const processingErrors = response.data.errors; diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 4897dc4669..36d42f87f1 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -167091,7 +167091,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ); } else { logger.info( - `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` + `Using the latest CodeQL CLI nightly, as requested.` ); } toolsInput = await getNightlyToolsUrl(logger); @@ -167113,15 +167113,16 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian const allowToolcacheValueFF = await features.getValue( "allow_toolcache_input" /* AllowToolcacheInput */ ); - const allowToolcacheValue = toolsInputFromRepositoryProperty || allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); + const allowToolcacheValue = toolsInputFromRepositoryProperty || // Repository properties bypass all restrictions + allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); if (allowToolcacheValue) { if (toolsInputFromRepositoryProperty) { logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.` + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the '${"github-codeql-tools" /* TOOLS */}' repository property.` ); } else { logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested.` ); } latestToolcacheVersion = getLatestToolcacheVersion(logger); @@ -167133,7 +167134,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian if (allowToolcacheValue) { if (toolsInputFromRepositoryProperty) { logger.info( - `Found no CodeQL CLI in the toolcache, ignoring the 'github-codeql-tools' repository property...` + `Found no CodeQL CLI in the toolcache, ignoring the '${"github-codeql-tools" /* TOOLS */}' repository property...` ); } else { logger.info( @@ -167146,7 +167147,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian `Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.` ); } else { - logger.info( + logger.warning( `Ignoring 'tools: ${toolsInput}' because the feature is not enabled.` ); } @@ -167500,7 +167501,7 @@ var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion, toolsInputFromRepositoryProperty = false) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { try { const { codeqlFolder, @@ -167515,8 +167516,7 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV variant, defaultCliVersion, features, - logger, - toolsInputFromRepositoryProperty + logger ); logger.debug( `Bundle download status report: ${JSON.stringify( @@ -169771,7 +169771,7 @@ var core14 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); var github2 = __toESM(require_github()); var io6 = __toESM(require_io()); -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -169787,8 +169787,7 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe defaultCliVersion, features, logger, - true, - toolsInputFromRepositoryProperty + true ); await codeql.printVersion(); logger.endGroup(); @@ -170296,20 +170295,33 @@ async function waitForProcessing(repositoryNwo, sarifID, logger, options = { ); break; } + if (!response) { + logger.warning( + "Unable to check analysis status due to missing response. It should still be processed in the background." + ); + break; + } const status = response.data.processing_status; logger.info(`Analysis upload status is ${status}.`); if (status === "pending") { logger.debug("Analysis processing is still pending..."); } else if (options.isUnsuccessfulExecution) { - handleProcessingResultForUnsuccessfulExecution( - response, - status, - logger - ); + if (response) { + handleProcessingResultForUnsuccessfulExecution( + response, + status, + logger + ); + } break; } else if (status === "complete") { break; } else if (status === "failed") { + if (!response) { + throw new Error( + "Code Scanning could not process the submitted SARIF file: Unable to retrieve error details." + ); + } const message = `Code Scanning could not process the submitted SARIF file: ${response.data.errors}`; const processingErrors = response.data.errors; diff --git a/lib/init-action.js b/lib/init-action.js index 98f1a259ea..2c9d70be0b 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -104077,6 +104077,19 @@ var getOptionalInput = function(name) { const value = core4.getInput(name); return value.length > 0 ? value : void 0; }; +function resolveToolsInput(repositoryProperties, toolsPropertyName, logger) { + const toolsWorkflowInput = getOptionalInput("tools"); + const toolsPropertyValue = repositoryProperties[toolsPropertyName]; + const effectiveToolsInput = toolsWorkflowInput ?? toolsPropertyValue; + if (effectiveToolsInput) { + if (toolsWorkflowInput) { + logger.info(`Setting tools: ${effectiveToolsInput} based on workflow input.`); + } else { + logger.info(`Setting tools: ${effectiveToolsInput} based on the '${toolsPropertyName}' repository property.`); + } + } + return effectiveToolsInput; +} function getTemporaryDirectory() { const value = process.env["CODEQL_ACTION_TEMP"]; return value !== void 0 && value !== "" ? value : getRequiredEnvParam("RUNNER_TEMP"); @@ -108225,7 +108238,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ); } else { logger.info( - `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` + `Using the latest CodeQL CLI nightly, as requested.` ); } toolsInput = await getNightlyToolsUrl(logger); @@ -108247,15 +108260,16 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian const allowToolcacheValueFF = await features.getValue( "allow_toolcache_input" /* AllowToolcacheInput */ ); - const allowToolcacheValue = toolsInputFromRepositoryProperty || allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); + const allowToolcacheValue = toolsInputFromRepositoryProperty || // Repository properties bypass all restrictions + allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); if (allowToolcacheValue) { if (toolsInputFromRepositoryProperty) { logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.` + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the '${"github-codeql-tools" /* TOOLS */}' repository property.` ); } else { logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested.` ); } latestToolcacheVersion = getLatestToolcacheVersion(logger); @@ -108267,7 +108281,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian if (allowToolcacheValue) { if (toolsInputFromRepositoryProperty) { logger.info( - `Found no CodeQL CLI in the toolcache, ignoring the 'github-codeql-tools' repository property...` + `Found no CodeQL CLI in the toolcache, ignoring the '${"github-codeql-tools" /* TOOLS */}' repository property...` ); } else { logger.info( @@ -108280,7 +108294,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian `Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.` ); } else { - logger.info( + logger.warning( `Ignoring 'tools: ${toolsInput}' because the feature is not enabled.` ); } @@ -108656,7 +108670,7 @@ var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion, toolsInputFromRepositoryProperty = false) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { try { const { codeqlFolder, @@ -108671,8 +108685,7 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV variant, defaultCliVersion, features, - logger, - toolsInputFromRepositoryProperty + logger ); logger.debug( `Bundle download status report: ${JSON.stringify( @@ -109260,7 +109273,7 @@ async function getJobRunUuidSarifOptions(codeql) { } // src/init.ts -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -109276,8 +109289,7 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe defaultCliVersion, features, logger, - true, - toolsInputFromRepositoryProperty + true ); await codeql.printVersion(); logger.endGroup(); @@ -109948,7 +109960,7 @@ async function sendStartingStatusReport(startedAt, config, logger) { await sendStatusReport(statusReportBase); } } -async function sendCompletedStatusReport(startedAt, config, configFile, toolsDownloadStatusReport, toolsFeatureFlagsValid, toolsSource, toolsVersion, overlayBaseDatabaseStats, dependencyCachingResults, logger, error3) { +async function sendCompletedStatusReport(startedAt, config, configFile, toolsDownloadStatusReport, toolsFeatureFlagsValid, toolsSource, toolsVersion, effectiveToolsInput, overlayBaseDatabaseStats, dependencyCachingResults, logger, error3) { const statusReportBase = await createStatusReportBase( "init" /* Init */, getActionsStatus(error3), @@ -109965,7 +109977,7 @@ async function sendCompletedStatusReport(startedAt, config, configFile, toolsDow const workflowLanguages = getOptionalInput("languages"); const initStatusReport = { ...statusReportBase, - tools_input: getOptionalInput("tools") || "", + tools_input: effectiveToolsInput || "", tools_resolved_version: toolsVersion, tools_source: toolsSource || "UNKNOWN" /* Unknown */, workflow_languages: workflowLanguages || "" @@ -110009,6 +110021,7 @@ async function run(startedAt) { let toolsSource; let toolsVersion; let zstdAvailability; + let effectiveToolsInput; try { initializeEnvironment(getActionVersion()); persistInputs(); @@ -110059,10 +110072,11 @@ async function run(startedAt) { gitHubVersion.type ); toolsFeatureFlagsValid = codeQLDefaultVersionInfo.toolsFeatureFlagsValid; - const toolsWorkflowInput = getOptionalInput("tools"); - const toolsPropertyValue = repositoryPropertiesResult.orElse({})["github-codeql-tools" /* TOOLS */]; - const effectiveToolsInput = toolsWorkflowInput ?? toolsPropertyValue; - const toolsInputFromRepositoryProperty = toolsWorkflowInput === void 0 && toolsPropertyValue !== void 0; + effectiveToolsInput = resolveToolsInput( + repositoryPropertiesResult.orElse({}), + "github-codeql-tools" /* TOOLS */, + logger + ); const initCodeQLResult = await initCodeQL( effectiveToolsInput, apiDetails, @@ -110070,8 +110084,7 @@ async function run(startedAt) { gitHubVersion.type, codeQLDefaultVersionInfo, features, - logger, - toolsInputFromRepositoryProperty + logger ); codeql = initCodeQLResult.codeql; toolsDownloadStatusReport = initCodeQLResult.toolsDownloadStatusReport; @@ -110406,6 +110419,7 @@ exec ${goBinaryPath} "$@"` toolsFeatureFlagsValid, toolsSource, toolsVersion, + effectiveToolsInput, overlayBaseDatabaseStats, dependencyCachingStatus, logger, @@ -110423,6 +110437,7 @@ exec ${goBinaryPath} "$@"` toolsFeatureFlagsValid, toolsSource, toolsVersion, + effectiveToolsInput, overlayBaseDatabaseStats, dependencyCachingStatus, logger diff --git a/lib/setup-codeql-action.js b/lib/setup-codeql-action.js index 90052f7930..7784118bba 100644 --- a/lib/setup-codeql-action.js +++ b/lib/setup-codeql-action.js @@ -100236,7 +100236,7 @@ var require_follow_redirects = __commonJS({ if (this._ending) { throw new WriteAfterEndError(); } - if (!isString2(data) && !isBuffer(data)) { + if (!isString3(data) && !isBuffer(data)) { throw new TypeError("data should be a string, Buffer or Uint8Array"); } if (isFunction(encoding)) { @@ -100491,7 +100491,7 @@ var require_follow_redirects = __commonJS({ function request2(input, options, callback) { if (isURL(input)) { input = spreadUrlObject(input); - } else if (isString2(input)) { + } else if (isString3(input)) { input = spreadUrlObject(parseUrl2(input)); } else { callback = options; @@ -100507,7 +100507,7 @@ var require_follow_redirects = __commonJS({ maxBodyLength: exports3.maxBodyLength }, input, options); options.nativeProtocols = nativeProtocols; - if (!isString2(options.host) && !isString2(options.hostname)) { + if (!isString3(options.host) && !isString3(options.hostname)) { options.hostname = "::1"; } assert.equal(options.protocol, protocol, "protocol mismatch"); @@ -100534,7 +100534,7 @@ var require_follow_redirects = __commonJS({ parsed = new URL2(input); } else { parsed = validateUrl(url.parse(input)); - if (!isString2(parsed.protocol)) { + if (!isString3(parsed.protocol)) { throw new InvalidUrlError({ input }); } } @@ -100606,11 +100606,11 @@ var require_follow_redirects = __commonJS({ request2.destroy(error3); } function isSubdomain(subdomain, domain) { - assert(isString2(subdomain) && isString2(domain)); + assert(isString3(subdomain) && isString3(domain)); var dot = subdomain.length - domain.length - 1; return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain); } - function isString2(value) { + function isString3(value) { return typeof value === "string" || value instanceof String; } function isFunction(value) { @@ -103620,6 +103620,19 @@ var getOptionalInput = function(name) { const value = core4.getInput(name); return value.length > 0 ? value : void 0; }; +function resolveToolsInput(repositoryProperties, toolsPropertyName, logger) { + const toolsWorkflowInput = getOptionalInput("tools"); + const toolsPropertyValue = repositoryProperties[toolsPropertyName]; + const effectiveToolsInput = toolsWorkflowInput ?? toolsPropertyValue; + if (effectiveToolsInput) { + if (toolsWorkflowInput) { + logger.info(`Setting tools: ${effectiveToolsInput} based on workflow input.`); + } else { + logger.info(`Setting tools: ${effectiveToolsInput} based on the '${toolsPropertyName}' repository property.`); + } + } + return effectiveToolsInput; +} function getTemporaryDirectory() { const value = process.env["CODEQL_ACTION_TEMP"]; return value !== void 0 && value !== "" ? value : getRequiredEnvParam("RUNNER_TEMP"); @@ -103936,6 +103949,12 @@ async function getAnalysisKey() { core5.exportVariable("CODEQL_ACTION_ANALYSIS_KEY" /* ANALYSIS_KEY */, analysisKey); return analysisKey; } +async function getRepositoryProperties(repositoryNwo) { + return getApiClient().request("GET /repos/:owner/:repo/properties/values", { + owner: repositoryNwo.owner, + repo: repositoryNwo.repo + }); +} function isEnablementError(msg) { return [ /Code Security must be enabled/i, @@ -104794,6 +104813,112 @@ function initFeatures(gitHubVersion, repositoryNwo, tempDir, logger) { } } +// src/feature-flags/properties.ts +var GITHUB_CODEQL_PROPERTY_PREFIX = "github-codeql-"; +var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { + RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; + RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; + RepositoryPropertyName2["FILE_COVERAGE_ON_PRS"] = "github-codeql-file-coverage-on-prs"; + RepositoryPropertyName2["TOOLS"] = "github-codeql-tools"; + return RepositoryPropertyName2; +})(RepositoryPropertyName || {}); +function isString2(value) { + return typeof value === "string"; +} +var stringProperty = { + validate: isString2, + parse: parseStringRepositoryProperty +}; +var booleanProperty = { + // The value from the API should come as a string, which we then parse into a boolean. + validate: isString2, + parse: parseBooleanRepositoryProperty +}; +var repositoryPropertyParsers = { + ["github-codeql-disable-overlay" /* DISABLE_OVERLAY */]: booleanProperty, + ["github-codeql-extra-queries" /* EXTRA_QUERIES */]: stringProperty, + ["github-codeql-file-coverage-on-prs" /* FILE_COVERAGE_ON_PRS */]: booleanProperty, + ["github-codeql-tools" /* TOOLS */]: stringProperty +}; +async function loadPropertiesFromApi(logger, repositoryNwo) { + try { + const response = await getRepositoryProperties(repositoryNwo); + const remoteProperties = response.data; + if (!Array.isArray(remoteProperties)) { + throw new Error( + `Expected repository properties API to return an array, but got: ${JSON.stringify(response.data)}` + ); + } + logger.debug( + `Retrieved ${remoteProperties.length} repository properties: ${remoteProperties.map((p) => p.property_name).join(", ")}` + ); + const properties = {}; + const unrecognisedProperties = []; + for (const property of remoteProperties) { + if (property.property_name === void 0) { + throw new Error( + `Expected repository property object to have a 'property_name', but got: ${JSON.stringify(property)}` + ); + } + if (isKnownPropertyName(property.property_name)) { + setProperty2(properties, property.property_name, property.value, logger); + } else if (property.property_name.startsWith(GITHUB_CODEQL_PROPERTY_PREFIX) && !isDynamicWorkflow()) { + unrecognisedProperties.push(property.property_name); + } + } + if (Object.keys(properties).length === 0) { + logger.debug("No known repository properties were found."); + } else { + logger.debug( + "Loaded the following values for the repository properties:" + ); + for (const [property, value] of Object.entries(properties).sort( + ([nameA], [nameB]) => nameA.localeCompare(nameB) + )) { + logger.debug(` ${property}: ${value}`); + } + } + if (unrecognisedProperties.length > 0) { + const unrecognisedPropertyList = unrecognisedProperties.map((name) => `'${name}'`).join(", "); + logger.warning( + `Found repository properties (${unrecognisedPropertyList}), which look like CodeQL Action repository properties, but which are not understood by this version of the CodeQL Action. Do you need to update to a newer version?` + ); + } + return properties; + } catch (e) { + throw new Error( + `Encountered an error while trying to determine repository properties: ${e}` + ); + } +} +function setProperty2(properties, name, value, logger) { + const propertyOptions = repositoryPropertyParsers[name]; + if (propertyOptions.validate(value)) { + properties[name] = propertyOptions.parse(name, value, logger); + } else { + throw new Error( + `Unexpected value for repository property '${name}' (${typeof value}), got: ${JSON.stringify(value)}` + ); + } +} +function parseBooleanRepositoryProperty(name, value, logger) { + if (value !== "true" && value !== "false") { + logger.warning( + `Repository property '${name}' has unexpected value '${value}'. Expected 'true' or 'false'. Defaulting to false.` + ); + } + return value === "true"; +} +function parseStringRepositoryProperty(_name, value) { + return value; +} +var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( + Object.values(RepositoryPropertyName) +); +function isKnownPropertyName(name) { + return KNOWN_REPOSITORY_PROPERTY_NAMES.has(name); +} + // src/init.ts var core12 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); @@ -105063,20 +105188,6 @@ var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); // src/config/db-config.ts var jsonschema = __toESM(require_lib2()); var semver5 = __toESM(require_semver2()); - -// src/feature-flags/properties.ts -var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { - RepositoryPropertyName2["DISABLE_OVERLAY"] = "github-codeql-disable-overlay"; - RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; - RepositoryPropertyName2["FILE_COVERAGE_ON_PRS"] = "github-codeql-file-coverage-on-prs"; - RepositoryPropertyName2["TOOLS"] = "github-codeql-tools"; - return RepositoryPropertyName2; -})(RepositoryPropertyName || {}); -var KNOWN_REPOSITORY_PROPERTY_NAMES = new Set( - Object.values(RepositoryPropertyName) -); - -// src/config/db-config.ts var PACK_IDENTIFIER_PATTERN = (function() { const alphaNumeric = "[a-z0-9]"; const alphaNumericDash = "[a-z0-9-]"; @@ -105705,7 +105816,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ); } else { logger.info( - `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` + `Using the latest CodeQL CLI nightly, as requested.` ); } toolsInput = await getNightlyToolsUrl(logger); @@ -105727,15 +105838,16 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian const allowToolcacheValueFF = await features.getValue( "allow_toolcache_input" /* AllowToolcacheInput */ ); - const allowToolcacheValue = toolsInputFromRepositoryProperty || allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); + const allowToolcacheValue = toolsInputFromRepositoryProperty || // Repository properties bypass all restrictions + allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); if (allowToolcacheValue) { if (toolsInputFromRepositoryProperty) { logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.` + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the '${"github-codeql-tools" /* TOOLS */}' repository property.` ); } else { logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested.` ); } latestToolcacheVersion = getLatestToolcacheVersion(logger); @@ -105747,7 +105859,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian if (allowToolcacheValue) { if (toolsInputFromRepositoryProperty) { logger.info( - `Found no CodeQL CLI in the toolcache, ignoring the 'github-codeql-tools' repository property...` + `Found no CodeQL CLI in the toolcache, ignoring the '${"github-codeql-tools" /* TOOLS */}' repository property...` ); } else { logger.info( @@ -105760,7 +105872,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian `Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.` ); } else { - logger.info( + logger.warning( `Ignoring 'tools: ${toolsInput}' because the feature is not enabled.` ); } @@ -106114,7 +106226,7 @@ var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion, toolsInputFromRepositoryProperty = false) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { try { const { codeqlFolder, @@ -106129,8 +106241,7 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV variant, defaultCliVersion, features, - logger, - toolsInputFromRepositoryProperty + logger ); logger.debug( `Bundle download status report: ${JSON.stringify( @@ -106718,7 +106829,7 @@ async function getJobRunUuidSarifOptions(codeql) { } // src/init.ts -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -106734,8 +106845,7 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe defaultCliVersion, features, logger, - true, - toolsInputFromRepositoryProperty + true ); await codeql.printVersion(); logger.endGroup(); @@ -106956,7 +107066,7 @@ async function sendUnhandledErrorStatusReport(actionName, actionStartedAt, error } // src/setup-codeql-action.ts -async function sendCompletedStatusReport(startedAt, toolsDownloadStatusReport, toolsFeatureFlagsValid, toolsSource, toolsVersion, logger, error3) { +async function sendCompletedStatusReport(startedAt, toolsDownloadStatusReport, toolsFeatureFlagsValid, toolsSource, toolsVersion, effectiveToolsInput, logger, error3) { const statusReportBase = await createStatusReportBase( "setup-codeql" /* SetupCodeQL */, getActionsStatus(error3), @@ -106972,7 +107082,7 @@ async function sendCompletedStatusReport(startedAt, toolsDownloadStatusReport, t } const initStatusReport = { ...statusReportBase, - tools_input: getOptionalInput("tools") || "", + tools_input: effectiveToolsInput || "", tools_resolved_version: toolsVersion, tools_source: toolsSource || "UNKNOWN" /* Unknown */, workflow_languages: "" @@ -106993,6 +107103,7 @@ async function run(startedAt) { let toolsFeatureFlagsValid; let toolsSource; let toolsVersion; + let effectiveToolsInput; try { initializeEnvironment(getActionVersion()); const apiDetails = { @@ -107011,6 +107122,10 @@ async function run(startedAt) { getTemporaryDirectory(), logger ); + const repositoryPropertiesResult = await loadPropertiesFromApi( + logger, + repositoryNwo + ); const jobRunUuid = v4_default(); logger.info(`Job run UUID is ${jobRunUuid}.`); core14.exportVariable("JOB_RUN_UUID" /* JOB_RUN_UUID */, jobRunUuid); @@ -107029,8 +107144,13 @@ async function run(startedAt) { gitHubVersion.type ); toolsFeatureFlagsValid = codeQLDefaultVersionInfo.toolsFeatureFlagsValid; + effectiveToolsInput = resolveToolsInput( + repositoryPropertiesResult, + "github-codeql-tools" /* TOOLS */, + logger + ); const initCodeQLResult = await initCodeQL( - getOptionalInput("tools"), + effectiveToolsInput, apiDetails, getTemporaryDirectory(), gitHubVersion.type, @@ -107069,6 +107189,7 @@ async function run(startedAt) { toolsFeatureFlagsValid, toolsSource, toolsVersion, + effectiveToolsInput, logger ); } diff --git a/lib/upload-lib.js b/lib/upload-lib.js index 5f119603d4..fb8c05c041 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -108394,7 +108394,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ); } else { logger.info( - `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` + `Using the latest CodeQL CLI nightly, as requested.` ); } toolsInput = await getNightlyToolsUrl(logger); @@ -108416,15 +108416,16 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian const allowToolcacheValueFF = await features.getValue( "allow_toolcache_input" /* AllowToolcacheInput */ ); - const allowToolcacheValue = toolsInputFromRepositoryProperty || allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); + const allowToolcacheValue = toolsInputFromRepositoryProperty || // Repository properties bypass all restrictions + allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); if (allowToolcacheValue) { if (toolsInputFromRepositoryProperty) { logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.` + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the '${"github-codeql-tools" /* TOOLS */}' repository property.` ); } else { logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested.` ); } latestToolcacheVersion = getLatestToolcacheVersion(logger); @@ -108436,7 +108437,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian if (allowToolcacheValue) { if (toolsInputFromRepositoryProperty) { logger.info( - `Found no CodeQL CLI in the toolcache, ignoring the 'github-codeql-tools' repository property...` + `Found no CodeQL CLI in the toolcache, ignoring the '${"github-codeql-tools" /* TOOLS */}' repository property...` ); } else { logger.info( @@ -108449,7 +108450,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian `Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.` ); } else { - logger.info( + logger.warning( `Ignoring 'tools: ${toolsInput}' because the feature is not enabled.` ); } @@ -108803,7 +108804,7 @@ var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion, toolsInputFromRepositoryProperty = false) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { try { const { codeqlFolder, @@ -108818,8 +108819,7 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV variant, defaultCliVersion, features, - logger, - toolsInputFromRepositoryProperty + logger ); logger.debug( `Bundle download status report: ${JSON.stringify( @@ -110539,7 +110539,7 @@ var core12 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); var github2 = __toESM(require_github()); var io5 = __toESM(require_io()); -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -110555,8 +110555,7 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe defaultCliVersion, features, logger, - true, - toolsInputFromRepositoryProperty + true ); await codeql.printVersion(); logger.endGroup(); @@ -111140,20 +111139,33 @@ async function waitForProcessing(repositoryNwo, sarifID, logger, options = { ); break; } + if (!response) { + logger.warning( + "Unable to check analysis status due to missing response. It should still be processed in the background." + ); + break; + } const status = response.data.processing_status; logger.info(`Analysis upload status is ${status}.`); if (status === "pending") { logger.debug("Analysis processing is still pending..."); } else if (options.isUnsuccessfulExecution) { - handleProcessingResultForUnsuccessfulExecution( - response, - status, - logger - ); + if (response) { + handleProcessingResultForUnsuccessfulExecution( + response, + status, + logger + ); + } break; } else if (status === "complete") { break; } else if (status === "failed") { + if (!response) { + throw new Error( + "Code Scanning could not process the submitted SARIF file: Unable to retrieve error details." + ); + } const message = `Code Scanning could not process the submitted SARIF file: ${response.data.errors}`; const processingErrors = response.data.errors; diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index 9042fe0c10..0cf5e88cb6 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -109056,7 +109056,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ); } else { logger.info( - `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` + `Using the latest CodeQL CLI nightly, as requested.` ); } toolsInput = await getNightlyToolsUrl(logger); @@ -109078,15 +109078,16 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian const allowToolcacheValueFF = await features.getValue( "allow_toolcache_input" /* AllowToolcacheInput */ ); - const allowToolcacheValue = toolsInputFromRepositoryProperty || allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); + const allowToolcacheValue = toolsInputFromRepositoryProperty || // Repository properties bypass all restrictions + allowToolcacheValueFF && (isDynamicWorkflow() || isInTestMode()); if (allowToolcacheValue) { if (toolsInputFromRepositoryProperty) { logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the 'github-codeql-tools' repository property.` + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the '${"github-codeql-tools" /* TOOLS */}' repository property.` ); } else { logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: ${toolsInput}'.` + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested.` ); } latestToolcacheVersion = getLatestToolcacheVersion(logger); @@ -109098,7 +109099,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian if (allowToolcacheValue) { if (toolsInputFromRepositoryProperty) { logger.info( - `Found no CodeQL CLI in the toolcache, ignoring the 'github-codeql-tools' repository property...` + `Found no CodeQL CLI in the toolcache, ignoring the '${"github-codeql-tools" /* TOOLS */}' repository property...` ); } else { logger.info( @@ -109111,7 +109112,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian `Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.` ); } else { - logger.info( + logger.warning( `Ignoring 'tools: ${toolsInput}' because the feature is not enabled.` ); } @@ -109465,7 +109466,7 @@ var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; -async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion, toolsInputFromRepositoryProperty = false) { +async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { try { const { codeqlFolder, @@ -109480,8 +109481,7 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV variant, defaultCliVersion, features, - logger, - toolsInputFromRepositoryProperty + logger ); logger.debug( `Bundle download status report: ${JSON.stringify( @@ -111201,7 +111201,7 @@ var core13 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); var github2 = __toESM(require_github()); var io5 = __toESM(require_io()); -async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, toolsInputFromRepositoryProperty = false) { +async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) { logger.startGroup("Setup CodeQL tools"); const { codeql, @@ -111217,8 +111217,7 @@ async function initCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVe defaultCliVersion, features, logger, - true, - toolsInputFromRepositoryProperty + true ); await codeql.printVersion(); logger.endGroup(); @@ -111684,20 +111683,33 @@ async function waitForProcessing(repositoryNwo, sarifID, logger, options = { ); break; } + if (!response) { + logger.warning( + "Unable to check analysis status due to missing response. It should still be processed in the background." + ); + break; + } const status = response.data.processing_status; logger.info(`Analysis upload status is ${status}.`); if (status === "pending") { logger.debug("Analysis processing is still pending..."); } else if (options.isUnsuccessfulExecution) { - handleProcessingResultForUnsuccessfulExecution( - response, - status, - logger - ); + if (response) { + handleProcessingResultForUnsuccessfulExecution( + response, + status, + logger + ); + } break; } else if (status === "complete") { break; } else if (status === "failed") { + if (!response) { + throw new Error( + "Code Scanning could not process the submitted SARIF file: Unable to retrieve error details." + ); + } const message = `Code Scanning could not process the submitted SARIF file: ${response.data.errors}`; const processingErrors = response.data.errors; diff --git a/src/actions-util.ts b/src/actions-util.ts index 296b196151..da80b232c2 100644 --- a/src/actions-util.ts +++ b/src/actions-util.ts @@ -53,26 +53,29 @@ export const getOptionalInput = function (name: string): string | undefined { * * @param repositoryProperties - The loaded repository properties object * @param toolsPropertyName - The name of the tools property to look up - * @returns An object containing the effective tools input and whether it came from repository property + * @param logger - Logger for outputting resolution messages + * @returns The effective tools input value */ export function resolveToolsInput( repositoryProperties: Record, toolsPropertyName: string, -): { - effectiveToolsInput: string | undefined; - toolsInputFromRepositoryProperty: boolean; -} { + logger: Logger, +): string | undefined { const toolsWorkflowInput = getOptionalInput("tools"); const toolsPropertyValue: string | undefined = repositoryProperties[toolsPropertyName]; const effectiveToolsInput = toolsWorkflowInput ?? toolsPropertyValue; - const toolsInputFromRepositoryProperty = - toolsWorkflowInput === undefined && toolsPropertyValue !== undefined; - - return { - effectiveToolsInput, - toolsInputFromRepositoryProperty, - }; + + // Log the source of the tools input for transparency + if (effectiveToolsInput) { + if (toolsWorkflowInput) { + logger.info(`Setting tools: ${effectiveToolsInput} based on workflow input.`); + } else { + logger.info(`Setting tools: ${effectiveToolsInput} based on the '${toolsPropertyName}' repository property.`); + } + } + + return effectiveToolsInput; } export function getTemporaryDirectory(): string { diff --git a/src/codeql.ts b/src/codeql.ts index 4978de66f8..ee2773c01b 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -323,7 +323,6 @@ export async function setupCodeQL( features: FeatureEnablement, logger: Logger, checkVersion: boolean, - toolsInputFromRepositoryProperty: boolean, ): Promise<{ codeql: CodeQL; toolsDownloadStatusReport?: ToolsDownloadStatusReport; @@ -346,7 +345,6 @@ export async function setupCodeQL( defaultCliVersion, features, logger, - toolsInputFromRepositoryProperty, ); logger.debug( diff --git a/src/init-action.ts b/src/init-action.ts index 9a878363e7..223f92b074 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -305,13 +305,11 @@ async function run(startedAt: Date) { // Determine the effective tools input. // The explicit `tools` workflow input takes precedence. If none is provided, // fall back to the 'github-codeql-tools' repository property (if set). - const resolvedToolsInput = resolveToolsInput( + effectiveToolsInput = resolveToolsInput( repositoryPropertiesResult.orElse({}), RepositoryPropertyName.TOOLS, + logger, ); - effectiveToolsInput = resolvedToolsInput.effectiveToolsInput; - const toolsInputFromRepositoryProperty = - resolvedToolsInput.toolsInputFromRepositoryProperty; const initCodeQLResult = await initCodeQL( effectiveToolsInput, @@ -321,7 +319,6 @@ async function run(startedAt: Date) { codeQLDefaultVersionInfo, features, logger, - toolsInputFromRepositoryProperty, ); codeql = initCodeQLResult.codeql; toolsDownloadStatusReport = initCodeQLResult.toolsDownloadStatusReport; diff --git a/src/init.ts b/src/init.ts index 6519ec361e..8e3fa21a4a 100644 --- a/src/init.ts +++ b/src/init.ts @@ -41,7 +41,6 @@ export async function initCodeQL( defaultCliVersion: CodeQLDefaultVersionInfo, features: FeatureEnablement, logger: Logger, - toolsInputFromRepositoryProperty: boolean, ): Promise<{ codeql: CodeQL; toolsDownloadStatusReport?: ToolsDownloadStatusReport; @@ -65,7 +64,6 @@ export async function initCodeQL( features, logger, true, - toolsInputFromRepositoryProperty, ); await codeql.printVersion(); logger.endGroup(); diff --git a/src/setup-codeql-action.ts b/src/setup-codeql-action.ts index 619da8959f..535528f428 100644 --- a/src/setup-codeql-action.ts +++ b/src/setup-codeql-action.ts @@ -156,13 +156,11 @@ async function run(startedAt: Date): Promise { // Determine the effective tools input. // The explicit `tools` workflow input takes precedence. If none is provided, // fall back to the 'github-codeql-tools' repository property (if set). - const resolvedToolsInput = resolveToolsInput( + effectiveToolsInput = resolveToolsInput( repositoryPropertiesResult, RepositoryPropertyName.TOOLS, + logger, ); - effectiveToolsInput = resolvedToolsInput.effectiveToolsInput; - const toolsInputFromRepositoryProperty = - resolvedToolsInput.toolsInputFromRepositoryProperty; const initCodeQLResult = await initCodeQL( effectiveToolsInput, @@ -172,7 +170,6 @@ async function run(startedAt: Date): Promise { codeQLDefaultVersionInfo, features, logger, - toolsInputFromRepositoryProperty, ); codeql = initCodeQLResult.codeql; toolsDownloadStatusReport = initCodeQLResult.toolsDownloadStatusReport; diff --git a/src/setup-codeql.test.ts b/src/setup-codeql.test.ts index 72a53cbcbc..413c9fcbd0 100644 --- a/src/setup-codeql.test.ts +++ b/src/setup-codeql.test.ts @@ -113,7 +113,6 @@ test.serial( false, features, getRunnerLogger(true), - false, ); t.is(source.sourceType, "download"); @@ -137,7 +136,6 @@ test.serial( false, features, getRunnerLogger(true), - false, ); t.is(source.toolsVersion, LINKED_CLI_VERSION.cliVersion); @@ -163,7 +161,6 @@ test.serial( false, features, logger, - false, ); // First, ensure that the CLI version is the linked version, so that backwards @@ -217,7 +214,6 @@ test.serial( SAMPLE_DEFAULT_CLI_VERSION, features, logger, - false, ); // Basic sanity check that the version we got back is indeed @@ -273,7 +269,6 @@ test.serial( SAMPLE_DEFAULT_CLI_VERSION, features, logger, - false, ); // Basic sanity check that the version we got back is indeed the version that the @@ -328,7 +323,6 @@ test.serial( false, features, logger, - false, ); // Check that the `CodeQLToolsSource` object matches our expectations. @@ -345,7 +339,7 @@ test.serial( // Afterwards, ensure that we see the expected messages in the log. checkExpectedLogMessages(t, loggedMessages, [ - "Using the latest CodeQL CLI nightly, as requested by 'tools: nightly'.", + "Using the latest CodeQL CLI nightly, as requested.", `Bundle version ${expectedDate} is not in SemVer format. Will treat it as pre-release ${expectedVersion}.`, `Attempting to obtain CodeQL tools. CLI version: unknown, bundle tag name: ${expectedTag}`, `Using CodeQL CLI sourced from ${expectedURL}`, @@ -390,7 +384,6 @@ test.serial( false, features, logger, - false, ); // Check that the `CodeQLToolsSource` object matches our expectations. @@ -445,7 +438,6 @@ test.serial( false, features, logger, - false, ); // Check that the toolcache functions were called with the expected arguments @@ -464,7 +456,7 @@ test.serial( // Check that key messages we would expect to find in the log are present. const expectedMessages: string[] = [ - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: toolcache'.`, + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested.`, `CLI version ${latestToolcacheVersion} is the latest version in the toolcache.`, `Using CodeQL CLI version ${latestToolcacheVersion} from toolcache at ${latestVersionPath}`, ]; @@ -513,7 +505,6 @@ const toolcacheInputFallbackMacro = test.macro({ false, features, logger, - false, ); // Check that the toolcache functions were called with the expected arguments @@ -550,7 +541,7 @@ test.serial( { GITHUB_EVENT_NAME: "dynamic" }, [], [ - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by 'tools: toolcache'.`, + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested.`, `Found no CodeQL CLI in the toolcache, ignoring 'tools: toolcache'...`, ], ); diff --git a/src/setup-codeql.ts b/src/setup-codeql.ts index 8222f96e2a..25544e3f50 100644 --- a/src/setup-codeql.ts +++ b/src/setup-codeql.ts @@ -265,24 +265,6 @@ async function findOverridingToolsInCache( return undefined; } -/** - * Creates a user-friendly description of the tools input origin for log messages. - * - * @param toolsInput The tools input value - * @param toolsInputFromRepositoryProperty Whether the tools input came from repository property - * @returns A description like "'tools: toolcache'" or "the 'github-codeql-tools' repository property" - */ -function getToolsInputOriginDescription( - toolsInput: string | undefined, - toolsInputFromRepositoryProperty: boolean, -): string { - if (toolsInputFromRepositoryProperty) { - return `the '${RepositoryPropertyName.TOOLS}' repository property`; - } else { - return `'tools: ${toolsInput}'`; - } -} - /** * Determines where the CodeQL CLI we want to use comes from. This can be from a local file, * the Actions toolcache, or a download. @@ -305,7 +287,7 @@ export async function getCodeQLSource( tarSupportsZstd: boolean, features: FeatureEnablement, logger: Logger, - toolsInputFromRepositoryProperty: boolean, + toolsInputFromRepositoryProperty: boolean = false, ): Promise { // If there is an explicit `tools` input, it's not one of the reserved values, and it doesn't appear // to point to a URL, then we assume it is a local path and use the CLI from there. @@ -380,7 +362,7 @@ export async function getCodeQLSource( ); } else { logger.info( - `Using the latest CodeQL CLI nightly, as requested by ${getToolsInputOriginDescription(toolsInput, toolsInputFromRepositoryProperty)}.`, + `Using the latest CodeQL CLI nightly, as requested.`, ); } toolsInput = await getNightlyToolsUrl(logger); @@ -405,7 +387,7 @@ export async function getCodeQLSource( tagName = defaults.bundleVersion; logger.info( - `${getToolsInputOriginDescription(toolsInput, toolsInputFromRepositoryProperty)} was requested, so using CodeQL version ${cliVersion}, the version shipped with the Action.`, + `'tools: ${toolsInput}' was requested, so using CodeQL version ${cliVersion}, the version shipped with the Action.`, ); if (toolsInput === "latest") { @@ -421,23 +403,27 @@ export async function getCodeQLSource( // We only allow `toolsInput === "toolcache"` for `dynamic` events. In general, using `toolsInput === "toolcache"` // can lead to alert wobble and so it shouldn't be used for an analysis where results are intended to be uploaded. - // We also allow this in test mode, and when the value was set via a repository property (in which case the - // organization admin has explicitly opted in to this behavior). + // We also allow this in test mode or when the input comes from a repository property. const allowToolcacheValueFF = await features.getValue( Feature.AllowToolcacheInput, ); const allowToolcacheValue = - allowToolcacheValueFF && - (toolsInputFromRepositoryProperty || - isDynamicWorkflow() || - util.isInTestMode()); + toolsInputFromRepositoryProperty || // Repository properties bypass all restrictions + (allowToolcacheValueFF && + (isDynamicWorkflow() || util.isInTestMode())); if (allowToolcacheValue) { // If `toolsInput === "toolcache"`, try to find the latest version of the CLI that's available in the toolcache // and use that. We perform this check here since we can set `cliVersion` directly and don't want to default to // the linked version. - logger.info( - `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by ${getToolsInputOriginDescription(toolsInput, toolsInputFromRepositoryProperty)}.`, - ); + if (toolsInputFromRepositoryProperty) { + logger.info( + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested by the '${RepositoryPropertyName.TOOLS}' repository property.`, + ); + } else { + logger.info( + `Attempting to use the latest CodeQL CLI version in the toolcache, as requested.`, + ); + } latestToolcacheVersion = getLatestToolcacheVersion(logger); if (latestToolcacheVersion) { @@ -447,17 +433,23 @@ export async function getCodeQLSource( if (latestToolcacheVersion === undefined) { if (allowToolcacheValue) { - logger.info( - `Found no CodeQL CLI in the toolcache, ignoring ${getToolsInputOriginDescription(toolsInput, toolsInputFromRepositoryProperty)}...`, - ); + if (toolsInputFromRepositoryProperty) { + logger.info( + `Found no CodeQL CLI in the toolcache, ignoring the '${RepositoryPropertyName.TOOLS}' repository property...`, + ); + } else { + logger.info( + `Found no CodeQL CLI in the toolcache, ignoring 'tools: ${toolsInput}'...`, + ); + } } else { if (allowToolcacheValueFF) { logger.warning( - `Ignoring ${getToolsInputOriginDescription(toolsInput, toolsInputFromRepositoryProperty)} because the workflow was not triggered dynamically.`, + `Ignoring 'tools: ${toolsInput}' because the workflow was not triggered dynamically.`, ); } else { logger.warning( - `Ignoring ${getToolsInputOriginDescription(toolsInput, toolsInputFromRepositoryProperty)} because the feature is not enabled.`, + `Ignoring 'tools: ${toolsInput}' because the feature is not enabled.`, ); } } @@ -817,7 +809,7 @@ export async function setupCodeQLBundle( defaultCliVersion: CodeQLDefaultVersionInfo, features: FeatureEnablement, logger: Logger, - toolsInputFromRepositoryProperty: boolean, + toolsInputFromRepositoryProperty: boolean = false, ): Promise { if (!(await util.isBinaryAccessible("tar", logger))) { throw new util.ConfigurationError( diff --git a/src/upload-lib.ts b/src/upload-lib.ts index 2464fe5eaa..2aa8c17264 100644 --- a/src/upload-lib.ts +++ b/src/upload-lib.ts @@ -883,6 +883,12 @@ export async function waitForProcessing( ); break; } + if (!response) { + logger.warning( + "Unable to check analysis status due to missing response. It should still be processed in the background.", + ); + break; + } const status = response.data.processing_status as ProcessingStatus; logger.info(`Analysis upload status is ${status}.`); @@ -891,15 +897,22 @@ export async function waitForProcessing( } else if (options.isUnsuccessfulExecution) { // We expect a specific processing error for unsuccessful executions, so // handle these separately. - handleProcessingResultForUnsuccessfulExecution( - response, - status, - logger, - ); + if (response) { + handleProcessingResultForUnsuccessfulExecution( + response, + status, + logger, + ); + } break; } else if (status === "complete") { break; } else if (status === "failed") { + if (!response) { + throw new Error( + "Code Scanning could not process the submitted SARIF file: Unable to retrieve error details.", + ); + } const message = `Code Scanning could not process the submitted SARIF file:\n${response.data.errors}`; const processingErrors = response.data.errors as string[]; throw shouldConsiderConfigurationError(processingErrors) From 66fe24470127297861c65aca2e9a31999472848d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20San=20Jos=C3=A9?= Date: Wed, 15 Apr 2026 17:38:24 +0200 Subject: [PATCH 6/6] Changes from CR --- lib/analyze-action.js | 6 ++---- lib/init-action-post.js | 6 ++---- lib/init-action.js | 14 ++++++++------ lib/setup-codeql-action.js | 14 ++++++++------ lib/upload-lib.js | 6 ++---- lib/upload-sarif-action.js | 6 ++---- src/actions-util.ts | 12 ++++++++---- src/setup-codeql.test.ts | 7 +++++++ src/setup-codeql.ts | 9 +++------ 9 files changed, 42 insertions(+), 38 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 44e1aae238..3452d0f33b 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -109311,7 +109311,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty = false) { +async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -109356,9 +109356,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ) ); } else { - logger.info( - `Using the latest CodeQL CLI nightly, as requested.` - ); + logger.info(`Using the latest CodeQL CLI nightly, as requested.`); } toolsInput = await getNightlyToolsUrl(logger); } diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 498ede3906..b9861740e9 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -167156,7 +167156,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty = false) { +async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -167201,9 +167201,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ) ); } else { - logger.info( - `Using the latest CodeQL CLI nightly, as requested.` - ); + logger.info(`Using the latest CodeQL CLI nightly, as requested.`); } toolsInput = await getNightlyToolsUrl(logger); } diff --git a/lib/init-action.js b/lib/init-action.js index 4ab691fecd..3d854b45bf 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -104109,9 +104109,13 @@ function resolveToolsInput(repositoryProperties, toolsPropertyName, logger) { const effectiveToolsInput = toolsWorkflowInput ?? toolsPropertyValue; if (effectiveToolsInput) { if (toolsWorkflowInput) { - logger.info(`Setting tools: ${effectiveToolsInput} based on workflow input.`); + logger.info( + `Setting tools: ${effectiveToolsInput} based on workflow input.` + ); } else { - logger.info(`Setting tools: ${effectiveToolsInput} based on the '${toolsPropertyName}' repository property.`); + logger.info( + `Setting tools: ${effectiveToolsInput} based on the '${toolsPropertyName}' repository property.` + ); } } return effectiveToolsInput; @@ -108268,7 +108272,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty = false) { +async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -108313,9 +108317,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ) ); } else { - logger.info( - `Using the latest CodeQL CLI nightly, as requested.` - ); + logger.info(`Using the latest CodeQL CLI nightly, as requested.`); } toolsInput = await getNightlyToolsUrl(logger); } diff --git a/lib/setup-codeql-action.js b/lib/setup-codeql-action.js index ea371b7d3a..91a2ed2305 100644 --- a/lib/setup-codeql-action.js +++ b/lib/setup-codeql-action.js @@ -103650,9 +103650,13 @@ function resolveToolsInput(repositoryProperties, toolsPropertyName, logger) { const effectiveToolsInput = toolsWorkflowInput ?? toolsPropertyValue; if (effectiveToolsInput) { if (toolsWorkflowInput) { - logger.info(`Setting tools: ${effectiveToolsInput} based on workflow input.`); + logger.info( + `Setting tools: ${effectiveToolsInput} based on workflow input.` + ); } else { - logger.info(`Setting tools: ${effectiveToolsInput} based on the '${toolsPropertyName}' repository property.`); + logger.info( + `Setting tools: ${effectiveToolsInput} based on the '${toolsPropertyName}' repository property.` + ); } } return effectiveToolsInput; @@ -105878,7 +105882,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty = false) { +async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -105923,9 +105927,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ) ); } else { - logger.info( - `Using the latest CodeQL CLI nightly, as requested.` - ); + logger.info(`Using the latest CodeQL CLI nightly, as requested.`); } toolsInput = await getNightlyToolsUrl(logger); } diff --git a/lib/upload-lib.js b/lib/upload-lib.js index 8aeb9a0852..dd7b6302c5 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -108453,7 +108453,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty = false) { +async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -108498,9 +108498,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ) ); } else { - logger.info( - `Using the latest CodeQL CLI nightly, as requested.` - ); + logger.info(`Using the latest CodeQL CLI nightly, as requested.`); } toolsInput = await getNightlyToolsUrl(logger); } diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index b3e7f749d1..f2d310ad63 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -109119,7 +109119,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { } return void 0; } -async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty = false) { +async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, features, logger, toolsInputFromRepositoryProperty) { if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); @@ -109164,9 +109164,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian ) ); } else { - logger.info( - `Using the latest CodeQL CLI nightly, as requested.` - ); + logger.info(`Using the latest CodeQL CLI nightly, as requested.`); } toolsInput = await getNightlyToolsUrl(logger); } diff --git a/src/actions-util.ts b/src/actions-util.ts index d8b8d2d1c4..d7c02ad691 100644 --- a/src/actions-util.ts +++ b/src/actions-util.ts @@ -65,16 +65,20 @@ export function resolveToolsInput( const toolsPropertyValue: string | undefined = repositoryProperties[toolsPropertyName]; const effectiveToolsInput = toolsWorkflowInput ?? toolsPropertyValue; - + // Log the source of the tools input for transparency if (effectiveToolsInput) { if (toolsWorkflowInput) { - logger.info(`Setting tools: ${effectiveToolsInput} based on workflow input.`); + logger.info( + `Setting tools: ${effectiveToolsInput} based on workflow input.`, + ); } else { - logger.info(`Setting tools: ${effectiveToolsInput} based on the '${toolsPropertyName}' repository property.`); + logger.info( + `Setting tools: ${effectiveToolsInput} based on the '${toolsPropertyName}' repository property.`, + ); } } - + return effectiveToolsInput; } diff --git a/src/setup-codeql.test.ts b/src/setup-codeql.test.ts index 413c9fcbd0..3a06724a01 100644 --- a/src/setup-codeql.test.ts +++ b/src/setup-codeql.test.ts @@ -113,6 +113,7 @@ test.serial( false, features, getRunnerLogger(true), + false, ); t.is(source.sourceType, "download"); @@ -136,6 +137,7 @@ test.serial( false, features, getRunnerLogger(true), + false, ); t.is(source.toolsVersion, LINKED_CLI_VERSION.cliVersion); @@ -161,6 +163,7 @@ test.serial( false, features, logger, + false, ); // First, ensure that the CLI version is the linked version, so that backwards @@ -323,6 +326,7 @@ test.serial( false, features, logger, + false, ); // Check that the `CodeQLToolsSource` object matches our expectations. @@ -384,6 +388,7 @@ test.serial( false, features, logger, + false, ); // Check that the `CodeQLToolsSource` object matches our expectations. @@ -438,6 +443,7 @@ test.serial( false, features, logger, + false, ); // Check that the toolcache functions were called with the expected arguments @@ -505,6 +511,7 @@ const toolcacheInputFallbackMacro = test.macro({ false, features, logger, + false, ); // Check that the toolcache functions were called with the expected arguments diff --git a/src/setup-codeql.ts b/src/setup-codeql.ts index 25544e3f50..bcb34dbce2 100644 --- a/src/setup-codeql.ts +++ b/src/setup-codeql.ts @@ -287,7 +287,7 @@ export async function getCodeQLSource( tarSupportsZstd: boolean, features: FeatureEnablement, logger: Logger, - toolsInputFromRepositoryProperty: boolean = false, + toolsInputFromRepositoryProperty: boolean, ): Promise { // If there is an explicit `tools` input, it's not one of the reserved values, and it doesn't appear // to point to a URL, then we assume it is a local path and use the CLI from there. @@ -361,9 +361,7 @@ export async function getCodeQLSource( ), ); } else { - logger.info( - `Using the latest CodeQL CLI nightly, as requested.`, - ); + logger.info(`Using the latest CodeQL CLI nightly, as requested.`); } toolsInput = await getNightlyToolsUrl(logger); } @@ -409,8 +407,7 @@ export async function getCodeQLSource( ); const allowToolcacheValue = toolsInputFromRepositoryProperty || // Repository properties bypass all restrictions - (allowToolcacheValueFF && - (isDynamicWorkflow() || util.isInTestMode())); + (allowToolcacheValueFF && (isDynamicWorkflow() || util.isInTestMode())); if (allowToolcacheValue) { // If `toolsInput === "toolcache"`, try to find the latest version of the CLI that's available in the toolcache // and use that. We perform this check here since we can set `cliVersion` directly and don't want to default to