From d5f0374a1f31bffc753a6ab5b56d9de935c74ec9 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Sun, 15 Feb 2026 17:22:20 +0000 Subject: [PATCH] Force `nightly` bundle when FF is enabled --- lib/analyze-action.js | 16 ++++++++--- lib/init-action-post.js | 16 ++++++++--- lib/init-action.js | 16 ++++++++--- lib/setup-codeql-action.js | 16 ++++++++--- lib/upload-lib.js | 16 ++++++++--- lib/upload-sarif-action.js | 16 ++++++++--- src/setup-codeql.test.ts | 59 ++++++++++++++++++++++++++++++++++++++ src/setup-codeql.ts | 23 +++++++++++---- 8 files changed, 149 insertions(+), 29 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 38418657a..ff5731b50 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -108980,10 +108980,18 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian let cliVersion2; let tagName; let url2; - if (toolsInput !== void 0 && CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) { - logger.info( - `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` - ); + const forceNightlyValueFF = await features.getValue("force_nightly" /* ForceNightly */); + const forceNightly = forceNightlyValueFF && (isDynamicWorkflow() || isInTestMode()); + if (forceNightly || toolsInput !== void 0 && CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) { + if (forceNightly) { + logger.info( + `Using the latest CodeQL CLI nightly, as forced by the ${"force_nightly" /* ForceNightly */} feature flag.` + ); + } else { + logger.info( + `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` + ); + } toolsInput = await getNightlyToolsUrl(logger); } const forceShippedTools = toolsInput && CODEQL_BUNDLE_VERSION_ALIAS.includes(toolsInput); diff --git a/lib/init-action-post.js b/lib/init-action-post.js index f138ebda8..e943a4f54 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -166042,10 +166042,18 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian let cliVersion2; let tagName; let url2; - if (toolsInput !== void 0 && CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) { - logger.info( - `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` - ); + const forceNightlyValueFF = await features.getValue("force_nightly" /* ForceNightly */); + const forceNightly = forceNightlyValueFF && (isDynamicWorkflow() || isInTestMode()); + if (forceNightly || toolsInput !== void 0 && CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) { + if (forceNightly) { + logger.info( + `Using the latest CodeQL CLI nightly, as forced by the ${"force_nightly" /* ForceNightly */} feature flag.` + ); + } else { + logger.info( + `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` + ); + } toolsInput = await getNightlyToolsUrl(logger); } const forceShippedTools = toolsInput && CODEQL_BUNDLE_VERSION_ALIAS.includes(toolsInput); diff --git a/lib/init-action.js b/lib/init-action.js index 088f81b39..5712761bc 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -107383,10 +107383,18 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian let cliVersion2; let tagName; let url; - if (toolsInput !== void 0 && CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) { - logger.info( - `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` - ); + const forceNightlyValueFF = await features.getValue("force_nightly" /* ForceNightly */); + const forceNightly = forceNightlyValueFF && (isDynamicWorkflow() || isInTestMode()); + if (forceNightly || toolsInput !== void 0 && CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) { + if (forceNightly) { + logger.info( + `Using the latest CodeQL CLI nightly, as forced by the ${"force_nightly" /* ForceNightly */} feature flag.` + ); + } else { + logger.info( + `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` + ); + } toolsInput = await getNightlyToolsUrl(logger); } const forceShippedTools = toolsInput && CODEQL_BUNDLE_VERSION_ALIAS.includes(toolsInput); diff --git a/lib/setup-codeql-action.js b/lib/setup-codeql-action.js index 2476d73c5..c2b1a5119 100644 --- a/lib/setup-codeql-action.js +++ b/lib/setup-codeql-action.js @@ -105125,10 +105125,18 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian let cliVersion2; let tagName; let url; - if (toolsInput !== void 0 && CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) { - logger.info( - `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` - ); + const forceNightlyValueFF = await features.getValue("force_nightly" /* ForceNightly */); + const forceNightly = forceNightlyValueFF && (isDynamicWorkflow() || isInTestMode()); + if (forceNightly || toolsInput !== void 0 && CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) { + if (forceNightly) { + logger.info( + `Using the latest CodeQL CLI nightly, as forced by the ${"force_nightly" /* ForceNightly */} feature flag.` + ); + } else { + logger.info( + `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` + ); + } toolsInput = await getNightlyToolsUrl(logger); } const forceShippedTools = toolsInput && CODEQL_BUNDLE_VERSION_ALIAS.includes(toolsInput); diff --git a/lib/upload-lib.js b/lib/upload-lib.js index f8954636b..5562a4e0c 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -107823,10 +107823,18 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian let cliVersion2; let tagName; let url2; - if (toolsInput !== void 0 && CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) { - logger.info( - `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` - ); + const forceNightlyValueFF = await features.getValue("force_nightly" /* ForceNightly */); + const forceNightly = forceNightlyValueFF && (isDynamicWorkflow() || isInTestMode()); + if (forceNightly || toolsInput !== void 0 && CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) { + if (forceNightly) { + logger.info( + `Using the latest CodeQL CLI nightly, as forced by the ${"force_nightly" /* ForceNightly */} feature flag.` + ); + } else { + logger.info( + `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` + ); + } toolsInput = await getNightlyToolsUrl(logger); } const forceShippedTools = toolsInput && CODEQL_BUNDLE_VERSION_ALIAS.includes(toolsInput); diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index 7fee390cc..e154e97e7 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -108385,10 +108385,18 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian let cliVersion2; let tagName; let url2; - if (toolsInput !== void 0 && CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) { - logger.info( - `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` - ); + const forceNightlyValueFF = await features.getValue("force_nightly" /* ForceNightly */); + const forceNightly = forceNightlyValueFF && (isDynamicWorkflow() || isInTestMode()); + if (forceNightly || toolsInput !== void 0 && CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) { + if (forceNightly) { + logger.info( + `Using the latest CodeQL CLI nightly, as forced by the ${"force_nightly" /* ForceNightly */} feature flag.` + ); + } else { + logger.info( + `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` + ); + } toolsInput = await getNightlyToolsUrl(logger); } const forceShippedTools = toolsInput && CODEQL_BUNDLE_VERSION_ALIAS.includes(toolsInput); diff --git a/src/setup-codeql.test.ts b/src/setup-codeql.test.ts index e502bfb05..c93271975 100644 --- a/src/setup-codeql.test.ts +++ b/src/setup-codeql.test.ts @@ -329,6 +329,65 @@ test("getCodeQLSource correctly returns nightly CLI version when tools == nightl }); }); +test("getCodeQLSource correctly returns nightly CLI version when forced by FF", async (t) => { + const loggedMessages: LoggedMessage[] = []; + const logger = getRecordingLogger(loggedMessages); + const features = createFeatures([Feature.ForceNightly]); + + process.env["GITHUB_EVENT_NAME"] = "dynamic"; + + const expectedDate = "30260213"; + const expectedTag = `codeql-bundle-${expectedDate}`; + + // Ensure that we consistently select "zstd" for the test. + sinon.stub(process, "platform").value("linux"); + sinon.stub(tar, "isZstdAvailable").resolves({ + available: true, + foundZstdBinary: true, + }); + + const client = github.getOctokit("123"); + const listReleases = sinon.stub(client.rest.repos, "listReleases"); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + listReleases.resolves({ + data: [{ tag_name: expectedTag }], + } as any); + sinon.stub(api, "getApiClient").value(() => client); + + await withTmpDir(async (tmpDir) => { + setupActionsVars(tmpDir, tmpDir); + const source = await setupCodeql.getCodeQLSource( + undefined, + SAMPLE_DEFAULT_CLI_VERSION, + SAMPLE_DOTCOM_API_DETAILS, + GitHubVariant.DOTCOM, + false, + features, + logger, + ); + + // Check that the `CodeQLToolsSource` object matches our expectations. + const expectedVersion = `0.0.0-${expectedDate}`; + const expectedURL = `https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/${expectedTag}/${setupCodeql.getCodeQLBundleName("zstd")}`; + t.deepEqual(source, { + bundleVersion: expectedDate, + cliVersion: undefined, + codeqlURL: expectedURL, + compressionMethod: "zstd", + sourceType: "download", + toolsVersion: expectedVersion, + } satisfies setupCodeql.CodeQLToolsSource); + + // Afterwards, ensure that we see the expected messages in the log. + checkExpectedLogMessages(t, loggedMessages, [ + `Using the latest CodeQL CLI nightly, as forced by the ${Feature.ForceNightly} feature flag.`, + `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}`, + ]); + }); +}); + test("getCodeQLSource correctly returns latest version from toolcache when tools == toolcache", async (t) => { const loggedMessages: LoggedMessage[] = []; const logger = getRecordingLogger(loggedMessages); diff --git a/src/setup-codeql.ts b/src/setup-codeql.ts index 08dd1a407..e907da456 100644 --- a/src/setup-codeql.ts +++ b/src/setup-codeql.ts @@ -321,13 +321,26 @@ export async function getCodeQLSource( */ let url: string | undefined; + // We only allow forcing the nightly CLI via the FF for `dynamic` events (or in test mode). + // For advanced workflows, a value from `CODEQL_NIGHTLY_TOOLS_INPUTS` can be specified. + const forceNightlyValueFF = await features.getValue(Feature.ForceNightly); + const forceNightly = + forceNightlyValueFF && (isDynamicWorkflow() || util.isInTestMode()); + if ( - toolsInput !== undefined && - CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput) + forceNightly || + (toolsInput !== undefined && + CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) ) { - logger.info( - `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.`, - ); + if (forceNightly) { + logger.info( + `Using the latest CodeQL CLI nightly, as forced by the ${Feature.ForceNightly} feature flag.`, + ); + } else { + logger.info( + `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.`, + ); + } toolsInput = await getNightlyToolsUrl(logger); }