From 99fe83948eb780db2b4bd9b5f63c498673f3b857 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 16 Sep 2026 12:44:04 +0100 Subject: [PATCH 001/107] Refactor: Add `determineCheckoutPath` function for `analyze` action --- lib/entry-points.js | 13 +++++++------ src/analyze-action.ts | 11 +++++------ src/analyze.ts | 12 ++++++++++++ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 3fbacc32e4..ef7547dda4 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -153801,6 +153801,9 @@ var CodeQLAnalysisError = class extends Error { message; error; }; +function determineCheckoutPath(action) { + return action.actions.getRequiredInput("checkout_path"); +} async function setupPythonExtractor(logger) { const codeqlPython = process.env["CODEQL_PYTHON"]; if (codeqlPython === void 0 || codeqlPython.length === 0) { @@ -156544,11 +156547,9 @@ async function runAutobuildIfLegacyGoWorkflow(config, logger) { ); await runAutobuild(config, "go" /* go */, logger); } -async function run({ - startedAt, - logger, - actions -}) { +async function run(action) { + const startedAt = action.startedAt; + const logger = action.logger; let uploadResults = void 0; let runStats = void 0; let config = void 0; @@ -156614,7 +156615,7 @@ async function run({ getOptionalInput("ram") || process.env["CODEQL_RAM"], logger ); - const checkoutPath = actions.getRequiredInput("checkout_path"); + const checkoutPath = determineCheckoutPath(action); const diffRangePackDir = await setupDiffInformedQueryRun( logger, checkoutPath diff --git a/src/analyze-action.ts b/src/analyze-action.ts index 7963fa52bf..67b025ead7 100644 --- a/src/analyze-action.ts +++ b/src/analyze-action.ts @@ -10,6 +10,7 @@ import * as analyses from "./analyses"; import { CodeQLAnalysisError, dbIsFinalized, + determineCheckoutPath, QueriesStatusReport, runFinalize, runQueries, @@ -212,13 +213,11 @@ async function runAutobuildIfLegacyGoWorkflow(config: Config, logger: Logger) { await runAutobuild(config, BuiltInLanguage.go, logger); } -async function run({ - startedAt, - logger, - actions, -}: ActionState<["Base", "Logger", "Actions"]>) { +async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) { // To capture errors appropriately, keep as much code within the try-catch as // possible, and only use safe functions outside. + const startedAt = action.startedAt; + const logger = action.logger; let uploadResults: | Partial> @@ -311,7 +310,7 @@ async function run({ logger, ); - const checkoutPath = actions.getRequiredInput("checkout_path"); + const checkoutPath = determineCheckoutPath(action); // Setup diff informed analysis if needed (based on whether init created the file) const diffRangePackDir = await setupDiffInformedQueryRun( diff --git a/src/analyze.ts b/src/analyze.ts index 8f90711682..3580f80aa4 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -5,6 +5,7 @@ import { performance } from "perf_hooks"; import * as io from "@actions/io"; import * as yaml from "js-yaml"; +import type { ActionState } from "./action-common"; import { getTemporaryDirectory } from "./actions-util"; import * as analyses from "./analyses"; import { setupCppAutobuild } from "./autobuild"; @@ -85,6 +86,17 @@ export interface QueriesStatusReport event_reports?: EventReport[]; } +/** + * Determines the path at which the repository being analysed is checked out at. + * Returns the value of the required `checkout_path` input and validates that it + * refers to the root of a repository. + * + * @param action The action state. + */ +export function determineCheckoutPath(action: ActionState<["Actions"]>) { + return action.actions.getRequiredInput("checkout_path"); +} + async function setupPythonExtractor(logger: Logger) { const codeqlPython = process.env["CODEQL_PYTHON"]; if (codeqlPython === undefined || codeqlPython.length === 0) { From 5dab0ccf518dc8b6da0d5a182150ae1b5db7253a Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 16 Sep 2026 12:49:02 +0100 Subject: [PATCH 002/107] Persist repository root from `init` action in CodeQL Action state --- lib/entry-points.js | 43 ++++++++++++++++++++++++++++--------- src/analyze-action.test.ts | 2 ++ src/analyze-action.ts | 2 +- src/analyze.ts | 30 ++++++++++++++++++++++++-- src/config-utils.test.ts | 12 ++++++----- src/config-utils.ts | 16 ++++++++++---- src/config/action-config.ts | 5 +++++ src/testing-utils.ts | 1 + 8 files changed, 89 insertions(+), 22 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index ef7547dda4..7994d26d98 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -150444,7 +150444,7 @@ async function initActionState({ analysisKinds, logger, enableFileCoverageInformation -}, userConfig) { +}, userConfig, repositoryRoot) { const languages = await getLanguages( codeql, languagesInput, @@ -150480,6 +150480,7 @@ async function initActionState({ ); return { version: getActionVersion(), + repositoryRoot, analysisKinds, languages, buildMode, @@ -150630,7 +150631,7 @@ async function checkRunnerResources(codeql, features, diskUsage, ramInput, logge } return new Success(void 0); } -async function checkOverlayEnablement(codeql, features, languages, sourceRoot, buildMode, ramInput, codeScanningConfig, repositoryProperties, gitVersion, logger) { +async function checkOverlayEnablement(codeql, features, languages, repositoryRoot, sourceRoot, buildMode, ramInput, codeScanningConfig, repositoryProperties, gitVersion, logger) { const modeEnv = process.env.CODEQL_OVERLAY_DATABASE_MODE; if (modeEnv === "overlay" /* Overlay */ || modeEnv === "overlay-base" /* OverlayBase */ || modeEnv === "none" /* None */) { logger.info( @@ -150645,6 +150646,7 @@ async function checkOverlayEnablement(codeql, features, languages, sourceRoot, b true, codeql, languages, + repositoryRoot, sourceRoot, buildMode, gitVersion, @@ -150717,13 +150719,14 @@ async function checkOverlayEnablement(codeql, features, languages, sourceRoot, b false, codeql, languages, + repositoryRoot, sourceRoot, buildMode, gitVersion, logger ); } -async function validateOverlayDatabaseMode(overlayDatabaseMode, useOverlayDatabaseCaching, overlayModeSetExplicitly, codeql, languages, sourceRoot, buildMode, gitVersion, logger) { +async function validateOverlayDatabaseMode(overlayDatabaseMode, useOverlayDatabaseCaching, overlayModeSetExplicitly, codeql, languages, repositoryRoot, sourceRoot, buildMode, gitVersion, logger) { if (buildMode !== "none" /* None */ && (await Promise.all( languages.map( async (l) => l !== "go" /* go */ && // Workaround to allow overlay analysis for Go with any build @@ -150744,14 +150747,13 @@ async function validateOverlayDatabaseMode(overlayDatabaseMode, useOverlayDataba ); return new Failure("incompatible-codeql" /* IncompatibleCodeQl */); } - const gitRoot = await getGitRoot(sourceRoot); - if (gitRoot === void 0) { + if (repositoryRoot === void 0) { logger.warning( `Cannot build an ${overlayDatabaseMode} database because the source root "${sourceRoot}" is not inside a git repository. Falling back to creating a normal full database instead.` ); return new Failure("no-git-root" /* NoGitRoot */); } - if (hasSubmodules(gitRoot)) { + if (hasSubmodules(repositoryRoot)) { if (gitVersion === void 0) { logger.warning( `Cannot build an ${overlayDatabaseMode} database because the repository has submodules and the Git version could not be determined. Falling back to creating a normal full database instead.` @@ -150886,8 +150888,9 @@ async function determineUserConfig(action, tempDir, inputs) { async function initConfig(actionState, inputs) { const { logger, features } = actionState; const { tempDir } = inputs; + const repositoryRoot = await getGitRoot(inputs.sourceRoot); const userConfig = await determineUserConfig(actionState, tempDir, inputs); - const config = await initActionState(inputs, userConfig); + const config = await initActionState(inputs, userConfig, repositoryRoot); if (config.analysisKinds.length === 1 && isCodeQualityEnabled(config)) { if (hasQueryCustomisation(config.computedConfig)) { throw new ConfigurationError( @@ -150940,6 +150943,7 @@ async function initConfig(actionState, inputs) { inputs.codeql, inputs.features, config.languages, + repositoryRoot, inputs.sourceRoot, config.buildMode, inputs.ramInput, @@ -153801,8 +153805,27 @@ var CodeQLAnalysisError = class extends Error { message; error; }; -function determineCheckoutPath(action) { - return action.actions.getRequiredInput("checkout_path"); +async function determineCheckoutPath(action) { + const checkoutPathInput = action.actions.getRequiredInput("checkout_path"); + const repositoryRoot = await getGitRoot(checkoutPathInput); + if (repositoryRoot === void 0) { + action.logger.warning( + [ + `The directory at '${checkoutPathInput}' is not in the work tree of a git repository.`, + "If the repository being analyzed is checked out elsewhere,", + "you must explicitly set the 'checkout_path' input for the 'codeql-action/analyze' step to", + "the checkout path." + ].join(" ") + ); + } else if (repositoryRoot !== path16.resolve(checkoutPathInput)) { + action.logger.warning( + [ + `The directory at '${checkoutPathInput}' is not the root of the repository ('${repositoryRoot}').`, + "Set the 'checkout_path' input for the 'codeql-action/analyze' step to the root path of the checkout." + ].join(" ") + ); + } + return checkoutPathInput; } async function setupPythonExtractor(logger) { const codeqlPython = process.env["CODEQL_PYTHON"]; @@ -156615,7 +156638,7 @@ async function run(action) { getOptionalInput("ram") || process.env["CODEQL_RAM"], logger ); - const checkoutPath = determineCheckoutPath(action); + const checkoutPath = await determineCheckoutPath(action); const diffRangePackDir = await setupDiffInformedQueryRun( logger, checkoutPath diff --git a/src/analyze-action.test.ts b/src/analyze-action.test.ts index 923908a641..ffba5a03dc 100644 --- a/src/analyze-action.test.ts +++ b/src/analyze-action.test.ts @@ -45,6 +45,7 @@ test.serial( requiredInputStub.withArgs("token").returns("fake-token"); requiredInputStub.withArgs("upload-database").returns("false"); requiredInputStub.withArgs("output").returns("out"); + requiredInputStub.withArgs("checkout_path").returns(""); const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput"); optionalInputStub.withArgs("expect-error").returns("false"); sinon.stub(api, "getGitHubVersion").resolves(gitHubVersion); @@ -104,6 +105,7 @@ test.serial( requiredInputStub.withArgs("token").returns("fake-token"); requiredInputStub.withArgs("upload-database").returns("false"); requiredInputStub.withArgs("output").returns("out"); + requiredInputStub.withArgs("checkout_path").returns(""); const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput"); optionalInputStub.withArgs("expect-error").returns("false"); sinon.stub(api, "getGitHubVersion").resolves(gitHubVersion); diff --git a/src/analyze-action.ts b/src/analyze-action.ts index 67b025ead7..7c117f75a8 100644 --- a/src/analyze-action.ts +++ b/src/analyze-action.ts @@ -310,7 +310,7 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) { logger, ); - const checkoutPath = determineCheckoutPath(action); + const checkoutPath = await determineCheckoutPath(action); // Setup diff informed analysis if needed (based on whether init created the file) const diffRangePackDir = await setupDiffInformedQueryRun( diff --git a/src/analyze.ts b/src/analyze.ts index 3580f80aa4..306ccd434f 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -22,6 +22,7 @@ import { } from "./diff-informed-analysis-utils"; import { EnvVar } from "./environment"; import { FeatureEnablement, Feature } from "./feature-flags"; +import { getGitRoot } from "./git-utils"; import { BuiltInLanguage, Language } from "./languages"; import { Logger, withGroupAsync } from "./logging"; import { OverlayDatabaseMode } from "./overlay/overlay-database-mode"; @@ -93,8 +94,33 @@ export interface QueriesStatusReport * * @param action The action state. */ -export function determineCheckoutPath(action: ActionState<["Actions"]>) { - return action.actions.getRequiredInput("checkout_path"); +export async function determineCheckoutPath( + action: ActionState<["Logger", "Actions"]>, +) { + const checkoutPathInput = action.actions.getRequiredInput("checkout_path"); + + // Try to obtain the root path of the repository and validate that it matches the input. + const repositoryRoot = await getGitRoot(checkoutPathInput); + + if (repositoryRoot === undefined) { + action.logger.warning( + [ + `The directory at '${checkoutPathInput}' is not in the work tree of a git repository.`, + "If the repository being analyzed is checked out elsewhere,", + "you must explicitly set the 'checkout_path' input for the 'codeql-action/analyze' step to", + "the checkout path.", + ].join(" "), + ); + } else if (repositoryRoot !== path.resolve(checkoutPathInput)) { + action.logger.warning( + [ + `The directory at '${checkoutPathInput}' is not the root of the repository ('${repositoryRoot}').`, + "Set the 'checkout_path' input for the 'codeql-action/analyze' step to the root path of the checkout.", + ].join(" "), + ); + } + + return checkoutPathInput; } async function setupPythonExtractor(logger: Logger) { diff --git a/src/config-utils.test.ts b/src/config-utils.test.ts index 29d72f3af4..ec18bec453 100644 --- a/src/config-utils.test.ts +++ b/src/config-utils.test.ts @@ -172,6 +172,7 @@ test.serial("load empty config", async (t) => { createTestInitConfigInputs({ languagesInput: languages, repository: { owner: "github", repo: "example" }, + sourceRoot: tempDir, tempDir, codeql, logger, @@ -186,6 +187,7 @@ test.serial("load empty config", async (t) => { logger, }), {}, + undefined, ); t.deepEqual(config, expectedConfig); @@ -216,6 +218,7 @@ test.serial("load code quality config", async (t) => { analysisKinds: [AnalysisKind.CodeQuality], languagesInput: languages, repository: { owner: "github", repo: "example" }, + sourceRoot: tempDir, tempDir, codeql, logger, @@ -296,6 +299,7 @@ test.serial( analysisKinds: [AnalysisKind.CodeQuality], languagesInput: languages, repository: { owner: "github", repo: "example" }, + sourceRoot: tempDir, tempDir, codeql, repositoryProperties, @@ -512,6 +516,7 @@ test.serial("load non-empty input", async (t) => { // And the config we expect it to parse to const expectedConfig = createTestConfig({ languages: [BuiltInLanguage.javascript], + repositoryRoot: undefined, buildMode: BuildMode.None, originalUserInput: userConfig, computedConfig: userConfig, @@ -532,6 +537,7 @@ test.serial("load non-empty input", async (t) => { state, createTestInitConfigInputs({ languagesInput, + sourceRoot: tempDir, buildModeInput: "none", configFile: configFilePath, debugArtifactName: "my-artifact", @@ -1092,11 +1098,6 @@ const checkOverlayEnablementMacro = makeMacro({ return lang === BuiltInLanguage.java; }); - // Mock git root detection - if (setup.gitRoot !== undefined) { - sinon.stub(gitUtils, "getGitRoot").resolves(setup.gitRoot); - } - // Mock submodule detection sinon.stub(gitUtils, "hasSubmodules").returns(setup.hasSubmodules); @@ -1109,6 +1110,7 @@ const checkOverlayEnablementMacro = makeMacro({ codeql, features, setup.languages, + setup.gitRoot, // repositoryRoot tempDir, // sourceRoot setup.buildMode, undefined, diff --git a/src/config-utils.ts b/src/config-utils.ts index 288b4f02fb..37337b68d3 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -385,6 +385,7 @@ export async function initActionState( enableFileCoverageInformation, }: InitConfigInputs, userConfig: UserConfig, + repositoryRoot: string | undefined, ): Promise { const languages = await getLanguages( codeql, @@ -436,6 +437,7 @@ export async function initActionState( return { version: getActionVersion(), + repositoryRoot, analysisKinds, languages, buildMode, @@ -718,6 +720,7 @@ export async function checkOverlayEnablement( codeql: CodeQL, features: FeatureEnablement, languages: Language[], + repositoryRoot: string | undefined, sourceRoot: string, buildMode: BuildMode | undefined, ramInput: string | undefined, @@ -747,6 +750,7 @@ export async function checkOverlayEnablement( true, codeql, languages, + repositoryRoot, sourceRoot, buildMode, gitVersion, @@ -836,6 +840,7 @@ export async function checkOverlayEnablement( false, codeql, languages, + repositoryRoot, sourceRoot, buildMode, gitVersion, @@ -855,6 +860,7 @@ async function validateOverlayDatabaseMode( overlayModeSetExplicitly: boolean, codeql: CodeQL, languages: Language[], + repositoryRoot: string | undefined, sourceRoot: string, buildMode: BuildMode | undefined, gitVersion: GitVersionInfo | undefined, @@ -890,8 +896,7 @@ async function validateOverlayDatabaseMode( ); return new Failure(OverlayDisabledReason.IncompatibleCodeQl); } - const gitRoot = await getGitRoot(sourceRoot); - if (gitRoot === undefined) { + if (repositoryRoot === undefined) { logger.warning( `Cannot build an ${overlayDatabaseMode} database because ` + `the source root "${sourceRoot}" is not inside a git repository. ` + @@ -899,7 +904,7 @@ async function validateOverlayDatabaseMode( ); return new Failure(OverlayDisabledReason.NoGitRoot); } - if (hasSubmodules(gitRoot)) { + if (hasSubmodules(repositoryRoot)) { if (gitVersion === undefined) { logger.warning( `Cannot build an ${overlayDatabaseMode} database because ` + @@ -1160,9 +1165,11 @@ export async function initConfig( const { logger, features } = actionState; const { tempDir } = inputs; + const repositoryRoot = await getGitRoot(inputs.sourceRoot); + const userConfig = await determineUserConfig(actionState, tempDir, inputs); - const config = await initActionState(inputs, userConfig); + const config = await initActionState(inputs, userConfig, repositoryRoot); // If Code Quality analysis is the only enabled analysis kind, then we will initialise // the database for Code Quality. That entails disabling the default queries and only @@ -1244,6 +1251,7 @@ export async function initConfig( inputs.codeql, inputs.features, config.languages, + repositoryRoot, inputs.sourceRoot, config.buildMode, inputs.ramInput, diff --git a/src/config/action-config.ts b/src/config/action-config.ts index de6882e77e..2b69141d2e 100644 --- a/src/config/action-config.ts +++ b/src/config/action-config.ts @@ -16,6 +16,11 @@ export interface Config { * The version of the CodeQL Action that the configuration is for. */ version: string; + /** + * The path at which the repository being analysed is checked out at, if available. + * Persisted in the CodeQL Action configuration state, so that we can consult it in later workflow steps. + */ + repositoryRoot: string | undefined; /** * Set of analysis kinds that are enabled. */ diff --git a/src/testing-utils.ts b/src/testing-utils.ts index f15cee2e71..b50d51c94e 100644 --- a/src/testing-utils.ts +++ b/src/testing-utils.ts @@ -968,6 +968,7 @@ export function createTestConfig(overrides: Partial): Config { {}, { version: getActionVersion(), + repositoryRoot: undefined, analysisKinds: [AnalysisKind.CodeScanning], languages: [], buildMode: undefined, From ba615b5d9d7156e92e6950dd84dc3ee1d4d5f4ea Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 16 Sep 2026 15:27:29 +0100 Subject: [PATCH 003/107] Verify persisted repository root path in `analyze` action --- lib/entry-points.js | 13 +++++++++++-- src/analyze-action.ts | 2 +- src/analyze.ts | 15 +++++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 7994d26d98..ca6dd881b0 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -153805,7 +153805,7 @@ var CodeQLAnalysisError = class extends Error { message; error; }; -async function determineCheckoutPath(action) { +async function determineCheckoutPath(action, config) { const checkoutPathInput = action.actions.getRequiredInput("checkout_path"); const repositoryRoot = await getGitRoot(checkoutPathInput); if (repositoryRoot === void 0) { @@ -153824,6 +153824,15 @@ async function determineCheckoutPath(action) { "Set the 'checkout_path' input for the 'codeql-action/analyze' step to the root path of the checkout." ].join(" ") ); + } else if (config.repositoryRoot !== void 0 && repositoryRoot !== config.repositoryRoot) { + action.logger.warning( + [ + `The repository path at '${repositoryRoot}' does not match that found by the 'codeql-action/init' step: '${config.repositoryRoot}'.`, + "Ensure that the 'checkout_path' input for the 'codeql-action/analyze' step is set to the path of the same repository that", + "the 'codeql-action/init' step determined. This is either the GitHub Actions workspace or the repository root corresponding to", + "the 'source-root' input if that was provided." + ].join(" ") + ); } return checkoutPathInput; } @@ -156638,7 +156647,7 @@ async function run(action) { getOptionalInput("ram") || process.env["CODEQL_RAM"], logger ); - const checkoutPath = await determineCheckoutPath(action); + const checkoutPath = await determineCheckoutPath(action, config); const diffRangePackDir = await setupDiffInformedQueryRun( logger, checkoutPath diff --git a/src/analyze-action.ts b/src/analyze-action.ts index 7c117f75a8..8cc13c1ba0 100644 --- a/src/analyze-action.ts +++ b/src/analyze-action.ts @@ -310,7 +310,7 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) { logger, ); - const checkoutPath = await determineCheckoutPath(action); + const checkoutPath = await determineCheckoutPath(action, config); // Setup diff informed analysis if needed (based on whether init created the file) const diffRangePackDir = await setupDiffInformedQueryRun( diff --git a/src/analyze.ts b/src/analyze.ts index 306ccd434f..f1a1841f38 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -93,9 +93,11 @@ export interface QueriesStatusReport * refers to the root of a repository. * * @param action The action state. + * @param config The CodeQL Action configuration state. */ export async function determineCheckoutPath( action: ActionState<["Logger", "Actions"]>, + config: configUtils.Config, ) { const checkoutPathInput = action.actions.getRequiredInput("checkout_path"); @@ -118,6 +120,19 @@ export async function determineCheckoutPath( "Set the 'checkout_path' input for the 'codeql-action/analyze' step to the root path of the checkout.", ].join(" "), ); + } else if ( + config.repositoryRoot !== undefined && + repositoryRoot !== config.repositoryRoot + ) { + // The repository root that was persisted by the `init` step doesn't match the one we have found here. + action.logger.warning( + [ + `The repository path at '${repositoryRoot}' does not match that found by the 'codeql-action/init' step: '${config.repositoryRoot}'.`, + "Ensure that the 'checkout_path' input for the 'codeql-action/analyze' step is set to the path of the same repository that", + "the 'codeql-action/init' step determined. This is either the GitHub Actions workspace or the repository root corresponding to", + "the 'source-root' input if that was provided.", + ].join(" "), + ); } return checkoutPathInput; From 54a43494ca0def0db032b3ec35007ddcffc822a1 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 16 Sep 2026 12:21:40 +0100 Subject: [PATCH 004/107] Propagate `checkoutPath` to `getRef` --- lib/entry-points.js | 90 +++++++++++++--------- src/actions-util.ts | 4 +- src/analyze-action.ts | 2 +- src/codeql.ts | 2 +- src/config-utils.ts | 13 +++- src/database-upload.ts | 6 +- src/environment.ts | 7 ++ src/git-utils.test.ts | 161 ++++++++++++++++++++++++--------------- src/git-utils.ts | 45 ++++++----- src/init-action-post.ts | 5 +- src/overlay/caching.ts | 3 +- src/status-report.ts | 2 +- src/trap-caching.test.ts | 1 + src/trap-caching.ts | 18 ++++- src/upload-lib.ts | 9 ++- 15 files changed, 230 insertions(+), 138 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index ca6dd881b0..dc209ae627 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -142187,6 +142187,12 @@ var Env = class extends ReadOnlyEnv { this.vars[name] = value; this.changed = true; } + /** Sets all environment variables given by `vars`. */ + setAll(vars) { + for (const [key, val] of Object.entries(vars)) { + this.set(key, val); + } + } /** Gets a value indicating whether `set` was called at least once. */ hasChanged() { return this.changed; @@ -147019,7 +147025,7 @@ var runGitCommand = async function(workingDirectory, args, customErrorMessage, o throw error3; } }; -var getCommitOid = async function(checkoutPath, ref = "HEAD") { +var getCommitOid = async function(env, checkoutPath, ref = "HEAD") { try { const stdout = await runGitCommand( checkoutPath, @@ -147028,7 +147034,7 @@ var getCommitOid = async function(checkoutPath, ref = "HEAD") { ); return stdout.trim(); } catch { - return getOptionalInput("sha") || getRequiredEnvParam("GITHUB_SHA"); + return getOptionalInput("sha") || env.getRequired("GITHUB_SHA" /* GITHUB_SHA */); } }; var determineBaseBranchHeadCommitOid = async function(checkoutPathOverride) { @@ -147138,12 +147144,12 @@ var getFileOidsUnderPath = async function(basePath) { } return fileOidMap; }; -function getRefFromEnv() { +function getRefFromEnv(env) { let refEnv; try { - refEnv = getRequiredEnvParam("GITHUB_REF"); + refEnv = env.getRequired("GITHUB_REF" /* GITHUB_REF */); } catch (e) { - const maybeRef = process.env["CODE_SCANNING_REF"]; + const maybeRef = env.getOptional("CODE_SCANNING_REF" /* CODE_SCANNING_REF */); if (maybeRef === void 0 || maybeRef.length === 0) { throw e; } @@ -147151,10 +147157,10 @@ function getRefFromEnv() { } return refEnv; } -async function getRef() { +async function getRef(env, checkoutPath) { const refInput = getOptionalInput("ref"); const shaInput = getOptionalInput("sha"); - const checkoutPath = getOptionalInput("checkout_path") || getOptionalInput("source-root") || getRequiredEnvParam("GITHUB_WORKSPACE"); + checkoutPath = checkoutPath ?? env.getRequired("GITHUB_WORKSPACE" /* GITHUB_WORKSPACE */); const hasRefInput = !!refInput; const hasShaInput = !!shaInput; if ((hasRefInput || hasShaInput) && !(hasRefInput && hasShaInput)) { @@ -147162,8 +147168,8 @@ async function getRef() { "Both 'ref' and 'sha' are required if one of them is provided." ); } - const ref = refInput || getRefFromEnv(); - const sha = shaInput || getRequiredEnvParam("GITHUB_SHA"); + const ref = refInput || getRefFromEnv(env); + const sha = shaInput || env.getRequired("GITHUB_SHA" /* GITHUB_SHA */); if (refInput) { return refInput; } @@ -147171,8 +147177,9 @@ async function getRef() { if (!pull_ref_regex.test(ref)) { return ref; } - const head = await getCommitOid(checkoutPath, "HEAD"); + const head = await getCommitOid(env, checkoutPath, "HEAD"); const hasChangedRef = sha !== head && await getCommitOid( + env, checkoutPath, ref.replace(/^refs\/pull\//, "refs/remotes/pull/") ) !== head; @@ -147189,16 +147196,16 @@ async function getRef() { function removeRefsHeadsPrefix(ref) { return ref.startsWith("refs/heads/") ? ref.slice("refs/heads/".length) : ref; } -async function isAnalyzingDefaultBranch() { - if (process.env.CODE_SCANNING_IS_ANALYZING_DEFAULT_BRANCH === "true") { +async function isAnalyzingDefaultBranch(env, checkoutPath) { + if (env.getOptional("CODE_SCANNING_IS_ANALYZING_DEFAULT_BRANCH") === "true") { return true; } - let currentRef = await getRef(); + let currentRef = await getRef(env, checkoutPath); currentRef = removeRefsHeadsPrefix(currentRef); - const event = getWorkflowEvent(); + const event = getWorkflowEvent(env); let defaultBranch = event?.repository?.default_branch; - if (getWorkflowEventName() === "schedule") { - defaultBranch = removeRefsHeadsPrefix(getRefFromEnv()); + if (getWorkflowEventName(env) === "schedule") { + defaultBranch = removeRefsHeadsPrefix(getRefFromEnv(env)); } return currentRef === defaultBranch; } @@ -147470,7 +147477,7 @@ function getRegistryTypesFromEnv(logger, env = getEnv()) { async function createStatusReportBase(actionName, status, actionStartedAt, config, diskInfo, logger, cause, exception) { try { const commitOid = getOptionalInput("sha") || process.env["GITHUB_SHA"] || ""; - const ref = await getRef(); + const ref = await getRef(getEnv(), config?.repositoryRoot); const jobRunUUID = process.env["CODEQL_ACTION_JOB_RUN_UUID" /* JOB_RUN_UUID */] || ""; const workflowRunID = getWorkflowRunID(); const workflowRunAttempt = getWorkflowRunAttempt(); @@ -150101,7 +150108,7 @@ var CACHE_VERSION = 1; var CODEQL_TRAP_CACHE_PREFIX = "codeql-trap"; var MINIMUM_CACHE_MB_TO_UPLOAD = 10; var MAX_CACHE_OPERATION_MS2 = 12e4; -async function downloadTrapCaches(codeql, languages, logger) { +async function downloadTrapCaches(codeql, languages, logger, repositoryRoot) { const result = {}; const languagesSupportingCaching = await getLanguagesSupportingCaching( codeql, @@ -150121,7 +150128,7 @@ async function downloadTrapCaches(codeql, languages, logger) { fs9.mkdirSync(cacheDir2, { recursive: true }); result[language] = cacheDir2; } - if (await isAnalyzingDefaultBranch()) { + if (await isAnalyzingDefaultBranch(getEnv(), repositoryRoot)) { logger.info( "Analyzing default branch. Skipping downloading of TRAP caches." ); @@ -150160,7 +150167,9 @@ async function downloadTrapCaches(codeql, languages, logger) { return result; } async function uploadTrapCaches(codeql, config, logger) { - if (!await isAnalyzingDefaultBranch()) return false; + if (!await isAnalyzingDefaultBranch(getEnv(), config.repositoryRoot)) { + return false; + } for (const language of config.languages) { const cacheDir2 = config.trapCaches[language]; if (cacheDir2 === void 0) continue; @@ -150196,6 +150205,7 @@ async function uploadTrapCaches(codeql, config, logger) { return true; } async function cleanupTrapCaches(config, features, logger) { + const env = getEnv(); if (!await features.getValue("cleanup_trap_caches" /* CleanupTrapCaches */)) { return { trap_cache_cleanup_skipped_because: "feature disabled" @@ -150204,7 +150214,7 @@ async function cleanupTrapCaches(config, features, logger) { logger.warning( "TRAP cache cleanup is deprecated and will be removed in May 2026. We recommend instead disabling TRAP caching by passing the `trap-caching: false` input to the `init` Action." ); - if (!await isAnalyzingDefaultBranch()) { + if (!await isAnalyzingDefaultBranch(env, config.repositoryRoot)) { return { trap_cache_cleanup_skipped_because: "not analyzing default branch" }; @@ -150213,7 +150223,7 @@ async function cleanupTrapCaches(config, features, logger) { let totalBytesCleanedUp = 0; const allCaches = await listActionsCaches( CODEQL_TRAP_CACHE_PREFIX, - await getRef() + await getRef(env, config.repositoryRoot) ); for (const language of config.languages) { if (config.trapCaches[language]) { @@ -150505,9 +150515,14 @@ async function initActionState({ enableFileCoverageInformation }; } -async function downloadCacheWithTime(codeQL, languages, logger) { +async function downloadCacheWithTime(codeQL, languages, logger, repositoryRoot) { const start = import_perf_hooks2.performance.now(); - const trapCaches = await downloadTrapCaches(codeQL, languages, logger); + const trapCaches = await downloadTrapCaches( + codeQL, + languages, + logger, + repositoryRoot + ); const trapCacheDownloadTime = import_perf_hooks2.performance.now() - start; return { trapCaches, trapCacheDownloadTime }; } @@ -150705,7 +150720,7 @@ async function checkOverlayEnablement(codeql, features, languages, repositoryRoo logger.info( `Setting overlay database mode to ${overlayDatabaseMode} with caching because we are analyzing a pull request.` ); - } else if (await isAnalyzingDefaultBranch()) { + } else if (await isAnalyzingDefaultBranch(getEnv(), repositoryRoot)) { overlayDatabaseMode = "overlay-base" /* OverlayBase */; logger.info( `Setting overlay database mode to ${overlayDatabaseMode} with caching because we are analyzing the default branch.` @@ -150992,7 +151007,8 @@ async function initConfig(actionState, inputs) { const { trapCaches, trapCacheDownloadTime } = await downloadCacheWithTime( inputs.codeql, config.languages, - logger + logger, + repositoryRoot ); config.trapCaches = trapCaches; config.trapCacheDownloadTime = trapCacheDownloadTime; @@ -151455,7 +151471,7 @@ async function getCacheSaveKey(config, codeQlVersion, checkoutPath, logger) { `Failed to get workflow run ID or attempt ID. Reason: ${getErrorMessage(e)}` ); } - const sha = await getCommitOid(checkoutPath); + const sha = await getCommitOid(getEnv(), checkoutPath); const restoreKeyPrefix = await getCacheRestoreKeyPrefix( config, codeQlVersion @@ -153408,7 +153424,7 @@ async function getTrapCachingExtractorConfigArgs(config) { async function getTrapCachingExtractorConfigArgsForLang(config, language) { const cacheDir2 = config.trapCaches[language]; if (cacheDir2 === void 0) return []; - const write = await isAnalyzingDefaultBranch(); + const write = await isAnalyzingDefaultBranch(getEnv(), config.repositoryRoot); return [ `-O=${language}.trap.cache.dir=${cacheDir2}`, `-O=${language}.trap.cache.bound=${TRAP_CACHE_SIZE_MB}`, @@ -154227,7 +154243,7 @@ async function cleanupAndUploadDatabases(action, repositoryNwo, codeql, config, logger.debug("Not running against github.com or GHEC-DR. Skipping upload."); return []; } - if (!await isAnalyzingDefaultBranch()) { + if (!await isAnalyzingDefaultBranch(action.env, checkoutPath)) { logger.debug("Not analyzing default branch. Skipping upload."); return []; } @@ -154244,7 +154260,7 @@ async function cleanupAndUploadDatabases(action, repositoryNwo, codeql, config, includeDiagnostics: false }); bundledDbSize = fs18.statSync(bundledDb).size; - const commitOid = await getCommitOid(checkoutPath); + const commitOid = await getCommitOid(action.env, checkoutPath); const maxAttempts = 4; let uploadDurationMs; for (let attempt = 1; attempt <= maxAttempts; attempt++) { @@ -156242,12 +156258,13 @@ async function uploadPostProcessedFiles(logger, checkoutPath, uploadTarget, post logger.debug(`Compressing serialized SARIF`); const zippedSarif = import_zlib.default.gzipSync(sarifPayload).toString("base64"); const checkoutURI = url.pathToFileURL(checkoutPath).href; + const env = getEnv(); const payload = uploadTarget.transformPayload( buildPayload( - await getCommitOid(checkoutPath), - await getRef(), + await getCommitOid(env, checkoutPath), + await getRef(env, checkoutPath), postProcessingResults.analysisKey, - getRequiredEnvParam("GITHUB_WORKFLOW"), + env.getRequired("GITHUB_WORKFLOW" /* GITHUB_WORKFLOW */), zippedSarif, getWorkflowRunID(), getWorkflowRunAttempt(), @@ -156723,7 +156740,7 @@ async function run(action) { checkoutPath ); databaseUploadResults = await cleanupAndUploadDatabases( - { logger, features }, + { ...action, features }, repositoryNwo, codeql, config, @@ -163024,6 +163041,7 @@ async function removeUploadedSarif(uploadFailedSarifResult, logger) { // src/init-action-post.ts async function run4(startedAt) { const logger = getActionsLogger(); + const env = getEnv(); let config; let uploadFailedSarifResult; let dependencyCachingUsage; @@ -163054,10 +163072,10 @@ async function run4(startedAt) { repositoryNwo, features, jobStatus2, - getEnv(), + env, logger ); - if (await isAnalyzingDefaultBranch() && config.dependencyCachingEnabled !== "none" /* None */) { + if (await isAnalyzingDefaultBranch(env, config.repositoryRoot) && config.dependencyCachingEnabled !== "none" /* None */) { dependencyCachingUsage = await getDependencyCacheUsage(logger); } } diff --git a/src/actions-util.ts b/src/actions-util.ts index 677bb04b1b..da9127bdeb 100644 --- a/src/actions-util.ts +++ b/src/actions-util.ts @@ -94,7 +94,7 @@ export function getActionVersion(): string { * * This will be "dynamic" for default setup workflow runs. */ -export function getWorkflowEventName(env: Env = getEnv()) { +export function getWorkflowEventName(env: ReadOnlyEnv = getEnv()) { return env.getRequired(ActionsEnvVars.GITHUB_EVENT_NAME); } @@ -121,7 +121,7 @@ function getRelativeScriptPath(env: Env): string { } /** Returns the contents of `GITHUB_EVENT_PATH` as a JSON object. */ -export function getWorkflowEvent(env: Env = getEnv()): any { +export function getWorkflowEvent(env: ReadOnlyEnv = getEnv()): any { const eventJsonFile = env.getRequired(ActionsEnvVars.GITHUB_EVENT_PATH); try { return JSON.parse(fs.readFileSync(eventJsonFile, "utf-8")); diff --git a/src/analyze-action.ts b/src/analyze-action.ts index 8cc13c1ba0..25d62c2930 100644 --- a/src/analyze-action.ts +++ b/src/analyze-action.ts @@ -406,7 +406,7 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) { // Note: Take care with the ordering of this call since databases may be cleaned up // at the `overlay` or `clear` level. databaseUploadResults = await cleanupAndUploadDatabases( - { logger, features }, + { ...action, features }, repositoryNwo, codeql, config, diff --git a/src/codeql.ts b/src/codeql.ts index 65e73d9451..66d387ba47 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -1212,7 +1212,7 @@ export async function getTrapCachingExtractorConfigArgsForLang( ): Promise { const cacheDir = config.trapCaches[language]; if (cacheDir === undefined) return []; - const write = await isAnalyzingDefaultBranch(); + const write = await isAnalyzingDefaultBranch(getEnv(), config.repositoryRoot); return [ `-O=${language}.trap.cache.dir=${cacheDir}`, `-O=${language}.trap.cache.bound=${TRAP_CACHE_SIZE_MB}`, diff --git a/src/config-utils.ts b/src/config-utils.ts index 37337b68d3..3c4970c727 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -46,7 +46,7 @@ import { makeTelemetryDiagnostic, } from "./diagnostics"; import { prepareDiffInformedAnalysis } from "./diff-informed-analysis-utils"; -import { EnvVar } from "./environment"; +import { EnvVar, getEnv } from "./environment"; import * as errorMessages from "./error-messages"; import { Feature, FeatureEnablement, FeatureWithoutCLI } from "./feature-flags"; import { @@ -467,12 +467,18 @@ async function downloadCacheWithTime( codeQL: CodeQL, languages: Language[], logger: Logger, + repositoryRoot: string | undefined, ): Promise<{ trapCaches: { [language: string]: string }; trapCacheDownloadTime: number; }> { const start = performance.now(); - const trapCaches = await downloadTrapCaches(codeQL, languages, logger); + const trapCaches = await downloadTrapCaches( + codeQL, + languages, + logger, + repositoryRoot, + ); const trapCacheDownloadTime = performance.now() - start; return { trapCaches, trapCacheDownloadTime }; } @@ -824,7 +830,7 @@ export async function checkOverlayEnablement( `Setting overlay database mode to ${overlayDatabaseMode} ` + "with caching because we are analyzing a pull request.", ); - } else if (await isAnalyzingDefaultBranch()) { + } else if (await isAnalyzingDefaultBranch(getEnv(), repositoryRoot)) { overlayDatabaseMode = OverlayDatabaseMode.OverlayBase; logger.info( `Setting overlay database mode to ${overlayDatabaseMode} ` + @@ -1305,6 +1311,7 @@ export async function initConfig( inputs.codeql, config.languages, logger, + repositoryRoot, ); config.trapCaches = trapCaches; config.trapCacheDownloadTime = trapCacheDownloadTime; diff --git a/src/database-upload.ts b/src/database-upload.ts index 9e4339fd47..35dfd90785 100644 --- a/src/database-upload.ts +++ b/src/database-upload.ts @@ -46,7 +46,7 @@ export interface DatabaseUploadResult { } export async function cleanupAndUploadDatabases( - action: ActionState<["Logger", "FeatureFlags"]>, + action: ActionState<["ReadOnlyEnv", "Logger", "FeatureFlags"]>, repositoryNwo: RepositoryNwo, codeql: CodeQL, config: Config, @@ -81,7 +81,7 @@ export async function cleanupAndUploadDatabases( return []; } - if (!(await gitUtils.isAnalyzingDefaultBranch())) { + if (!(await gitUtils.isAnalyzingDefaultBranch(action.env, checkoutPath))) { // We only want to upload a database if we are analyzing the default branch. logger.debug("Not analyzing default branch. Skipping upload."); return []; @@ -113,7 +113,7 @@ export async function cleanupAndUploadDatabases( includeDiagnostics: false, }); bundledDbSize = fs.statSync(bundledDb).size; - const commitOid = await gitUtils.getCommitOid(checkoutPath); + const commitOid = await gitUtils.getCommitOid(action.env, checkoutPath); // Upload with manual retry logic. We disable Octokit's built-in retries // because the request body is a ReadStream, which can only be consumed // once. diff --git a/src/environment.ts b/src/environment.ts index bf4bb4f717..90a9d43588 100644 --- a/src/environment.ts +++ b/src/environment.ts @@ -307,6 +307,13 @@ export class Env< this.changed = true; } + /** Sets all environment variables given by `vars`. */ + public setAll(vars: Record): void { + for (const [key, val] of Object.entries(vars)) { + this.set(key, val); + } + } + /** Gets a value indicating whether `set` was called at least once. */ public hasChanged(): boolean { return this.changed; diff --git a/src/git-utils.test.ts b/src/git-utils.test.ts index b77d40a7ec..8679f49a77 100644 --- a/src/git-utils.test.ts +++ b/src/git-utils.test.ts @@ -7,31 +7,36 @@ import test from "ava"; import * as sinon from "sinon"; import * as actionsUtil from "./actions-util"; +import { ActionsEnvVars, EnvVar } from "./environment"; import * as gitUtils from "./git-utils"; -import { setupActionsVars, setupTests } from "./testing-utils"; +import { getTestEnv, setupActionsVars, setupTests } from "./testing-utils"; import { withTmpDir } from "./util"; setupTests(test); -test.serial("getRef() throws on the empty string", async (t) => { - process.env["GITHUB_REF"] = ""; - await t.throwsAsync(gitUtils.getRef); +test("getRef() throws on the empty string", async (t) => { + const env = getTestEnv({ [ActionsEnvVars.GITHUB_REF]: "" }); + await t.throwsAsync(() => gitUtils.getRef(env, "")); }); test.serial( "getRef() returns merge PR ref if GITHUB_SHA still checked out", async (t) => { await withTmpDir(async (tmpDir: string) => { - setupActionsVars(tmpDir, tmpDir); const expectedRef = "refs/pull/1/merge"; const currentSha = "a".repeat(40); - process.env["GITHUB_REF"] = expectedRef; - process.env["GITHUB_SHA"] = currentSha; + + const env = getTestEnv(); + setupActionsVars(tmpDir, tmpDir, {}, env); + env.setAll({ + [ActionsEnvVars.GITHUB_REF]: expectedRef, + [ActionsEnvVars.GITHUB_SHA]: currentSha, + }); const callback = sinon.stub(gitUtils, "getCommitOid"); - callback.withArgs("HEAD").resolves(currentSha); + callback.withArgs(sinon.match.any, "HEAD").resolves(currentSha); - const actualRef = await gitUtils.getRef(); + const actualRef = await gitUtils.getRef(env, tmpDir); t.deepEqual(actualRef, expectedRef); }); }, @@ -41,17 +46,22 @@ test.serial( "getRef() returns merge PR ref if GITHUB_REF still checked out but sha has changed (actions checkout@v1)", async (t) => { await withTmpDir(async (tmpDir: string) => { - setupActionsVars(tmpDir, tmpDir); const expectedRef = "refs/pull/1/merge"; - process.env["GITHUB_REF"] = expectedRef; - process.env["GITHUB_SHA"] = "b".repeat(40); + const env = getTestEnv(); + setupActionsVars(tmpDir, tmpDir, {}, env); + env.setAll({ + [ActionsEnvVars.GITHUB_REF]: expectedRef, + [ActionsEnvVars.GITHUB_SHA]: "b".repeat(40), + }); const sha = "a".repeat(40); const callback = sinon.stub(gitUtils, "getCommitOid"); - callback.withArgs("refs/remotes/pull/1/merge").resolves(sha); - callback.withArgs("HEAD").resolves(sha); + callback + .withArgs(sinon.match.any, "refs/remotes/pull/1/merge") + .resolves(sha); + callback.withArgs(sinon.match.any, "HEAD").resolves(sha); - const actualRef = await gitUtils.getRef(); + const actualRef = await gitUtils.getRef(env, tmpDir); t.deepEqual(actualRef, expectedRef); }); }, @@ -61,15 +71,22 @@ test.serial( "getRef() returns head PR ref if GITHUB_REF no longer checked out", async (t) => { await withTmpDir(async (tmpDir: string) => { - setupActionsVars(tmpDir, tmpDir); - process.env["GITHUB_REF"] = "refs/pull/1/merge"; - process.env["GITHUB_SHA"] = "a".repeat(40); + const env = getTestEnv(); + setupActionsVars(tmpDir, tmpDir, {}, env); + env.setAll({ + [ActionsEnvVars.GITHUB_REF]: "refs/pull/1/merge", + [ActionsEnvVars.GITHUB_SHA]: "a".repeat(40), + }); const callback = sinon.stub(gitUtils, "getCommitOid"); - callback.withArgs(tmpDir, "refs/pull/1/merge").resolves("a".repeat(40)); - callback.withArgs(tmpDir, "HEAD").resolves("b".repeat(40)); - - const actualRef = await gitUtils.getRef(); + callback + .withArgs(sinon.match.any, tmpDir, "refs/pull/1/merge") + .resolves("a".repeat(40)); + callback + .withArgs(sinon.match.any, tmpDir, "HEAD") + .resolves("b".repeat(40)); + + const actualRef = await gitUtils.getRef(env, tmpDir); t.deepEqual(actualRef, "refs/pull/1/head"); }); }, @@ -79,7 +96,6 @@ test.serial( "getRef() returns ref provided as an input and ignores current HEAD", async (t) => { await withTmpDir(async (tmpDir: string) => { - setupActionsVars(tmpDir, tmpDir); const getAdditionalInputStub = sinon.stub( actionsUtil, "getOptionalInput", @@ -88,14 +104,20 @@ test.serial( getAdditionalInputStub.withArgs("sha").resolves("b".repeat(40)); // These values are be ignored - process.env["GITHUB_REF"] = "refs/pull/1/merge"; - process.env["GITHUB_SHA"] = "a".repeat(40); + const env = getTestEnv(); + setupActionsVars(tmpDir, tmpDir, {}, env); + env.setAll({ + [ActionsEnvVars.GITHUB_REF]: "refs/pull/1/merge", + [ActionsEnvVars.GITHUB_SHA]: "a".repeat(40), + }); const callback = sinon.stub(gitUtils, "getCommitOid"); - callback.withArgs("refs/pull/1/merge").resolves("b".repeat(40)); - callback.withArgs("HEAD").resolves("b".repeat(40)); + callback + .withArgs(sinon.match.any, "refs/pull/1/merge") + .resolves("b".repeat(40)); + callback.withArgs(sinon.match.any, "HEAD").resolves("b".repeat(40)); - const actualRef = await gitUtils.getRef(); + const actualRef = await gitUtils.getRef(env, tmpDir); t.deepEqual(actualRef, "refs/pull/2/merge"); }); }, @@ -105,14 +127,17 @@ test.serial( "getRef() returns CODE_SCANNING_REF as a fallback for GITHUB_REF", async (t) => { await withTmpDir(async (tmpDir: string) => { - setupActionsVars(tmpDir, tmpDir); const expectedRef = "refs/pull/1/HEAD"; const currentSha = "a".repeat(40); - process.env["CODE_SCANNING_REF"] = expectedRef; - process.env["GITHUB_REF"] = ""; - process.env["GITHUB_SHA"] = currentSha; + const env = getTestEnv(); + setupActionsVars(tmpDir, tmpDir, {}, env); + env.setAll({ + [EnvVar.CODE_SCANNING_REF]: expectedRef, + [ActionsEnvVars.GITHUB_REF]: "", + [ActionsEnvVars.GITHUB_SHA]: currentSha, + }); - const actualRef = await gitUtils.getRef(); + const actualRef = await gitUtils.getRef(env, tmpDir); t.deepEqual(actualRef, expectedRef); }); }, @@ -122,14 +147,17 @@ test.serial( "getRef() returns GITHUB_REF over CODE_SCANNING_REF if both are provided", async (t) => { await withTmpDir(async (tmpDir: string) => { - setupActionsVars(tmpDir, tmpDir); const expectedRef = "refs/pull/1/merge"; const currentSha = "a".repeat(40); - process.env["CODE_SCANNING_REF"] = "refs/pull/1/HEAD"; - process.env["GITHUB_REF"] = expectedRef; - process.env["GITHUB_SHA"] = currentSha; + const env = getTestEnv(); + setupActionsVars(tmpDir, tmpDir, {}, env); + env.setAll({ + [EnvVar.CODE_SCANNING_REF]: "refs/pull/1/HEAD", + [ActionsEnvVars.GITHUB_REF]: expectedRef, + [ActionsEnvVars.GITHUB_SHA]: currentSha, + }); - const actualRef = await gitUtils.getRef(); + const actualRef = await gitUtils.getRef(env, tmpDir); t.deepEqual(actualRef, expectedRef); }); }, @@ -139,7 +167,9 @@ test.serial( "getRef() throws an error if only `ref` is provided as an input", async (t) => { await withTmpDir(async (tmpDir: string) => { - setupActionsVars(tmpDir, tmpDir); + const env = getTestEnv(); + setupActionsVars(tmpDir, tmpDir, {}, env); + const getAdditionalInputStub = sinon.stub( actionsUtil, "getOptionalInput", @@ -148,7 +178,7 @@ test.serial( await t.throwsAsync( async () => { - await gitUtils.getRef(); + await gitUtils.getRef(env, tmpDir); }, { instanceOf: Error, @@ -164,8 +194,12 @@ test.serial( "getRef() throws an error if only `sha` is provided as an input", async (t) => { await withTmpDir(async (tmpDir: string) => { - setupActionsVars(tmpDir, tmpDir); - process.env["GITHUB_WORKSPACE"] = "/tmp"; + const env = getTestEnv(); + setupActionsVars(tmpDir, tmpDir, {}, env); + env.setAll({ + [ActionsEnvVars.GITHUB_WORKSPACE]: "/tmp", + }); + const getAdditionalInputStub = sinon.stub( actionsUtil, "getOptionalInput", @@ -174,7 +208,7 @@ test.serial( await t.throwsAsync( async () => { - await gitUtils.getRef(); + await gitUtils.getRef(env, tmpDir); }, { instanceOf: Error, @@ -187,13 +221,16 @@ test.serial( ); test.serial("isAnalyzingDefaultBranch()", async (t) => { - process.env["GITHUB_EVENT_NAME"] = "push"; - process.env["CODE_SCANNING_IS_ANALYZING_DEFAULT_BRANCH"] = "true"; - t.deepEqual(await gitUtils.isAnalyzingDefaultBranch(), true); - process.env["CODE_SCANNING_IS_ANALYZING_DEFAULT_BRANCH"] = "false"; + const env = getTestEnv({ + [ActionsEnvVars.GITHUB_EVENT_NAME]: "push", + CODE_SCANNING_IS_ANALYZING_DEFAULT_BRANCH: "true", + }); + t.deepEqual(await gitUtils.isAnalyzingDefaultBranch(env, ""), true); + + env.set("CODE_SCANNING_IS_ANALYZING_DEFAULT_BRANCH", "false"); await withTmpDir(async (tmpDir) => { - setupActionsVars(tmpDir, tmpDir); + setupActionsVars(tmpDir, tmpDir, {}, env); const envFile = path.join(tmpDir, "event.json"); fs.writeFileSync( envFile, @@ -203,17 +240,17 @@ test.serial("isAnalyzingDefaultBranch()", async (t) => { }, }), ); - process.env["GITHUB_EVENT_PATH"] = envFile; + env.set(ActionsEnvVars.GITHUB_EVENT_PATH, envFile); - process.env["GITHUB_REF"] = "main"; - process.env["GITHUB_SHA"] = "1234"; - t.deepEqual(await gitUtils.isAnalyzingDefaultBranch(), true); + env.set(ActionsEnvVars.GITHUB_REF, "main"); + env.set(ActionsEnvVars.GITHUB_SHA, "1234"); + t.deepEqual(await gitUtils.isAnalyzingDefaultBranch(env, tmpDir), true); - process.env["GITHUB_REF"] = "refs/heads/main"; - t.deepEqual(await gitUtils.isAnalyzingDefaultBranch(), true); + env.set(ActionsEnvVars.GITHUB_REF, "refs/heads/main"); + t.deepEqual(await gitUtils.isAnalyzingDefaultBranch(env, tmpDir), true); - process.env["GITHUB_REF"] = "feature"; - t.deepEqual(await gitUtils.isAnalyzingDefaultBranch(), false); + env.set(ActionsEnvVars.GITHUB_REF, "feature"); + t.deepEqual(await gitUtils.isAnalyzingDefaultBranch(env, tmpDir), false); fs.writeFileSync( envFile, @@ -221,9 +258,9 @@ test.serial("isAnalyzingDefaultBranch()", async (t) => { schedule: "0 0 * * *", }), ); - process.env["GITHUB_EVENT_NAME"] = "schedule"; - process.env["GITHUB_REF"] = "refs/heads/main"; - t.deepEqual(await gitUtils.isAnalyzingDefaultBranch(), true); + env.set(ActionsEnvVars.GITHUB_EVENT_NAME, "schedule"); + env.set(ActionsEnvVars.GITHUB_REF, "refs/heads/main"); + t.deepEqual(await gitUtils.isAnalyzingDefaultBranch(env, tmpDir), true); const getAdditionalInputStub = sinon.stub(actionsUtil, "getOptionalInput"); getAdditionalInputStub @@ -232,9 +269,9 @@ test.serial("isAnalyzingDefaultBranch()", async (t) => { getAdditionalInputStub .withArgs("sha") .resolves("0000000000000000000000000000000000000000"); - process.env["GITHUB_EVENT_NAME"] = "schedule"; - process.env["GITHUB_REF"] = "refs/heads/main"; - t.deepEqual(await gitUtils.isAnalyzingDefaultBranch(), false); + env.set(ActionsEnvVars.GITHUB_EVENT_NAME, "schedule"); + env.set(ActionsEnvVars.GITHUB_REF, "refs/heads/main"); + t.deepEqual(await gitUtils.isAnalyzingDefaultBranch(env, tmpDir), false); }); }); diff --git a/src/git-utils.ts b/src/git-utils.ts index 0f5bf52a47..2e042e361a 100644 --- a/src/git-utils.ts +++ b/src/git-utils.ts @@ -13,6 +13,7 @@ import { getWorkflowEvent, getWorkflowEventName, } from "./actions-util"; +import { ActionsEnvVars, EnvVar, type ReadOnlyEnv } from "./environment"; import { ConfigurationError, getRequiredEnvParam } from "./util"; /** @@ -101,6 +102,7 @@ export const runGitCommand = async function ( * Gets the SHA of the commit that is currently checked out. */ export const getCommitOid = async function ( + env: ReadOnlyEnv, checkoutPath: string, ref = "HEAD", ): Promise { @@ -119,7 +121,9 @@ export const getCommitOid = async function ( ); return stdout.trim(); } catch { - return getOptionalInput("sha") || getRequiredEnvParam("GITHUB_SHA"); + return ( + getOptionalInput("sha") || env.getRequired(ActionsEnvVars.GITHUB_SHA) + ); } }; @@ -314,18 +318,18 @@ export const getFileOidsUnderPath = async function ( return fileOidMap; }; -function getRefFromEnv(): string { +function getRefFromEnv(env: ReadOnlyEnv): string { // To workaround a limitation of Actions dynamic workflows not setting // the GITHUB_REF in some cases, we accept also the ref within the // CODE_SCANNING_REF variable. When possible, however, we prefer to use // the GITHUB_REF as that is a protected variable and cannot be overwritten. let refEnv: string; try { - refEnv = getRequiredEnvParam("GITHUB_REF"); + refEnv = env.getRequired(ActionsEnvVars.GITHUB_REF); } catch (e) { // If the GITHUB_REF is not set, we try to rescue by getting the // CODE_SCANNING_REF. - const maybeRef = process.env["CODE_SCANNING_REF"]; + const maybeRef = env.getOptional(EnvVar.CODE_SCANNING_REF); if (maybeRef === undefined || maybeRef.length === 0) { throw e; } @@ -337,15 +341,16 @@ function getRefFromEnv(): string { /** * Get the ref currently being analyzed. */ -export async function getRef(): Promise { +export async function getRef( + env: ReadOnlyEnv, + checkoutPath: string | undefined, +): Promise { // Will be in the form "refs/heads/master" on a push event // or in the form "refs/pull/N/merge" on a pull_request event const refInput = getOptionalInput("ref"); const shaInput = getOptionalInput("sha"); - const checkoutPath = - getOptionalInput("checkout_path") || - getOptionalInput("source-root") || - getRequiredEnvParam("GITHUB_WORKSPACE"); + checkoutPath = + checkoutPath ?? env.getRequired(ActionsEnvVars.GITHUB_WORKSPACE); const hasRefInput = !!refInput; const hasShaInput = !!shaInput; @@ -356,8 +361,8 @@ export async function getRef(): Promise { ); } - const ref = refInput || getRefFromEnv(); - const sha = shaInput || getRequiredEnvParam("GITHUB_SHA"); + const ref = refInput || getRefFromEnv(env); + const sha = shaInput || env.getRequired(ActionsEnvVars.GITHUB_SHA); // If the ref is a user-provided input, we have to skip logic // and assume that it is really where they want to upload the results. @@ -374,7 +379,7 @@ export async function getRef(): Promise { return ref; } - const head = await getCommitOid(checkoutPath, "HEAD"); + const head = await getCommitOid(env, checkoutPath, "HEAD"); // in actions/checkout@v2+ we can check if git rev-parse HEAD == GITHUB_SHA // in actions/checkout@v1 this may not be true as it checks out the repository @@ -384,6 +389,7 @@ export async function getRef(): Promise { const hasChangedRef = sha !== head && (await getCommitOid( + env, checkoutPath, ref.replace(/^refs\/pull\//, "refs/remotes/pull/"), )) !== head; @@ -410,20 +416,23 @@ function removeRefsHeadsPrefix(ref: string): string { * environment variable can be set in cases where repository information might not be available, for * example dynamic workflows. */ -export async function isAnalyzingDefaultBranch(): Promise { - if (process.env.CODE_SCANNING_IS_ANALYZING_DEFAULT_BRANCH === "true") { +export async function isAnalyzingDefaultBranch( + env: ReadOnlyEnv, + checkoutPath: string | undefined, +): Promise { + if (env.getOptional("CODE_SCANNING_IS_ANALYZING_DEFAULT_BRANCH") === "true") { return true; } // Get the current ref and trim and refs/heads/ prefix - let currentRef = await getRef(); + let currentRef = await getRef(env, checkoutPath); currentRef = removeRefsHeadsPrefix(currentRef); - const event = getWorkflowEvent(); + const event = getWorkflowEvent(env); let defaultBranch = event?.repository?.default_branch; - if (getWorkflowEventName() === "schedule") { - defaultBranch = removeRefsHeadsPrefix(getRefFromEnv()); + if (getWorkflowEventName(env) === "schedule") { + defaultBranch = removeRefsHeadsPrefix(getRefFromEnv(env)); } return currentRef === defaultBranch; diff --git a/src/init-action-post.ts b/src/init-action-post.ts index 749020ac64..985538b8a9 100644 --- a/src/init-action-post.ts +++ b/src/init-action-post.ts @@ -50,6 +50,7 @@ async function run(startedAt: Date) { // possible, and only use safe functions outside. const logger = getActionsLogger(); + const env = getEnv(); let config: Config | undefined; let uploadFailedSarifResult: | initActionPostHelper.UploadFailedSarifResult @@ -91,7 +92,7 @@ async function run(startedAt: Date) { repositoryNwo, features, jobStatus, - getEnv(), + env, logger, ); @@ -100,7 +101,7 @@ async function run(startedAt: Date) { // do this under these circumstances to avoid slowing down analyses for PRs // and where caching may not be enabled. if ( - (await gitUtils.isAnalyzingDefaultBranch()) && + (await gitUtils.isAnalyzingDefaultBranch(env, config.repositoryRoot)) && config.dependencyCachingEnabled !== CachingKind.None ) { dependencyCachingUsage = await getDependencyCacheUsage(logger); diff --git a/src/overlay/caching.ts b/src/overlay/caching.ts index d246626780..9b5906dde3 100644 --- a/src/overlay/caching.ts +++ b/src/overlay/caching.ts @@ -15,6 +15,7 @@ import { CleanupLevel, getBaseDatabaseOidsFilePath, getCodeQLDatabasePath, + getEnv, getErrorMessage, isInTestMode, tryGetFolderBytes, @@ -377,7 +378,7 @@ export async function getCacheSaveKey( `Failed to get workflow run ID or attempt ID. Reason: ${getErrorMessage(e)}`, ); } - const sha = await getCommitOid(checkoutPath); + const sha = await getCommitOid(getEnv(), checkoutPath); const restoreKeyPrefix = await getCacheRestoreKeyPrefix( config, codeQlVersion, diff --git a/src/status-report.ts b/src/status-report.ts index c392b51922..fa26d049e5 100644 --- a/src/status-report.ts +++ b/src/status-report.ts @@ -366,7 +366,7 @@ export async function createStatusReportBase( try { const commitOid = getOptionalInput("sha") || process.env["GITHUB_SHA"] || ""; - const ref = await getRef(); + const ref = await getRef(getEnv(), config?.repositoryRoot); const jobRunUUID = process.env[EnvVar.JOB_RUN_UUID] || ""; const workflowRunID = getWorkflowRunID(); const workflowRunAttempt = getWorkflowRunAttempt(); diff --git a/src/trap-caching.test.ts b/src/trap-caching.test.ts index 478305e577..15ab494812 100644 --- a/src/trap-caching.test.ts +++ b/src/trap-caching.test.ts @@ -182,6 +182,7 @@ test.serial( stubCodeql, [BuiltInLanguage.javascript, BuiltInLanguage.cpp], logger, + undefined, ); t.assert( stubRestore.calledOnceWith( diff --git a/src/trap-caching.ts b/src/trap-caching.ts index a802aac892..fbcd9951b9 100644 --- a/src/trap-caching.ts +++ b/src/trap-caching.ts @@ -14,6 +14,7 @@ import { Language } from "./languages"; import { Logger } from "./logging"; import { asHTTPError, + getEnv, getErrorMessage, tryGetFolderBytes, waitForResultWithTimeLimit, @@ -43,6 +44,7 @@ const MAX_CACHE_OPERATION_MS = 120_000; // Two minutes * @param codeql The CodeQL instance to use. * @param languages The languages being analyzed. * @param logger A logger to record some informational messages to. + * @param repositoryRoot The path at which the repository is checked out at. * @returns A partial map from languages to TRAP cache paths on disk, with * languages for which we shouldn't use TRAP caching omitted. */ @@ -50,6 +52,7 @@ export async function downloadTrapCaches( codeql: CodeQL, languages: Language[], logger: Logger, + repositoryRoot: string | undefined, ): Promise<{ [language: string]: string }> { const result: { [language: string]: string } = {}; const languagesSupportingCaching = await getLanguagesSupportingCaching( @@ -72,7 +75,7 @@ export async function downloadTrapCaches( result[language] = cacheDir; } - if (await gitUtils.isAnalyzingDefaultBranch()) { + if (await gitUtils.isAnalyzingDefaultBranch(getEnv(), repositoryRoot)) { logger.info( "Analyzing default branch. Skipping downloading of TRAP caches.", ); @@ -132,7 +135,12 @@ export async function uploadTrapCaches( config: Config, logger: Logger, ): Promise { - if (!(await gitUtils.isAnalyzingDefaultBranch())) return false; // Only upload caches from the default branch + // Only upload caches from the default branch + if ( + !(await gitUtils.isAnalyzingDefaultBranch(getEnv(), config.repositoryRoot)) + ) { + return false; + } for (const language of config.languages) { const cacheDir = config.trapCaches[language]; @@ -180,6 +188,8 @@ export async function cleanupTrapCaches( features: FeatureEnablement, logger: Logger, ): Promise { + const env = getEnv(); + if (!(await features.getValue(Feature.CleanupTrapCaches))) { return { trap_cache_cleanup_skipped_because: "feature disabled", @@ -189,7 +199,7 @@ export async function cleanupTrapCaches( "TRAP cache cleanup is deprecated and will be removed in May 2026. " + "We recommend instead disabling TRAP caching by passing the `trap-caching: false` input to the `init` Action.", ); - if (!(await gitUtils.isAnalyzingDefaultBranch())) { + if (!(await gitUtils.isAnalyzingDefaultBranch(env, config.repositoryRoot))) { return { trap_cache_cleanup_skipped_because: "not analyzing default branch", }; @@ -200,7 +210,7 @@ export async function cleanupTrapCaches( const allCaches = await apiClient.listActionsCaches( CODEQL_TRAP_CACHE_PREFIX, - await gitUtils.getRef(), + await gitUtils.getRef(env, config.repositoryRoot), ); for (const language of config.languages) { diff --git a/src/upload-lib.ts b/src/upload-lib.ts index da5552cf24..e323ae73f4 100644 --- a/src/upload-lib.ts +++ b/src/upload-lib.ts @@ -14,7 +14,7 @@ import { getGitHubVersion, wrapApiConfigurationError } from "./api-client"; import { CodeQL, getCodeQL } from "./codeql"; import { getConfig } from "./config-utils"; import { readDiffRangesJsonFile } from "./diff-informed-analysis-utils"; -import { EnvVar } from "./environment"; +import { ActionsEnvVars, EnvVar } from "./environment"; import { FeatureEnablement } from "./feature-flags"; import * as fingerprints from "./fingerprints"; import * as gitUtils from "./git-utils"; @@ -761,12 +761,13 @@ export async function uploadPostProcessedFiles( const zippedSarif = zlib.gzipSync(sarifPayload).toString("base64"); const checkoutURI = url.pathToFileURL(checkoutPath).href; + const env = util.getEnv(); const payload = uploadTarget.transformPayload( buildPayload( - await gitUtils.getCommitOid(checkoutPath), - await gitUtils.getRef(), + await gitUtils.getCommitOid(env, checkoutPath), + await gitUtils.getRef(env, checkoutPath), postProcessingResults.analysisKey, - util.getRequiredEnvParam("GITHUB_WORKFLOW"), + env.getRequired(ActionsEnvVars.GITHUB_WORKFLOW), zippedSarif, actionsUtil.getWorkflowRunID(), actionsUtil.getWorkflowRunAttempt(), From f5716fadf424f3d54ef11acb4fcb594ec749a006 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 22 Sep 2026 12:09:16 +0100 Subject: [PATCH 005/107] Allow `getCheckoutPathInputOrThrow` to get root from config --- lib/entry-points.js | 29 +++++--- src/init-action-post-helper.ts | 12 +++- src/workflow.test.ts | 125 ++++++++++++++++++++++++++++++++- src/workflow.ts | 33 +++++++-- 4 files changed, 180 insertions(+), 19 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index dc209ae627..21b19f5206 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -162185,14 +162185,20 @@ function getUploadInputOrThrow(workflow, jobName, matrixVars) { matrixVars ); } -function getCheckoutPathInputOrThrow(workflow, jobName, matrixVars) { - return getInputOrThrow( - workflow, - jobName, - getAnalyzeActionName(), - "checkout_path", - matrixVars - ) || getRequiredEnvParam("GITHUB_WORKSPACE"); +function getRepositoryRootOrThrow(workflow, jobName, matrixVars, config, env = getEnv()) { + return ( + // If the CodeQL Action already has a persisted repository root, then we can just use that. + config.repositoryRoot ?? // Otherwise, try to retrieve it from a `checkout_path` input in the workflow specification. + getInputOrThrow( + workflow, + jobName, + getAnalyzeActionName(), + "checkout_path", + matrixVars + ) ?? // Finally, if all of the above fail, just use the value of `GITHUB_WORKSPACE` since that + // is what is used by default. + env.getRequired("GITHUB_WORKSPACE" /* GITHUB_WORKSPACE */) + ); } async function checkWorkflow(logger, codeql) { if (!isDynamicWorkflow() && process.env["CODEQL_ACTION_SKIP_WORKFLOW_VALIDATION" /* SKIP_WORKFLOW_VALIDATION */] !== "true") { @@ -162763,7 +162769,12 @@ async function prepareFailedSarif(logger, features, config) { }); } const category = getCategoryInputOrThrow(workflow, jobName, matrix); - const checkoutPath = getCheckoutPathInputOrThrow(workflow, jobName, matrix); + const checkoutPath = getRepositoryRootOrThrow( + workflow, + jobName, + matrix, + config + ); const result = await generateFailedSarif( logger, features, diff --git a/src/init-action-post-helper.ts b/src/init-action-post-helper.ts index 0e6dae13aa..f4333cf686 100644 --- a/src/init-action-post-helper.ts +++ b/src/init-action-post-helper.ts @@ -44,7 +44,7 @@ import { } from "./util"; import { getCategoryInputOrThrow, - getCheckoutPathInputOrThrow, + getRepositoryRootOrThrow, getUploadInputOrThrow, getWorkflow, } from "./workflow"; @@ -144,7 +144,15 @@ async function prepareFailedSarif( }); } const category = getCategoryInputOrThrow(workflow, jobName, matrix); - const checkoutPath = getCheckoutPathInputOrThrow(workflow, jobName, matrix); + + // Try to determine the path at which the repository that we failed to analyse is checked out at. + // We need this to relativise the paths in the SARIF. + const checkoutPath = getRepositoryRootOrThrow( + workflow, + jobName, + matrix, + config, + ); const result = await generateFailedSarif( logger, diff --git a/src/workflow.test.ts b/src/workflow.test.ts index c7f168a9dc..2373e8bd1c 100644 --- a/src/workflow.test.ts +++ b/src/workflow.test.ts @@ -4,10 +4,12 @@ import * as sinon from "sinon"; import * as actionsUtil from "./actions-util"; import { createStubCodeQL, getCodeQLForTesting } from "./codeql"; -import { EnvVar } from "./environment"; +import { ActionsEnvVars, EnvVar } from "./environment"; import { checkExpectedLogMessages, + createTestConfig, getRecordingLogger, + getTestEnv, LoggedMessage, setupTests, } from "./testing-utils"; @@ -1002,3 +1004,124 @@ test.serial( t.is(messages.length, 0); }, ); + +test("getRepositoryRootOrThrow - gets root from config", async (t) => { + const expectedRoot = "/path/to/root"; + const repositoryRoot = workflow.getRepositoryRootOrThrow( + {}, + "testJob", + {}, + createTestConfig({ repositoryRoot: expectedRoot }), + getTestEnv(), + ); + + t.is(repositoryRoot, expectedRoot); +}); + +test("getRepositoryRootOrThrow - gets root from workflow", async (t) => { + const expectedRoot = "/path/to/root"; + const repositoryRoot = workflow.getRepositoryRootOrThrow( + { + jobs: { + testJob: { + steps: [ + { + uses: "github/codeql-action/analyze", + with: { checkout_path: expectedRoot }, + }, + ], + }, + }, + }, + "testJob", + {}, + createTestConfig({}), + getTestEnv(), + ); + + t.is(repositoryRoot, expectedRoot); +}); + +test("getRepositoryRootOrThrow - gets root from environment", async (t) => { + const expectedRoot = "/path/to/root"; + const repositoryRoot = workflow.getRepositoryRootOrThrow( + { + jobs: { testJob: { steps: [{ uses: "github/codeql-action/analyze" }] } }, + }, + "testJob", + {}, + createTestConfig({}), + getTestEnv({ [ActionsEnvVars.GITHUB_WORKSPACE]: expectedRoot }), + ); + + t.is(repositoryRoot, expectedRoot); +}); + +test("getRepositoryRootOrThrow - throws if there's no matching job", async (t) => { + t.throws( + () => + workflow.getRepositoryRootOrThrow( + { + jobs: { + otherJob: { + steps: [ + { + uses: "github/codeql-action/analyze", + with: { checkout_path: "/some/path" }, + }, + ], + }, + }, + }, + "testJob", + {}, + createTestConfig({}), + getTestEnv(), + ), + { message: /since the workflow has no job named testJob./ }, + ); +}); + +test("getRepositoryRootOrThrow - throws if there's no analyze step", async (t) => { + t.throws( + () => + workflow.getRepositoryRootOrThrow( + { + jobs: { + testJob: { steps: [] }, + }, + }, + "testJob", + {}, + createTestConfig({}), + getTestEnv(), + ), + { message: /since the testJob job does not call/ }, + ); +}); + +test("getRepositoryRootOrThrow - throws if the env var is not set", async (t) => { + t.throws( + () => + workflow.getRepositoryRootOrThrow( + { + jobs: { + testJob: { + steps: [ + { + uses: "github/codeql-action/analyze", + }, + ], + }, + }, + }, + "testJob", + {}, + createTestConfig({}), + getTestEnv(), + ), + { + message: `${ActionsEnvVars.GITHUB_WORKSPACE} environment variable must be set`, + }, + ); +}); diff --git a/src/workflow.ts b/src/workflow.ts index 151cfd5c5d..dd810f3a03 100644 --- a/src/workflow.ts +++ b/src/workflow.ts @@ -8,7 +8,8 @@ import * as yaml from "js-yaml"; import { isDynamicWorkflow } from "./actions-util"; import * as api from "./api-client"; import { CodeQL } from "./codeql"; -import { EnvVar } from "./environment"; +import type { Config } from "./config-utils"; +import { ActionsEnvVars, EnvVar, getEnv, ReadOnlyEnv } from "./environment"; import { Logger } from "./logging"; import { getRequiredEnvParam, @@ -441,27 +442,45 @@ export function getUploadInputOrThrow( } /** - * Makes a best effort attempt to retrieve the checkout_path input for the - * particular job, given a set of matrix variables. + * Makes a best effort attempt to determine the root path of the repository that the analysis + * relates to. We need that to make paths in SARIF files relative. + * + * - If available, we take the `repositoryRoot` from the `config`. + * - If it isn't, we fall back to trying to extract a `checkout_path` input from the `workflow`. + * - Finally, we fall back to the value of `GITHUB_WORKSPACE`. * * Typically you'll want to wrap this function in a try/catch block and handle the error. * - * @returns the checkout_path input - * @throws an error if the checkout_path input could not be determined + * @param workflow The workflow specification of the currently running workflow. + * @param jobName The name of the job that is currently running. + * @param matrixVars The matrix variables, if any. + * @param config The CodeQL Action configuration state. + * @param env The environment variables. + * + * @returns The repository root path, or its best approximation. + * @throws `Error` if the repository root could not be determined. */ -export function getCheckoutPathInputOrThrow( +export function getRepositoryRootOrThrow( workflow: Workflow, jobName: string, matrixVars: { [key: string]: string } | undefined, + config: Config, + env: ReadOnlyEnv = getEnv(), ): string { return ( + // If the CodeQL Action already has a persisted repository root, then we can just use that. + config.repositoryRoot ?? + // Otherwise, try to retrieve it from a `checkout_path` input in the workflow specification. getInputOrThrow( workflow, jobName, getAnalyzeActionName(), "checkout_path", matrixVars, - ) || getRequiredEnvParam("GITHUB_WORKSPACE") // if unspecified, checkout_path defaults to ${{ github.workspace }} + ) ?? + // Finally, if all of the above fail, just use the value of `GITHUB_WORKSPACE` since that + // is what is used by default. + env.getRequired(ActionsEnvVars.GITHUB_WORKSPACE) ); } From 6fb4a88ed6ee94bc0e8d2491d745a439eff1ce9d Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 22 Sep 2026 12:32:16 +0100 Subject: [PATCH 006/107] Normalise the results of `getGitRoot` --- lib/entry-points.js | 2 +- src/git-utils.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 21b19f5206..61524b0700 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -147111,7 +147111,7 @@ var getGitRoot = async function(sourceRoot) { ["rev-parse", "--show-toplevel"], `Cannot find Git repository root from the source root ${sourceRoot}.` ); - return stdout.trim(); + return path4.normalize(stdout.trim()); } catch { return void 0; } diff --git a/src/git-utils.ts b/src/git-utils.ts index 2e042e361a..da1189035a 100644 --- a/src/git-utils.ts +++ b/src/git-utils.ts @@ -245,7 +245,7 @@ export const getGitRoot = async function ( ["rev-parse", "--show-toplevel"], `Cannot find Git repository root from the source root ${sourceRoot}.`, ); - return stdout.trim(); + return path.normalize(stdout.trim()); } catch { // Errors are already logged by runGitCommand() return undefined; From a876e23075cbbc1aa1f5a0a1adc3e71e9e00edac Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 22 Sep 2026 13:17:05 +0100 Subject: [PATCH 007/107] Add tests for `determineCheckoutPath` --- src/analyze.test.ts | 88 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/src/analyze.test.ts b/src/analyze.test.ts index 7523d239bf..88e5925070 100644 --- a/src/analyze.test.ts +++ b/src/analyze.test.ts @@ -11,9 +11,11 @@ import { resolveQuerySuiteAlias, addSarifExtension, diffRangeExtensionPackContents, + determineCheckoutPath, } from "./analyze"; import { createStubCodeQL } from "./codeql"; import { Feature } from "./feature-flags"; +import * as gitUtils from "./git-utils"; import { BuiltInLanguage } from "./languages"; import { getRunnerLogger } from "./logging"; import { @@ -21,12 +23,98 @@ import { setupActionsVars, createFeatures, createTestConfig, + callee, } from "./testing-utils"; import * as uploadLib from "./upload-lib"; import * as util from "./util"; setupTests(test); +test.serial( + "determineCheckoutPath - logs when checkout_path is not in a work tree", + async (t) => { + const expectedPath = "/checkout/path"; + const target = callee(determineCheckoutPath) + .withActions((actions) => { + sinon + .stub(actions, "getRequiredInput") + .withArgs("checkout_path") + .returns("/checkout/path"); + }) + .withArgs(createTestConfig({})); + sinon.stub(gitUtils, "getGitRoot").resolves(undefined); + + await target + .logs(t, "is not in the work tree of a git repository") + .passes(t.is, expectedPath); + }, +); + +test.serial( + "determineCheckoutPath - logs when checkout_path is not a repo root", + async (t) => { + const expectedPath = "/checkout/path"; + const target = callee(determineCheckoutPath) + .withActions((actions) => { + sinon + .stub(actions, "getRequiredInput") + .withArgs("checkout_path") + .returns("/checkout/path"); + }) + .withArgs(createTestConfig({})); + sinon.stub(gitUtils, "getGitRoot").resolves("/checkout"); + + await target + .logs(t, "is not the root of the repository") + .passes(t.is, expectedPath); + }, +); + +test.serial( + "determineCheckoutPath - logs when checkout_path is not the same as repo root in config", + async (t) => { + const expectedPath = "/checkout/path"; + const target = callee(determineCheckoutPath) + .withActions((actions) => { + sinon + .stub(actions, "getRequiredInput") + .withArgs("checkout_path") + .returns("/checkout/path"); + }) + .withArgs(createTestConfig({ repositoryRoot: "/some/other/path" })); + sinon.stub(gitUtils, "getGitRoot").resolves("/checkout/path"); + + await target + .logs(t, "does not match that found by the 'codeql-action/init' step") + .passes(t.is, expectedPath); + }, +); + +test.serial( + "determineCheckoutPath - doesn't log any of the messages when all is as expected", + async (t) => { + const expectedPath = "/checkout/path"; + const target = callee(determineCheckoutPath) + .withActions((actions) => { + sinon + .stub(actions, "getRequiredInput") + .withArgs("checkout_path") + .returns("/checkout/path"); + }) + .withArgs(createTestConfig({ repositoryRoot: "/checkout/path" })); + sinon.stub(gitUtils, "getGitRoot").resolves("/checkout/path"); + + await target + .notLogs( + t, + "is not in the work tree of a git repository", + "is not the root of the repository", + "does not match that found by the 'codeql-action/init' step", + ) + .passes(t.is, expectedPath); + }, +); + /** * Checks the status report produced by the analyze Action. * From 72509a81baf838ee8e5ca4ada26a136ca380ce2b Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 22 Sep 2026 16:25:29 +0100 Subject: [PATCH 008/107] Consistently use resolved path --- lib/entry-points.js | 1005 ++++++++++++++++++++++--------------------- src/analyze.test.ts | 22 +- src/analyze.ts | 11 +- src/git-utils.ts | 2 +- 4 files changed, 521 insertions(+), 519 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 61524b0700..038cc085a2 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -2384,9 +2384,9 @@ var require_dispatcher_base = __commonJS({ } close(callback) { if (callback === void 0) { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { this.close((err, data) => { - return err ? reject(err) : resolve14(data); + return err ? reject(err) : resolve15(data); }); }); } @@ -2424,12 +2424,12 @@ var require_dispatcher_base = __commonJS({ err = null; } if (callback === void 0) { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { this.destroy(err, (err2, data) => { return err2 ? ( /* istanbul ignore next: should never error */ reject(err2) - ) : resolve14(data); + ) : resolve15(data); }); }); } @@ -4696,8 +4696,8 @@ var require_util2 = __commonJS({ function createDeferredPromise() { let res; let rej; - const promise = new Promise((resolve14, reject) => { - res = resolve14; + const promise = new Promise((resolve15, reject) => { + res = resolve15; rej = reject; }); return { promise, resolve: res, reject: rej }; @@ -6943,12 +6943,12 @@ upgrade: ${upgrade}\r cb(); } } - const waitForDrain = () => new Promise((resolve14, reject) => { + const waitForDrain = () => new Promise((resolve15, reject) => { assert(callback === null); if (socket[kError]) { reject(socket[kError]); } else { - callback = resolve14; + callback = resolve15; } }); socket.on("close", onDrain).on("drain", onDrain); @@ -7585,12 +7585,12 @@ var require_client_h2 = __commonJS({ cb(); } } - const waitForDrain = () => new Promise((resolve14, reject) => { + const waitForDrain = () => new Promise((resolve15, reject) => { assert(callback === null); if (socket[kError]) { reject(socket[kError]); } else { - callback = resolve14; + callback = resolve15; } }); h2stream.on("close", onDrain).on("drain", onDrain); @@ -8068,16 +8068,16 @@ var require_client = __commonJS({ return this[kNeedDrain] < 2; } async [kClose]() { - return new Promise((resolve14) => { + return new Promise((resolve15) => { if (this[kSize]) { - this[kClosedResolve] = resolve14; + this[kClosedResolve] = resolve15; } else { - resolve14(null); + resolve15(null); } }); } async [kDestroy](err) { - return new Promise((resolve14) => { + return new Promise((resolve15) => { const requests = this[kQueue].splice(this[kPendingIdx]); for (let i = 0; i < requests.length; i++) { const request3 = requests[i]; @@ -8088,7 +8088,7 @@ var require_client = __commonJS({ this[kClosedResolve](); this[kClosedResolve] = null; } - resolve14(null); + resolve15(null); }; if (this[kHTTPContext]) { this[kHTTPContext].destroy(err, callback); @@ -8139,7 +8139,7 @@ var require_client = __commonJS({ }); } try { - const socket = await new Promise((resolve14, reject) => { + const socket = await new Promise((resolve15, reject) => { client[kConnector]({ host, hostname, @@ -8151,7 +8151,7 @@ var require_client = __commonJS({ if (err) { reject(err); } else { - resolve14(socket2); + resolve15(socket2); } }); }); @@ -8487,8 +8487,8 @@ var require_pool_base = __commonJS({ if (this[kQueue].isEmpty()) { await Promise.all(this[kClients].map((c) => c.close())); } else { - await new Promise((resolve14) => { - this[kClosedResolve] = resolve14; + await new Promise((resolve15) => { + this[kClosedResolve] = resolve15; }); } } @@ -9731,7 +9731,7 @@ var require_readable = __commonJS({ if (this._readableState.closeEmitted) { return null; } - return await new Promise((resolve14, reject) => { + return await new Promise((resolve15, reject) => { if (this[kContentLength] > limit) { this.destroy(new AbortError()); } @@ -9744,7 +9744,7 @@ var require_readable = __commonJS({ if (signal?.aborted) { reject(signal.reason ?? new AbortError()); } else { - resolve14(null); + resolve15(null); } }).on("error", noop3).on("data", function(chunk) { limit -= chunk.length; @@ -9763,7 +9763,7 @@ var require_readable = __commonJS({ } async function consume(stream2, type) { assert(!stream2[kConsume]); - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { if (isUnusable(stream2)) { const rState = stream2._readableState; if (rState.destroyed && rState.closeEmitted === false) { @@ -9780,7 +9780,7 @@ var require_readable = __commonJS({ stream2[kConsume] = { type, stream: stream2, - resolve: resolve14, + resolve: resolve15, reject, length: 0, body: [] @@ -9850,18 +9850,18 @@ var require_readable = __commonJS({ return buffer; } function consumeEnd(consume2) { - const { type, body, resolve: resolve14, stream: stream2, length } = consume2; + const { type, body, resolve: resolve15, stream: stream2, length } = consume2; try { if (type === "text") { - resolve14(chunksDecode(body, length)); + resolve15(chunksDecode(body, length)); } else if (type === "json") { - resolve14(JSON.parse(chunksDecode(body, length))); + resolve15(JSON.parse(chunksDecode(body, length))); } else if (type === "arrayBuffer") { - resolve14(chunksConcat(body, length).buffer); + resolve15(chunksConcat(body, length).buffer); } else if (type === "blob") { - resolve14(new Blob(body, { type: stream2[kContentType] })); + resolve15(new Blob(body, { type: stream2[kContentType] })); } else if (type === "bytes") { - resolve14(chunksConcat(body, length)); + resolve15(chunksConcat(body, length)); } consumeFinish(consume2); } catch (err) { @@ -10118,9 +10118,9 @@ var require_api_request = __commonJS({ }; function request3(opts, callback) { if (callback === void 0) { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { request3.call(this, opts, (err, data) => { - return err ? reject(err) : resolve14(data); + return err ? reject(err) : resolve15(data); }); }); } @@ -10343,9 +10343,9 @@ var require_api_stream = __commonJS({ }; function stream2(opts, factory, callback) { if (callback === void 0) { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { stream2.call(this, opts, factory, (err, data) => { - return err ? reject(err) : resolve14(data); + return err ? reject(err) : resolve15(data); }); }); } @@ -10630,9 +10630,9 @@ var require_api_upgrade = __commonJS({ }; function upgrade(opts, callback) { if (callback === void 0) { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { upgrade.call(this, opts, (err, data) => { - return err ? reject(err) : resolve14(data); + return err ? reject(err) : resolve15(data); }); }); } @@ -10724,9 +10724,9 @@ var require_api_connect = __commonJS({ }; function connect(opts, callback) { if (callback === void 0) { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { connect.call(this, opts, (err, data) => { - return err ? reject(err) : resolve14(data); + return err ? reject(err) : resolve15(data); }); }); } @@ -14588,7 +14588,7 @@ var require_fetch = __commonJS({ function dispatch({ body }) { const url2 = requestCurrentURL(request3); const agent = fetchParams.controller.dispatcher; - return new Promise((resolve14, reject) => agent.dispatch( + return new Promise((resolve15, reject) => agent.dispatch( { path: url2.pathname + url2.search, origin: url2.origin, @@ -14664,7 +14664,7 @@ var require_fetch = __commonJS({ } } const onError = this.onError.bind(this); - resolve14({ + resolve15({ status, statusText, headersList, @@ -14710,7 +14710,7 @@ var require_fetch = __commonJS({ for (let i = 0; i < rawHeaders.length; i += 2) { headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } - resolve14({ + resolve15({ status, statusText: STATUS_CODES[status], headersList, @@ -18440,8 +18440,8 @@ var require_util8 = __commonJS({ return true; } function delay2(ms) { - return new Promise((resolve14) => { - setTimeout(resolve14, ms).unref(); + return new Promise((resolve15) => { + setTimeout(resolve15, ms).unref(); }); } module2.exports = { @@ -19164,11 +19164,11 @@ var require_lib = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -19184,7 +19184,7 @@ var require_lib = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -19271,26 +19271,26 @@ var require_lib = __commonJS({ } readBody() { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14) => __awaiter2(this, void 0, void 0, function* () { + return new Promise((resolve15) => __awaiter2(this, void 0, void 0, function* () { let output = Buffer.alloc(0); this.message.on("data", (chunk) => { output = Buffer.concat([output, chunk]); }); this.message.on("end", () => { - resolve14(output.toString()); + resolve15(output.toString()); }); })); }); } readBodyBuffer() { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14) => __awaiter2(this, void 0, void 0, function* () { + return new Promise((resolve15) => __awaiter2(this, void 0, void 0, function* () { const chunks = []; this.message.on("data", (chunk) => { chunks.push(chunk); }); this.message.on("end", () => { - resolve14(Buffer.concat(chunks)); + resolve15(Buffer.concat(chunks)); }); })); }); @@ -19498,14 +19498,14 @@ var require_lib = __commonJS({ */ requestRaw(info8, data) { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { function callbackForResult(err, res) { if (err) { reject(err); } else if (!res) { reject(new Error("Unknown error")); } else { - resolve14(res); + resolve15(res); } } this.requestRawWithCallback(info8, data, callbackForResult); @@ -19749,12 +19749,12 @@ var require_lib = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); - return new Promise((resolve14) => setTimeout(() => resolve14(), ms)); + return new Promise((resolve15) => setTimeout(() => resolve15(), ms)); }); } _processResponse(res, options) { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14, reject) => __awaiter2(this, void 0, void 0, function* () { + return new Promise((resolve15, reject) => __awaiter2(this, void 0, void 0, function* () { const statusCode = res.message.statusCode || 0; const response = { statusCode, @@ -19762,7 +19762,7 @@ var require_lib = __commonJS({ headers: {} }; if (statusCode === HttpCodes.NotFound) { - resolve14(response); + resolve15(response); } function dateTimeDeserializer(key, value) { if (typeof value === "string") { @@ -19801,7 +19801,7 @@ var require_lib = __commonJS({ err.result = response.result; reject(err); } else { - resolve14(response); + resolve15(response); } })); }); @@ -19818,11 +19818,11 @@ var require_auth = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -19838,7 +19838,7 @@ var require_auth = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -19922,11 +19922,11 @@ var require_oidc_utils = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -19942,7 +19942,7 @@ var require_oidc_utils = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -20020,11 +20020,11 @@ var require_summary = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -20040,7 +20040,7 @@ var require_summary = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -20409,11 +20409,11 @@ var require_io_util = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -20429,7 +20429,7 @@ var require_io_util = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -20606,11 +20606,11 @@ var require_io = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -20626,7 +20626,7 @@ var require_io = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -20867,11 +20867,11 @@ var require_toolrunner = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -20887,7 +20887,7 @@ var require_toolrunner = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -21116,7 +21116,7 @@ var require_toolrunner = __commonJS({ this.toolPath = path30.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath); } this.toolPath = yield io9.which(this.toolPath, true); - return new Promise((resolve14, reject) => __awaiter2(this, void 0, void 0, function* () { + return new Promise((resolve15, reject) => __awaiter2(this, void 0, void 0, function* () { this._debug(`exec tool: ${this.toolPath}`); this._debug("arguments:"); for (const arg of this.args) { @@ -21199,7 +21199,7 @@ var require_toolrunner = __commonJS({ if (error3) { reject(error3); } else { - resolve14(exitCode); + resolve15(exitCode); } }); if (this.options.input) { @@ -21365,11 +21365,11 @@ var require_exec = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -21385,7 +21385,7 @@ var require_exec = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -21485,11 +21485,11 @@ var require_platform = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -21505,7 +21505,7 @@ var require_platform = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -21614,11 +21614,11 @@ var require_core = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -21634,7 +21634,7 @@ var require_core = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -21912,11 +21912,11 @@ var require_utils3 = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -21932,7 +21932,7 @@ var require_utils3 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -28929,8 +28929,8 @@ var require_light = __commonJS({ return this.Promise.resolve(); } yieldLoop(t = 0) { - return new this.Promise(function(resolve14, reject) { - return setTimeout(resolve14, t); + return new this.Promise(function(resolve15, reject) { + return setTimeout(resolve15, t); }); } computePenalty() { @@ -29141,15 +29141,15 @@ var require_light = __commonJS({ return this._queue.length === 0; } async _tryToRun() { - var args, cb, error3, reject, resolve14, returned, task; + var args, cb, error3, reject, resolve15, returned, task; if (this._running < 1 && this._queue.length > 0) { this._running++; - ({ task, args, resolve: resolve14, reject } = this._queue.shift()); + ({ task, args, resolve: resolve15, reject } = this._queue.shift()); cb = await (async function() { try { returned = await task(...args); return function() { - return resolve14(returned); + return resolve15(returned); }; } catch (error1) { error3 = error1; @@ -29164,13 +29164,13 @@ var require_light = __commonJS({ } } schedule(task, ...args) { - var promise, reject, resolve14; - resolve14 = reject = null; + var promise, reject, resolve15; + resolve15 = reject = null; promise = new this.Promise(function(_resolve, _reject) { - resolve14 = _resolve; + resolve15 = _resolve; return reject = _reject; }); - this._queue.push({ task, args, resolve: resolve14, reject }); + this._queue.push({ task, args, resolve: resolve15, reject }); this._tryToRun(); return promise; } @@ -29571,14 +29571,14 @@ var require_light = __commonJS({ counts = this._states.counts; return counts[0] + counts[1] + counts[2] + counts[3] === at; }; - return new this.Promise((resolve14, reject) => { + return new this.Promise((resolve15, reject) => { if (finished()) { - return resolve14(); + return resolve15(); } else { return this.on("done", () => { if (finished()) { this.removeAllListeners("done"); - return resolve14(); + return resolve15(); } }); } @@ -29671,9 +29671,9 @@ var require_light = __commonJS({ options = parser$5.load(options, this.jobDefaults); } task = (...args2) => { - return new this.Promise(function(resolve14, reject) { + return new this.Promise(function(resolve15, reject) { return fn(...args2, function(...args3) { - return (args3[0] != null ? reject : resolve14)(args3); + return (args3[0] != null ? reject : resolve15)(args3); }); }); }; @@ -29913,7 +29913,7 @@ var require_helpers = __commonJS({ this.base = base; this.schemas = schemas; }; - SchemaContext.prototype.resolve = function resolve14(target) { + SchemaContext.prototype.resolve = function resolve15(target) { return (() => resolveUrl(this.base, target))(); }; SchemaContext.prototype.makeChild = function makeChild(schema, propertyName) { @@ -31018,7 +31018,7 @@ var require_validator = __commonJS({ } return schema; }; - Validator3.prototype.resolve = function resolve14(schema, switchSchema, ctx) { + Validator3.prototype.resolve = function resolve15(schema, switchSchema, ctx) { switchSchema = ctx.resolve(switchSchema); if (ctx.schemas[switchSchema]) { return { subschema: ctx.schemas[switchSchema], switchSchema }; @@ -32954,11 +32954,11 @@ var require_internal_globber = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -32974,7 +32974,7 @@ var require_internal_globber = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -32987,14 +32987,14 @@ var require_internal_globber = __commonJS({ }, i); function verb(n) { i[n] = o[n] && function(v) { - return new Promise(function(resolve14, reject) { - v = o[n](v), settle(resolve14, reject, v.done, v.value); + return new Promise(function(resolve15, reject) { + v = o[n](v), settle(resolve15, reject, v.done, v.value); }); }; } - function settle(resolve14, reject, d, v) { + function settle(resolve15, reject, d, v) { Promise.resolve(v).then(function(v2) { - resolve14({ value: v2, done: d }); + resolve15({ value: v2, done: d }); }, reject); } }; @@ -33244,11 +33244,11 @@ var require_internal_hash_files = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -33264,7 +33264,7 @@ var require_internal_hash_files = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -33277,14 +33277,14 @@ var require_internal_hash_files = __commonJS({ }, i); function verb(n) { i[n] = o[n] && function(v) { - return new Promise(function(resolve14, reject) { - v = o[n](v), settle(resolve14, reject, v.done, v.value); + return new Promise(function(resolve15, reject) { + v = o[n](v), settle(resolve15, reject, v.done, v.value); }); }; } - function settle(resolve14, reject, d, v) { + function settle(resolve15, reject, d, v) { Promise.resolve(v).then(function(v2) { - resolve14({ value: v2, done: d }); + resolve15({ value: v2, done: d }); }, reject); } }; @@ -33356,11 +33356,11 @@ var require_glob = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -33376,7 +33376,7 @@ var require_glob = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -34637,11 +34637,11 @@ var require_cacheUtils = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -34657,7 +34657,7 @@ var require_cacheUtils = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -34670,14 +34670,14 @@ var require_cacheUtils = __commonJS({ }, i); function verb(n) { i[n] = o[n] && function(v) { - return new Promise(function(resolve14, reject) { - v = o[n](v), settle(resolve14, reject, v.done, v.value); + return new Promise(function(resolve15, reject) { + v = o[n](v), settle(resolve15, reject, v.done, v.value); }); }; } - function settle(resolve14, reject, d, v) { + function settle(resolve15, reject, d, v) { Promise.resolve(v).then(function(v2) { - resolve14({ value: v2, done: d }); + resolve15({ value: v2, done: d }); }, reject); } }; @@ -34959,11 +34959,11 @@ function __metadata(metadataKey, metadataValue) { } function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -34979,7 +34979,7 @@ function __awaiter(thisArg, _arguments, P, generator) { } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -35170,14 +35170,14 @@ function __asyncValues(o) { }, i); function verb(n) { i[n] = o[n] && function(v) { - return new Promise(function(resolve14, reject) { - v = o[n](v), settle(resolve14, reject, v.done, v.value); + return new Promise(function(resolve15, reject) { + v = o[n](v), settle(resolve15, reject, v.done, v.value); }); }; } - function settle(resolve14, reject, d, v) { + function settle(resolve15, reject, d, v) { Promise.resolve(v).then(function(v2) { - resolve14({ value: v2, done: d }); + resolve15({ value: v2, done: d }); }, reject); } } @@ -36349,9 +36349,9 @@ var require_nodeHttpClient = __commonJS({ if (stream2.readable === false) { return Promise.resolve(); } - return new Promise((resolve14) => { + return new Promise((resolve15) => { const handler2 = () => { - resolve14(); + resolve15(); stream2.removeListener("close", handler2); stream2.removeListener("end", handler2); stream2.removeListener("error", handler2); @@ -36506,8 +36506,8 @@ var require_nodeHttpClient = __commonJS({ headers: request3.headers.toJSON({ preserveCase: true }), ...request3.requestOverrides }; - return new Promise((resolve14, reject) => { - const req = isInsecure ? node_http_1.default.request(options, resolve14) : node_https_1.default.request(options, resolve14); + return new Promise((resolve15, reject) => { + const req = isInsecure ? node_http_1.default.request(options, resolve15) : node_https_1.default.request(options, resolve15); req.once("error", (err) => { reject(new restError_js_1.RestError(err.message, { code: err.code ?? restError_js_1.RestError.REQUEST_SEND_ERROR, request: request3 })); }); @@ -36591,7 +36591,7 @@ var require_nodeHttpClient = __commonJS({ return stream2; } function streamToText(stream2) { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { const buffer = []; stream2.on("data", (chunk) => { if (Buffer.isBuffer(chunk)) { @@ -36601,7 +36601,7 @@ var require_nodeHttpClient = __commonJS({ } }); stream2.on("end", () => { - resolve14(Buffer.concat(buffer).toString("utf8")); + resolve15(Buffer.concat(buffer).toString("utf8")); }); stream2.on("error", (e) => { if (e && e?.name === "AbortError") { @@ -36879,7 +36879,7 @@ var require_helpers2 = __commonJS({ var AbortError_js_1 = require_AbortError(); var StandardAbortMessage = "The operation was aborted."; function delay2(delayInMs, value, options) { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { let timer = void 0; let onAborted = void 0; const rejectOnAbort = () => { @@ -36902,7 +36902,7 @@ var require_helpers2 = __commonJS({ } timer = setTimeout(() => { removeListeners(); - resolve14(value); + resolve15(value); }, delayInMs); if (options?.abortSignal) { options.abortSignal.addEventListener("abort", onAborted); @@ -38065,8 +38065,8 @@ var require_helpers3 = __commonJS({ function req(url2, opts = {}) { const href = typeof url2 === "string" ? url2 : url2.href; const req2 = (href.startsWith("https:") ? https3 : http).request(url2, opts); - const promise = new Promise((resolve14, reject) => { - req2.once("response", resolve14).once("error", reject).end(); + const promise = new Promise((resolve15, reject) => { + req2.once("response", resolve15).once("error", reject).end(); }); req2.then = promise.then.bind(promise); return req2; @@ -38243,7 +38243,7 @@ var require_parse_proxy_response = __commonJS({ var debug_1 = __importDefault2(require_src()); var debug6 = (0, debug_1.default)("https-proxy-agent:parse-proxy-response"); function parseProxyResponse(socket) { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { let buffersLength = 0; const buffers = []; function read() { @@ -38309,7 +38309,7 @@ var require_parse_proxy_response = __commonJS({ } debug6("got proxy server response: %o %o", firstLine, headers); cleanup(); - resolve14({ + resolve15({ connect: { statusCode, statusText, @@ -40395,7 +40395,7 @@ var require_createAbortablePromise = __commonJS({ var abort_controller_1 = require_commonjs3(); function createAbortablePromise(buildPromise, options) { const { cleanupBeforeAbort, abortSignal, abortErrorMsg } = options ?? {}; - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { function rejectOnAbort() { reject(new abort_controller_1.AbortError(abortErrorMsg ?? "The operation was aborted.")); } @@ -40413,7 +40413,7 @@ var require_createAbortablePromise = __commonJS({ try { buildPromise((x) => { removeListeners(); - resolve14(x); + resolve15(x); }, (x) => { removeListeners(); reject(x); @@ -40440,8 +40440,8 @@ var require_delay2 = __commonJS({ function delay2(timeInMs, options) { let token; const { abortSignal, abortErrorMsg } = options ?? {}; - return (0, createAbortablePromise_js_1.createAbortablePromise)((resolve14) => { - token = setTimeout(resolve14, timeInMs); + return (0, createAbortablePromise_js_1.createAbortablePromise)((resolve15) => { + token = setTimeout(resolve15, timeInMs); }, { cleanupBeforeAbort: () => clearTimeout(token), abortSignal, @@ -46738,7 +46738,7 @@ var require_utils_common = __commonJS({ return base64encode(res); } async function delay2(timeInMs, aborter, abortError) { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { let timeout; const abortHandler = () => { if (timeout !== void 0) { @@ -46750,7 +46750,7 @@ var require_utils_common = __commonJS({ if (aborter !== void 0) { aborter.removeEventListener("abort", abortHandler); } - resolve14(); + resolve15(); }; timeout = setTimeout(resolveHandler, timeInMs); if (aborter !== void 0) { @@ -48291,7 +48291,7 @@ var require_BufferScheduler = __commonJS({ * */ async do() { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { this.readable.on("data", (data) => { data = typeof data === "string" ? Buffer.from(data, this.encoding) : data; this.appendUnresolvedData(data); @@ -48319,11 +48319,11 @@ var require_BufferScheduler = __commonJS({ if (this.isStreamEnd && this.executingOutgoingHandlers === 0) { if (this.unresolvedLength > 0 && this.unresolvedLength < this.bufferSize) { const buffer = this.shiftBufferFromUnresolvedDataArray(); - this.outgoingHandler(() => buffer.getReadableStream(), buffer.size, this.offset).then(resolve14).catch(reject); + this.outgoingHandler(() => buffer.getReadableStream(), buffer.size, this.offset).then(resolve15).catch(reject); } else if (this.unresolvedLength >= this.bufferSize) { return; } else { - resolve14(); + resolve15(); } } }); @@ -48796,7 +48796,7 @@ var require_utils_common2 = __commonJS({ return base64encode(res); } async function delay2(timeInMs, aborter, abortError) { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { let timeout; const abortHandler = () => { if (timeout !== void 0) { @@ -48808,7 +48808,7 @@ var require_utils_common2 = __commonJS({ if (aborter !== void 0) { aborter.removeEventListener("abort", abortHandler); } - resolve14(); + resolve15(); }; timeout = setTimeout(resolveHandler, timeInMs); if (aborter !== void 0) { @@ -67006,7 +67006,7 @@ var require_AvroReadableFromStream = __commonJS({ this._position += chunk.length; return this.toUint8Array(chunk); } else { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { const cleanUp = () => { this._readable.removeListener("readable", readableCallback); this._readable.removeListener("error", rejectCallback); @@ -67021,7 +67021,7 @@ var require_AvroReadableFromStream = __commonJS({ if (callbackChunk) { this._position += callbackChunk.length; cleanUp(); - resolve14(this.toUint8Array(callbackChunk)); + resolve15(this.toUint8Array(callbackChunk)); } }; const rejectCallback = () => { @@ -68501,8 +68501,8 @@ var require_poller3 = __commonJS({ this.stopped = true; this.pollProgressCallbacks = []; this.operation = operation; - this.promise = new Promise((resolve14, reject) => { - this.resolve = resolve14; + this.promise = new Promise((resolve15, reject) => { + this.resolve = resolve15; this.reject = reject; }); this.promise.catch(() => { @@ -68755,7 +68755,7 @@ var require_lroEngine = __commonJS({ * The method used by the poller to wait before attempting to update its operation. */ delay() { - return new Promise((resolve14) => setTimeout(() => resolve14(), this.config.intervalInMs)); + return new Promise((resolve15) => setTimeout(() => resolve15(), this.config.intervalInMs)); } }; exports2.LroEngine = LroEngine; @@ -69001,8 +69001,8 @@ var require_Batch = __commonJS({ return Promise.resolve(); } this.parallelExecute(); - return new Promise((resolve14, reject) => { - this.emitter.on("finish", resolve14); + return new Promise((resolve15, reject) => { + this.emitter.on("finish", resolve15); this.emitter.on("error", (error3) => { this.state = BatchStates.Error; reject(error3); @@ -69063,12 +69063,12 @@ var require_utils6 = __commonJS({ async function streamToBuffer(stream2, buffer, offset, end, encoding) { let pos = 0; const count = end - offset; - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { const timeout = setTimeout(() => reject(new Error(`The operation cannot be completed in timeout.`)), constants_js_1.REQUEST_TIMEOUT); stream2.on("readable", () => { if (pos >= count) { clearTimeout(timeout); - resolve14(); + resolve15(); return; } let chunk = stream2.read(); @@ -69087,7 +69087,7 @@ var require_utils6 = __commonJS({ if (pos < count) { reject(new Error(`Stream drains before getting enough data needed. Data read: ${pos}, data need: ${count}`)); } - resolve14(); + resolve15(); }); stream2.on("error", (msg) => { clearTimeout(timeout); @@ -69098,7 +69098,7 @@ var require_utils6 = __commonJS({ async function streamToBuffer2(stream2, buffer, encoding) { let pos = 0; const bufferSize = buffer.length; - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { stream2.on("readable", () => { let chunk = stream2.read(); if (!chunk) { @@ -69115,25 +69115,25 @@ var require_utils6 = __commonJS({ pos += chunk.length; }); stream2.on("end", () => { - resolve14(pos); + resolve15(pos); }); stream2.on("error", reject); }); } async function streamToBuffer3(readableStream, encoding) { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { const chunks = []; readableStream.on("data", (data) => { chunks.push(typeof data === "string" ? Buffer.from(data, encoding) : data); }); readableStream.on("end", () => { - resolve14(Buffer.concat(chunks)); + resolve15(Buffer.concat(chunks)); }); readableStream.on("error", reject); }); } async function readStreamToLocalFile(rs, file) { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { const ws = node_fs_1.default.createWriteStream(file); rs.on("error", (err) => { reject(err); @@ -69141,7 +69141,7 @@ var require_utils6 = __commonJS({ ws.on("error", (err) => { reject(err); }); - ws.on("close", resolve14); + ws.on("close", resolve15); rs.pipe(ws); }); } @@ -70080,7 +70080,7 @@ var require_Clients = __commonJS({ * @returns The SAS URI consisting of the URI to the resource represented by this client, followed by the generated SAS token. */ generateSasUrl(options) { - return new Promise((resolve14) => { + return new Promise((resolve15) => { if (!(this.credential instanceof StorageSharedKeyCredential_js_1.StorageSharedKeyCredential)) { throw new RangeError("Can only generate the SAS when the client is initialized with a shared key credential"); } @@ -70091,7 +70091,7 @@ var require_Clients = __commonJS({ versionId: this._versionId, ...options }, this.credential).toString(); - resolve14((0, utils_common_js_1.appendToURLQuery)(this.url, sas)); + resolve15((0, utils_common_js_1.appendToURLQuery)(this.url, sas)); }); } /** @@ -70130,7 +70130,7 @@ var require_Clients = __commonJS({ * @returns The SAS URI consisting of the URI to the resource represented by this client, followed by the generated SAS token. */ generateUserDelegationSasUrl(options, userDelegationKey) { - return new Promise((resolve14) => { + return new Promise((resolve15) => { const sas = (0, BlobSASSignatureValues_js_1.generateBlobSASQueryParameters)({ containerName: this._containerName, blobName: this._name, @@ -70138,7 +70138,7 @@ var require_Clients = __commonJS({ versionId: this._versionId, ...options }, userDelegationKey, this.accountName).toString(); - resolve14((0, utils_common_js_1.appendToURLQuery)(this.url, sas)); + resolve15((0, utils_common_js_1.appendToURLQuery)(this.url, sas)); }); } /** @@ -71993,14 +71993,14 @@ var require_Mutex = __commonJS({ * @param key - lock key */ static async lock(key) { - return new Promise((resolve14) => { + return new Promise((resolve15) => { if (this.keys[key] === void 0 || this.keys[key] === MutexLockStatus.UNLOCKED) { this.keys[key] = MutexLockStatus.LOCKED; - resolve14(); + resolve15(); } else { this.onUnlockEvent(key, () => { this.keys[key] = MutexLockStatus.LOCKED; - resolve14(); + resolve15(); }); } }); @@ -72011,12 +72011,12 @@ var require_Mutex = __commonJS({ * @param key - */ static async unlock(key) { - return new Promise((resolve14) => { + return new Promise((resolve15) => { if (this.keys[key] === MutexLockStatus.LOCKED) { this.emitUnlockEvent(key); } delete this.keys[key]; - resolve14(); + resolve15(); }); } static keys = {}; @@ -73619,7 +73619,7 @@ var require_ContainerClient = __commonJS({ * @returns The SAS URI consisting of the URI to the resource represented by this client, followed by the generated SAS token. */ generateSasUrl(options) { - return new Promise((resolve14) => { + return new Promise((resolve15) => { if (!(this.credential instanceof StorageSharedKeyCredential_js_1.StorageSharedKeyCredential)) { throw new RangeError("Can only generate the SAS when the client is initialized with a shared key credential"); } @@ -73627,7 +73627,7 @@ var require_ContainerClient = __commonJS({ containerName: this._containerName, ...options }, this.credential).toString(); - resolve14((0, utils_common_js_1.appendToURLQuery)(this.url, sas)); + resolve15((0, utils_common_js_1.appendToURLQuery)(this.url, sas)); }); } /** @@ -73662,12 +73662,12 @@ var require_ContainerClient = __commonJS({ * @returns The SAS URI consisting of the URI to the resource represented by this client, followed by the generated SAS token. */ generateUserDelegationSasUrl(options, userDelegationKey) { - return new Promise((resolve14) => { + return new Promise((resolve15) => { const sas = (0, BlobSASSignatureValues_js_1.generateBlobSASQueryParameters)({ containerName: this._containerName, ...options }, userDelegationKey, this.accountName).toString(); - resolve14((0, utils_common_js_1.appendToURLQuery)(this.url, sas)); + resolve15((0, utils_common_js_1.appendToURLQuery)(this.url, sas)); }); } /** @@ -75063,11 +75063,11 @@ var require_uploadUtils = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -75083,7 +75083,7 @@ var require_uploadUtils = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -75250,11 +75250,11 @@ var require_requestUtils = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -75270,7 +75270,7 @@ var require_requestUtils = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -75310,7 +75310,7 @@ var require_requestUtils = __commonJS({ } function sleep(milliseconds) { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14) => setTimeout(resolve14, milliseconds)); + return new Promise((resolve15) => setTimeout(resolve15, milliseconds)); }); } function retry2(name_1, method_1, getStatusCode_1) { @@ -75571,11 +75571,11 @@ var require_downloadUtils = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -75591,7 +75591,7 @@ var require_downloadUtils = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -75887,8 +75887,8 @@ var require_downloadUtils = __commonJS({ } var promiseWithTimeout = (timeoutMs, promise) => __awaiter2(void 0, void 0, void 0, function* () { let timeoutHandle; - const timeoutPromise = new Promise((resolve14) => { - timeoutHandle = setTimeout(() => resolve14("timeout"), timeoutMs); + const timeoutPromise = new Promise((resolve15) => { + timeoutHandle = setTimeout(() => resolve15("timeout"), timeoutMs); }); return Promise.race([promise, timeoutPromise]).then((result) => { clearTimeout(timeoutHandle); @@ -76186,11 +76186,11 @@ var require_cacheHttpClient = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -76206,7 +76206,7 @@ var require_cacheHttpClient = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -79682,8 +79682,8 @@ var require_deferred = __commonJS({ */ constructor(preventUnhandledRejectionWarning = true) { this._state = DeferredState.PENDING; - this._promise = new Promise((resolve14, reject) => { - this._resolve = resolve14; + this._promise = new Promise((resolve15, reject) => { + this._resolve = resolve15; this._reject = reject; }); if (preventUnhandledRejectionWarning) { @@ -79898,11 +79898,11 @@ var require_unary_call = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -79918,7 +79918,7 @@ var require_unary_call = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -79967,11 +79967,11 @@ var require_server_streaming_call = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -79987,7 +79987,7 @@ var require_server_streaming_call = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -80037,11 +80037,11 @@ var require_client_streaming_call = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -80057,7 +80057,7 @@ var require_client_streaming_call = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -80106,11 +80106,11 @@ var require_duplex_streaming_call = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -80126,7 +80126,7 @@ var require_duplex_streaming_call = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -80174,11 +80174,11 @@ var require_test_transport = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -80194,7 +80194,7 @@ var require_test_transport = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -80391,11 +80391,11 @@ var require_test_transport = __commonJS({ responseTrailer: "test" }; function delay2(ms, abort) { - return (v) => new Promise((resolve14, reject) => { + return (v) => new Promise((resolve15, reject) => { if (abort === null || abort === void 0 ? void 0 : abort.aborted) { reject(new rpc_error_1.RpcError("user cancel", "CANCELLED")); } else { - const id = setTimeout(() => resolve14(v), ms); + const id = setTimeout(() => resolve15(v), ms); if (abort) { abort.addEventListener("abort", (ev) => { clearTimeout(id); @@ -81393,11 +81393,11 @@ var require_cacheTwirpClient = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -81413,7 +81413,7 @@ var require_cacheTwirpClient = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -81553,7 +81553,7 @@ var require_cacheTwirpClient = __commonJS({ } sleep(milliseconds) { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14) => setTimeout(resolve14, milliseconds)); + return new Promise((resolve15) => setTimeout(resolve15, milliseconds)); }); } getExponentialRetryTimeMilliseconds(attempt) { @@ -81618,11 +81618,11 @@ var require_tar = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -81638,7 +81638,7 @@ var require_tar = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -81870,11 +81870,11 @@ var require_cache4 = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -81890,7 +81890,7 @@ var require_cache4 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -82372,11 +82372,11 @@ var require_manifest = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -82392,7 +82392,7 @@ var require_manifest = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -82520,11 +82520,11 @@ var require_retry_helper = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -82540,7 +82540,7 @@ var require_retry_helper = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -82585,7 +82585,7 @@ var require_retry_helper = __commonJS({ } sleep(seconds) { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14) => setTimeout(resolve14, seconds * 1e3)); + return new Promise((resolve15) => setTimeout(resolve15, seconds * 1e3)); }); } }; @@ -82636,11 +82636,11 @@ var require_tool_cache = __commonJS({ })(); var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -82656,7 +82656,7 @@ var require_tool_cache = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -89136,11 +89136,11 @@ var require_artifact_twirp_client2 = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -89156,7 +89156,7 @@ var require_artifact_twirp_client2 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -89283,7 +89283,7 @@ var require_artifact_twirp_client2 = __commonJS({ } sleep(milliseconds) { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14) => setTimeout(resolve14, milliseconds)); + return new Promise((resolve15) => setTimeout(resolve15, milliseconds)); }); } getExponentialRetryTimeMilliseconds(attempt) { @@ -89424,11 +89424,11 @@ var require_blob_upload = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -89444,7 +89444,7 @@ var require_blob_upload = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -89463,7 +89463,7 @@ var require_blob_upload = __commonJS({ let lastProgressTime = Date.now(); const abortController = new AbortController(); const chunkTimer = (interval) => __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { const timer = setInterval(() => { if (Date.now() - lastProgressTime > interval) { reject(new Error("Upload progress stalled.")); @@ -89471,7 +89471,7 @@ var require_blob_upload = __commonJS({ }, interval); abortController.signal.addEventListener("abort", () => { clearInterval(timer); - resolve14(); + resolve15(); }); }); }); @@ -90416,9 +90416,9 @@ var require_readdir_glob = __commonJS({ var fs32 = require("fs"); var { EventEmitter: EventEmitter2 } = require("events"); var { Minimatch: Minimatch2 } = require_minimatch2(); - var { resolve: resolve14 } = require("path"); + var { resolve: resolve15 } = require("path"); function readdir3(dir, strict) { - return new Promise((resolve15, reject) => { + return new Promise((resolve16, reject) => { fs32.readdir(dir, { withFileTypes: true }, (err, files) => { if (err) { switch (err.code) { @@ -90426,7 +90426,7 @@ var require_readdir_glob = __commonJS({ if (strict) { reject(err); } else { - resolve15([]); + resolve16([]); } break; case "ENOTSUP": @@ -90436,7 +90436,7 @@ var require_readdir_glob = __commonJS({ case "ENAMETOOLONG": // Filename too long case "UNKNOWN": - resolve15([]); + resolve16([]); break; case "ELOOP": // Too many levels of symbolic links @@ -90445,30 +90445,30 @@ var require_readdir_glob = __commonJS({ break; } } else { - resolve15(files); + resolve16(files); } }); }); } function stat2(file, followSymlinks) { - return new Promise((resolve15, reject) => { + return new Promise((resolve16, reject) => { const statFunc = followSymlinks ? fs32.stat : fs32.lstat; statFunc(file, (err, stats) => { if (err) { switch (err.code) { case "ENOENT": if (followSymlinks) { - resolve15(stat2(file, false)); + resolve16(stat2(file, false)); } else { - resolve15(null); + resolve16(null); } break; default: - resolve15(null); + resolve16(null); break; } } else { - resolve15(stats); + resolve16(stats); } }); }); @@ -90558,7 +90558,7 @@ var require_readdir_glob = __commonJS({ (skip) => new Minimatch2(skip, { dot: true }) ); } - this.iterator = explore2(resolve14(cwd || "."), this.options.follow, this.options.stat, this._shouldSkipDirectory.bind(this)); + this.iterator = explore2(resolve15(cwd || "."), this.options.follow, this.options.stat, this._shouldSkipDirectory.bind(this)); this.paused = false; this.inactive = false; this.aborted = false; @@ -90725,10 +90725,10 @@ var require_async = __commonJS({ if (typeof args[arity - 1] === "function") { return asyncFn.apply(this, args); } - return new Promise((resolve14, reject2) => { + return new Promise((resolve15, reject2) => { args[arity - 1] = (err, ...cbArgs) => { if (err) return reject2(err); - resolve14(cbArgs.length > 1 ? cbArgs : cbArgs[0]); + resolve15(cbArgs.length > 1 ? cbArgs : cbArgs[0]); }; asyncFn.apply(this, args); }); @@ -90974,13 +90974,13 @@ var require_async = __commonJS({ var applyEachSeries = applyEach$1(mapSeries$1); const PROMISE_SYMBOL = /* @__PURE__ */ Symbol("promiseCallback"); function promiseCallback() { - let resolve14, reject2; + let resolve15, reject2; function callback(err, ...args) { if (err) return reject2(err); - resolve14(args.length > 1 ? args : args[0]); + resolve15(args.length > 1 ? args : args[0]); } callback[PROMISE_SYMBOL] = new Promise((res, rej) => { - resolve14 = res, reject2 = rej; + resolve15 = res, reject2 = rej; }); return callback; } @@ -91327,8 +91327,8 @@ var require_async = __commonJS({ }); } if (rejectOnError || !callback) { - return new Promise((resolve14, reject2) => { - res = resolve14; + return new Promise((resolve15, reject2) => { + res = resolve15; rej = reject2; }); } @@ -91367,10 +91367,10 @@ var require_async = __commonJS({ } const eventMethod = (name) => (handler2) => { if (!handler2) { - return new Promise((resolve14, reject2) => { + return new Promise((resolve15, reject2) => { once2(name, (err, data) => { if (err) return reject2(err); - resolve14(data); + resolve15(data); }); }); } @@ -97269,25 +97269,25 @@ var require_util13 = __commonJS({ }; }, createDeferredPromise: function() { - let resolve14; + let resolve15; let reject; const promise = new Promise((res, rej) => { - resolve14 = res; + resolve15 = res; reject = rej; }); return { promise, - resolve: resolve14, + resolve: resolve15, reject }; }, promisify(fn) { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { fn((err, ...args) => { if (err) { return reject(err); } - return resolve14(...args); + return resolve15(...args); }); }); }, @@ -98078,7 +98078,7 @@ var require_end_of_stream = __commonJS({ validateBoolean(opts.cleanup, "cleanup"); autoCleanup = opts.cleanup; } - return new Promise2((resolve14, reject) => { + return new Promise2((resolve15, reject) => { const cleanup = eos(stream2, opts, (err) => { if (autoCleanup) { cleanup(); @@ -98086,7 +98086,7 @@ var require_end_of_stream = __commonJS({ if (err) { reject(err); } else { - resolve14(); + resolve15(); } }); }); @@ -99252,7 +99252,7 @@ var require_readable3 = __commonJS({ error3 = this.readableEnded ? null : new AbortError(); this.destroy(error3); } - return new Promise2((resolve14, reject) => eos(this, (err) => err && err !== error3 ? reject(err) : resolve14(null))); + return new Promise2((resolve15, reject) => eos(this, (err) => err && err !== error3 ? reject(err) : resolve15(null))); }; Readable3.prototype.push = function(chunk, encoding) { return readableAddChunk(this, chunk, encoding, false); @@ -99796,12 +99796,12 @@ var require_readable3 = __commonJS({ } async function* createAsyncIterator(stream2, options) { let callback = nop; - function next(resolve14) { + function next(resolve15) { if (this === stream2) { callback(); callback = nop; } else { - callback = resolve14; + callback = resolve15; } } stream2.on("readable", next); @@ -100853,7 +100853,7 @@ var require_duplexify = __commonJS({ ); }; function fromAsyncGen(fn) { - let { promise, resolve: resolve14 } = createDeferredPromise(); + let { promise, resolve: resolve15 } = createDeferredPromise(); const ac = new AbortController2(); const signal = ac.signal; const value = fn( @@ -100868,7 +100868,7 @@ var require_duplexify = __commonJS({ throw new AbortError(void 0, { cause: signal.reason }); - ({ promise, resolve: resolve14 } = createDeferredPromise()); + ({ promise, resolve: resolve15 } = createDeferredPromise()); yield chunk; } })(), @@ -100879,8 +100879,8 @@ var require_duplexify = __commonJS({ return { value, write(chunk, encoding, cb) { - const _resolve = resolve14; - resolve14 = null; + const _resolve = resolve15; + resolve15 = null; _resolve({ chunk, done: false, @@ -100888,8 +100888,8 @@ var require_duplexify = __commonJS({ }); }, final(cb) { - const _resolve = resolve14; - resolve14 = null; + const _resolve = resolve15; + resolve15 = null; _resolve({ done: true, cb @@ -101340,7 +101340,7 @@ var require_pipeline4 = __commonJS({ callback(); } }; - const wait = () => new Promise2((resolve14, reject) => { + const wait = () => new Promise2((resolve15, reject) => { if (error3) { reject(error3); } else { @@ -101348,7 +101348,7 @@ var require_pipeline4 = __commonJS({ if (error3) { reject(error3); } else { - resolve14(); + resolve15(); } }; } @@ -101992,8 +101992,8 @@ var require_operators = __commonJS({ next = null; } if (!done && (queue2.length >= highWaterMark || cnt >= concurrency)) { - await new Promise2((resolve14) => { - resume = resolve14; + await new Promise2((resolve15) => { + resume = resolve15; }); } } @@ -102027,8 +102027,8 @@ var require_operators = __commonJS({ queue2.shift(); maybeResume(); } - await new Promise2((resolve14) => { - next = resolve14; + await new Promise2((resolve15) => { + next = resolve15; }); } } finally { @@ -102286,7 +102286,7 @@ var require_promises = __commonJS({ var { finished } = require_end_of_stream(); require_stream2(); function pipeline2(...streams) { - return new Promise2((resolve14, reject) => { + return new Promise2((resolve15, reject) => { let signal; let end; const lastArg = streams[streams.length - 1]; @@ -102301,7 +102301,7 @@ var require_promises = __commonJS({ if (err) { reject(err); } else { - resolve14(value); + resolve15(value); } }, { @@ -107088,11 +107088,11 @@ var require_core2 = __commonJS({ this._finalize(); } var self2 = this; - return new Promise(function(resolve14, reject) { + return new Promise(function(resolve15, reject) { var errored; self2._module.on("end", function() { if (!errored) { - resolve14(); + resolve15(); } }); self2._module.on("error", function(err) { @@ -109451,8 +109451,8 @@ var require_streamx = __commonJS({ return this; }, next() { - return new Promise(function(resolve14, reject) { - promiseResolve = resolve14; + return new Promise(function(resolve15, reject) { + promiseResolve = resolve15; promiseReject = reject; const data = stream2.read(); if (data !== null) ondata(data); @@ -109481,11 +109481,11 @@ var require_streamx = __commonJS({ } function destroy(err) { stream2.destroy(err); - return new Promise((resolve14, reject) => { - if (stream2._duplexState & DESTROYED) return resolve14({ value: void 0, done: true }); + return new Promise((resolve15, reject) => { + if (stream2._duplexState & DESTROYED) return resolve15({ value: void 0, done: true }); stream2.once("close", function() { if (err) reject(err); - else resolve14({ value: void 0, done: true }); + else resolve15({ value: void 0, done: true }); }); }); } @@ -109529,8 +109529,8 @@ var require_streamx = __commonJS({ const writes = pending + (ws._duplexState & WRITE_WRITING ? 1 : 0); if (writes === 0) return Promise.resolve(true); if (state.drains === null) state.drains = []; - return new Promise((resolve14) => { - state.drains.push({ writes, resolve: resolve14 }); + return new Promise((resolve15) => { + state.drains.push({ writes, resolve: resolve15 }); }); } write(data) { @@ -109635,10 +109635,10 @@ var require_streamx = __commonJS({ cb(null); } function pipelinePromise(...streams) { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { return pipeline2(...streams, (err) => { if (err) return reject(err); - resolve14(); + resolve15(); }); }); } @@ -110281,16 +110281,16 @@ var require_extract = __commonJS({ entryCallback = null; cb(err); } - function onnext(resolve14, reject) { + function onnext(resolve15, reject) { if (error3) { return reject(error3); } if (entryStream) { - resolve14({ value: entryStream, done: false }); + resolve15({ value: entryStream, done: false }); entryStream = null; return; } - promiseResolve = resolve14; + promiseResolve = resolve15; promiseReject = reject; consumeCallback(null); if (extract2._finished && promiseResolve) { @@ -110318,11 +110318,11 @@ var require_extract = __commonJS({ function destroy(err) { extract2.destroy(err); consumeCallback(err); - return new Promise((resolve14, reject) => { - if (extract2.destroyed) return resolve14({ value: void 0, done: true }); + return new Promise((resolve15, reject) => { + if (extract2.destroyed) return resolve15({ value: void 0, done: true }); extract2.once("close", function() { if (err) reject(err); - else resolve14({ value: void 0, done: true }); + else resolve15({ value: void 0, done: true }); }); }); } @@ -111118,11 +111118,11 @@ var require_zip2 = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -111138,7 +111138,7 @@ var require_zip2 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -111253,11 +111253,11 @@ var require_upload_artifact = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -111273,7 +111273,7 @@ var require_upload_artifact = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -111519,11 +111519,11 @@ var require_lib4 = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -111539,7 +111539,7 @@ var require_lib4 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -111625,26 +111625,26 @@ var require_lib4 = __commonJS({ } readBody() { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14) => __awaiter2(this, void 0, void 0, function* () { + return new Promise((resolve15) => __awaiter2(this, void 0, void 0, function* () { let output = Buffer.alloc(0); this.message.on("data", (chunk) => { output = Buffer.concat([output, chunk]); }); this.message.on("end", () => { - resolve14(output.toString()); + resolve15(output.toString()); }); })); }); } readBodyBuffer() { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14) => __awaiter2(this, void 0, void 0, function* () { + return new Promise((resolve15) => __awaiter2(this, void 0, void 0, function* () { const chunks = []; this.message.on("data", (chunk) => { chunks.push(chunk); }); this.message.on("end", () => { - resolve14(Buffer.concat(chunks)); + resolve15(Buffer.concat(chunks)); }); })); }); @@ -111853,14 +111853,14 @@ var require_lib4 = __commonJS({ */ requestRaw(info8, data) { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { function callbackForResult(err, res) { if (err) { reject(err); } else if (!res) { reject(new Error("Unknown error")); } else { - resolve14(res); + resolve15(res); } } this.requestRawWithCallback(info8, data, callbackForResult); @@ -112042,12 +112042,12 @@ var require_lib4 = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); - return new Promise((resolve14) => setTimeout(() => resolve14(), ms)); + return new Promise((resolve15) => setTimeout(() => resolve15(), ms)); }); } _processResponse(res, options) { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14, reject) => __awaiter2(this, void 0, void 0, function* () { + return new Promise((resolve15, reject) => __awaiter2(this, void 0, void 0, function* () { const statusCode = res.message.statusCode || 0; const response = { statusCode, @@ -112055,7 +112055,7 @@ var require_lib4 = __commonJS({ headers: {} }; if (statusCode === HttpCodes.NotFound) { - resolve14(response); + resolve15(response); } function dateTimeDeserializer(key, value) { if (typeof value === "string") { @@ -112094,7 +112094,7 @@ var require_lib4 = __commonJS({ err.result = response.result; reject(err); } else { - resolve14(response); + resolve15(response); } })); }); @@ -112138,11 +112138,11 @@ var require_utils8 = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -112158,7 +112158,7 @@ var require_utils8 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -118023,11 +118023,11 @@ var require_download_artifact = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -118043,7 +118043,7 @@ var require_download_artifact = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -118094,7 +118094,7 @@ var require_download_artifact = __commonJS({ } catch (error3) { retryCount++; core32.debug(`Failed to download artifact after ${retryCount} retries due to ${error3.message}. Retrying in 5 seconds...`); - yield new Promise((resolve14) => setTimeout(resolve14, 5e3)); + yield new Promise((resolve15) => setTimeout(resolve15, 5e3)); } } throw new Error(`Artifact download failed after ${retryCount} retries.`); @@ -118108,7 +118108,7 @@ var require_download_artifact = __commonJS({ throw new Error(`Unexpected HTTP response from blob storage: ${response.message.statusCode} ${response.message.statusMessage}`); } let sha256Digest = void 0; - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { const timerFn = () => { const timeoutError = new Error(`Blob storage chunk did not respond in ${opts.timeout}ms`); response.message.destroy(timeoutError); @@ -118133,7 +118133,7 @@ var require_download_artifact = __commonJS({ sha256Digest = hashStream.read(); core32.info(`SHA256 digest of downloaded artifact is ${sha256Digest}`); } - resolve14({ sha256Digest: `sha256:${sha256Digest}` }); + resolve15({ sha256Digest: `sha256:${sha256Digest}` }); }).on("error", (error3) => { reject(error3); }); @@ -118416,11 +118416,11 @@ var require_get_artifact = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -118436,7 +118436,7 @@ var require_get_artifact = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -118539,11 +118539,11 @@ var require_delete_artifact = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -118559,7 +118559,7 @@ var require_delete_artifact = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -118645,11 +118645,11 @@ var require_list_artifacts = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -118665,7 +118665,7 @@ var require_list_artifacts = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -118802,11 +118802,11 @@ var require_client2 = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -118822,7 +118822,7 @@ var require_client2 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -119291,11 +119291,11 @@ var require_lib5 = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -119311,7 +119311,7 @@ var require_lib5 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -119397,26 +119397,26 @@ var require_lib5 = __commonJS({ } readBody() { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14) => __awaiter2(this, void 0, void 0, function* () { + return new Promise((resolve15) => __awaiter2(this, void 0, void 0, function* () { let output = Buffer.alloc(0); this.message.on("data", (chunk) => { output = Buffer.concat([output, chunk]); }); this.message.on("end", () => { - resolve14(output.toString()); + resolve15(output.toString()); }); })); }); } readBodyBuffer() { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14) => __awaiter2(this, void 0, void 0, function* () { + return new Promise((resolve15) => __awaiter2(this, void 0, void 0, function* () { const chunks = []; this.message.on("data", (chunk) => { chunks.push(chunk); }); this.message.on("end", () => { - resolve14(Buffer.concat(chunks)); + resolve15(Buffer.concat(chunks)); }); })); }); @@ -119625,14 +119625,14 @@ var require_lib5 = __commonJS({ */ requestRaw(info8, data) { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { function callbackForResult(err, res) { if (err) { reject(err); } else if (!res) { reject(new Error("Unknown error")); } else { - resolve14(res); + resolve15(res); } } this.requestRawWithCallback(info8, data, callbackForResult); @@ -119814,12 +119814,12 @@ var require_lib5 = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); - return new Promise((resolve14) => setTimeout(() => resolve14(), ms)); + return new Promise((resolve15) => setTimeout(() => resolve15(), ms)); }); } _processResponse(res, options) { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14, reject) => __awaiter2(this, void 0, void 0, function* () { + return new Promise((resolve15, reject) => __awaiter2(this, void 0, void 0, function* () { const statusCode = res.message.statusCode || 0; const response = { statusCode, @@ -119827,7 +119827,7 @@ var require_lib5 = __commonJS({ headers: {} }; if (statusCode === HttpCodes.NotFound) { - resolve14(response); + resolve15(response); } function dateTimeDeserializer(key, value) { if (typeof value === "string") { @@ -119866,7 +119866,7 @@ var require_lib5 = __commonJS({ err.result = response.result; reject(err); } else { - resolve14(response); + resolve15(response); } })); }); @@ -119883,11 +119883,11 @@ var require_auth2 = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -119903,7 +119903,7 @@ var require_auth2 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -119987,11 +119987,11 @@ var require_oidc_utils2 = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -120007,7 +120007,7 @@ var require_oidc_utils2 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -120085,11 +120085,11 @@ var require_summary2 = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -120105,7 +120105,7 @@ var require_summary2 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -120451,11 +120451,11 @@ var require_io_util2 = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -120471,7 +120471,7 @@ var require_io_util2 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -120624,11 +120624,11 @@ var require_io2 = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -120644,7 +120644,7 @@ var require_io2 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -120872,11 +120872,11 @@ var require_toolrunner2 = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -120892,7 +120892,7 @@ var require_toolrunner2 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -121120,7 +121120,7 @@ var require_toolrunner2 = __commonJS({ this.toolPath = path30.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath); } this.toolPath = yield io9.which(this.toolPath, true); - return new Promise((resolve14, reject) => __awaiter2(this, void 0, void 0, function* () { + return new Promise((resolve15, reject) => __awaiter2(this, void 0, void 0, function* () { this._debug(`exec tool: ${this.toolPath}`); this._debug("arguments:"); for (const arg of this.args) { @@ -121203,7 +121203,7 @@ var require_toolrunner2 = __commonJS({ if (error3) { reject(error3); } else { - resolve14(exitCode); + resolve15(exitCode); } }); if (this.options.input) { @@ -121356,11 +121356,11 @@ var require_exec2 = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -121376,7 +121376,7 @@ var require_exec2 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -121467,11 +121467,11 @@ var require_platform2 = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -121487,7 +121487,7 @@ var require_platform2 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -121586,11 +121586,11 @@ var require_core3 = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -121606,7 +121606,7 @@ var require_core3 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -122709,11 +122709,11 @@ var require_utils11 = __commonJS({ "use strict"; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -122729,7 +122729,7 @@ var require_utils11 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -122939,19 +122939,19 @@ Header Information: ${JSON.stringify(response.message.headers, void 0, 2)} exports2.getProperRetention = getProperRetention; function sleep(milliseconds) { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14) => setTimeout(resolve14, milliseconds)); + return new Promise((resolve15) => setTimeout(resolve15, milliseconds)); }); } exports2.sleep = sleep; function digestForStream(stream2) { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { const crc64 = new crc64_1.default(); const md5 = crypto_1.default.createHash("md5"); stream2.on("data", (data) => { crc64.update(data); md5.update(data); - }).on("end", () => resolve14({ + }).on("end", () => resolve15({ crc64: crc64.digest("base64"), md5: md5.digest("base64") })).on("error", reject); @@ -123075,11 +123075,11 @@ var require_upload_gzip = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -123095,7 +123095,7 @@ var require_upload_gzip = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -123108,14 +123108,14 @@ var require_upload_gzip = __commonJS({ }, i); function verb(n) { i[n] = o[n] && function(v) { - return new Promise(function(resolve14, reject) { - v = o[n](v), settle(resolve14, reject, v.done, v.value); + return new Promise(function(resolve15, reject) { + v = o[n](v), settle(resolve15, reject, v.done, v.value); }); }; } - function settle(resolve14, reject, d, v) { + function settle(resolve15, reject, d, v) { Promise.resolve(v).then(function(v2) { - resolve14({ value: v2, done: d }); + resolve15({ value: v2, done: d }); }, reject); } }; @@ -123156,14 +123156,14 @@ var require_upload_gzip = __commonJS({ return Number.MAX_SAFE_INTEGER; } } - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { const inputStream = fs32.createReadStream(originalFilePath); const gzip = zlib3.createGzip(); const outputStream = fs32.createWriteStream(tempFilePath); inputStream.pipe(gzip).pipe(outputStream); outputStream.on("finish", () => __awaiter2(this, void 0, void 0, function* () { const size = (yield stat2(tempFilePath)).size; - resolve14(size); + resolve15(size); })); outputStream.on("error", (error3) => { console.log(error3); @@ -123175,7 +123175,7 @@ var require_upload_gzip = __commonJS({ exports2.createGZipFileOnDisk = createGZipFileOnDisk; function createGZipFileInBuffer(originalFilePath) { return __awaiter2(this, void 0, void 0, function* () { - return new Promise((resolve14) => __awaiter2(this, void 0, void 0, function* () { + return new Promise((resolve15) => __awaiter2(this, void 0, void 0, function* () { var _a2, e_1, _b, _c; const inputStream = fs32.createReadStream(originalFilePath); const gzip = zlib3.createGzip(); @@ -123201,7 +123201,7 @@ var require_upload_gzip = __commonJS({ if (e_1) throw e_1.error; } } - resolve14(Buffer.concat(chunks)); + resolve15(Buffer.concat(chunks)); })); }); } @@ -123242,11 +123242,11 @@ var require_requestUtils2 = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -123262,7 +123262,7 @@ var require_requestUtils2 = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -123359,11 +123359,11 @@ var require_upload_http_client = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -123379,7 +123379,7 @@ var require_upload_http_client = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -123751,11 +123751,11 @@ var require_download_http_client = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -123771,7 +123771,7 @@ var require_download_http_client = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -123904,10 +123904,10 @@ var require_download_http_client = __commonJS({ }; const resetDestinationStream = (fileDownloadPath) => __awaiter2(this, void 0, void 0, function* () { destinationStream.close(); - yield new Promise((resolve14) => { - destinationStream.on("close", resolve14); + yield new Promise((resolve15) => { + destinationStream.on("close", resolve15); if (destinationStream.writableFinished) { - resolve14(); + resolve15(); } }); yield (0, utils_1.rmFile)(fileDownloadPath); @@ -123956,7 +123956,7 @@ var require_download_http_client = __commonJS({ */ pipeResponseToFile(response, destinationStream, isGzip) { return __awaiter2(this, void 0, void 0, function* () { - yield new Promise((resolve14, reject) => { + yield new Promise((resolve15, reject) => { if (isGzip) { const gunzip = zlib3.createGunzip(); response.message.on("error", (error3) => { @@ -123969,7 +123969,7 @@ var require_download_http_client = __commonJS({ destinationStream.close(); reject(error3); }).pipe(destinationStream).on("close", () => { - resolve14(); + resolve15(); }).on("error", (error3) => { core32.info(`An error occurred while writing a downloaded file to ${destinationStream.path}`); reject(error3); @@ -123980,7 +123980,7 @@ var require_download_http_client = __commonJS({ destinationStream.close(); reject(error3); }).pipe(destinationStream).on("close", () => { - resolve14(); + resolve15(); }).on("error", (error3) => { core32.info(`An error occurred while writing a downloaded file to ${destinationStream.path}`); reject(error3); @@ -124094,11 +124094,11 @@ var require_artifact_client = __commonJS({ }; var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve14) { - resolve14(value); + return value instanceof P ? value : new P(function(resolve15) { + resolve15(value); }); } - return new (P || (P = Promise))(function(resolve14, reject) { + return new (P || (P = Promise))(function(resolve15, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -124114,7 +124114,7 @@ var require_artifact_client = __commonJS({ } } function step(result) { - result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -145904,8 +145904,8 @@ function durationMsSince(startTime) { } async function delay(milliseconds, opts) { const { allowProcessExit } = opts || {}; - return new Promise((resolve14) => { - const timer = setTimeout(resolve14, milliseconds); + return new Promise((resolve15) => { + const timer = setTimeout(resolve15, milliseconds); if (allowProcessExit) { timer.unref(); } @@ -147111,7 +147111,7 @@ var getGitRoot = async function(sourceRoot) { ["rev-parse", "--show-toplevel"], `Cannot find Git repository root from the source root ${sourceRoot}.` ); - return path4.normalize(stdout.trim()); + return path4.resolve(stdout.trim()); } catch { return void 0; } @@ -151730,7 +151730,7 @@ async function extractTarZst(tar, dest, tarVersion, logger) { args.push("-f", tar instanceof stream.Readable ? "-" : tar, "-C", dest); process.stdout.write(`[command]tar ${args.join(" ")} `); - await new Promise((resolve14, reject) => { + await new Promise((resolve15, reject) => { const tarProcess = (0, import_child_process.spawn)("tar", args, { stdio: "pipe" }); let stdout = ""; tarProcess.stdout?.on("data", (data) => { @@ -151766,7 +151766,7 @@ async function extractTarZst(tar, dest, tarVersion, logger) { ) ); } - resolve14(); + resolve15(); }); }); } catch (e) { @@ -151881,7 +151881,7 @@ async function downloadAndExtractZstdWithStreaming(codeqlURL, dest, authorizatio authorization ? { authorization } : {}, headers ); - const response = await new Promise((resolve14, reject) => { + const response = await new Promise((resolve15, reject) => { const request3 = import_follow_redirects.https.get( codeqlURL, { @@ -151891,7 +151891,7 @@ async function downloadAndExtractZstdWithStreaming(codeqlURL, dest, authorizatio // Use the agent to respect proxy settings. agent }, - (r) => resolve14(r) + (r) => resolve15(r) ); request3.on("error", reject); request3.setTimeout(STREAMING_STALL_TIMEOUT_MS, () => { @@ -153823,20 +153823,21 @@ var CodeQLAnalysisError = class extends Error { }; async function determineCheckoutPath(action, config) { const checkoutPathInput = action.actions.getRequiredInput("checkout_path"); - const repositoryRoot = await getGitRoot(checkoutPathInput); + const absCheckoutPathInput = path16.resolve(checkoutPathInput); + const repositoryRoot = await getGitRoot(absCheckoutPathInput); if (repositoryRoot === void 0) { action.logger.warning( [ - `The directory at '${checkoutPathInput}' is not in the work tree of a git repository.`, + `The directory at '${absCheckoutPathInput}' is not in the work tree of a git repository.`, "If the repository being analyzed is checked out elsewhere,", "you must explicitly set the 'checkout_path' input for the 'codeql-action/analyze' step to", "the checkout path." ].join(" ") ); - } else if (repositoryRoot !== path16.resolve(checkoutPathInput)) { + } else if (repositoryRoot !== absCheckoutPathInput) { action.logger.warning( [ - `The directory at '${checkoutPathInput}' is not the root of the repository ('${repositoryRoot}').`, + `The directory at '${absCheckoutPathInput}' is not the root of the repository ('${repositoryRoot}').`, "Set the 'checkout_path' input for the 'codeql-action/analyze' step to the root path of the checkout." ].join(" ") ); @@ -153850,7 +153851,7 @@ async function determineCheckoutPath(action, config) { ].join(" ") ); } - return checkoutPathInput; + return absCheckoutPathInput; } async function setupPythonExtractor(logger) { const codeqlPython = process.env["CODEQL_PYTHON"]; @@ -154289,7 +154290,7 @@ async function cleanupAndUploadDatabases(action, repositoryNwo, codeql, config, logger.debug( `Database upload attempt ${attempt} of ${maxAttempts} failed for ${language}: ${getErrorMessage(e)}. Retrying in ${backoffMs / 1e3}s...` ); - await new Promise((resolve14) => setTimeout(resolve14, backoffMs)); + await new Promise((resolve15) => setTimeout(resolve15, backoffMs)); } } reports.push({ @@ -159645,11 +159646,11 @@ var Archiver = class extends import_readable_stream2.Transform { this._finalize(); } var self2 = this; - return new Promise(function(resolve14, reject) { + return new Promise(function(resolve15, reject) { var errored; self2._module.on("end", function() { if (!errored) { - resolve14(); + resolve15(); } }); self2._module.on("error", function(err) { @@ -164002,7 +164003,7 @@ var NetworkReachabilityBackend = class { proxy; agent; async checkConnection(url2) { - return new Promise((resolve14, reject) => { + return new Promise((resolve15, reject) => { const req = https2.request( url2, { @@ -164015,7 +164016,7 @@ var NetworkReachabilityBackend = class { (res) => { res.destroy(); if (res.statusCode !== void 0 && res.statusCode < 400) { - resolve14(res.statusCode); + resolve15(res.statusCode); } else { reject(new ReachabilityError(res.statusCode)); } diff --git a/src/analyze.test.ts b/src/analyze.test.ts index 88e5925070..4ec428abb9 100644 --- a/src/analyze.test.ts +++ b/src/analyze.test.ts @@ -33,13 +33,13 @@ setupTests(test); test.serial( "determineCheckoutPath - logs when checkout_path is not in a work tree", async (t) => { - const expectedPath = "/checkout/path"; + const expectedPath = path.resolve("/checkout/path"); const target = callee(determineCheckoutPath) .withActions((actions) => { sinon .stub(actions, "getRequiredInput") .withArgs("checkout_path") - .returns("/checkout/path"); + .returns(expectedPath); }) .withArgs(createTestConfig({})); sinon.stub(gitUtils, "getGitRoot").resolves(undefined); @@ -53,13 +53,13 @@ test.serial( test.serial( "determineCheckoutPath - logs when checkout_path is not a repo root", async (t) => { - const expectedPath = "/checkout/path"; + const expectedPath = path.resolve("/checkout/path"); const target = callee(determineCheckoutPath) .withActions((actions) => { sinon .stub(actions, "getRequiredInput") .withArgs("checkout_path") - .returns("/checkout/path"); + .returns(expectedPath); }) .withArgs(createTestConfig({})); sinon.stub(gitUtils, "getGitRoot").resolves("/checkout"); @@ -73,16 +73,16 @@ test.serial( test.serial( "determineCheckoutPath - logs when checkout_path is not the same as repo root in config", async (t) => { - const expectedPath = "/checkout/path"; + const expectedPath = path.resolve("/checkout/path"); const target = callee(determineCheckoutPath) .withActions((actions) => { sinon .stub(actions, "getRequiredInput") .withArgs("checkout_path") - .returns("/checkout/path"); + .returns(expectedPath); }) .withArgs(createTestConfig({ repositoryRoot: "/some/other/path" })); - sinon.stub(gitUtils, "getGitRoot").resolves("/checkout/path"); + sinon.stub(gitUtils, "getGitRoot").resolves(expectedPath); await target .logs(t, "does not match that found by the 'codeql-action/init' step") @@ -93,16 +93,16 @@ test.serial( test.serial( "determineCheckoutPath - doesn't log any of the messages when all is as expected", async (t) => { - const expectedPath = "/checkout/path"; + const expectedPath = path.resolve("/checkout/path"); const target = callee(determineCheckoutPath) .withActions((actions) => { sinon .stub(actions, "getRequiredInput") .withArgs("checkout_path") - .returns("/checkout/path"); + .returns(expectedPath); }) - .withArgs(createTestConfig({ repositoryRoot: "/checkout/path" })); - sinon.stub(gitUtils, "getGitRoot").resolves("/checkout/path"); + .withArgs(createTestConfig({ repositoryRoot: expectedPath })); + sinon.stub(gitUtils, "getGitRoot").resolves(expectedPath); await target .notLogs( diff --git a/src/analyze.ts b/src/analyze.ts index f1a1841f38..e482aa2eec 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -102,21 +102,22 @@ export async function determineCheckoutPath( const checkoutPathInput = action.actions.getRequiredInput("checkout_path"); // Try to obtain the root path of the repository and validate that it matches the input. - const repositoryRoot = await getGitRoot(checkoutPathInput); + const absCheckoutPathInput = path.resolve(checkoutPathInput); + const repositoryRoot = await getGitRoot(absCheckoutPathInput); if (repositoryRoot === undefined) { action.logger.warning( [ - `The directory at '${checkoutPathInput}' is not in the work tree of a git repository.`, + `The directory at '${absCheckoutPathInput}' is not in the work tree of a git repository.`, "If the repository being analyzed is checked out elsewhere,", "you must explicitly set the 'checkout_path' input for the 'codeql-action/analyze' step to", "the checkout path.", ].join(" "), ); - } else if (repositoryRoot !== path.resolve(checkoutPathInput)) { + } else if (repositoryRoot !== absCheckoutPathInput) { action.logger.warning( [ - `The directory at '${checkoutPathInput}' is not the root of the repository ('${repositoryRoot}').`, + `The directory at '${absCheckoutPathInput}' is not the root of the repository ('${repositoryRoot}').`, "Set the 'checkout_path' input for the 'codeql-action/analyze' step to the root path of the checkout.", ].join(" "), ); @@ -135,7 +136,7 @@ export async function determineCheckoutPath( ); } - return checkoutPathInput; + return absCheckoutPathInput; } async function setupPythonExtractor(logger: Logger) { diff --git a/src/git-utils.ts b/src/git-utils.ts index da1189035a..9045a7c3d7 100644 --- a/src/git-utils.ts +++ b/src/git-utils.ts @@ -245,7 +245,7 @@ export const getGitRoot = async function ( ["rev-parse", "--show-toplevel"], `Cannot find Git repository root from the source root ${sourceRoot}.`, ); - return path.normalize(stdout.trim()); + return path.resolve(stdout.trim()); } catch { // Errors are already logged by runGitCommand() return undefined; From c2215db9ae4573ad44ad55d6030d072f42038ba0 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 28 Sep 2026 10:51:26 +0100 Subject: [PATCH 009/107] Update `git-utils` tests --- src/git-utils.test.ts | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/git-utils.test.ts b/src/git-utils.test.ts index 6f5f37401c..0240a09501 100644 --- a/src/git-utils.test.ts +++ b/src/git-utils.test.ts @@ -34,13 +34,15 @@ test.serial( }); const callback = sinon.stub(gitUtils, "getCommitOid"); - callback.withArgs(sinon.match.string, "HEAD").resolves(currentSha); + callback + .withArgs(sinon.match.any, sinon.match.string, "HEAD") + .resolves(currentSha); const actualRef = await gitUtils.getRef(env, tmpDir); t.deepEqual(actualRef, expectedRef); t.is(callback.callCount, 1); - t.true(callback.calledOnceWith(tmpDir, "HEAD")); + t.true(callback.calledOnceWith(env, tmpDir, "HEAD")); }); }, ); @@ -60,16 +62,22 @@ test.serial( const callback = sinon.stub(gitUtils, "getCommitOid"); callback - .withArgs(sinon.match.string, "refs/remotes/pull/1/merge") + .withArgs( + sinon.match.any, + sinon.match.string, + "refs/remotes/pull/1/merge", + ) + .resolves(sha); + callback + .withArgs(sinon.match.any, sinon.match.string, "HEAD") .resolves(sha); - callback.withArgs(sinon.match.any, "HEAD").resolves(sha); const actualRef = await gitUtils.getRef(env, tmpDir); t.deepEqual(actualRef, expectedRef); t.is(callback.callCount, 2); - t.true(callback.calledWith(tmpDir, "HEAD")); - t.true(callback.calledWith(tmpDir, "refs/remotes/pull/1/merge")); + t.true(callback.calledWith(env, tmpDir, "HEAD")); + t.true(callback.calledWith(env, tmpDir, "refs/remotes/pull/1/merge")); }); }, ); @@ -87,17 +95,19 @@ test.serial( const callback = sinon.stub(gitUtils, "getCommitOid"); callback - .withArgs(tmpDir, "refs/remotes/pull/1/merge") + .withArgs(sinon.match.any, tmpDir, "refs/remotes/pull/1/merge") .resolves("a".repeat(40)); - callback.withArgs(tmpDir, "HEAD").resolves("b".repeat(40)); + callback + .withArgs(sinon.match.any, tmpDir, "HEAD") + .resolves("b".repeat(40)); callback.throws(new Error("Unexpected getCommitOid call in test.")); const actualRef = await gitUtils.getRef(env, tmpDir); t.deepEqual(actualRef, "refs/pull/1/head"); t.is(callback.callCount, 2); - t.true(callback.calledWith(tmpDir, "refs/remotes/pull/1/merge")); - t.true(callback.calledWith(tmpDir, "HEAD")); + t.true(callback.calledWith(env, tmpDir, "refs/remotes/pull/1/merge")); + t.true(callback.calledWith(env, tmpDir, "HEAD")); }); }, ); @@ -122,8 +132,12 @@ test.serial( }); const callback = sinon.stub(gitUtils, "getCommitOid"); - callback.withArgs(tmpDir, "refs/pull/1/merge").resolves("b".repeat(40)); - callback.withArgs(sinon.match.any, "HEAD").resolves("b".repeat(40)); + callback + .withArgs(sinon.match.any, tmpDir, "refs/pull/1/merge") + .resolves("b".repeat(40)); + callback + .withArgs(sinon.match.any, sinon.match.string, "HEAD") + .resolves("b".repeat(40)); const actualRef = await gitUtils.getRef(env, tmpDir); t.deepEqual(actualRef, "refs/pull/2/merge"); From 909fda1468f8ef25624848914b92c3faeba7cfe7 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 6 Oct 2026 13:36:35 +0100 Subject: [PATCH 010/107] Allow logging functions to accept `string[]` directly --- lib/entry-points.js | 20 ++++++++++++++++---- src/logging.test.ts | 17 +++++++++++++++++ src/logging.ts | 43 +++++++++++++++++++++++++++++++++++-------- src/testing-utils.ts | 14 +++++++------- 4 files changed, 75 insertions(+), 19 deletions(-) create mode 100644 src/logging.test.ts diff --git a/lib/entry-points.js b/lib/entry-points.js index ad7ac988a1..1a75678e97 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -170435,12 +170435,24 @@ function fixCodeQualityCategory(logger2, category, env = getEnv()) { // src/logging.ts var core4 = __toESM(require_core()); +var joinMessageStrings = (message) => { + if (Array.isArray(message)) { + return message.join(" "); + } else { + return message; + } +}; +var autoJoinMessageStrings = (fn) => { + return (message) => { + return fn(joinMessageStrings(message)); + }; +}; function getActionsLogger() { return { - debug: core4.debug, - info: core4.info, - warning: core4.warning, - error: core4.error, + debug: autoJoinMessageStrings(core4.debug), + info: autoJoinMessageStrings(core4.info), + warning: autoJoinMessageStrings(core4.warning), + error: autoJoinMessageStrings(core4.error), isDebug: core4.isDebug, startGroup: core4.startGroup, endGroup: core4.endGroup diff --git a/src/logging.test.ts b/src/logging.test.ts new file mode 100644 index 0000000000..33f6f8c162 --- /dev/null +++ b/src/logging.test.ts @@ -0,0 +1,17 @@ +import test from "ava"; + +import { joinMessageStrings } from "./logging"; +import { setupTests } from "./testing-utils"; + +setupTests(test); + +test("joinMessageStrings", async (t) => { + // For strings and errors, it is the identity function. + t.deepEqual(joinMessageStrings("Hello"), "Hello"); + + const error = new Error("Some error"); + t.deepEqual(joinMessageStrings(error), error); + + // For arrays of strings, we get a join-ed string. + t.deepEqual(joinMessageStrings(["foo", "bar"]), "foo bar"); +}); diff --git a/src/logging.ts b/src/logging.ts index 2c34cb54d4..177aca6c7b 100644 --- a/src/logging.ts +++ b/src/logging.ts @@ -1,10 +1,16 @@ import * as core from "@actions/core"; +/** Types that all of our logging functions accept. */ +export type Loggable = string | string[]; + +/** Some logging functions also accept errors directly. */ +export type LoggableError = Loggable | Error; + export interface Logger { - debug: (message: string) => void; - info: (message: string) => void; - warning: (message: string | Error) => void; - error: (message: string | Error) => void; + debug: (message: Loggable) => void; + info: (message: Loggable) => void; + warning: (message: LoggableError) => void; + error: (message: LoggableError) => void; isDebug: () => boolean; @@ -12,12 +18,33 @@ export interface Logger { endGroup: () => void; } +/** If `message` is an array of strings, the array is `join`-ed into one string separated by spaces. */ +export const joinMessageStrings = ( + message: string[] | string | T, +): string | T => { + if (Array.isArray(message)) { + return message.join(" "); + } else { + return message; + } +}; + +/** + * Wraps a logging function so that `joinMessageStrings` is applied to the input before + * calling the wrapped logging function. + */ +const autoJoinMessageStrings = (fn: (msg: string | T) => void) => { + return (message: string[] | string | T) => { + return fn(joinMessageStrings(message)); + }; +}; + export function getActionsLogger(): Logger { return { - debug: core.debug, - info: core.info, - warning: core.warning, - error: core.error, + debug: autoJoinMessageStrings(core.debug), + info: autoJoinMessageStrings(core.info), + warning: autoJoinMessageStrings(core.warning), + error: autoJoinMessageStrings(core.error), isDebug: core.isDebug, startGroup: core.startGroup, endGroup: core.endGroup, diff --git a/src/testing-utils.ts b/src/testing-utils.ts index a5ba50554c..df81f51bb4 100644 --- a/src/testing-utils.ts +++ b/src/testing-utils.ts @@ -30,7 +30,7 @@ import { featureConfig, FeatureEnablement, } from "./feature-flags"; -import { Logger } from "./logging"; +import { joinMessageStrings, Loggable, LoggableError, Logger } from "./logging"; import { OverlayDatabaseMode } from "./overlay/overlay-database-mode"; import { getBundlePlatform } from "./platform"; import { ActionName } from "./status-report"; @@ -622,8 +622,8 @@ export class RecordingLogger implements Logger { constructor(private readonly logToConsole: boolean = true) {} - private addMessage(level: LogLevel, message: string | Error): void { - this.messages.push({ type: level, message }); + private addMessage(level: LogLevel, message: LoggableError): void { + this.messages.push({ type: level, message: joinMessageStrings(message) }); if (this.logToConsole) { // eslint-disable-next-line no-console @@ -648,19 +648,19 @@ export class RecordingLogger implements Logger { return true; } - debug(message: string) { + debug(message: Loggable) { this.addMessage("debug", message); } - info(message: string) { + info(message: Loggable) { this.addMessage("info", message); } - warning(message: string | Error) { + warning(message: LoggableError) { this.addMessage("warning", message); } - error(message: string | Error) { + error(message: LoggableError) { this.addMessage("error", message); } From cb7acf539626ded596e80ac0f4d7c38fc25a89d6 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 6 Oct 2026 13:45:35 +0100 Subject: [PATCH 011/107] Refactor `getCodeQLActionRepository` out of `setup-codeql` --- lib/entry-points.js | 22 ++++++++++++---------- src/setup-codeql.test.ts | 18 ------------------ src/setup-codeql.ts | 20 ++++---------------- src/setup/repository.test.ts | 31 +++++++++++++++++++++++++++++++ src/setup/repository.ts | 19 +++++++++++++++++++ 5 files changed, 66 insertions(+), 44 deletions(-) create mode 100644 src/setup/repository.test.ts create mode 100644 src/setup/repository.ts diff --git a/lib/entry-points.js b/lib/entry-points.js index 1a75678e97..f0cc985d11 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -175634,6 +175634,18 @@ function logPerLanguageBundleFallback({ logger: logger2 }, language, location) { ); } +// src/setup/repository.ts +var CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action"; +function getCodeQLActionRepository(logger2) { + if (isRunningLocalAction()) { + logger2.info( + "The CodeQL Action is checked out locally. Using the default CodeQL Action repository." + ); + return CODEQL_DEFAULT_ACTION_REPOSITORY; + } + return getRequiredEnvParam("GITHUB_ACTION_REPOSITORY"); +} + // src/tar.ts var import_child_process = require("child_process"); var fs12 = __toESM(require("fs")); @@ -176025,21 +176037,11 @@ function writeToolcacheMarkerFile(extractedPath, logger2) { } // src/setup-codeql.ts -var CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action"; var CODEQL_NIGHTLIES_REPOSITORY_OWNER = "dsp-testing"; var CODEQL_NIGHTLIES_REPOSITORY_NAME = "codeql-cli-nightlies"; var CODEQL_BUNDLE_VERSION_ALIAS = ["linked", "latest"]; var CODEQL_NIGHTLY_TOOLS_INPUTS = ["nightly", "nightly-latest"]; var CODEQL_TOOLCACHE_INPUT = "toolcache"; -function getCodeQLActionRepository(logger2) { - if (isRunningLocalAction()) { - logger2.info( - "The CodeQL Action is checked out locally. Using the default CodeQL Action repository." - ); - return CODEQL_DEFAULT_ACTION_REPOSITORY; - } - return getRequiredEnvParam("GITHUB_ACTION_REPOSITORY"); -} async function getCodeQLBundleDownloadURL(tagName, apiDetails, codeQLBundleName, logger2) { const codeQLActionRepository = getCodeQLActionRepository(logger2); const potentialDownloadSources = [ diff --git a/src/setup-codeql.test.ts b/src/setup-codeql.test.ts index c33ac0700a..e7a93455fe 100644 --- a/src/setup-codeql.test.ts +++ b/src/setup-codeql.test.ts @@ -126,24 +126,6 @@ test.serial("convert to semver", (t) => { } }); -test.serial("getCodeQLActionRepository", (t) => { - const logger = getRunnerLogger(true); - - initializeEnvironment("1.2.3"); - - // isRunningLocalAction() === true - delete process.env["GITHUB_ACTION_REPOSITORY"]; - process.env["RUNNER_TEMP"] = path.dirname(__dirname); - const repoLocalRunner = setupCodeql.getCodeQLActionRepository(logger); - t.deepEqual(repoLocalRunner, "github/codeql-action"); - - // isRunningLocalAction() === false - sinon.stub(actionsUtil, "isRunningLocalAction").returns(false); - process.env["GITHUB_ACTION_REPOSITORY"] = "xxx/yyy"; - const repoEnv = setupCodeql.getCodeQLActionRepository(logger); - t.deepEqual(repoEnv, "xxx/yyy"); -}); - test.serial( "getCodeQLSource sets CLI version for a semver tagged bundle", async (t) => { diff --git a/src/setup-codeql.ts b/src/setup-codeql.ts index d306d40d63..793191b8b1 100644 --- a/src/setup-codeql.ts +++ b/src/setup-codeql.ts @@ -14,7 +14,6 @@ import { isAnalyzingPullRequest, isDynamicWorkflow, isGitHubHostedRunner, - isRunningLocalAction, } from "./actions-util"; import * as api from "./api-client"; import { @@ -45,6 +44,10 @@ import { logPerLanguageBundleFallback, } from "./per-language-bundles"; import { getBundlePlatform } from "./platform"; +import { + CODEQL_DEFAULT_ACTION_REPOSITORY, + getCodeQLActionRepository, +} from "./setup/repository"; import * as tar from "./tar"; import { deleteToolcacheBundles, @@ -66,7 +69,6 @@ export enum ToolsSource { Download = "DOWNLOAD", } -const CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action"; const CODEQL_NIGHTLIES_REPOSITORY_OWNER = "dsp-testing"; const CODEQL_NIGHTLIES_REPOSITORY_NAME = "codeql-cli-nightlies"; @@ -74,20 +76,6 @@ const CODEQL_BUNDLE_VERSION_ALIAS: string[] = ["linked", "latest"]; const CODEQL_NIGHTLY_TOOLS_INPUTS = ["nightly", "nightly-latest"]; const CODEQL_TOOLCACHE_INPUT = "toolcache"; -export function getCodeQLActionRepository(logger: Logger): string { - if (isRunningLocalAction()) { - // This handles the case where the Action does not come from an Action repository, - // e.g. our integration tests which use the Action code from the current checkout. - // In these cases, the GITHUB_ACTION_REPOSITORY environment variable is not set. - logger.info( - "The CodeQL Action is checked out locally. Using the default CodeQL Action repository.", - ); - return CODEQL_DEFAULT_ACTION_REPOSITORY; - } - - return util.getRequiredEnvParam("GITHUB_ACTION_REPOSITORY"); -} - async function getCodeQLBundleDownloadURL( tagName: string, apiDetails: api.GitHubApiDetails, diff --git a/src/setup/repository.test.ts b/src/setup/repository.test.ts new file mode 100644 index 0000000000..c3dccbf9c2 --- /dev/null +++ b/src/setup/repository.test.ts @@ -0,0 +1,31 @@ +import * as path from "path"; + +import test from "ava"; +import * as sinon from "sinon"; + +import * as actionsUtil from "../actions-util"; +import { getRunnerLogger } from "../logging"; +import { setupTests } from "../testing-utils"; +import { initializeEnvironment } from "../util"; + +import { getCodeQLActionRepository } from "./repository"; + +setupTests(test); + +test.serial("getCodeQLActionRepository", (t) => { + const logger = getRunnerLogger(true); + + initializeEnvironment("1.2.3"); + + // isRunningLocalAction() === true + delete process.env["GITHUB_ACTION_REPOSITORY"]; + process.env["RUNNER_TEMP"] = path.dirname(__dirname); + const repoLocalRunner = getCodeQLActionRepository(logger); + t.deepEqual(repoLocalRunner, "github/codeql-action"); + + // isRunningLocalAction() === false + sinon.stub(actionsUtil, "isRunningLocalAction").returns(false); + process.env["GITHUB_ACTION_REPOSITORY"] = "xxx/yyy"; + const repoEnv = getCodeQLActionRepository(logger); + t.deepEqual(repoEnv, "xxx/yyy"); +}); diff --git a/src/setup/repository.ts b/src/setup/repository.ts new file mode 100644 index 0000000000..908cc39ee7 --- /dev/null +++ b/src/setup/repository.ts @@ -0,0 +1,19 @@ +import { isRunningLocalAction } from "../actions-util"; +import { Logger } from "../logging"; +import * as util from "../util"; + +export const CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action"; + +export function getCodeQLActionRepository(logger: Logger): string { + if (isRunningLocalAction()) { + // This handles the case where the Action does not come from an Action repository, + // e.g. our integration tests which use the Action code from the current checkout. + // In these cases, the GITHUB_ACTION_REPOSITORY environment variable is not set. + logger.info( + "The CodeQL Action is checked out locally. Using the default CodeQL Action repository.", + ); + return CODEQL_DEFAULT_ACTION_REPOSITORY; + } + + return util.getRequiredEnvParam("GITHUB_ACTION_REPOSITORY"); +} From 3f57a005543dac0b43f0fa212b72e5c09612cfa0 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 6 Oct 2026 14:00:12 +0100 Subject: [PATCH 012/107] Use `ActionState` for `getCodeQLActionRepository` --- lib/entry-points.js | 13 ++++++++----- src/actions-util.ts | 4 ++-- src/setup-codeql.ts | 5 ++++- src/setup/repository.test.ts | 27 +++++++++++++++------------ src/setup/repository.ts | 23 +++++++++++++++++------ 5 files changed, 46 insertions(+), 26 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index f0cc985d11..3a4bdcb05c 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -175636,14 +175636,14 @@ function logPerLanguageBundleFallback({ logger: logger2 }, language, location) { // src/setup/repository.ts var CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action"; -function getCodeQLActionRepository(logger2) { - if (isRunningLocalAction()) { - logger2.info( +function getCodeQLActionRepository(action) { + if (isRunningLocalAction(action.env)) { + action.logger.info( "The CodeQL Action is checked out locally. Using the default CodeQL Action repository." ); return CODEQL_DEFAULT_ACTION_REPOSITORY; } - return getRequiredEnvParam("GITHUB_ACTION_REPOSITORY"); + return action.env.getRequired("GITHUB_ACTION_REPOSITORY" /* GITHUB_ACTION_REPOSITORY */); } // src/tar.ts @@ -176043,7 +176043,10 @@ var CODEQL_BUNDLE_VERSION_ALIAS = ["linked", "latest"]; var CODEQL_NIGHTLY_TOOLS_INPUTS = ["nightly", "nightly-latest"]; var CODEQL_TOOLCACHE_INPUT = "toolcache"; async function getCodeQLBundleDownloadURL(tagName, apiDetails, codeQLBundleName, logger2) { - const codeQLActionRepository = getCodeQLActionRepository(logger2); + const codeQLActionRepository = getCodeQLActionRepository({ + logger: logger2, + env: getEnv() + }); const potentialDownloadSources = [ // This GitHub instance, and this Action. [apiDetails.url, codeQLActionRepository], diff --git a/src/actions-util.ts b/src/actions-util.ts index 6c7d6a78d2..d51fdbe1da 100644 --- a/src/actions-util.ts +++ b/src/actions-util.ts @@ -103,7 +103,7 @@ export function getWorkflowEventName(env: Env = getEnv()) { * Returns whether the current workflow is executing a local copy of the Action, e.g. we're running * a workflow on the codeql-action repo itself. */ -export function isRunningLocalAction(env: Env = getEnv()): boolean { +export function isRunningLocalAction(env: ReadOnlyEnv = getEnv()): boolean { const relativeScriptPath = getRelativeScriptPath(env); return ( relativeScriptPath.startsWith("..") || path.isAbsolute(relativeScriptPath) @@ -115,7 +115,7 @@ export function isRunningLocalAction(env: Env = getEnv()): boolean { * * This can be used to get the Action's name or tell if we're running a local Action. */ -function getRelativeScriptPath(env: Env): string { +function getRelativeScriptPath(env: ReadOnlyEnv): string { const runnerTemp = env.getRequired(ActionsEnvVars.RUNNER_TEMP); const actionsDirectory = path.join(path.dirname(runnerTemp), "_actions"); return path.relative(actionsDirectory, __filename); diff --git a/src/setup-codeql.ts b/src/setup-codeql.ts index 793191b8b1..c97729471f 100644 --- a/src/setup-codeql.ts +++ b/src/setup-codeql.ts @@ -82,7 +82,10 @@ async function getCodeQLBundleDownloadURL( codeQLBundleName: string, logger: Logger, ): Promise { - const codeQLActionRepository = getCodeQLActionRepository(logger); + const codeQLActionRepository = getCodeQLActionRepository({ + logger, + env: getEnv(), + }); const potentialDownloadSources = [ // This GitHub instance, and this Action. [apiDetails.url, codeQLActionRepository], diff --git a/src/setup/repository.test.ts b/src/setup/repository.test.ts index c3dccbf9c2..56eb74786f 100644 --- a/src/setup/repository.test.ts +++ b/src/setup/repository.test.ts @@ -4,28 +4,31 @@ import test from "ava"; import * as sinon from "sinon"; import * as actionsUtil from "../actions-util"; -import { getRunnerLogger } from "../logging"; -import { setupTests } from "../testing-utils"; +import { ActionsEnvVars } from "../environment"; +import { callee, setupTests } from "../testing-utils"; import { initializeEnvironment } from "../util"; import { getCodeQLActionRepository } from "./repository"; setupTests(test); -test.serial("getCodeQLActionRepository", (t) => { - const logger = getRunnerLogger(true); - +test.serial("getCodeQLActionRepository", async (t) => { initializeEnvironment("1.2.3"); + const target = callee(getCodeQLActionRepository) + .withArgs() + .withEnv((env) => { + env.set(ActionsEnvVars.RUNNER_TEMP, path.dirname(__dirname)); + }); + // isRunningLocalAction() === true - delete process.env["GITHUB_ACTION_REPOSITORY"]; - process.env["RUNNER_TEMP"] = path.dirname(__dirname); - const repoLocalRunner = getCodeQLActionRepository(logger); - t.deepEqual(repoLocalRunner, "github/codeql-action"); + await target.passes(t.deepEqual, "github/codeql-action"); // isRunningLocalAction() === false sinon.stub(actionsUtil, "isRunningLocalAction").returns(false); - process.env["GITHUB_ACTION_REPOSITORY"] = "xxx/yyy"; - const repoEnv = getCodeQLActionRepository(logger); - t.deepEqual(repoEnv, "xxx/yyy"); + await target + .withEnv((env) => { + env.set(ActionsEnvVars.GITHUB_ACTION_REPOSITORY, "xxx/yyy"); + }) + .passes(t.deepEqual, "xxx/yyy"); }); diff --git a/src/setup/repository.ts b/src/setup/repository.ts index 908cc39ee7..c58470630b 100644 --- a/src/setup/repository.ts +++ b/src/setup/repository.ts @@ -1,19 +1,30 @@ +import { ActionState } from "../action-common"; import { isRunningLocalAction } from "../actions-util"; -import { Logger } from "../logging"; -import * as util from "../util"; +import { ActionsEnvVars } from "../environment"; +/** The NWO of the standard CodeQL Action repository. */ export const CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action"; -export function getCodeQLActionRepository(logger: Logger): string { - if (isRunningLocalAction()) { +/** + * Retrieves the NWO of the repository that the CodeQL Action is loaded from. + * Typically, this will be `github/codeql-action`, but it may be something else for + * forks of the Action or in environments other than GitHub.com. + * + * If this function detects that we are running the Action locally (e.g. in tests), + * then we default to `CODEQL_DEFAULT_ACTION_REPOSITORY`. + */ +export function getCodeQLActionRepository( + action: ActionState<["ReadOnlyEnv", "Logger"]>, +): string { + if (isRunningLocalAction(action.env)) { // This handles the case where the Action does not come from an Action repository, // e.g. our integration tests which use the Action code from the current checkout. // In these cases, the GITHUB_ACTION_REPOSITORY environment variable is not set. - logger.info( + action.logger.info( "The CodeQL Action is checked out locally. Using the default CodeQL Action repository.", ); return CODEQL_DEFAULT_ACTION_REPOSITORY; } - return util.getRequiredEnvParam("GITHUB_ACTION_REPOSITORY"); + return action.env.getRequired(ActionsEnvVars.GITHUB_ACTION_REPOSITORY); } From da07d40a0f387325a497ae40e0e02b45044b7f38 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 6 Oct 2026 14:29:42 +0100 Subject: [PATCH 013/107] Refactor `getCodeQLBundleDownloadURL` out of `setup-codeql` --- lib/entry-points.js | 172 ++++++++++++++++------------------------ package-lock.json | 2 +- package.json | 1 - src/setup-codeql.ts | 73 ++--------------- src/setup/repository.ts | 99 +++++++++++++++++++++++ 5 files changed, 176 insertions(+), 171 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 3a4bdcb05c..71b6915a9c 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -42967,11 +42967,11 @@ var require_tracingPolicy = __commonJS({ var import_log = require_log3(); var import_core_util = require_commonjs4(); var import_restError = require_restError3(); - var import_util58 = require_internal3(); + var import_util59 = require_internal3(); var tracingPolicyName2 = "tracingPolicy"; function tracingPolicy2(options = {}) { const userAgentPromise = (0, import_userAgent.getUserAgentValue)(options.userAgentPrefix); - const sanitizer = new import_util58.Sanitizer({ + const sanitizer = new import_util59.Sanitizer({ additionalAllowedQueryParameters: options.additionalAllowedQueryParameters }); const tracingClient = tryCreateTracingClient(); @@ -46597,11 +46597,11 @@ var require_response2 = __commonJS({ }); module2.exports = __toCommonJS2(response_exports); var import_core_rest_pipeline = require_commonjs6(); - var import_util58 = require_util9(); + var import_util59 = require_util9(); var originalResponse = /* @__PURE__ */ Symbol("Original FullOperationResponse"); function toCompatResponse2(response, options) { - let request3 = (0, import_util58.toWebResourceLike)(response.request); - let headers = (0, import_util58.toHttpHeadersLike)(response.headers); + let request3 = (0, import_util59.toWebResourceLike)(response.request); + let headers = (0, import_util59.toHttpHeadersLike)(response.headers); if (options?.createProxy) { return new Proxy(response, { get(target, prop, receiver) { @@ -46642,7 +46642,7 @@ var require_response2 = __commonJS({ return { ...compatResponse, headers, - request: (0, import_util58.toPipelineRequest)(compatResponse.request) + request: (0, import_util59.toPipelineRequest)(compatResponse.request) }; } } @@ -46749,7 +46749,7 @@ var require_requestPolicyFactoryPolicy = __commonJS({ requestPolicyFactoryPolicyName: () => requestPolicyFactoryPolicyName2 }); module2.exports = __toCommonJS2(requestPolicyFactoryPolicy_exports); - var import_util58 = require_util9(); + var import_util59 = require_util9(); var import_response = require_response2(); var HttpPipelineLogLevel2 = /* @__PURE__ */ ((HttpPipelineLogLevel22) => { HttpPipelineLogLevel22[HttpPipelineLogLevel22["ERROR"] = 1] = "ERROR"; @@ -46773,14 +46773,14 @@ var require_requestPolicyFactoryPolicy = __commonJS({ async sendRequest(request3, next) { let httpPipeline = { async sendRequest(httpRequest) { - const response2 = await next((0, import_util58.toPipelineRequest)(httpRequest)); + const response2 = await next((0, import_util59.toPipelineRequest)(httpRequest)); return (0, import_response.toCompatResponse)(response2, { createProxy: true }); } }; for (const factory of orderedFactories) { httpPipeline = factory.create(httpPipeline, mockRequestPolicyOptions); } - const webResourceLike = (0, import_util58.toWebResourceLike)(request3, { createProxy: true }); + const webResourceLike = (0, import_util59.toWebResourceLike)(request3, { createProxy: true }); const response = await httpPipeline.sendRequest(webResourceLike); return (0, import_response.toPipelineResponse)(response); } @@ -46815,12 +46815,12 @@ var require_httpClientAdapter = __commonJS({ }); module2.exports = __toCommonJS2(httpClientAdapter_exports); var import_response = require_response2(); - var import_util58 = require_util9(); + var import_util59 = require_util9(); function convertHttpClient2(requestPolicyClient) { return { sendRequest: async (request3) => { const response = await requestPolicyClient.sendRequest( - (0, import_util58.toWebResourceLike)(request3, { createProxy: true }) + (0, import_util59.toWebResourceLike)(request3, { createProxy: true }) ); return (0, import_response.toPipelineResponse)(response); } @@ -46858,7 +46858,7 @@ var require_commonjs9 = __commonJS({ disableKeepAlivePolicyName: () => import_disableKeepAlivePolicy.disableKeepAlivePolicyName, requestPolicyFactoryPolicyName: () => import_requestPolicyFactoryPolicy.requestPolicyFactoryPolicyName, toCompatResponse: () => import_response.toCompatResponse, - toHttpHeadersLike: () => import_util58.toHttpHeadersLike + toHttpHeadersLike: () => import_util59.toHttpHeadersLike }); module2.exports = __toCommonJS2(src_exports); var import_extendedClient = require_extendedClient(); @@ -46866,7 +46866,7 @@ var require_commonjs9 = __commonJS({ var import_requestPolicyFactoryPolicy = require_requestPolicyFactoryPolicy(); var import_disableKeepAlivePolicy = require_disableKeepAlivePolicy(); var import_httpClientAdapter = require_httpClientAdapter(); - var import_util58 = require_util9(); + var import_util59 = require_util9(); } }); @@ -107096,41 +107096,6 @@ var require_tool_cache = __commonJS({ } }); -// node_modules/fast-deep-equal/index.js -var require_fast_deep_equal = __commonJS({ - "node_modules/fast-deep-equal/index.js"(exports2, module2) { - "use strict"; - module2.exports = function equal(a, b) { - if (a === b) return true; - if (a && b && typeof a == "object" && typeof b == "object") { - if (a.constructor !== b.constructor) return false; - var length, i, keys; - if (Array.isArray(a)) { - length = a.length; - if (length != b.length) return false; - for (i = length; i-- !== 0; ) - if (!equal(a[i], b[i])) return false; - return true; - } - if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; - if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); - if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); - keys = Object.keys(a); - length = keys.length; - if (length !== Object.keys(b).length) return false; - for (i = length; i-- !== 0; ) - if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; - for (i = length; i-- !== 0; ) { - var key = keys[i]; - if (!equal(a[key], b[key])) return false; - } - return true; - } - return a !== a && b !== b; - }; - } -}); - // node_modules/follow-redirects/debug.js var require_debug3 = __commonJS({ "node_modules/follow-redirects/debug.js"(exports2, module2) { @@ -175209,7 +175174,6 @@ var path13 = __toESM(require("path")); var import_perf_hooks4 = require("perf_hooks"); var core12 = __toESM(require_core()); var toolcache3 = __toESM(require_tool_cache()); -var import_fast_deep_equal = __toESM(require_fast_deep_equal()); var semver10 = __toESM(require_semver2()); // src/codeql-bundle.ts @@ -175645,6 +175609,55 @@ function getCodeQLActionRepository(action) { } return action.env.getRequired("GITHUB_ACTION_REPOSITORY" /* GITHUB_ACTION_REPOSITORY */); } +var DEFAULT_DOWNLOAD_SOURCE = [ + GITHUB_DOTCOM_URL, + CODEQL_DEFAULT_ACTION_REPOSITORY +]; +var isSameDownloadSource = ([srcUrl, srcRepo], [otherUrl, otherRepo]) => { + return srcUrl === otherUrl && srcRepo === otherRepo; +}; +async function getCodeQLAssetDownloadURL(action, apiDetails, tagName, assetName, assetKind = "CodeQL bundle") { + const codeQLActionRepository = getCodeQLActionRepository(action); + const potentialDownloadSources = [ + // This GitHub instance, and this Action. + [apiDetails.url, codeQLActionRepository], + // This GitHub instance, and the canonical Action. + [apiDetails.url, CODEQL_DEFAULT_ACTION_REPOSITORY], + // GitHub.com, and the canonical Action. + DEFAULT_DOWNLOAD_SOURCE + ]; + const uniqueDownloadSources = potentialDownloadSources.filter( + (source, index2, self2) => { + return !self2.slice(0, index2).some((other) => isSameDownloadSource(source, other)); + } + ); + for (const [apiURL, repository] of uniqueDownloadSources) { + if (isSameDownloadSource(DEFAULT_DOWNLOAD_SOURCE, [apiURL, repository])) { + break; + } + const [repositoryOwner, repositoryName] = repository.split("/"); + try { + const release2 = await getApiClient().rest.repos.getReleaseByTag({ + owner: repositoryOwner, + repo: repositoryName, + tag: tagName + }); + for (const asset of release2.data.assets) { + if (asset.name === assetName) { + action.logger.info( + `Found ${assetKind} ${assetName} in ${repository} on ${apiURL} with URL ${asset.url}.` + ); + return asset.url; + } + } + } catch (e) { + action.logger.info( + `Looked for ${assetKind} ${assetName} in ${repository} on ${apiURL} but got error ${e}.` + ); + } + } + return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${assetName}`; +} // src/tar.ts var import_child_process = require("child_process"); @@ -176042,52 +176055,6 @@ var CODEQL_NIGHTLIES_REPOSITORY_NAME = "codeql-cli-nightlies"; var CODEQL_BUNDLE_VERSION_ALIAS = ["linked", "latest"]; var CODEQL_NIGHTLY_TOOLS_INPUTS = ["nightly", "nightly-latest"]; var CODEQL_TOOLCACHE_INPUT = "toolcache"; -async function getCodeQLBundleDownloadURL(tagName, apiDetails, codeQLBundleName, logger2) { - const codeQLActionRepository = getCodeQLActionRepository({ - logger: logger2, - env: getEnv() - }); - const potentialDownloadSources = [ - // This GitHub instance, and this Action. - [apiDetails.url, codeQLActionRepository], - // This GitHub instance, and the canonical Action. - [apiDetails.url, CODEQL_DEFAULT_ACTION_REPOSITORY], - // GitHub.com, and the canonical Action. - [GITHUB_DOTCOM_URL, CODEQL_DEFAULT_ACTION_REPOSITORY] - ]; - const uniqueDownloadSources = potentialDownloadSources.filter( - (source, index2, self2) => { - return !self2.slice(0, index2).some((other) => (0, import_fast_deep_equal.default)(source, other)); - } - ); - for (const downloadSource of uniqueDownloadSources) { - const [apiURL, repository] = downloadSource; - if (apiURL === GITHUB_DOTCOM_URL && repository === CODEQL_DEFAULT_ACTION_REPOSITORY) { - break; - } - const [repositoryOwner, repositoryName] = repository.split("/"); - try { - const release2 = await getApiClient().rest.repos.getReleaseByTag({ - owner: repositoryOwner, - repo: repositoryName, - tag: tagName - }); - for (const asset of release2.data.assets) { - if (asset.name === codeQLBundleName) { - logger2.info( - `Found CodeQL bundle ${codeQLBundleName} in ${repository} on ${apiURL} with URL ${asset.url}.` - ); - return asset.url; - } - } - } catch (e) { - logger2.info( - `Looked for CodeQL bundle ${codeQLBundleName} in ${repository} on ${apiURL} but got error ${e}.` - ); - } - } - return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${codeQLBundleName}`; -} function tryGetBundleVersionFromTagName(tagName, logger2) { const match2 = tagName.match(/^codeql-bundle-(.+)$/); if (match2 === null || match2.length < 2) { @@ -176444,9 +176411,10 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, useO ); } compressionMethod = cliVersion2 !== void 0 && await useZstdBundle(cliVersion2, tarSupportsZstd) ? "zstd" : "gzip"; + const action = { env: getEnv(), logger: logger2 }; const platform2 = getBundlePlatform(); const perLanguageBundleLanguage = await getPerLanguageBundleLanguage( - { env: getEnv(), features, logger: logger2 }, + { ...action, features }, { rawLanguages, cliVersion: cliVersion2, @@ -176455,11 +176423,11 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, useO variant } ); - const resolveBundleURL = (language) => getCodeQLBundleDownloadURL( - bundleTagName, + const resolveBundleURL = (language) => getCodeQLAssetDownloadURL( + action, apiDetails, - getCodeQLBundleName(compressionMethod, platform2, language), - logger2 + bundleTagName, + getCodeQLBundleName(compressionMethod, platform2, language) ); const combinedBundleURL = await resolveBundleURL(); if (perLanguageBundleLanguage !== void 0) { @@ -182926,7 +182894,7 @@ var import_async = __toESM(require_async(), 1); var import_path7 = require("path"); // node_modules/archiver/lib/error.js -var import_util36 = __toESM(require("util"), 1); +var import_util37 = __toESM(require("util"), 1); var ERROR_CODES = { ABORTED: "archive was aborted", DIRECTORYDIRPATHREQUIRED: "diretory dirpath argument must be a non-empty string value", @@ -182951,7 +182919,7 @@ function ArchiverError(code, data) { this.code = code; this.data = data; } -import_util36.default.inherits(ArchiverError, Error); +import_util37.default.inherits(ArchiverError, Error); // node_modules/archiver/lib/core.js var import_readable_stream2 = __toESM(require_ours(), 1); diff --git a/package-lock.json b/package-lock.json index 27bf393bfd..8d3781fe5b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,6 @@ "@octokit/plugin-rest-endpoint-methods": "^18.0.0", "@octokit/plugin-retry": "^8.1.1", "archiver": "^8.0.0", - "fast-deep-equal": "^3.1.3", "follow-redirects": "^1.16.0", "get-folder-size": "^5.0.0", "https-proxy-agent": "^7.0.6", @@ -5817,6 +5816,7 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", + "dev": true, "license": "MIT" }, "node_modules/fast-diff": { diff --git a/package.json b/package.json index 5ebf14292b..52c11027f8 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,6 @@ "@octokit/plugin-rest-endpoint-methods": "^18.0.0", "@octokit/plugin-retry": "^8.1.1", "archiver": "^8.0.0", - "fast-deep-equal": "^3.1.3", "follow-redirects": "^1.16.0", "get-folder-size": "^5.0.0", "https-proxy-agent": "^7.0.6", diff --git a/src/setup-codeql.ts b/src/setup-codeql.ts index c97729471f..29a1809e4b 100644 --- a/src/setup-codeql.ts +++ b/src/setup-codeql.ts @@ -5,7 +5,6 @@ import { performance } from "perf_hooks"; import * as core from "@actions/core"; import * as toolcache from "@actions/tool-cache"; -import { default as deepEqual } from "fast-deep-equal"; import * as semver from "semver"; import { v4 as uuidV4 } from "uuid"; @@ -44,10 +43,7 @@ import { logPerLanguageBundleFallback, } from "./per-language-bundles"; import { getBundlePlatform } from "./platform"; -import { - CODEQL_DEFAULT_ACTION_REPOSITORY, - getCodeQLActionRepository, -} from "./setup/repository"; +import { getCodeQLAssetDownloadURL } from "./setup/repository"; import * as tar from "./tar"; import { deleteToolcacheBundles, @@ -76,64 +72,6 @@ const CODEQL_BUNDLE_VERSION_ALIAS: string[] = ["linked", "latest"]; const CODEQL_NIGHTLY_TOOLS_INPUTS = ["nightly", "nightly-latest"]; const CODEQL_TOOLCACHE_INPUT = "toolcache"; -async function getCodeQLBundleDownloadURL( - tagName: string, - apiDetails: api.GitHubApiDetails, - codeQLBundleName: string, - logger: Logger, -): Promise { - const codeQLActionRepository = getCodeQLActionRepository({ - logger, - env: getEnv(), - }); - const potentialDownloadSources = [ - // This GitHub instance, and this Action. - [apiDetails.url, codeQLActionRepository], - // This GitHub instance, and the canonical Action. - [apiDetails.url, CODEQL_DEFAULT_ACTION_REPOSITORY], - // GitHub.com, and the canonical Action. - [util.GITHUB_DOTCOM_URL, CODEQL_DEFAULT_ACTION_REPOSITORY], - ]; - // We now filter out any duplicates. - // Duplicates will happen either because the GitHub instance is GitHub.com, or because the Action is not a fork. - const uniqueDownloadSources = potentialDownloadSources.filter( - (source, index, self) => { - return !self.slice(0, index).some((other) => deepEqual(source, other)); - }, - ); - for (const downloadSource of uniqueDownloadSources) { - const [apiURL, repository] = downloadSource; - // If we've reached the final case, short-circuit the API check since we know the bundle exists and is public. - if ( - apiURL === util.GITHUB_DOTCOM_URL && - repository === CODEQL_DEFAULT_ACTION_REPOSITORY - ) { - break; - } - const [repositoryOwner, repositoryName] = repository.split("/"); - try { - const release = await api.getApiClient().rest.repos.getReleaseByTag({ - owner: repositoryOwner, - repo: repositoryName, - tag: tagName, - }); - for (const asset of release.data.assets) { - if (asset.name === codeQLBundleName) { - logger.info( - `Found CodeQL bundle ${codeQLBundleName} in ${repository} on ${apiURL} with URL ${asset.url}.`, - ); - return asset.url; - } - } - } catch (e) { - logger.info( - `Looked for CodeQL bundle ${codeQLBundleName} in ${repository} on ${apiURL} but got error ${e}.`, - ); - } - } - return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${codeQLBundleName}`; -} - function tryGetBundleVersionFromTagName( tagName: string, logger: Logger, @@ -707,9 +645,10 @@ export async function getCodeQLSource( ? "zstd" : "gzip"; + const action = { env: getEnv(), logger }; const platform = getBundlePlatform(); const perLanguageBundleLanguage = await getPerLanguageBundleLanguage( - { env: getEnv(), features, logger }, + { ...action, features }, { rawLanguages, cliVersion, @@ -721,11 +660,11 @@ export async function getCodeQLSource( // Resolves the combined or per-language bundle URL for the requested release. const resolveBundleURL = (language?: BuiltInLanguage) => - getCodeQLBundleDownloadURL( - bundleTagName, + getCodeQLAssetDownloadURL( + action, apiDetails, + bundleTagName, getCodeQLBundleName(compressionMethod, platform, language), - logger, ); const combinedBundleURL = await resolveBundleURL(); diff --git a/src/setup/repository.ts b/src/setup/repository.ts index c58470630b..53ca44f3e2 100644 --- a/src/setup/repository.ts +++ b/src/setup/repository.ts @@ -1,6 +1,8 @@ import { ActionState } from "../action-common"; import { isRunningLocalAction } from "../actions-util"; +import * as api from "../api-client"; import { ActionsEnvVars } from "../environment"; +import { GITHUB_DOTCOM_URL } from "../util"; /** The NWO of the standard CodeQL Action repository. */ export const CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action"; @@ -28,3 +30,100 @@ export function getCodeQLActionRepository( return action.env.getRequired(ActionsEnvVars.GITHUB_ACTION_REPOSITORY); } + +/**A download source is a pair of strings. */ +export type DownloadSource = [string, string]; + +/** GitHub.com, and the canonical Action. */ +export const DEFAULT_DOWNLOAD_SOURCE: DownloadSource = [ + GITHUB_DOTCOM_URL, + CODEQL_DEFAULT_ACTION_REPOSITORY, +]; + +/** Decides if the two provided download sources are the same. */ +const isSameDownloadSource = ( + [srcUrl, srcRepo]: DownloadSource, + [otherUrl, otherRepo]: DownloadSource, +) => { + return srcUrl === otherUrl && srcRepo === otherRepo; +}; + +/** A download URL is represented as a string. */ +export type DownloadURL = string; + +/** + * Tries to find a download URL for `assetName` in a release tagged with `tagName`. + * + * Depending on where and how the CodeQL Action is running, we may be using different `apiDetails` and there may be + * different options for where to source CodeQL releases from. + * + * This function either returns the download URL for the asset for the first release we find, or + * defaults to the assumed download URL for the asset on the default CodeQL Action repository on GitHub.com. + * In the latter case, this function does not guarantee that the asset actually exists. + * + * @param action The Action state. + * @param apiDetails The details of the GitHub API in use. + * @param tagName The name of the release tag we want to obtain the asset from. + * @param assetName The name of the asset we should look for in the release. + * @param [assetKind="CodeQL bundle"] The kind of asset we are looking for to show in log messages. + * @returns A URL that we can use to download the asset. + */ +export async function getCodeQLAssetDownloadURL( + action: ActionState<["ReadOnlyEnv", "Logger"]>, + apiDetails: api.GitHubApiDetails, + tagName: string, + assetName: string, + assetKind: "CodeQL bundle" = "CodeQL bundle", +): Promise { + const codeQLActionRepository = getCodeQLActionRepository(action); + + const potentialDownloadSources: Array<[string, string]> = [ + // This GitHub instance, and this Action. + [apiDetails.url, codeQLActionRepository], + // This GitHub instance, and the canonical Action. + [apiDetails.url, CODEQL_DEFAULT_ACTION_REPOSITORY], + // GitHub.com, and the canonical Action. + DEFAULT_DOWNLOAD_SOURCE, + ]; + + // We now filter out any duplicates. + // Duplicates will happen either because the GitHub instance is GitHub.com, or because the Action is not a fork. + const uniqueDownloadSources = potentialDownloadSources.filter( + (source, index, self) => { + return !self + .slice(0, index) + .some((other) => isSameDownloadSource(source, other)); + }, + ); + + for (const [apiURL, repository] of uniqueDownloadSources) { + // If we've reached the final case, short-circuit the API check since we know the bundle exists and is public. + if (isSameDownloadSource(DEFAULT_DOWNLOAD_SOURCE, [apiURL, repository])) { + break; + } + + const [repositoryOwner, repositoryName] = repository.split("/"); + try { + const release = await api.getApiClient().rest.repos.getReleaseByTag({ + owner: repositoryOwner, + repo: repositoryName, + tag: tagName, + }); + + for (const asset of release.data.assets) { + if (asset.name === assetName) { + action.logger.info( + `Found ${assetKind} ${assetName} in ${repository} on ${apiURL} with URL ${asset.url}.`, + ); + return asset.url; + } + } + } catch (e) { + action.logger.info( + `Looked for ${assetKind} ${assetName} in ${repository} on ${apiURL} but got error ${e}.`, + ); + } + } + + return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${assetName}`; +} From 35f12ded428e57cae1cfa0e0c84b789eb44a4fda Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 6 Oct 2026 16:10:21 +0100 Subject: [PATCH 014/107] Add utility for assertions on sinon stubs with better output by default --- src/testing-utils.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/testing-utils.ts b/src/testing-utils.ts index df81f51bb4..2b188857a9 100644 --- a/src/testing-utils.ts +++ b/src/testing-utils.ts @@ -163,6 +163,34 @@ export function setupTests(testFn: TestFn) { }); } +export interface AvaSinonAssertions { + /** + * Asserts that `stub` must have been called once with at least the `expected` arguments. + */ + onceWith: ( + stub: sinon.SinonStub, + ...expected: sinon.MatchPartialArguments + ) => boolean; +} + +/** Adds additional assertions for use with `sinon` to `t`. */ +export function addSinonAssertions( + t: ExecutionContext, +): ExecutionContext & AvaSinonAssertions { + return { + ...t, + onceWith: (stub, ...expected) => { + if (stub.callCount > 0) { + // Reduce the arguments of the first call to the same number that was provided, + // so that extra arguments don't lead to a failure. + return t.deepEqual(stub.args[0].slice(0, expected.length), expected); + } else { + return t.fail("The stub wasn't called."); + } + }, + }; +} + /** * Declare a reusable test implementation, with better type safety than `test.macro`. */ From a4f9f6fc121605c2b77d8dd9d562eb148dba7c13 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 6 Oct 2026 16:11:27 +0100 Subject: [PATCH 015/107] Type the `assetKind` parameter --- src/setup/repository.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/setup/repository.ts b/src/setup/repository.ts index 53ca44f3e2..4101be6770 100644 --- a/src/setup/repository.ts +++ b/src/setup/repository.ts @@ -51,6 +51,9 @@ const isSameDownloadSource = ( /** A download URL is represented as a string. */ export type DownloadURL = string; +/** Enumerates log-friendly descriptions of different kinds of assets we might look for in releases. */ +export type ReleaseAssetKind = "CodeQL bundle" | "private registry proxy"; + /** * Tries to find a download URL for `assetName` in a release tagged with `tagName`. * @@ -73,7 +76,7 @@ export async function getCodeQLAssetDownloadURL( apiDetails: api.GitHubApiDetails, tagName: string, assetName: string, - assetKind: "CodeQL bundle" = "CodeQL bundle", + assetKind: ReleaseAssetKind = "CodeQL bundle", ): Promise { const codeQLActionRepository = getCodeQLActionRepository(action); From de99f0ee4b789bac85c60c23cf5617af3a93e08f Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 6 Oct 2026 16:30:20 +0100 Subject: [PATCH 016/107] Add `getDefaultDotComDownloadURL` --- lib/entry-points.js | 5 ++++- src/setup/repository.ts | 10 +++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 71b6915a9c..49d38c393f 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -175616,6 +175616,9 @@ var DEFAULT_DOWNLOAD_SOURCE = [ var isSameDownloadSource = ([srcUrl, srcRepo], [otherUrl, otherRepo]) => { return srcUrl === otherUrl && srcRepo === otherRepo; }; +function getDefaultDotComDownloadURL(tagName, assetName) { + return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${assetName}`; +} async function getCodeQLAssetDownloadURL(action, apiDetails, tagName, assetName, assetKind = "CodeQL bundle") { const codeQLActionRepository = getCodeQLActionRepository(action); const potentialDownloadSources = [ @@ -175656,7 +175659,7 @@ async function getCodeQLAssetDownloadURL(action, apiDetails, tagName, assetName, ); } } - return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${assetName}`; + return getDefaultDotComDownloadURL(tagName, assetName); } // src/tar.ts diff --git a/src/setup/repository.ts b/src/setup/repository.ts index 4101be6770..3d760858e7 100644 --- a/src/setup/repository.ts +++ b/src/setup/repository.ts @@ -51,6 +51,14 @@ const isSameDownloadSource = ( /** A download URL is represented as a string. */ export type DownloadURL = string; +/** Gets the default GitHub.com download URL for `assetName` in a release tagged `tagName`. */ +export function getDefaultDotComDownloadURL( + tagName: string, + assetName: string, +): DownloadURL { + return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${assetName}`; +} + /** Enumerates log-friendly descriptions of different kinds of assets we might look for in releases. */ export type ReleaseAssetKind = "CodeQL bundle" | "private registry proxy"; @@ -128,5 +136,5 @@ export async function getCodeQLAssetDownloadURL( } } - return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${assetName}`; + return getDefaultDotComDownloadURL(tagName, assetName); } From 133ffebe62eccf0a18bf2fa6f884063a7fd6ff7d Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 6 Oct 2026 16:13:32 +0100 Subject: [PATCH 017/107] Use `getCodeQLAssetDownloadURL` for `start-proxy` --- lib/entry-points.js | 62 +++++--------- src/start-proxy-action.ts | 7 +- src/start-proxy.test.ts | 173 +++++++++++++++++++++++++------------- src/start-proxy.ts | 82 +++++------------- 4 files changed, 166 insertions(+), 158 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 49d38c393f..84c57c813b 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -187489,8 +187489,6 @@ async function sendFailedStatusReport(logger2, startedAt, language, unwrappedErr } } var UPDATEJOB_PROXY = "update-job-proxy"; -var UPDATEJOB_PROXY_VERSION = "v2.0.20250624110901"; -var UPDATEJOB_PROXY_URL_PREFIX = "https://github.com/github/codeql-action/releases/download/codeql-bundle-v2.22.0/"; function isPAT(value) { return isAuthToken(value, [ GITHUB_PAT_CLASSIC_PATTERN, @@ -187608,21 +187606,11 @@ function getCredentials(logger2, registrySecrets, registriesCredentials, languag function getProxyPackage(platform2) { return `${UPDATEJOB_PROXY}-${platform2}.tar.gz`; } -function getFallbackUrl(proxyPackage) { - return `${UPDATEJOB_PROXY_URL_PREFIX}${proxyPackage}`; -} -async function getReleaseByVersion(version) { - return getApiClient().rest.repos.getReleaseByTag({ - owner: "github", - repo: "codeql-action", - tag: version - }); -} async function getCliVersionFromFeatures(features) { const gitHubVersion = await getGitHubVersion(); return await features.getEnabledDefaultCliVersions(gitHubVersion.type); } -async function getDownloadUrl(action) { +async function getDownloadUrl(action, apiDetails) { let platform2 = getBundlePlatform(action.platform, action.arch); if (platform2 === void 0) { action.logger.warning( @@ -187639,33 +187627,25 @@ async function getDownloadUrl(action) { cliVersion, tagName: bundleVersion }; - const cliRelease = await getReleaseByVersion(versionInfo.tagName); - for (const asset of cliRelease.data.assets) { - if (asset.name === proxyPackage) { - action.logger.info( - `Found '${proxyPackage}' in release '${versionInfo.tagName}' at '${asset.url}'` - ); - return { - url: asset.url, - // The `update-job-proxy` doesn't have a version as such. Since we now bundle it - // with CodeQL CLI bundle releases, we use the corresponding CLI version to - // differentiate between (potentially) different versions of `update-job-proxy`. - version: versionInfo.cliVersion - }; - } - } + const proxyAssetUrl = await getCodeQLAssetDownloadURL( + action, + apiDetails, + versionInfo.tagName, + proxyPackage, + "private registry proxy" + ); + return { + url: proxyAssetUrl, + // The `update-job-proxy` doesn't have a version as such. Since we now bundle it + // with CodeQL CLI bundle releases, we use the corresponding CLI version to + // differentiate between (potentially) different versions of `update-job-proxy`. + version: versionInfo.cliVersion + }; } catch (ex) { - action.logger.warning( + throw new Error( `Failed to retrieve information about the linked release: ${getErrorMessage(ex)}` ); } - action.logger.info( - `Did not find '${proxyPackage}' in the linked release, falling back to hard-coded version.` - ); - return { - url: getFallbackUrl(proxyPackage), - version: UPDATEJOB_PROXY_VERSION - }; } async function downloadProxy(logger2, url2, authorization) { try { @@ -187708,13 +187688,12 @@ async function cacheProxy(logger2, source, filename, version) { function getProxyFilename() { return process.platform === "win32" ? `${UPDATEJOB_PROXY}.exe` : UPDATEJOB_PROXY; } -async function getProxyBinaryPath(action) { +async function getProxyBinaryPath(action, apiDetails) { const logger2 = action.logger; const proxyFileName = getProxyFilename(); - const proxyInfo = await getDownloadUrl(action); + const proxyInfo = await getDownloadUrl(action, apiDetails); let proxyBin = toolcache4.find(proxyFileName, proxyInfo.version); if (!proxyBin) { - const apiDetails = getApiDetails(); const authorization = getAuthorizationHeaderFor( logger2, apiDetails, @@ -188091,7 +188070,10 @@ async function run7(action) { all_credentials: credentials, ca }; - const proxyBin = await getProxyBinaryPath({ ...action, features }); + const proxyBin = await getProxyBinaryPath( + { ...action, features }, + getApiDetails(action.env) + ); const proxyInfo = await startProxy( proxyBin, proxyConfig, diff --git a/src/start-proxy-action.ts b/src/start-proxy-action.ts index d965a2dd6b..b9c7795ef1 100644 --- a/src/start-proxy-action.ts +++ b/src/start-proxy-action.ts @@ -5,7 +5,7 @@ import * as core from "@actions/core"; import { Action, ActionState, runInActions } from "./action-common"; import * as actionsUtil from "./actions-util"; -import { getGitHubVersion } from "./api-client"; +import { getApiDetails, getGitHubVersion } from "./api-client"; import { FeatureEnablement, initFeatures } from "./feature-flags"; import { BuiltInLanguage, parseBuiltInLanguage } from "./languages"; import { Logger } from "./logging"; @@ -98,7 +98,10 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) { }; // Start the Proxy - const proxyBin = await getProxyBinaryPath({ ...action, features }); + const proxyBin = await getProxyBinaryPath( + { ...action, features }, + getApiDetails(action.env), + ); const proxyInfo = await startProxy( proxyBin, proxyConfig, diff --git a/src/start-proxy.test.ts b/src/start-proxy.test.ts index bd24897136..b0bdd7bd33 100644 --- a/src/start-proxy.test.ts +++ b/src/start-proxy.test.ts @@ -6,17 +6,21 @@ import test, { ExecutionContext } from "ava"; import sinon from "sinon"; import { ActionState } from "./action-common"; +import * as actionsUtil from "./actions-util"; import * as apiClient from "./api-client"; import * as defaults from "./defaults.json"; +import { ActionsEnvVars } from "./environment"; import { setUpFeatureFlagTests } from "./feature-flags/testing-util"; import { UnvalidatedObject, validateSchema } from "./json"; import { makeFromSchema } from "./json/testing-util"; import { BuiltInLanguage } from "./languages"; import { getRunnerLogger, Logger } from "./logging"; import { BundlePlatform, getBundlePlatform } from "./platform"; +import * as repository from "./setup/repository"; import * as startProxyExports from "./start-proxy"; import * as statusReport from "./status-report"; import { + addSinonAssertions, assertNotLogged, checkExpectedLogMessages, createFeatures, @@ -24,6 +28,7 @@ import { makeMacro, makeTestToken, RecordingLogger, + SAMPLE_DOTCOM_API_DETAILS, setupTests, withRecordingLoggerAsync, } from "./testing-utils"; @@ -705,15 +710,23 @@ function mockGetApiClient(endpoints: any) { type ReleaseAssets = Array<{ name: string; url?: string }>; -function mockGetReleaseByTag(assets?: ReleaseAssets) { +function mockGetReleaseByTag(expectedTag?: string, assets?: ReleaseAssets) { const getReleaseByTag = assets === undefined ? sinon.stub().rejects() - : sinon.stub().resolves({ - status: 200, - data: { assets }, - headers: {}, - url: "GET /repos/:owner/:repo/releases/tags/:tag", + : sinon.stub().callsFake(({ tag }) => { + if (tag === expectedTag) { + return { + status: 200, + data: { assets }, + headers: {}, + url: "GET /repos/:owner/:repo/releases/tags/:tag", + }; + } else { + return { + status: 404, + }; + } }); return mockGetApiClient({ repos: { getReleaseByTag } }); @@ -751,25 +764,33 @@ test.serial( logger, features, }); - const info = await startProxyExports.getDownloadUrl(state); - t.is(info.version, startProxyExports.UPDATEJOB_PROXY_VERSION); - t.is( - info.url, - startProxyExports.getFallbackUrl( - startProxyExports.getProxyPackage(BundlePlatform.Linux64), - ), + // Stub this to always return `true` so we get the default repo for the tests. + sinon.stub(actionsUtil, "isRunningLocalAction").returns(true); + + const info = await startProxyExports.getDownloadUrl( + state, + SAMPLE_DOTCOM_API_DETAILS, ); t.true( logger.hasMessage(`Unsupported platform android on architecture ppc`), ); + + t.is(info.version, defaults.cliVersion); + t.is( + info.url, + repository.getDefaultDotComDownloadURL( + defaults.bundleVersion, + startProxyExports.getProxyPackage(BundlePlatform.Linux64), + ), + ); }); }, ); test.serial( - "getDownloadUrl returns fallback when `getReleaseByVersion` rejects", + "getDownloadUrl returns default bundle URL for linked version", async (t) => { const logger = new RecordingLogger(); mockGetReleaseByTag(); @@ -777,12 +798,20 @@ test.serial( await withTmpDir(async (tempDir) => { const features = mockOfflineFeatures(tempDir, logger); const state = initAllState({ logger, features }); - const info = await startProxyExports.getDownloadUrl(state); - t.is(info.version, startProxyExports.UPDATEJOB_PROXY_VERSION); + // Stub this to always return `true` so we get the default repo for the tests. + sinon.stub(actionsUtil, "isRunningLocalAction").returns(true); + + const info = await startProxyExports.getDownloadUrl( + state, + SAMPLE_DOTCOM_API_DETAILS, + ); + + t.is(info.version, defaults.cliVersion); t.is( info.url, - startProxyExports.getFallbackUrl( + repository.getDefaultDotComDownloadURL( + defaults.bundleVersion, startProxyExports.getProxyPackage(getTestPlatform(state)), ), ); @@ -791,7 +820,7 @@ test.serial( ); test.serial( - "getDownloadUrl returns fallback when there's no matching release asset", + "getDownloadUrl doesn't check that the default asset exists", async (t) => { const logger = new RecordingLogger(); const testAssets = [[], [{ name: "foo" }]]; @@ -800,14 +829,21 @@ test.serial( const features = mockOfflineFeatures(tempDir, logger); const state = initAllState({ logger, features }); + // Stub this to always return `true` so we get the default repo for the tests. + sinon.stub(actionsUtil, "isRunningLocalAction").returns(true); + for (const assets of testAssets) { - const stub = mockGetReleaseByTag(assets); - const info = await startProxyExports.getDownloadUrl(state); + const stub = mockGetReleaseByTag(defaults.bundleVersion, assets); + const info = await startProxyExports.getDownloadUrl( + state, + SAMPLE_DOTCOM_API_DETAILS, + ); - t.is(info.version, startProxyExports.UPDATEJOB_PROXY_VERSION); + t.is(info.version, defaults.cliVersion); t.is( info.url, - startProxyExports.getFallbackUrl( + repository.getDefaultDotComDownloadURL( + defaults.bundleVersion, startProxyExports.getProxyPackage(getTestPlatform(state)), ), ); @@ -828,11 +864,22 @@ test.serial("getDownloadUrl returns matching release asset", async (t) => { url: "url-we-want", }, ]; - mockGetReleaseByTag(assets); + const getReleaseByTag = mockGetReleaseByTag(defaults.bundleVersion, assets); await withTmpDir(async (tempDir) => { + state.env.set(ActionsEnvVars.RUNNER_TEMP, tempDir); const features = mockOfflineFeatures(tempDir, logger); - const info = await startProxyExports.getDownloadUrl({ ...state, features }); + + // Stub this to always return `false` so we force `getCodeQLAssetDownloadURL` to use the (mocked) API. + sinon.stub(actionsUtil, "isRunningLocalAction").returns(false); + state.env.set(ActionsEnvVars.GITHUB_ACTION_REPOSITORY, "test/repo"); + + const info = await startProxyExports.getDownloadUrl( + { ...state, features }, + SAMPLE_DOTCOM_API_DETAILS, + ); + + t.is(getReleaseByTag.callCount, 1); t.is(info.version, defaults.cliVersion); t.is(info.url, "url-we-want"); @@ -965,9 +1012,13 @@ test.serial( const toolcachePath = "/path/to/proxy/dir"; sinon.stub(toolcache, "find").returns(toolcachePath); + // Stub this to always return `true` so we get the default repo for the tests. + sinon.stub(actionsUtil, "isRunningLocalAction").returns(true); + const features = mockOfflineFeatures(tempDir, logger); const path = await startProxyExports.getProxyBinaryPath( initAllState({ logger, features }), + SAMPLE_DOTCOM_API_DETAILS, ); t.assert(path); @@ -985,7 +1036,7 @@ test.serial( const logger = new RecordingLogger(); const state = initAllState({ logger }); const downloadUrl = "url-we-want"; - mockGetReleaseByTag([ + const getApiClient = mockGetReleaseByTag(defaults.bundleVersion, [ { name: startProxyExports.getProxyPackage(getTestPlatform(state)), url: downloadUrl, @@ -994,11 +1045,6 @@ test.serial( const toolcachePath = "/path/to/proxy/dir"; const find = sinon.stub(toolcache, "find").returns(""); - const getApiDetails = sinon.stub(apiClient, "getApiDetails").returns({ - auth: "", - url: "", - apiURL: "", - }); const getAuthorizationHeaderFor = sinon .stub(apiClient, "getAuthorizationHeaderFor") .returns(undefined); @@ -1012,15 +1058,27 @@ test.serial( .resolves(extractedPath); const cacheDir = sinon.stub(toolcache, "cacheDir").resolves(toolcachePath); - const path = await startProxyExports.getProxyBinaryPath({ - ...state, - features: createFeatures([]), - }); + // Stub this to always return `false` so we force `getCodeQLAssetDownloadURL` to use the (mocked) API. + sinon.stub(actionsUtil, "isRunningLocalAction").returns(false); + state.env.set(ActionsEnvVars.GITHUB_ACTION_REPOSITORY, "test/repo"); + const path = await startProxyExports.getProxyBinaryPath( + { + ...state, + features: createFeatures([]), + }, + SAMPLE_DOTCOM_API_DETAILS, + ); + + t.is(getApiClient.callCount, 1); t.assert(find.calledOnce); - t.assert(getApiDetails.calledOnce); t.assert(getAuthorizationHeaderFor.calledOnce); - t.assert(downloadTool.calledOnceWith(downloadUrl)); + + const st = addSinonAssertions(t); + st.onceWith(downloadTool, downloadUrl); + st.onceWith(extractTar, archivePath); + st.onceWith(cacheDir, extractedPath); + t.assert(extractTar.calledOnceWith(archivePath)); t.assert(cacheDir.calledOnceWith(extractedPath)); t.assert(path); @@ -1030,7 +1088,7 @@ test.serial( ); checkExpectedLogMessages(t, logger.messages, [ - `Found '${startProxyExports.getProxyPackage(getTestPlatform(state))}' in release '${defaults.bundleVersion}' at '${downloadUrl}'`, + `Found private registry proxy ${startProxyExports.getProxyPackage(getTestPlatform(state))} in test/repo on https://github.com with URL ${downloadUrl}`, ]); }, ); @@ -1042,8 +1100,8 @@ test.serial( const state = initAllState({ logger }); const expectedTag = "codeql-bundle-v2.20.1"; const expectedParams = { - owner: "github", - repo: "codeql-action", + owner: "test", + repo: "repo", tag: expectedTag, }; const downloadUrl = "url-we-want"; @@ -1066,11 +1124,6 @@ test.serial( await withTmpDir(async (tempDir) => { const toolcachePath = "/path/to/proxy/dir"; const find = sinon.stub(toolcache, "find").returns(""); - const getApiDetails = sinon.stub(apiClient, "getApiDetails").returns({ - auth: "", - url: "", - apiURL: "", - }); const getAuthorizationHeaderFor = sinon .stub(apiClient, "getAuthorizationHeaderFor") .returns(undefined); @@ -1100,22 +1153,28 @@ test.serial( .resolves({ enabledVersions: [{ cliVersion: "2.20.1", tagName: expectedTag }], }); - const path = await startProxyExports.getProxyBinaryPath({ - ...state, - features, - }); - t.assert(getDefaultCliVersion.calledOnce); - sinon.assert.calledOnceWithMatch( - getReleaseByTag, - sinon.match(expectedParams), + // Stub this to always return `false` so we force `getCodeQLAssetDownloadURL` to use the (mocked) API. + sinon.stub(actionsUtil, "isRunningLocalAction").returns(false); + state.env.set(ActionsEnvVars.GITHUB_ACTION_REPOSITORY, "test/repo"); + + const path = await startProxyExports.getProxyBinaryPath( + { + ...state, + features, + }, + SAMPLE_DOTCOM_API_DETAILS, ); + + t.assert(getDefaultCliVersion.calledOnce); + + const st = addSinonAssertions(t); + st.onceWith(getReleaseByTag, expectedParams); t.assert(find.calledOnce); - t.assert(getApiDetails.calledOnce); t.assert(getAuthorizationHeaderFor.calledOnce); - t.assert(downloadTool.calledOnceWith(downloadUrl)); - t.assert(extractTar.calledOnceWith(archivePath)); - t.assert(cacheDir.calledOnceWith(extractedPath)); + st.onceWith(downloadTool, downloadUrl); + st.onceWith(extractTar, archivePath); + st.onceWith(cacheDir, extractedPath); t.assert(path); t.is( @@ -1125,7 +1184,7 @@ test.serial( }); checkExpectedLogMessages(t, logger.messages, [ - `Found '${startProxyExports.getProxyPackage(getTestPlatform(state))}' in release '${expectedTag}' at '${downloadUrl}'`, + `Found private registry proxy ${startProxyExports.getProxyPackage(getTestPlatform(state))} in test/repo on https://github.com with URL url-we-want.`, ]); }, ); diff --git a/src/start-proxy.ts b/src/start-proxy.ts index 6221c9940f..9558b119ee 100644 --- a/src/start-proxy.ts +++ b/src/start-proxy.ts @@ -5,10 +5,9 @@ import * as toolcache from "@actions/tool-cache"; import { ActionState } from "./action-common"; import { - getApiClient, - getApiDetails, getAuthorizationHeaderFor, getGitHubVersion, + GitHubApiDetails, } from "./api-client"; import * as artifactScanner from "./artifact-scanner"; import { Config } from "./config-utils"; @@ -22,6 +21,7 @@ import * as json from "./json"; import { BuiltInLanguage } from "./languages"; import { Logger } from "./logging"; import { BundlePlatform, getBundlePlatform } from "./platform"; +import { getCodeQLAssetDownloadURL } from "./setup/repository"; import { Address, Registry, @@ -171,10 +171,8 @@ export async function sendFailedStatusReport( } } +/** The basename of the proxy artifacts. */ export const UPDATEJOB_PROXY = "update-job-proxy"; -export const UPDATEJOB_PROXY_VERSION = "v2.0.20250624110901"; -const UPDATEJOB_PROXY_URL_PREFIX = - "https://github.com/github/codeql-action/releases/download/codeql-bundle-v2.22.0/"; function isPAT(value: string) { return artifactScanner.isAuthToken(value, [ @@ -379,30 +377,6 @@ export function getProxyPackage(platform: BundlePlatform): string { return `${UPDATEJOB_PROXY}-${platform}.tar.gz`; } -/** - * Gets the fallback URL for downloading the proxy release asset. - * - * @param proxyPackage The asset name. - * @returns The full URL to download the specified asset from the fallback release. - */ -export function getFallbackUrl(proxyPackage: string): string { - return `${UPDATEJOB_PROXY_URL_PREFIX}${proxyPackage}`; -} - -/** - * Uses the GitHub API to obtain information about the CodeQL CLI bundle release - * that is tagged by `version`. - * - * @returns The response from the GitHub API. - */ -async function getReleaseByVersion(version: string) { - return getApiClient().rest.repos.getReleaseByTag({ - owner: "github", - repo: "codeql-action", - tag: version, - }); -} - /** Uses `features` to determine the default CLI version. */ async function getCliVersionFromFeatures( features: FeatureEnablement, @@ -419,7 +393,8 @@ async function getCliVersionFromFeatures( * @returns Returns the download URL and version of the proxy package we plan to use. */ export async function getDownloadUrl( - action: ActionState<["Base", "Logger", "FeatureFlags"]>, + action: ActionState<["Base", "ReadOnlyEnv", "Logger", "FeatureFlags"]>, + apiDetails: GitHubApiDetails, ): Promise<{ url: string; version: string }> { // Default to linux64 if we don't recognise the platform+arch pair. // This maintains the behaviour we had before switching to `getBundlePlatform` here. @@ -448,37 +423,26 @@ export async function getDownloadUrl( }; // Try to retrieve information about the CLI bundle release identified by `versionInfo`. - const cliRelease = await getReleaseByVersion(versionInfo.tagName); + const proxyAssetUrl = await getCodeQLAssetDownloadURL( + action, + apiDetails, + versionInfo.tagName, + proxyPackage, + "private registry proxy", + ); - // Search the release's assets to find the one we are looking for. - for (const asset of cliRelease.data.assets) { - if (asset.name === proxyPackage) { - action.logger.info( - `Found '${proxyPackage}' in release '${versionInfo.tagName}' at '${asset.url}'`, - ); - return { - url: asset.url, - // The `update-job-proxy` doesn't have a version as such. Since we now bundle it - // with CodeQL CLI bundle releases, we use the corresponding CLI version to - // differentiate between (potentially) different versions of `update-job-proxy`. - version: versionInfo.cliVersion, - }; - } - } + return { + url: proxyAssetUrl, + // The `update-job-proxy` doesn't have a version as such. Since we now bundle it + // with CodeQL CLI bundle releases, we use the corresponding CLI version to + // differentiate between (potentially) different versions of `update-job-proxy`. + version: versionInfo.cliVersion, + }; } catch (ex) { - action.logger.warning( + throw new Error( `Failed to retrieve information about the linked release: ${getErrorMessage(ex)}`, ); } - - // Fallback to the hard-coded URL. - action.logger.info( - `Did not find '${proxyPackage}' in the linked release, falling back to hard-coded version.`, - ); - return { - url: getFallbackUrl(proxyPackage), - version: UPDATEJOB_PROXY_VERSION, - }; } /** @@ -569,15 +533,15 @@ export function getProxyFilename() { * @returns The path to the proxy binary. */ export async function getProxyBinaryPath( - action: ActionState<["Base", "Logger", "FeatureFlags"]>, + action: ActionState<["Base", "ReadOnlyEnv", "Logger", "FeatureFlags"]>, + apiDetails: GitHubApiDetails, ): Promise { const logger = action.logger; const proxyFileName = getProxyFilename(); - const proxyInfo = await getDownloadUrl(action); + const proxyInfo = await getDownloadUrl(action, apiDetails); let proxyBin = toolcache.find(proxyFileName, proxyInfo.version); if (!proxyBin) { - const apiDetails = getApiDetails(); const authorization = getAuthorizationHeaderFor( logger, apiDetails, From f9a9962aa30c39b96d0879722aeb8c3fb5bb9bbf Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 6 Oct 2026 17:26:09 +0100 Subject: [PATCH 018/107] Fix `onceWith` not asserting the `once` part --- src/testing-utils.ts | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/testing-utils.ts b/src/testing-utils.ts index 2b188857a9..4e8d175200 100644 --- a/src/testing-utils.ts +++ b/src/testing-utils.ts @@ -179,13 +179,25 @@ export function addSinonAssertions( ): ExecutionContext & AvaSinonAssertions { return { ...t, - onceWith: (stub, ...expected) => { - if (stub.callCount > 0) { - // Reduce the arguments of the first call to the same number that was provided, - // so that extra arguments don't lead to a failure. - return t.deepEqual(stub.args[0].slice(0, expected.length), expected); + onceWith: ( + stub: sinon.SinonStub, + ...expected: sinon.MatchPartialArguments + ) => { + // Fail if the stub hasn't been called at all so that we can safely compare + // the arguments of the first call in the else branch. + if (stub.callCount === 0) { + t.fail("The stub wasn't called."); } else { - return t.fail("The stub wasn't called."); + // Reduce the arguments of each to the same number that was provided, + // so that extra arguments don't lead to a failure. + const actual = stub.args.map>( + (args: TArgs) => + args.slice( + 0, + expected.length, + ) as sinon.MatchPartialArguments, + ); + return t.deepEqual(actual, [expected]); } }, }; From 9a9f454be59475b0d0e8b38c4ededb813cd423da Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Tue, 6 Oct 2026 10:47:23 -0500 Subject: [PATCH 019/107] Hoist core of `changenotes.mts assemble` into own function --- pr-checks/changenotes.ts | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/pr-checks/changenotes.ts b/pr-checks/changenotes.ts index 933d255cd5..a5888a4114 100755 --- a/pr-checks/changenotes.ts +++ b/pr-checks/changenotes.ts @@ -50,6 +50,28 @@ function getChangenotes(): ChangenoteFile[] { }); } +/** + * Populates the '[UNRELEASED]' section of CHANGELOG.md with the contents + * of the changenotes in {@link CHANGENOTES_DIR} and then deletes those changenotes. + * @param contents The contents of CHANGELOG.md + * @returns The updated contents of CHANGELOG.md + */ +export function transferChangenotesToChangelog(contents: string): string { + const changenotes = getChangenotes(); + const changenoteBodies = changenotes.map((c) => c.content); + const changenotePaths = changenotes.map((c) => c.absolutePath); + + const changelog = parseChangelog(contents); + addBodyLinesToUnreleasedSection(changelog, changenoteBodies); + const updatedChangelog = renderChangelog(changelog); + + for (const p of changenotePaths) { + fs.unlinkSync(p); + } + + return updatedChangelog; +} + const entryPoint = process.argv[1]; if (entryPoint && import.meta.url === pathToFileURL(entryPoint).href) { try { @@ -91,26 +113,13 @@ function usage(): ExitCode { function assemble(): ExitCode { try { - const changenotes = getChangenotes(); - const changenoteBodies = changenotes.map((c) => c.content); - const changenotePaths = changenotes.map((c) => c.absolutePath); - withChangelog((contents) => { - const changelog = parseChangelog(contents); - addBodyLinesToUnreleasedSection(changelog, changenoteBodies); - return renderChangelog(changelog); + return transferChangenotesToChangelog(contents); }, {}); - - // Delete changenotes only after successful processing. - for (const p of changenotePaths) { - fs.unlinkSync(p); - } - return ExitCode.Success; } catch (e) { console.error("Failed to assemble changenotes to 'CHANGELOG.md'", e); } - return ExitCode.Failure; } From fb4048e3e76e624a364b1f97ca4017bd9d92d626 Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Tue, 6 Oct 2026 10:51:08 -0500 Subject: [PATCH 020/107] Transfer change-notes to CHANGELOG.md via update-release-branch.ts --- pr-checks/update-release-branch.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pr-checks/update-release-branch.ts b/pr-checks/update-release-branch.ts index 93e50f7ad2..736e95b618 100755 --- a/pr-checks/update-release-branch.ts +++ b/pr-checks/update-release-branch.ts @@ -23,6 +23,7 @@ import { parseArgs } from "node:util"; import { type ApiClient, getApiClient } from "./api-client"; import * as changelog from "./changelog"; +import { transferChangenotesToChangelog } from "./changenotes"; import { DryRunOption, REPO_ROOT } from "./config"; import { getCurrentVersion, @@ -693,7 +694,10 @@ export async function prepareNewBranch( console.log("Updating changelog"); changelog.withChangelog( - (contents) => changelog.setVersionAndDate(version, contents), + (contents) => { + const populatedContents = transferChangenotesToChangelog(contents); + return changelog.setVersionAndDate(version, populatedContents); + }, { ...options, initChangelog: true }, ); From badda692f46e206a8144c3017fb33d8417b31cc6 Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Tue, 6 Oct 2026 12:16:16 -0500 Subject: [PATCH 021/107] Trim whitespace of change-notes before insertion --- pr-checks/changenotes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pr-checks/changenotes.ts b/pr-checks/changenotes.ts index a5888a4114..d05f4ea892 100755 --- a/pr-checks/changenotes.ts +++ b/pr-checks/changenotes.ts @@ -58,7 +58,7 @@ function getChangenotes(): ChangenoteFile[] { */ export function transferChangenotesToChangelog(contents: string): string { const changenotes = getChangenotes(); - const changenoteBodies = changenotes.map((c) => c.content); + const changenoteBodies = changenotes.map((c) => c.content.trim()); const changenotePaths = changenotes.map((c) => c.absolutePath); const changelog = parseChangelog(contents); From 0f6901c9a809585a1989e73114ffc5f81a356445 Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Tue, 6 Oct 2026 13:52:08 -0500 Subject: [PATCH 022/107] Commit change-note deletions --- pr-checks/update-release-branch.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pr-checks/update-release-branch.ts b/pr-checks/update-release-branch.ts index 736e95b618..d6d50f6287 100755 --- a/pr-checks/update-release-branch.ts +++ b/pr-checks/update-release-branch.ts @@ -701,7 +701,7 @@ export async function prepareNewBranch( { ...options, initChangelog: true }, ); - runGit(["add", "CHANGELOG.md"], { + runGit(["add", "CHANGELOG.md", "unreleased-change-notes"], { dryRun: options.dryRun, }); runGit(["commit", "-m", `Update changelog for v${version}`], { From aae22cc693c64bb85f59e3376879149e16e6889c Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Tue, 6 Oct 2026 14:50:28 -0500 Subject: [PATCH 023/107] Use config vars over hardcoded literals --- pr-checks/update-release-branch.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pr-checks/update-release-branch.ts b/pr-checks/update-release-branch.ts index d6d50f6287..9d46fd3ecd 100755 --- a/pr-checks/update-release-branch.ts +++ b/pr-checks/update-release-branch.ts @@ -24,7 +24,12 @@ import { parseArgs } from "node:util"; import { type ApiClient, getApiClient } from "./api-client"; import * as changelog from "./changelog"; import { transferChangenotesToChangelog } from "./changenotes"; -import { DryRunOption, REPO_ROOT } from "./config"; +import { + CHANGELOG_FILE, + CHANGENOTES_DIR, + DryRunOption, + REPO_ROOT, +} from "./config"; import { getCurrentVersion, replaceVersionInPackageJson, @@ -701,7 +706,7 @@ export async function prepareNewBranch( { ...options, initChangelog: true }, ); - runGit(["add", "CHANGELOG.md", "unreleased-change-notes"], { + runGit(["add", CHANGELOG_FILE, CHANGENOTES_DIR], { dryRun: options.dryRun, }); runGit(["commit", "-m", `Update changelog for v${version}`], { From 772ffcd99900db4f9e34cf418500c4b823d48464 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 6 Oct 2026 10:58:36 +0100 Subject: [PATCH 024/107] Bump minimum CodeQL CLI version to 2.20.7 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- CHANGELOG.md | 1 + lib/entry-points.js | 2 +- src/codeql.ts | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8bc73a5ff..e0a72fae33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th - _Upcoming breaking change_: CodeQL version 2.21.2 and earlier were discontinued on 24 September 2026 alongside GitHub Enterprise Server 3.17, and will be unsupported by the next minor release of the CodeQL Action. Added a deprecation warning for customers using these versions of CodeQL. [#4188](https://github.com/github/codeql-action/pull/4188) - Update default CodeQL bundle version to [2.27.2](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.27.2). [#4203](https://github.com/github/codeql-action/pull/4203) +- _Breaking change_: Bump the minimum required CodeQL bundle version to 2.20.7. [#XXXX](https://github.com/github/codeql-action/pull/XXXX) ## 4.38.2 - 24 Sept 2026 diff --git a/lib/entry-points.js b/lib/entry-points.js index 93084ea9be..2702988bc9 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -176872,7 +176872,7 @@ async function getCombinedTracerConfig(logger2, codeql, config) { // src/codeql.ts var cachedCodeQL = void 0; -var CODEQL_MINIMUM_VERSION = "2.19.4"; +var CODEQL_MINIMUM_VERSION = "2.20.7"; var CODEQL_NEXT_MINIMUM_VERSION = "2.21.3"; var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.17"; var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-09-24"; diff --git a/src/codeql.ts b/src/codeql.ts index 4d4e4a091d..f8231e44bb 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -253,7 +253,7 @@ let cachedCodeQL: CodeQL | undefined = undefined; * The version flags below can be used to conditionally enable certain features * on versions newer than this. */ -const CODEQL_MINIMUM_VERSION = "2.19.4"; +const CODEQL_MINIMUM_VERSION = "2.20.7"; /** * This version will shortly become the oldest version of CodeQL that the Action will run with. From 05d28f2f71f50affc8ed18ad2fed8afc86ebb401 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 6 Oct 2026 10:58:50 +0100 Subject: [PATCH 025/107] Bump version to 4.39.0 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- lib/entry-points.js | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 2702988bc9..00a0da96b2 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -170143,7 +170143,7 @@ function getDiffRangesJsonFilePath(env = getEnv()) { return path2.join(getTemporaryDirectory(env), PR_DIFF_RANGE_JSON_FILENAME); } function getActionVersion() { - return "4.38.3"; + return "4.39.0"; } function getWorkflowEventName(env = getEnv()) { return env.getRequired("GITHUB_EVENT_NAME" /* GITHUB_EVENT_NAME */); diff --git a/package-lock.json b/package-lock.json index 167f0801b3..e3b9d3025c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codeql", - "version": "4.38.3", + "version": "4.39.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codeql", - "version": "4.38.3", + "version": "4.39.0", "license": "MIT", "workspaces": [ "pr-checks" diff --git a/package.json b/package.json index 5ebf14292b..c49797fcbf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeql", - "version": "4.38.3", + "version": "4.39.0", "private": true, "description": "CodeQL action", "scripts": { From 74aeac99e7363fad2281014f585a2b69c293cbb7 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 6 Oct 2026 10:59:09 +0100 Subject: [PATCH 026/107] Stop testing CodeQL versions older than 2.20.7 in PR checks Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/workflows/__go-tracing-autobuilder.yml | 2 -- .github/workflows/__go-tracing-custom-build-steps.yml | 2 -- .github/workflows/__go-tracing-legacy-workflow.yml | 2 -- .github/workflows/__multi-language-autodetect.yml | 4 ---- .github/workflows/__rust.yml | 2 +- .github/workflows/debug-artifacts-failure-safe.yml | 2 +- .github/workflows/debug-artifacts-safe.yml | 4 ++-- pr-checks/checks/multi-language-autodetect.yml | 1 - pr-checks/checks/rust.yml | 4 ++-- pr-checks/sync.ts | 2 -- 10 files changed, 6 insertions(+), 19 deletions(-) diff --git a/.github/workflows/__go-tracing-autobuilder.yml b/.github/workflows/__go-tracing-autobuilder.yml index ccbb1b5a6e..ac33402619 100644 --- a/.github/workflows/__go-tracing-autobuilder.yml +++ b/.github/workflows/__go-tracing-autobuilder.yml @@ -44,8 +44,6 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - version: stable-v2.19.4 - os: ubuntu-latest version: stable-v2.20.7 - os: ubuntu-latest diff --git a/.github/workflows/__go-tracing-custom-build-steps.yml b/.github/workflows/__go-tracing-custom-build-steps.yml index 2acc617cb1..edaccddd0a 100644 --- a/.github/workflows/__go-tracing-custom-build-steps.yml +++ b/.github/workflows/__go-tracing-custom-build-steps.yml @@ -44,8 +44,6 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - version: stable-v2.19.4 - os: ubuntu-latest version: stable-v2.20.7 - os: ubuntu-latest diff --git a/.github/workflows/__go-tracing-legacy-workflow.yml b/.github/workflows/__go-tracing-legacy-workflow.yml index a43705b703..5f976dd4ea 100644 --- a/.github/workflows/__go-tracing-legacy-workflow.yml +++ b/.github/workflows/__go-tracing-legacy-workflow.yml @@ -44,8 +44,6 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - version: stable-v2.19.4 - os: ubuntu-latest version: stable-v2.20.7 - os: ubuntu-latest diff --git a/.github/workflows/__multi-language-autodetect.yml b/.github/workflows/__multi-language-autodetect.yml index 0a0f201ead..38133994ca 100644 --- a/.github/workflows/__multi-language-autodetect.yml +++ b/.github/workflows/__multi-language-autodetect.yml @@ -54,10 +54,6 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - version: stable-v2.19.4 - - os: macos-15-xlarge - version: stable-v2.19.4 - os: ubuntu-latest version: stable-v2.20.7 - os: macos-15-xlarge diff --git a/.github/workflows/__rust.yml b/.github/workflows/__rust.yml index b3638ca6df..f26b4eb2eb 100644 --- a/.github/workflows/__rust.yml +++ b/.github/workflows/__rust.yml @@ -35,7 +35,7 @@ jobs: matrix: include: - os: ubuntu-latest - version: stable-v2.19.4 + version: stable-v2.20.7 - os: ubuntu-latest version: stable-v2.22.1 - os: ubuntu-latest diff --git a/.github/workflows/debug-artifacts-failure-safe.yml b/.github/workflows/debug-artifacts-failure-safe.yml index f67cef5c75..936fe6e950 100644 --- a/.github/workflows/debug-artifacts-failure-safe.yml +++ b/.github/workflows/debug-artifacts-failure-safe.yml @@ -30,7 +30,7 @@ jobs: fail-fast: false matrix: version: - - stable-v2.20.3 + - stable-v2.20.7 - default - linked - nightly-latest diff --git a/.github/workflows/debug-artifacts-safe.yml b/.github/workflows/debug-artifacts-safe.yml index c27f195113..8792aea324 100644 --- a/.github/workflows/debug-artifacts-safe.yml +++ b/.github/workflows/debug-artifacts-safe.yml @@ -29,7 +29,7 @@ jobs: fail-fast: false matrix: version: - - stable-v2.20.3 + - stable-v2.20.7 - default - linked - nightly-latest @@ -85,7 +85,7 @@ jobs: uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - name: Check expected artifacts exist run: | - VERSIONS="stable-v2.20.3 default linked nightly-latest" + VERSIONS="stable-v2.20.7 default linked nightly-latest" LANGUAGES="cpp csharp go java javascript python" for version in $VERSIONS; do pushd "./my-debug-artifacts-${version//./}" diff --git a/pr-checks/checks/multi-language-autodetect.yml b/pr-checks/checks/multi-language-autodetect.yml index b9d80d1077..22f0d79918 100644 --- a/pr-checks/checks/multi-language-autodetect.yml +++ b/pr-checks/checks/multi-language-autodetect.yml @@ -10,7 +10,6 @@ operatingSystems: - os: macos runner-image: macos-15-xlarge codeql-versions: - - stable-v2.19.4 - stable-v2.20.7 - stable-v2.21.4 - stable-v2.22.4 diff --git a/pr-checks/checks/rust.yml b/pr-checks/checks/rust.yml index 8589ba80e5..c7dbd97f56 100644 --- a/pr-checks/checks/rust.yml +++ b/pr-checks/checks/rust.yml @@ -1,8 +1,8 @@ name: "Rust analysis" description: "Tests creation of a Rust database" versions: - # experimental rust support introduced, requires action to set `CODEQL_ENABLE_EXPERIMENTAL_FEATURES` - - stable-v2.19.4 + # oldest supported version; experimental rust support, requires action to set `CODEQL_ENABLE_EXPERIMENTAL_FEATURES` + - stable-v2.20.7 # first public preview version - stable-v2.22.1 - linked diff --git a/pr-checks/sync.ts b/pr-checks/sync.ts index 9b40c2e411..28d8fe9a25 100755 --- a/pr-checks/sync.ts +++ b/pr-checks/sync.ts @@ -136,8 +136,6 @@ type LanguageSetups = Partial>; // The default set of CodeQL Bundle versions to use for the PR checks. const defaultTestVersions = [ // The oldest supported CodeQL version. If bumping, update `CODEQL_MINIMUM_VERSION` in `codeql.ts` - "stable-v2.19.4", - // The last CodeQL release in the 2.20 series. "stable-v2.20.7", // The last CodeQL release in the 2.21 series. "stable-v2.21.4", From 17e7897d6cacc3811b9617a129291bd17291b932 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 6 Oct 2026 10:59:21 +0100 Subject: [PATCH 027/107] Add CodeQL 2.25.6 to the PR check matrix Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/workflows/__go-tracing-autobuilder.yml | 2 ++ .github/workflows/__go-tracing-custom-build-steps.yml | 2 ++ .github/workflows/__go-tracing-legacy-workflow.yml | 2 ++ .github/workflows/__multi-language-autodetect.yml | 4 ++++ pr-checks/sync.ts | 2 ++ 5 files changed, 12 insertions(+) diff --git a/.github/workflows/__go-tracing-autobuilder.yml b/.github/workflows/__go-tracing-autobuilder.yml index ac33402619..fb471c5eac 100644 --- a/.github/workflows/__go-tracing-autobuilder.yml +++ b/.github/workflows/__go-tracing-autobuilder.yml @@ -54,6 +54,8 @@ jobs: version: stable-v2.23.9 - os: ubuntu-latest version: stable-v2.24.3 + - os: ubuntu-latest + version: stable-v2.25.6 - os: ubuntu-latest version: default - os: ubuntu-latest diff --git a/.github/workflows/__go-tracing-custom-build-steps.yml b/.github/workflows/__go-tracing-custom-build-steps.yml index edaccddd0a..b3b043def9 100644 --- a/.github/workflows/__go-tracing-custom-build-steps.yml +++ b/.github/workflows/__go-tracing-custom-build-steps.yml @@ -54,6 +54,8 @@ jobs: version: stable-v2.23.9 - os: ubuntu-latest version: stable-v2.24.3 + - os: ubuntu-latest + version: stable-v2.25.6 - os: ubuntu-latest version: default - os: ubuntu-latest diff --git a/.github/workflows/__go-tracing-legacy-workflow.yml b/.github/workflows/__go-tracing-legacy-workflow.yml index 5f976dd4ea..20bdea6955 100644 --- a/.github/workflows/__go-tracing-legacy-workflow.yml +++ b/.github/workflows/__go-tracing-legacy-workflow.yml @@ -54,6 +54,8 @@ jobs: version: stable-v2.23.9 - os: ubuntu-latest version: stable-v2.24.3 + - os: ubuntu-latest + version: stable-v2.25.6 - os: ubuntu-latest version: default - os: ubuntu-latest diff --git a/.github/workflows/__multi-language-autodetect.yml b/.github/workflows/__multi-language-autodetect.yml index 38133994ca..8bc4514f0c 100644 --- a/.github/workflows/__multi-language-autodetect.yml +++ b/.github/workflows/__multi-language-autodetect.yml @@ -74,6 +74,10 @@ jobs: version: stable-v2.24.3 - os: macos-latest-xlarge version: stable-v2.24.3 + - os: ubuntu-latest + version: stable-v2.25.6 + - os: macos-latest-xlarge + version: stable-v2.25.6 - os: ubuntu-latest version: default - os: macos-latest-xlarge diff --git a/pr-checks/sync.ts b/pr-checks/sync.ts index 28d8fe9a25..8dc1dd1d1d 100755 --- a/pr-checks/sync.ts +++ b/pr-checks/sync.ts @@ -145,6 +145,8 @@ const defaultTestVersions = [ "stable-v2.23.9", // The last CodeQL release in the 2.24 series. "stable-v2.24.3", + // The last CodeQL release in the 2.25 series. + "stable-v2.25.6", // The default version of CodeQL for Dotcom, as determined by feature flags. "default", // The version of CodeQL shipped with the Action in `defaults.json`. During the release process From b97fbb3711f2eff433d8f4dd4d3f04cec3a7a349 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Mon, 5 Oct 2026 18:31:43 +0100 Subject: [PATCH 028/107] Remove `CODEQL_PROXY_*` workaround for CLIs older than 2.20.7 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- lib/entry-points.js | 5 ----- src/analyze-action.ts | 11 ----------- 2 files changed, 16 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 00a0da96b2..675b28f94c 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -180629,11 +180629,6 @@ async function run({ "`expect-error` input parameter is for internal use only. It should only be set by codeql-action or a fork." ); } - if (process.env.CODEQL_PROXY_HOST === "" && !await codeQlVersionAtLeast(codeql, "2.20.7")) { - delete process.env.CODEQL_PROXY_HOST; - delete process.env.CODEQL_PROXY_PORT; - delete process.env.CODEQL_PROXY_CA_CERTIFICATE; - } if (getOptionalInput("cleanup-level")) { logger2.info( "The 'cleanup-level' input is ignored since the CodeQL Action now automatically manages database cleanup. This input can safely be removed from your workflow." diff --git a/src/analyze-action.ts b/src/analyze-action.ts index 7963fa52bf..a954ed40f5 100644 --- a/src/analyze-action.ts +++ b/src/analyze-action.ts @@ -267,17 +267,6 @@ async function run({ ); } - // Unset the CODEQL_PROXY_* environment variables when using older CodeQL - // CLIs, as they are not needed and can cause issues. - if ( - process.env.CODEQL_PROXY_HOST === "" && - !(await util.codeQlVersionAtLeast(codeql, "2.20.7")) - ) { - delete process.env.CODEQL_PROXY_HOST; - delete process.env.CODEQL_PROXY_PORT; - delete process.env.CODEQL_PROXY_CA_CERTIFICATE; - } - if (actionsUtil.getOptionalInput("cleanup-level")) { logger.info( "The 'cleanup-level' input is ignored since the CodeQL Action now automatically " + From 10e415aae190955670b23436c13e7aa00afebe8c Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Mon, 5 Oct 2026 18:32:01 +0100 Subject: [PATCH 029/107] Remove Kotlin version limit workaround for CodeQL CLI 2.20.3 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- lib/entry-points.js | 4 ---- src/init-action.ts | 9 --------- 2 files changed, 13 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 675b28f94c..83ca4b4212 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -186597,10 +186597,6 @@ exec ${goBinaryPath} "$@"` if (await features.getValue("force_jgit" /* ForceJGit */)) { core22.exportVariable("CODEQL_GIT_BACKEND", "jgit"); } - const kotlinLimitVar = "CODEQL_EXTRACTOR_KOTLIN_OVERRIDE_MAXIMUM_VERSION_LIMIT"; - if (await codeQlVersionAtLeast(codeql, "2.20.3") && !await codeQlVersionAtLeast(codeql, "2.20.4")) { - core22.exportVariable(kotlinLimitVar, "2.1.20"); - } if (shouldRestoreCache(config.dependencyCachingEnabled)) { const dependencyCachingResult = await downloadDependencyCaches( codeql, diff --git a/src/init-action.ts b/src/init-action.ts index 31414bd80b..b226a0cb5d 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -630,15 +630,6 @@ async function run( core.exportVariable("CODEQL_GIT_BACKEND", "jgit"); } - const kotlinLimitVar = - "CODEQL_EXTRACTOR_KOTLIN_OVERRIDE_MAXIMUM_VERSION_LIMIT"; - if ( - (await codeQlVersionAtLeast(codeql, "2.20.3")) && - !(await codeQlVersionAtLeast(codeql, "2.20.4")) - ) { - core.exportVariable(kotlinLimitVar, "2.1.20"); - } - // Restore dependency cache(s), if they exist. if (shouldRestoreCache(config.dependencyCachingEnabled)) { const dependencyCachingResult = await downloadDependencyCaches( From 3c1b1b65a3694a5b9da80d475631847810c01824 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Mon, 5 Oct 2026 18:34:25 +0100 Subject: [PATCH 030/107] Remove CodeQL version check from debug artifact upload Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- lib/entry-points.js | 168 +++++++++++++------------------- src/analyze-action-post.ts | 4 - src/debug-artifacts.test.ts | 62 ++---------- src/debug-artifacts.ts | 32 +----- src/init-action-post-helper.ts | 9 +- src/tools-features.ts | 20 ---- src/upload-sarif-action-post.ts | 8 +- 7 files changed, 79 insertions(+), 224 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 83ca4b4212..2f95ef18f4 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -27216,8 +27216,8 @@ var require_gte = __commonJS({ "node_modules/semver/functions/gte.js"(exports2, module2) { "use strict"; var compare3 = require_compare(); - var gte8 = (a, b, loose) => compare3(a, b, loose) >= 0; - module2.exports = gte8; + var gte7 = (a, b, loose) => compare3(a, b, loose) >= 0; + module2.exports = gte7; } }); @@ -27238,7 +27238,7 @@ var require_cmp = __commonJS({ var eq = require_eq(); var neq = require_neq(); var gt = require_gt(); - var gte8 = require_gte(); + var gte7 = require_gte(); var lt2 = require_lt(); var lte2 = require_lte(); var cmp = (a, op, b, loose) => { @@ -27268,7 +27268,7 @@ var require_cmp = __commonJS({ case ">": return gt(a, b, loose); case ">=": - return gte8(a, b, loose); + return gte7(a, b, loose); case "<": return lt2(a, b, loose); case "<=": @@ -28076,7 +28076,7 @@ var require_outside = __commonJS({ var gt = require_gt(); var lt2 = require_lt(); var lte2 = require_lte(); - var gte8 = require_gte(); + var gte7 = require_gte(); var outside = (version, range2, hilo, options) => { version = new SemVer(version, options); range2 = new Range2(range2, options); @@ -28091,7 +28091,7 @@ var require_outside = __commonJS({ break; case "<": gtfn = lt2; - ltefn = gte8; + ltefn = gte7; ltfn = gt; comp = "<"; ecomp = "<="; @@ -28406,7 +28406,7 @@ var require_semver2 = __commonJS({ var lt2 = require_lt(); var eq = require_eq(); var neq = require_neq(); - var gte8 = require_gte(); + var gte7 = require_gte(); var lte2 = require_lte(); var cmp = require_cmp(); var coerce3 = require_coerce(); @@ -28445,7 +28445,7 @@ var require_semver2 = __commonJS({ lt: lt2, eq, neq, - gte: gte8, + gte: gte7, lte: lte2, cmp, coerce: coerce3, @@ -31736,7 +31736,7 @@ var require_brace_expansion = __commonJS({ function lte2(i, y) { return i <= y; } - function gte8(i, y) { + function gte7(i, y) { return i >= y; } function combine2(acc, base, pre, values, max, maxLength, dropEmpties, outBase) { @@ -31769,7 +31769,7 @@ var require_brace_expansion = __commonJS({ var reverse = y < x; if (reverse) { incr *= -1; - test = gte8; + test = gte7; } var pad = n.some(isPadded2); var length = 0; @@ -33921,8 +33921,8 @@ var require_semver3 = __commonJS({ function neq(a, b, loose) { return compare3(a, b, loose) !== 0; } - exports2.gte = gte8; - function gte8(a, b, loose) { + exports2.gte = gte7; + function gte7(a, b, loose) { return compare3(a, b, loose) >= 0; } exports2.lte = lte2; @@ -33953,7 +33953,7 @@ var require_semver3 = __commonJS({ case ">": return gt(a, b, loose); case ">=": - return gte8(a, b, loose); + return gte7(a, b, loose); case "<": return lt2(a, b, loose); case "<=": @@ -34498,7 +34498,7 @@ var require_semver3 = __commonJS({ break; case "<": gtfn = lt2; - ltefn = gte8; + ltefn = gte7; ltfn = gt; comp = "<"; ecomp = "<="; @@ -34719,7 +34719,7 @@ var require_cacheUtils = __commonJS({ var crypto3 = __importStar2(require("crypto")); var fs32 = __importStar2(require("fs")); var path30 = __importStar2(require("path")); - var semver12 = __importStar2(require_semver3()); + var semver11 = __importStar2(require_semver3()); var util4 = __importStar2(require("util")); var constants_1 = require_constants7(); var versionSalt = "1.0"; @@ -34812,7 +34812,7 @@ var require_cacheUtils = __commonJS({ function getCompressionMethod() { return __awaiter2(this, void 0, void 0, function* () { const versionOutput = yield getVersion("zstd", ["--quiet"]); - const version = semver12.clean(versionOutput); + const version = semver11.clean(versionOutput); core32.debug(`zstd version: ${version}`); if (versionOutput === "") { return constants_1.CompressionMethod.Gzip; @@ -106346,7 +106346,7 @@ var require_manifest = __commonJS({ exports2._findMatch = _findMatch; exports2._getOsVersion = _getOsVersion; exports2._readLinuxVersionFile = _readLinuxVersionFile; - var semver12 = __importStar2(require_semver2()); + var semver11 = __importStar2(require_semver2()); var core_1 = require_core(); var os7 = require("os"); var cp = require("child_process"); @@ -106360,7 +106360,7 @@ var require_manifest = __commonJS({ for (const candidate of candidates) { const version = candidate.version; (0, core_1.debug)(`check ${version} satisfies ${versionSpec}`); - if (semver12.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { + if (semver11.satisfies(version, versionSpec) && (!stable || candidate.stable === stable)) { file = candidate.files.find((item) => { (0, core_1.debug)(`${item.arch}===${archFilter} && ${item.platform}===${platFilter}`); let chk = item.arch === archFilter && item.platform === platFilter; @@ -106369,7 +106369,7 @@ var require_manifest = __commonJS({ if (osVersion === item.platform_version) { chk = true; } else { - chk = semver12.satisfies(osVersion, item.platform_version); + chk = semver11.satisfies(osVersion, item.platform_version); } } return chk; @@ -106629,7 +106629,7 @@ var require_tool_cache = __commonJS({ var os7 = __importStar2(require("os")); var path30 = __importStar2(require("path")); var httpm = __importStar2(require_lib()); - var semver12 = __importStar2(require_semver2()); + var semver11 = __importStar2(require_semver2()); var stream2 = __importStar2(require("stream")); var util4 = __importStar2(require("util")); var assert_1 = require("assert"); @@ -106902,7 +106902,7 @@ var require_tool_cache = __commonJS({ } function cacheDir2(sourceDir, tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - version = semver12.clean(version) || version; + version = semver11.clean(version) || version; arch2 = arch2 || os7.arch(); core32.debug(`Caching tool ${tool} ${version} ${arch2}`); core32.debug(`source dir: ${sourceDir}`); @@ -106920,7 +106920,7 @@ var require_tool_cache = __commonJS({ } function cacheFile(sourceFile, targetFile, tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - version = semver12.clean(version) || version; + version = semver11.clean(version) || version; arch2 = arch2 || os7.arch(); core32.debug(`Caching tool ${tool} ${version} ${arch2}`); core32.debug(`source file: ${sourceFile}`); @@ -106950,7 +106950,7 @@ var require_tool_cache = __commonJS({ } let toolPath = ""; if (versionSpec) { - versionSpec = semver12.clean(versionSpec) || ""; + versionSpec = semver11.clean(versionSpec) || ""; const cachePath = path30.join(_getCacheDirectory(), toolName, versionSpec, arch2); core32.debug(`checking cache: ${cachePath}`); if (fs32.existsSync(cachePath) && fs32.existsSync(`${cachePath}.complete`)) { @@ -107030,7 +107030,7 @@ var require_tool_cache = __commonJS({ } function _createToolPath(tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { - const folderPath = path30.join(_getCacheDirectory(), tool, semver12.clean(version) || version, arch2 || ""); + const folderPath = path30.join(_getCacheDirectory(), tool, semver11.clean(version) || version, arch2 || ""); core32.debug(`destination ${folderPath}`); const markerPath = `${folderPath}.complete`; yield io9.rmRF(folderPath); @@ -107040,15 +107040,15 @@ var require_tool_cache = __commonJS({ }); } function _completeToolPath(tool, version, arch2) { - const folderPath = path30.join(_getCacheDirectory(), tool, semver12.clean(version) || version, arch2 || ""); + const folderPath = path30.join(_getCacheDirectory(), tool, semver11.clean(version) || version, arch2 || ""); const markerPath = `${folderPath}.complete`; fs32.writeFileSync(markerPath, ""); core32.debug("finished caching tool"); } function isExplicitVersion(versionSpec) { - const c = semver12.clean(versionSpec) || ""; + const c = semver11.clean(versionSpec) || ""; core32.debug(`isExplicit: ${c}`); - const valid4 = semver12.valid(c) != null; + const valid4 = semver11.valid(c) != null; core32.debug(`explicit? ${valid4}`); return valid4; } @@ -107056,14 +107056,14 @@ var require_tool_cache = __commonJS({ let version = ""; core32.debug(`evaluating ${versions.length} versions`); versions = versions.sort((a, b) => { - if (semver12.gt(a, b)) { + if (semver11.gt(a, b)) { return 1; } return -1; }); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; - const satisfied = semver12.satisfies(potential, versionSpec); + const satisfied = semver11.satisfies(potential, versionSpec); if (satisfied) { version = potential; break; @@ -113555,7 +113555,7 @@ var require_brace_expansion2 = __commonJS({ function lte2(i, y) { return i <= y; } - function gte8(i, y) { + function gte7(i, y) { return i >= y; } function combine2(acc, pre, values, max, maxLength, dropEmpties) { @@ -113587,7 +113587,7 @@ var require_brace_expansion2 = __commonJS({ var reverse = y < x; if (reverse) { incr *= -1; - test = gte8; + test = gte7; } var pad = n.some(isPadded2); var length = 0; @@ -171720,7 +171720,7 @@ async function runInActions(action) { // src/feature-flags.ts var fs6 = __toESM(require("fs")); var path6 = __toESM(require("path")); -var semver4 = __toESM(require_semver2()); +var semver3 = __toESM(require_semver2()); // src/defaults.json var bundleVersion = "codeql-bundle-v2.27.2"; @@ -171840,14 +171840,9 @@ async function getDiffRangeFilePaths(sourceRoot, logger2) { } // src/tools-features.ts -var semver3 = __toESM(require_semver2()); function isSupportedToolsFeature(versionInfo, feature) { return !!versionInfo.features && versionInfo.features[feature]; } -var SafeArtifactUploadVersion = "2.20.3"; -function isSafeArtifactUpload(codeQlVersion) { - return !codeQlVersion ? true : semver3.gte(codeQlVersion, SafeArtifactUploadVersion); -} // src/feature-flags.ts var DEFAULT_VERSION_FEATURE_FLAG_PREFIX = "default_codeql_version_"; @@ -172298,7 +172293,7 @@ var GitHubFeatureFlags = class { DEFAULT_VERSION_FEATURE_FLAG_PREFIX.length, f.length - DEFAULT_VERSION_FEATURE_FLAG_SUFFIX.length ).replace(/_/g, "."); - if (!semver4.valid(version)) { + if (!semver3.valid(version)) { this.logger.warning( `Ignoring feature flag ${f} as it does not specify a valid CodeQL version.` ); @@ -172315,7 +172310,7 @@ var GitHubFeatureFlags = class { const response = await this.getAllFeatures(); const sortedCliVersions = Object.entries(response).map( ([f, isEnabled]) => isEnabled ? this.getCliVersionFromFeatureFlag(f) : void 0 - ).filter((f) => f !== void 0).sort(semver4.rcompare); + ).filter((f) => f !== void 0).sort(semver3.rcompare); if (sortedCliVersions.length === 0) { this.logger.warning( `Feature flags do not specify a default CLI version. Falling back to the CLI version shipped with the Action. This is ${cliVersion}.` @@ -172926,7 +172921,7 @@ function getDependencyCachingEnabled() { // src/config/db-config.ts var path8 = __toESM(require("path")); var jsonschema = __toESM(require_lib2()); -var semver5 = __toESM(require_semver2()); +var semver4 = __toESM(require_semver2()); // src/diagnostics.ts var import_fs = require("fs"); @@ -173341,7 +173336,7 @@ function parsePacksSpecification(packStr) { } if (version) { try { - new semver5.Range(version); + new semver4.Range(version); } catch { throw new ConfigurationError(getPacksStrInvalid(packStr)); } @@ -175196,7 +175191,7 @@ var import_perf_hooks4 = require("perf_hooks"); var core12 = __toESM(require_core()); var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); -var semver10 = __toESM(require_semver2()); +var semver9 = __toESM(require_semver2()); // src/codeql-bundle.ts function getCodeQLBundleName(compressionMethod, platform2, language) { @@ -175230,7 +175225,7 @@ function getCodeQLBundleFromUrl(url2) { // src/overlay/caching.ts var fs11 = __toESM(require("fs")); var actionsCache3 = __toESM(require_cache4()); -var semver6 = __toESM(require_semver2()); +var semver5 = __toESM(require_semver2()); var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500; var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; var CACHE_VERSION2 = 1; @@ -175507,7 +175502,7 @@ async function getCodeQlVersionsForOverlayBaseDatabases(rawLanguages, logger2) { if (!cache.key) continue; const suffix = cache.key.substring(cacheKeyPrefix.length); const match2 = suffix.match(versionRegex); - if (match2 && semver6.valid(match2[1])) { + if (match2 && semver5.valid(match2[1])) { versionSet.add(match2[1]); } } @@ -175517,7 +175512,7 @@ async function getCodeQlVersionsForOverlayBaseDatabases(rawLanguages, logger2) { ); return []; } - const versions = [...versionSet].sort(semver6.rcompare); + const versions = [...versionSet].sort(semver5.rcompare); logger2.info( `Found overlay databases for the following CodeQL versions in the Actions cache: ${versions.join(", ")}` ); @@ -175525,7 +175520,7 @@ async function getCodeQlVersionsForOverlayBaseDatabases(rawLanguages, logger2) { } // src/per-language-bundles.ts -var semver7 = __toESM(require_semver2()); +var semver6 = __toESM(require_semver2()); // src/platform.ts function getBundlePlatform(platform2 = process.platform, arch2 = process.arch) { @@ -175632,7 +175627,7 @@ async function getPerLanguageBundleLanguage({ if (cliVersion2 === void 0) { return explain("the requested CLI version is unknown"); } - if (!semver7.gte(cliVersion2, MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION)) { + if (!semver6.gte(cliVersion2, MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION)) { return explain( `the requested CodeQL version ${cliVersion2} is older than ${MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION}, which is the first version for which per-language bundles are published` ); @@ -175658,7 +175653,7 @@ var stream = __toESM(require("stream")); var import_toolrunner = __toESM(require_toolrunner()); var io4 = __toESM(require_io()); var toolcache = __toESM(require_tool_cache()); -var semver8 = __toESM(require_semver2()); +var semver7 = __toESM(require_semver2()); var MIN_REQUIRED_BSD_TAR_VERSION = "3.4.3"; var MIN_REQUIRED_GNU_TAR_VERSION = "1.31"; async function getTarVersion() { @@ -175700,9 +175695,9 @@ async function isZstdAvailable(logger2) { case "gnu": return { available: foundZstdBinary && // GNU tar only uses major and minor version numbers - semver8.gte( - semver8.coerce(version), - semver8.coerce(MIN_REQUIRED_GNU_TAR_VERSION) + semver7.gte( + semver7.coerce(version), + semver7.coerce(MIN_REQUIRED_GNU_TAR_VERSION) ), foundZstdBinary, version: tarVersion @@ -175711,7 +175706,7 @@ async function isZstdAvailable(logger2) { return { available: foundZstdBinary && // Do a loose comparison since these version numbers don't contain // a patch version number. - semver8.gte(version, MIN_REQUIRED_BSD_TAR_VERSION), + semver7.gte(version, MIN_REQUIRED_BSD_TAR_VERSION), foundZstdBinary, version: tarVersion }; @@ -175820,7 +175815,7 @@ var core11 = __toESM(require_core()); var import_http_client = __toESM(require_lib()); var toolcache2 = __toESM(require_tool_cache()); var import_follow_redirects = __toESM(require_follow_redirects()); -var semver9 = __toESM(require_semver2()); +var semver8 = __toESM(require_semver2()); var STREAMING_HIGH_WATERMARK_BYTES = 4 * 1024 * 1024; var STREAMING_STALL_TIMEOUT_MS = 5 * 60 * 1e3; var TOOLCACHE_TOOL_NAME = "CodeQL"; @@ -175946,7 +175941,7 @@ function getToolcacheToolDirectory(env) { ); } function getToolcacheVersionDirectoryName(version) { - return semver9.clean(version) || version; + return semver8.clean(version) || version; } function getToolcacheDirectory(version) { return path12.join( @@ -176126,13 +176121,13 @@ function tryGetTagNameFromUrl(url2, logger2) { return match2[1]; } function convertToSemVer(version, logger2) { - if (!semver10.valid(version)) { + if (!semver9.valid(version)) { logger2.debug( `Bundle version ${version} is not in SemVer format. Will treat it as pre-release 0.0.0-${version}.` ); version = `0.0.0-${version}`; } - const s = semver10.clean(version); + const s = semver9.clean(version); if (!s) { throw new Error(`Bundle version ${version} is not in SemVer format.`); } @@ -176348,7 +176343,7 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, rawLanguages, othe url2 = toolsInput; if (tagName) { const bundleVersion3 = tryGetBundleVersionFromTagName(tagName, logger2); - if (bundleVersion3 !== void 0 && semver10.valid(bundleVersion3)) { + if (bundleVersion3 !== void 0 && semver9.valid(bundleVersion3)) { cliVersion2 = convertToSemVer(bundleVersion3, logger2); } } @@ -176730,7 +176725,7 @@ async function downloadCodeQLBundle(action, source, apiDetails, tarVersion, temp async function useZstdBundle(cliVersion2, tarSupportsZstd) { return ( // In testing, gzip performs better than zstd on Windows. - process.platform !== "win32" && tarSupportsZstd && semver10.gte(cliVersion2, CODEQL_VERSION_ZSTD_BUNDLE) + process.platform !== "win32" && tarSupportsZstd && semver9.gte(cliVersion2, CODEQL_VERSION_ZSTD_BUNDLE) ); } function getTempExtractionDir(tempDir) { @@ -176784,7 +176779,7 @@ async function getLatestNightlyBundle(action, rawLanguages, otherLanguagePacksRe } } function getLatestToolcacheVersion(logger2) { - const allVersions = toolcache3.findAllVersions("CodeQL").sort((a, b) => semver10.compare(b, a)); + const allVersions = toolcache3.findAllVersions("CodeQL").sort((a, b) => semver9.compare(b, a)); logger2.debug( `Found the following versions of the CodeQL tools in the toolcache: ${JSON.stringify( allVersions @@ -180997,7 +180992,7 @@ function isPadded(el) { function lte(i, y) { return i <= y; } -function gte7(i, y) { +function gte6(i, y) { return i >= y; } function combine(acc, pre, values, max, maxLength, dropEmpties) { @@ -181032,7 +181027,7 @@ function expandSequence(body, isAlphaSequence, max, maxLength) { const reverse = y < x; if (reverse) { incr *= -1; - test = gte7; + test = gte6; } const pad = n.some(isPadded); let length = 0; @@ -185493,7 +185488,7 @@ async function scanArtifactsForTokens(filesToScan, logger2) { function sanitizeArtifactName(name) { return name.replace(/[^a-zA-Z0-9_-]+/g, ""); } -async function uploadCombinedSarifArtifacts(logger2, gitHubVariant, codeQlVersion) { +async function uploadCombinedSarifArtifacts(logger2, gitHubVariant) { const tempDir = getTemporaryDirectory(); if (process.env["CODEQL_ACTION_DEBUG_COMBINED_SARIF"] === "true") { await withGroup("Uploading combined SARIF debug artifact", async () => { @@ -185512,13 +185507,12 @@ async function uploadCombinedSarifArtifacts(logger2, gitHubVariant, codeQlVersio } } try { - await uploadDebugArtifacts( + await uploadArtifacts( logger2, toUpload, baseTempDir, "combined-sarif-artifacts", - gitHubVariant, - codeQlVersion + gitHubVariant ); } catch (e) { logger2.warning( @@ -185577,7 +185571,7 @@ async function tryBundleDatabase(codeql, config, language, logger2) { return void 0; } } -async function tryUploadAllAvailableDebugArtifacts(codeql, config, logger2, codeQlVersion) { +async function tryUploadAllAvailableDebugArtifacts(codeql, config, logger2) { const filesToUpload = []; try { for (const language of config.languages) { @@ -185630,13 +185624,12 @@ async function tryUploadAllAvailableDebugArtifacts(codeql, config, logger2, code try { await withGroup( "Uploading debug artifacts", - async () => uploadDebugArtifacts( + async () => uploadArtifacts( logger2, filesToUpload, config.dbLocation, config.debugArtifactName, - config.gitHubVersion.type, - codeQlVersion + config.gitHubVersion.type ) ); } catch (e) { @@ -185664,16 +185657,6 @@ function getArtifactSuffix(matrix) { } return suffix; } -async function uploadDebugArtifacts(logger2, toUpload, rootDir, artifactName, ghVariant, codeQlVersion) { - const uploadSupported = isSafeArtifactUpload(codeQlVersion); - if (!uploadSupported) { - core18.info( - `Skipping debug artifact upload because the current CLI does not support safe upload. Please upgrade to CLI v${SafeArtifactUploadVersion} or later.` - ); - return "upload-not-supported"; - } - return uploadArtifacts(logger2, toUpload, rootDir, artifactName, ghVariant); -} async function uploadArtifacts(logger2, toUpload, rootDir, artifactName, ghVariant) { if (toUpload.length === 0) { return "no-artifacts-to-upload"; @@ -185764,12 +185747,9 @@ async function runWrapper2() { logger2 ); if (config !== void 0) { - const codeql = await getCodeQL(logger2, config.codeQLCmd); - const version = await codeql.getVersion(); await uploadCombinedSarifArtifacts( logger2, - config.gitHubVersion.type, - version.version + config.gitHubVersion.type ); } } @@ -185891,7 +185871,7 @@ var fs29 = __toESM(require("fs")); var path25 = __toESM(require("path")); var core22 = __toESM(require_core()); var io7 = __toESM(require_io()); -var semver11 = __toESM(require_semver2()); +var semver10 = __toESM(require_semver2()); // src/config/inputs.ts async function getToolsInput(action, repositoryProperties) { @@ -186395,12 +186375,12 @@ async function run3(actionState) { const experimental = "2.19.3"; const publicPreview = "2.22.1"; const actualVer = (await codeql.getVersion()).version; - if (semver11.lt(actualVer, experimental)) { + if (semver10.lt(actualVer, experimental)) { throw new ConfigurationError( `Rust analysis is supported by CodeQL CLI version ${experimental} or higher, but found version ${actualVer}` ); } - if (semver11.lt(actualVer, publicPreview)) { + if (semver10.lt(actualVer, publicPreview)) { core22.exportVariable("CODEQL_ENABLE_EXPERIMENTAL_FEATURES" /* EXPERIMENTAL_FEATURES */, "true"); logger2.info("Experimental Rust analysis enabled"); } @@ -186906,13 +186886,7 @@ async function uploadFailureInfo(uploadAllAvailableDebugArtifacts, printDebugLog logger2.info( "Debug mode is on. Uploading available database bundles and logs as Actions debugging artifacts..." ); - const version = await codeql.getVersion(); - await uploadAllAvailableDebugArtifacts( - codeql, - config, - logger2, - version.version - ); + await uploadAllAvailableDebugArtifacts(codeql, config, logger2); await printDebugLogs2(config); } if (isSelfHostedRunner()) { @@ -188383,13 +188357,7 @@ async function runWrapper11() { } await withGroup( "Uploading combined SARIF debug artifact", - () => uploadCombinedSarifArtifacts( - logger2, - gitHubVersion.type, - // The codeqlVersion is not applicable for uploading non-codeql sarif. - // We can assume all versions are safe to upload. - void 0 - ) + () => uploadCombinedSarifArtifacts(logger2, gitHubVersion.type) ); } } catch (error3) { diff --git a/src/analyze-action-post.ts b/src/analyze-action-post.ts index 3f9b2fafb2..a8d6dc4331 100644 --- a/src/analyze-action-post.ts +++ b/src/analyze-action-post.ts @@ -9,7 +9,6 @@ import * as core from "@actions/core"; import * as actionsUtil from "./actions-util"; import { getGitHubVersion } from "./api-client"; -import { getCodeQL } from "./codeql"; import { getConfig } from "./config-utils"; import * as debugArtifacts from "./debug-artifacts"; import { @@ -38,12 +37,9 @@ export async function runWrapper() { logger, ); if (config !== undefined) { - const codeql = await getCodeQL(logger, config.codeQLCmd); - const version = await codeql.getVersion(); await debugArtifacts.uploadCombinedSarifArtifacts( logger, config.gitHubVersion.type, - version.version, ); } } diff --git a/src/debug-artifacts.test.ts b/src/debug-artifacts.test.ts index 370816aef5..16ecb6d5dd 100644 --- a/src/debug-artifacts.test.ts +++ b/src/debug-artifacts.test.ts @@ -55,25 +55,20 @@ test("getArtifactSuffix", (t) => { } }); -// These next tests check the correctness of the logic to determine whether or not -// artifacts are uploaded in debug mode. Since it's not easy to mock the actual -// call to upload an artifact, we just check that we get an "upload-failed" result, -// instead of actually uploading the artifact. -// -// For tests where we expect artifact upload to be blocked, we check for a different -// response from the function. +// These next tests check whether `uploadArtifacts` attempts to upload an artifact. Since it's not +// easy to mock the actual call to upload an artifact, we check that we get an "upload-failed" +// result, instead of actually uploading the artifact. -test("uploadDebugArtifacts when artifacts empty should emit 'no-artifacts-to-upload'", async (t) => { +test("uploadArtifacts returns 'no-artifacts-to-upload' when there are no files to upload", async (t) => { // Test that no error is thrown if artifacts list is empty. const logger = getActionsLogger(); await t.notThrowsAsync(async () => { - const uploaded = await debugArtifacts.uploadDebugArtifacts( + const uploaded = await debugArtifacts.uploadArtifacts( logger, [], "i-dont-exist", "artifactName", GitHubVariant.DOTCOM, - undefined, ); t.is( uploaded, @@ -83,17 +78,15 @@ test("uploadDebugArtifacts when artifacts empty should emit 'no-artifacts-to-upl }); }); -test("uploadDebugArtifacts when no codeql version is used should invoke artifact upload", async (t) => { - // Test that the artifact is uploaded. +test("uploadArtifacts attempts an upload when there are files to upload", async (t) => { const logger = getActionsLogger(); await t.notThrowsAsync(async () => { - const uploaded = await debugArtifacts.uploadDebugArtifacts( + const uploaded = await debugArtifacts.uploadArtifacts( logger, ["hucairz"], "i-dont-exist", "artifactName", GitHubVariant.DOTCOM, - undefined, ); t.is( uploaded, @@ -103,44 +96,3 @@ test("uploadDebugArtifacts when no codeql version is used should invoke artifact ); }); }); - -test("uploadDebugArtifacts when new codeql version is used should invoke artifact upload", async (t) => { - // Test that the artifact is uploaded. - const logger = getActionsLogger(); - await t.notThrowsAsync(async () => { - const uploaded = await debugArtifacts.uploadDebugArtifacts( - logger, - ["hucairz"], - "i-dont-exist", - "artifactName", - GitHubVariant.DOTCOM, - "2.20.3", - ); - t.is( - uploaded, - // The failure is expected since we don't want to actually upload any artifacts in unit tests. - "upload-failed", - "Expect failure to upload artifacts since root dir does not exist", - ); - }); -}); - -test("uploadDebugArtifacts when old codeql is used should avoid trying to upload artifacts", async (t) => { - // Test that the artifact is not uploaded. - const logger = getActionsLogger(); - await t.notThrowsAsync(async () => { - const uploaded = await debugArtifacts.uploadDebugArtifacts( - logger, - ["hucairz"], - "i-dont-exist", - "artifactName", - GitHubVariant.DOTCOM, - "2.20.2", - ); - t.is( - uploaded, - "upload-not-supported", - "Expected artifact upload to be blocked because of old CodeQL version", - ); - }); -}); diff --git a/src/debug-artifacts.ts b/src/debug-artifacts.ts index 9f5f1775d4..e0bdb5c5e6 100644 --- a/src/debug-artifacts.ts +++ b/src/debug-artifacts.ts @@ -15,10 +15,6 @@ import { EnvVar } from "./environment"; import * as json from "./json"; import { Language } from "./languages"; import { Logger, withGroup } from "./logging"; -import { - isSafeArtifactUpload, - SafeArtifactUploadVersion, -} from "./tools-features"; import { bundleDb, doesDirectoryExist, @@ -40,7 +36,6 @@ export function sanitizeArtifactName(name: string): string { export async function uploadCombinedSarifArtifacts( logger: Logger, gitHubVariant: GitHubVariant, - codeQlVersion: string | undefined, ) { const tempDir = getTemporaryDirectory(); @@ -70,13 +65,12 @@ export async function uploadCombinedSarifArtifacts( } try { - await uploadDebugArtifacts( + await uploadArtifacts( logger, toUpload, baseTempDir, "combined-sarif-artifacts", gitHubVariant, - codeQlVersion, ); } catch (e) { logger.warning( @@ -172,7 +166,6 @@ export async function tryUploadAllAvailableDebugArtifacts( codeql: CodeQL, config: Config, logger: Logger, - codeQlVersion: string | undefined, ) { const filesToUpload: string[] = []; try { @@ -231,13 +224,12 @@ export async function tryUploadAllAvailableDebugArtifacts( try { await withGroup("Uploading debug artifacts", async () => - uploadDebugArtifacts( + uploadArtifacts( logger, filesToUpload, config.dbLocation, config.debugArtifactName, config.gitHubVersion.type, - codeQlVersion, ), ); } catch (e) { @@ -283,26 +275,6 @@ export type UploadArtifactsResult = | "upload-successful" | "upload-failed"; -export async function uploadDebugArtifacts( - logger: Logger, - toUpload: string[], - rootDir: string, - artifactName: string, - ghVariant: GitHubVariant, - codeQlVersion: string | undefined, -): Promise { - const uploadSupported = isSafeArtifactUpload(codeQlVersion); - - if (!uploadSupported) { - core.info( - `Skipping debug artifact upload because the current CLI does not support safe upload. Please upgrade to CLI v${SafeArtifactUploadVersion} or later.`, - ); - return "upload-not-supported"; - } - - return uploadArtifacts(logger, toUpload, rootDir, artifactName, ghVariant); -} - /** * Uploads the specified files as a single workflow artifact. * diff --git a/src/init-action-post-helper.ts b/src/init-action-post-helper.ts index 0e6dae13aa..93ee391aaa 100644 --- a/src/init-action-post-helper.ts +++ b/src/init-action-post-helper.ts @@ -326,7 +326,6 @@ export async function uploadFailureInfo( codeql: CodeQL, config: Config, logger: Logger, - codeQlVersion: string, ) => Promise, printDebugLogs: (config: Config) => Promise, codeql: CodeQL, @@ -381,13 +380,7 @@ export async function uploadFailureInfo( logger.info( "Debug mode is on. Uploading available database bundles and logs as Actions debugging artifacts...", ); - const version = await codeql.getVersion(); - await uploadAllAvailableDebugArtifacts( - codeql, - config, - logger, - version.version, - ); + await uploadAllAvailableDebugArtifacts(codeql, config, logger); await printDebugLogs(config); } diff --git a/src/tools-features.ts b/src/tools-features.ts index 4931be65ba..35e626c887 100644 --- a/src/tools-features.ts +++ b/src/tools-features.ts @@ -1,5 +1,3 @@ -import * as semver from "semver"; - import type { VersionInfo } from "./cli/types"; export enum ToolsFeature { @@ -23,21 +21,3 @@ export function isSupportedToolsFeature( ): boolean { return !!versionInfo.features && versionInfo.features[feature]; } - -export const SafeArtifactUploadVersion = "2.20.3"; - -/** - * The first version of the CodeQL CLI where artifact upload is safe to use - * for failed runs. This is not really a feature flag, but it is easiest to - * model the behavior as a feature flag. - * - * This was not captured in a tools feature, so we need to use semver. - * - * @param codeQlVersion The version of the CodeQL CLI to check. If not provided, it is assumed to be safe. - * @returns True if artifact upload is safe to use for failed runs or false otherwise. - */ -export function isSafeArtifactUpload(codeQlVersion?: string): boolean { - return !codeQlVersion - ? true - : semver.gte(codeQlVersion, SafeArtifactUploadVersion); -} diff --git a/src/upload-sarif-action-post.ts b/src/upload-sarif-action-post.ts index bc0e1361c9..82961842e8 100644 --- a/src/upload-sarif-action-post.ts +++ b/src/upload-sarif-action-post.ts @@ -34,13 +34,7 @@ export async function runWrapper() { return; } await withGroup("Uploading combined SARIF debug artifact", () => - debugArtifacts.uploadCombinedSarifArtifacts( - logger, - gitHubVersion.type, - // The codeqlVersion is not applicable for uploading non-codeql sarif. - // We can assume all versions are safe to upload. - undefined, - ), + debugArtifacts.uploadCombinedSarifArtifacts(logger, gitHubVersion.type), ); } } catch (error) { From a8c7110b265f8213a1af4312354fe55c2c430f49 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 6 Oct 2026 10:36:29 +0100 Subject: [PATCH 031/107] Remove unreachable minimum version check for Rust analysis Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- lib/entry-points.js | 6 ------ src/init-action.ts | 8 +------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 2f95ef18f4..5857b85cb0 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -186372,14 +186372,8 @@ async function run3(actionState) { // requested rust - don't enable it via language autodetection. getRawLanguagesNoAutodetect(getOptionalInput("languages")).includes("rust" /* rust */) ) { - const experimental = "2.19.3"; const publicPreview = "2.22.1"; const actualVer = (await codeql.getVersion()).version; - if (semver10.lt(actualVer, experimental)) { - throw new ConfigurationError( - `Rust analysis is supported by CodeQL CLI version ${experimental} or higher, but found version ${actualVer}` - ); - } if (semver10.lt(actualVer, publicPreview)) { core22.exportVariable("CODEQL_ENABLE_EXPERIMENTAL_FEATURES" /* EXPERIMENTAL_FEATURES */, "true"); logger2.info("Experimental Rust analysis enabled"); diff --git a/src/init-action.ts b/src/init-action.ts index b226a0cb5d..7a9ba16814 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -349,7 +349,7 @@ async function run( // to the workflow log. No exceptions are thrown. await checkWorkflow(logger, codeql); - // Set CODEQL_ENABLE_EXPERIMENTAL_FEATURES for Rust if between 2.19.3 (included) and 2.22.1 (excluded) + // Set CODEQL_ENABLE_EXPERIMENTAL_FEATURES for Rust if the CLI is older than 2.22.1. // We need to set this environment variable before initializing the config, otherwise Rust // analysis will not be enabled (experimental language packs are only active with that environment // variable set to `true`). @@ -360,14 +360,8 @@ async function run( .getRawLanguagesNoAutodetect(getOptionalInput("languages")) .includes(BuiltInLanguage.rust) ) { - const experimental = "2.19.3"; const publicPreview = "2.22.1"; const actualVer = (await codeql.getVersion()).version; - if (semver.lt(actualVer, experimental)) { - throw new ConfigurationError( - `Rust analysis is supported by CodeQL CLI version ${experimental} or higher, but found version ${actualVer}`, - ); - } if (semver.lt(actualVer, publicPreview)) { core.exportVariable(EnvVar.EXPERIMENTAL_FEATURES, "true"); logger.info("Experimental Rust analysis enabled"); From 0b5c1fb0696653047574fdee4ed4d1ada7229139 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 6 Oct 2026 10:37:32 +0100 Subject: [PATCH 032/107] Remove redundant CLI version requirement from `CppDependencyInstallation` Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- lib/entry-points.js | 10 +++++----- src/analyze.ts | 2 +- src/autobuild.ts | 6 +++--- src/feature-flags.ts | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 5857b85cb0..7baf461da6 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -171882,7 +171882,7 @@ var featureConfig = { defaultValue: false, envVar: "CODEQL_EXTRACTOR_CPP_AUTOINSTALL_DEPENDENCIES", legacyApi: true, - minimumVersion: "2.15.0" + minimumVersion: void 0 }, ["csharp_cache_bmn" /* CsharpCacheBuildModeNone */]: { defaultValue: false, @@ -177508,7 +177508,7 @@ async function determineAutobuildLanguages(codeql, config, logger2) { } return languages; } -async function setupCppAutobuild(codeql, logger2) { +async function setupCppAutobuild(logger2) { const envVar = featureConfig["cpp_dependency_installation_enabled" /* CppDependencyInstallation */].envVar; const featureName = "C++ automatic installation of dependencies"; const gitHubVersion = await getGitHubVersion(); @@ -177519,7 +177519,7 @@ async function setupCppAutobuild(codeql, logger2) { getTemporaryDirectory(), logger2 ); - if (await features.getValue("cpp_dependency_installation_enabled" /* CppDependencyInstallation */, codeql)) { + if (await features.getValue("cpp_dependency_installation_enabled" /* CppDependencyInstallation */)) { if (process.env["RUNNER_ENVIRONMENT" /* RUNNER_ENVIRONMENT */] === "self-hosted" && process.env[envVar] !== "true") { logger2.info( `Disabling ${featureName} as we are on a self-hosted runner.${getWorkflowEventName() !== "dynamic" ? ` To override this, set the ${envVar} environment variable to 'true' in your workflow. See ${"https://docs.github.com/en/actions/learn-github-actions/variables#defining-environment-variables-for-a-single-workflow" /* DEFINE_ENV_VARIABLES */} for more information.` : ""}` @@ -177540,7 +177540,7 @@ async function runAutobuild(config, language, logger2) { logger2.startGroup(`Attempting to automatically build ${language} code`); const codeQL = await getCodeQL(logger2, config.codeQLCmd); if (language === "cpp" /* cpp */) { - await setupCppAutobuild(codeQL, logger2); + await setupCppAutobuild(logger2); } if (config.buildMode) { await codeQL.extractUsingBuildMode(config, language); @@ -177864,7 +177864,7 @@ async function runExtraction(codeql, features, config, logger2) { } if (config.buildMode) { if (language === "cpp" /* cpp */ && config.buildMode === "autobuild" /* Autobuild */) { - await setupCppAutobuild(codeql, logger2); + await setupCppAutobuild(logger2); } if (language === "java" /* java */ && config.buildMode === "none" /* None */) { process.env["CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_DEPENDENCY_DIR"] = getJavaTempDependencyDir(); diff --git a/src/analyze.ts b/src/analyze.ts index d585fd6d83..4eeb447e18 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -124,7 +124,7 @@ export async function runExtraction( language === BuiltInLanguage.cpp && config.buildMode === BuildMode.Autobuild ) { - await setupCppAutobuild(codeql, logger); + await setupCppAutobuild(logger); } // The Java and C# `build-mode: none` extractors place dependencies in the diff --git a/src/autobuild.ts b/src/autobuild.ts index 49b790102d..28f89b115d 100644 --- a/src/autobuild.ts +++ b/src/autobuild.ts @@ -112,7 +112,7 @@ export async function determineAutobuildLanguages( return languages; } -export async function setupCppAutobuild(codeql: CodeQL, logger: Logger) { +export async function setupCppAutobuild(logger: Logger) { const envVar = featureConfig[Feature.CppDependencyInstallation].envVar; const featureName = "C++ automatic installation of dependencies"; const gitHubVersion = await getGitHubVersion(); @@ -123,7 +123,7 @@ export async function setupCppAutobuild(codeql: CodeQL, logger: Logger) { getTemporaryDirectory(), logger, ); - if (await features.getValue(Feature.CppDependencyInstallation, codeql)) { + if (await features.getValue(Feature.CppDependencyInstallation)) { // disable autoinstall on self-hosted runners unless explicitly requested if ( process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] === "self-hosted" && @@ -157,7 +157,7 @@ export async function runAutobuild( logger.startGroup(`Attempting to automatically build ${language} code`); const codeQL = await getCodeQL(logger, config.codeQLCmd); if (language === BuiltInLanguage.cpp) { - await setupCppAutobuild(codeQL, logger); + await setupCppAutobuild(logger); } if (config.buildMode) { await codeQL.extractUsingBuildMode(config, language); diff --git a/src/feature-flags.ts b/src/feature-flags.ts index 59b50e2dfd..f74d0bd250 100644 --- a/src/feature-flags.ts +++ b/src/feature-flags.ts @@ -240,7 +240,7 @@ export const featureConfig = { defaultValue: false, envVar: "CODEQL_EXTRACTOR_CPP_AUTOINSTALL_DEPENDENCIES", legacyApi: true, - minimumVersion: "2.15.0", + minimumVersion: undefined, }, [Feature.CsharpCacheBuildModeNone]: { defaultValue: false, From 8e7104f1977baeca4027ac3108b59f8315395dab Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 6 Oct 2026 10:52:46 +0100 Subject: [PATCH 033/107] Clarify the oldest-version comment in the Rust PR check Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- pr-checks/checks/rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pr-checks/checks/rust.yml b/pr-checks/checks/rust.yml index c7dbd97f56..e0b91ae9ce 100644 --- a/pr-checks/checks/rust.yml +++ b/pr-checks/checks/rust.yml @@ -1,7 +1,7 @@ name: "Rust analysis" description: "Tests creation of a Rust database" versions: - # oldest supported version; experimental rust support, requires action to set `CODEQL_ENABLE_EXPERIMENTAL_FEATURES` + # oldest CodeQL version supported by the Action, where Rust support is experimental and requires the Action to set `CODEQL_ENABLE_EXPERIMENTAL_FEATURES` - stable-v2.20.7 # first public preview version - stable-v2.22.1 From 5d90bea8a60f0a5af605b413e3d74a742ee40692 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Wed, 7 Oct 2026 14:44:12 +0100 Subject: [PATCH 034/107] Add PR number to changelog entry and list it first Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0a72fae33..3d6eaebec1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,9 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th ## [UNRELEASED] +- _Breaking change_: Bump the minimum required CodeQL bundle version to 2.20.7. [#4205](https://github.com/github/codeql-action/pull/4205) - _Upcoming breaking change_: CodeQL version 2.21.2 and earlier were discontinued on 24 September 2026 alongside GitHub Enterprise Server 3.17, and will be unsupported by the next minor release of the CodeQL Action. Added a deprecation warning for customers using these versions of CodeQL. [#4188](https://github.com/github/codeql-action/pull/4188) - Update default CodeQL bundle version to [2.27.2](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.27.2). [#4203](https://github.com/github/codeql-action/pull/4203) -- _Breaking change_: Bump the minimum required CodeQL bundle version to 2.20.7. [#XXXX](https://github.com/github/codeql-action/pull/XXXX) ## 4.38.2 - 24 Sept 2026 From 4f73d1add86c1594c618b23d299266a8c96b616b Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 7 Oct 2026 18:15:22 +0100 Subject: [PATCH 035/107] Include primary cache keys as restore key --- lib/entry-points.js | 6 ++++-- src/dependency-caching.ts | 1 + src/overlay/caching.ts | 2 +- src/overlay/status.ts | 2 +- src/trap-caching.ts | 1 + 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 93084ea9be..6c4e6c20d6 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -174029,7 +174029,7 @@ async function getOverlayStatus(codeql, languages, diskUsage, logger2) { await fs8.promises.mkdir(path9.dirname(statusFile), { recursive: true }); const foundKey = await waitForResultWithTimeLimit( MAX_CACHE_OPERATION_MS, - actionsCache.restoreCache([statusFile], cacheKey3), + actionsCache.restoreCache([statusFile], cacheKey3, [cacheKey3]), () => { logger2.warning("Timed out restoring overlay status from cache."); } @@ -174140,6 +174140,7 @@ async function downloadTrapCaches(codeql, languages, logger2) { const found = await waitForResultWithTimeLimit( MAX_CACHE_OPERATION_MS2, actionsCache2.restoreCache([cacheDir2], preferredKey, [ + preferredKey, // Fall back to any cache with the right key prefix await cachePrefix(codeql, language) ]), @@ -175395,7 +175396,7 @@ async function downloadOverlayBaseDatabaseFromCache(codeql, config, logger2) { actionsCache3.restoreCache( [dbLocation], cacheRestoreKeyPrefix, - void 0, + [cacheRestoreKeyPrefix], { // Azure SDK download (which is the default) uses 128MB segments; see // https://github.com/actions/toolkit/blob/main/packages/cache/README.md. @@ -177680,6 +177681,7 @@ async function downloadDependencyCaches(codeql, features, languages, logger2) { } const primaryKey = await cacheKey2(codeql, features, language, patterns); const restoreKeys = [ + primaryKey, await cachePrefix2(codeql, features, language) ]; logger2.info( diff --git a/src/dependency-caching.ts b/src/dependency-caching.ts index f04d38f46c..e6495f3a7b 100644 --- a/src/dependency-caching.ts +++ b/src/dependency-caching.ts @@ -313,6 +313,7 @@ export async function downloadDependencyCaches( const primaryKey = await cacheKey(codeql, features, language, patterns); const restoreKeys: string[] = [ + primaryKey, await cachePrefix(codeql, features, language), ]; diff --git a/src/overlay/caching.ts b/src/overlay/caching.ts index d246626780..5fb76625f0 100644 --- a/src/overlay/caching.ts +++ b/src/overlay/caching.ts @@ -290,7 +290,7 @@ export async function downloadOverlayBaseDatabaseFromCache( actionsCache.restoreCache( [dbLocation], cacheRestoreKeyPrefix, - undefined, + [cacheRestoreKeyPrefix], { // Azure SDK download (which is the default) uses 128MB segments; see // https://github.com/actions/toolkit/blob/main/packages/cache/README.md. diff --git a/src/overlay/status.ts b/src/overlay/status.ts index 3acf382965..1a321af420 100644 --- a/src/overlay/status.ts +++ b/src/overlay/status.ts @@ -130,7 +130,7 @@ export async function getOverlayStatus( await fs.promises.mkdir(path.dirname(statusFile), { recursive: true }); const foundKey = await waitForResultWithTimeLimit( MAX_CACHE_OPERATION_MS, - actionsCache.restoreCache([statusFile], cacheKey), + actionsCache.restoreCache([statusFile], cacheKey, [cacheKey]), () => { logger.warning("Timed out restoring overlay status from cache."); }, diff --git a/src/trap-caching.ts b/src/trap-caching.ts index a802aac892..093b5399e2 100644 --- a/src/trap-caching.ts +++ b/src/trap-caching.ts @@ -99,6 +99,7 @@ export async function downloadTrapCaches( const found = await waitForResultWithTimeLimit( MAX_CACHE_OPERATION_MS, actionsCache.restoreCache([cacheDir], preferredKey, [ + preferredKey, // Fall back to any cache with the right key prefix await cachePrefix(codeql, language), ]), From a36029cea223e8cc6babbebd4d954d613b851760 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Oct 2026 17:55:12 +0000 Subject: [PATCH 036/107] Bump @octokit/plugin-paginate-rest from 15.0.0 to 16.0.0 Bumps [@octokit/plugin-paginate-rest](https://github.com/octokit/plugin-paginate-rest.js) from 15.0.0 to 16.0.0. - [Release notes](https://github.com/octokit/plugin-paginate-rest.js/releases) - [Commits](https://github.com/octokit/plugin-paginate-rest.js/compare/v15.0.0...v16.0.0) --- updated-dependencies: - dependency-name: "@octokit/plugin-paginate-rest" dependency-version: 16.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 27 ++++++--------------------- package.json | 2 +- pr-checks/package.json | 2 +- 3 files changed, 8 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index 167f0801b3..7a3074c863 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "@actions/io": "^2.0.0", "@actions/tool-cache": "^3.0.1", "@octokit/core": "^7.0.8", - "@octokit/plugin-paginate-rest": "^15.0.0", + "@octokit/plugin-paginate-rest": "^16.0.0", "@octokit/plugin-rest-endpoint-methods": "^18.0.0", "@octokit/plugin-retry": "^8.1.1", "archiver": "^8.0.0", @@ -2205,12 +2205,12 @@ "license": "MIT" }, "node_modules/@octokit/plugin-paginate-rest": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-15.0.0.tgz", - "integrity": "sha512-lw9A9YL5s4VPj+VEx8uMxaxQm2YTgrPDkrLEuZuu18R8TK3oPcXF4K6t52nx6xn1RcogZC9i188sAr/4XYJaQQ==", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-16.0.0.tgz", + "integrity": "sha512-7RtUeGZypAK4EA4LrjTCnsLALNOoUcYh5vOnCNXpdIQVTQCPh4OFu7324iPqAls3KGgVnZktKUnNKZCOKyHrlA==", "license": "MIT", "dependencies": { - "@octokit/types": "^17.0.0" + "@octokit/types": "^18.0.0" }, "engines": { "node": ">= 20" @@ -2219,21 +2219,6 @@ "@octokit/core": ">=6" } }, - "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": { - "version": "28.0.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-28.0.0.tgz", - "integrity": "sha512-0rFyLuyHvIj6uuZWuDslxkowFYdPXoNIkeAv4b27dzm2Tf4vGWXnPsMcxs7d65kLdMERgP3wc1AEPlqMz8e1cQ==", - "license": "MIT" - }, - "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-17.0.0.tgz", - "integrity": "sha512-ByP1v7YL5SMveFPP7+sj0/ZuWCOOg/Chs4NafOMpq6WNIM/hdGY0S7C0TCGDBWu1aGmOxmUIhMx3cO+IdwYZ1Q==", - "license": "MIT", - "dependencies": { - "@octokit/openapi-types": "^28.0.0" - } - }, "node_modules/@octokit/plugin-request-log": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", @@ -10500,7 +10485,7 @@ "@actions/core": "^2.0.3", "@actions/github": "^8.0.1", "@octokit/core": "^7.0.8", - "@octokit/plugin-paginate-rest": ">=15.0.0", + "@octokit/plugin-paginate-rest": ">=16.0.0", "@octokit/plugin-rest-endpoint-methods": "^18.0.0", "lite-matter": "^0.1.2", "mdast-util-from-markdown": "^2.0.3", diff --git a/package.json b/package.json index 5ebf14292b..d1e8b11882 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "@actions/io": "^2.0.0", "@actions/tool-cache": "^3.0.1", "@octokit/core": "^7.0.8", - "@octokit/plugin-paginate-rest": "^15.0.0", + "@octokit/plugin-paginate-rest": "^16.0.0", "@octokit/plugin-rest-endpoint-methods": "^18.0.0", "@octokit/plugin-retry": "^8.1.1", "archiver": "^8.0.0", diff --git a/pr-checks/package.json b/pr-checks/package.json index 3d6b3d07e6..468ba3995b 100644 --- a/pr-checks/package.json +++ b/pr-checks/package.json @@ -6,7 +6,7 @@ "@actions/core": "^2.0.3", "@actions/github": "^8.0.1", "@octokit/core": "^7.0.8", - "@octokit/plugin-paginate-rest": ">=15.0.0", + "@octokit/plugin-paginate-rest": ">=16.0.0", "@octokit/plugin-rest-endpoint-methods": "^18.0.0", "lite-matter": "^0.1.2", "mdast-util-from-markdown": "^2.0.3", From d5b1e793ceebf90fcdb4496df09f896e046ffbc0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Oct 2026 17:55:31 +0000 Subject: [PATCH 037/107] Bump eslint-plugin-jsdoc from 64.5.4 to 65.0.1 Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 64.5.4 to 65.0.1. - [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases) - [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v64.5.4...v65.0.1) --- updated-dependencies: - dependency-name: eslint-plugin-jsdoc dependency-version: 65.0.1 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 10 +++++----- package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 167f0801b3..768dc7edf1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -58,7 +58,7 @@ "eslint-import-resolver-typescript": "^4.4.5", "eslint-plugin-github": "^6.1.2", "eslint-plugin-import-x": "^4.17.1", - "eslint-plugin-jsdoc": "^64.5.4", + "eslint-plugin-jsdoc": "^65.0.1", "eslint-plugin-no-async-foreach": "^0.1.1", "glob": "^13.0.6", "globals": "^17.12.0", @@ -5381,15 +5381,15 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "64.5.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-64.5.4.tgz", - "integrity": "sha512-xfRhXPSSWT612muJ6XTvxuVJ8zYHv99qNgBqPVqF28aSqoy4s4XbSkrWXnYA2hl5ejC02yEpk6fqkj3BmJ6Xbg==", + "version": "65.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-65.0.1.tgz", + "integrity": "sha512-7IvB+ZS71WCw5tGKh6f6D5k55qtXKdrGTnIpQTBKWdpyZ5IfhGHfh0i6ArWlCJ4JEtz22YRk5Bqu1MvbOlpMKQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "@es-joy/jsdoccomment": "~0.98.0", "@es-joy/resolve.exports": "1.2.0", - "@typescript-eslint/utils": "^8.70.0", + "@typescript-eslint/utils": "^8.70.1", "are-docs-informative": "^0.1.1", "comment-parser": "1.4.9", "debug": "^4.4.3", diff --git a/package.json b/package.json index 5ebf14292b..1d5f23bbee 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "eslint-import-resolver-typescript": "^4.4.5", "eslint-plugin-github": "^6.1.2", "eslint-plugin-import-x": "^4.17.1", - "eslint-plugin-jsdoc": "^64.5.4", + "eslint-plugin-jsdoc": "^65.0.1", "eslint-plugin-no-async-foreach": "^0.1.1", "glob": "^13.0.6", "globals": "^17.12.0", From 39f1b3fa8d8dee53e188d34abe2f6aaad7216cfb Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Wed, 7 Oct 2026 13:11:34 -0500 Subject: [PATCH 038/107] Document change-notes process --- CONTRIBUTING.md | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 216097f893..fac24c3d4e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,6 +53,7 @@ Here are a few things you can do that will increase the likelihood of your pull - Write tests. - Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests. - Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). +- For user-facing changes, add a [change-note](#change-notes). ## Releasing (write access required) @@ -129,6 +130,57 @@ To deprecate an older version of the Action: 1. Upgrade the Actions warning for customers using the deprecated version to a non-fatal error, and mention that this version of the Action is no longer supported. 1. Make a PR to bump the `OLDEST_SUPPORTED_MAJOR_VERSION` in [config.ts](pr-checks/config.ts). Once this PR is merged, the release process will no longer backport changes to the deprecated release version. +## Change-notes + +Change-notes are Markdown files used to document user-facing changes. When making a change that affects users, create a change-note file in `unreleased-change-notes/` that describes the change. At the next release, the change-note files in `unreleased-change-notes/` will be combined into a new entry in `CHANGELOG.md`. + +### Change-note file format + +Change-note files must follow a certain format so that they can be automatically validated and processed. Failure to follow the format will result in a failed PR check. + +You may validate your change-note file locally by running `npx tsx pr-checks/changenotes.ts validate`. This command will scan all change-note files in `unreleased-change-notes/` and report any errors. + +#### File name + +Change-note files must be named according to the following pattern: `YYYY-MM-DD-.md`, where `YYYY-MM-DD` is the date of the change and `` is a short non-spaced description of the change. For example, a change-note file for a JSON-related bug fix that was made on January 1st, 2020 might be named `2020-01-01-fix-json-bug.md`. + +#### Frontmatter + +The first line of the file must be a YAML frontmatter block, which is delimited by lines containing three dashes (`---`). The frontmatter block must contain a single `category` field, whose value must be one of the following categories: + +| Category | Description | +| -------- | ----------- | +| `breaking` | A change that introduces backward-incompatible behavior. | +| `feature` | A new capability or behavior added to the Action. | +| `improvement` | An enhancement to existing functionality or performance. | +| `securityFix` | A change that addresses a security vulnerability. | +| `fix` | A bug fix that corrects unexpected behavior. | +| `unship` | Features or options that have been removed. | +| `deprecation` | Deprecation of features that will be removed in future versions. | +| `knownIssue` | A known issue or limitation in the current release. | +| `misc` | Other changes that do not fit into other categories. | + +#### Body + +The body of the change-note file must: + +- Be written in valid [GitHub-Flavored Markdown](https://github.github.com/gfm/). +- Describe the change in a way that is understandable to users of the Action. Limit the description to 1-2 sentences, and avoid technical details that are not relevant to users. +- Be structured as a single unordered Markdown list with hyphen (`-`) bullets. Each list item should describe a single change. If there are multiple changes, use multiple list items. + +### Example change-note file + +``` +--- +category: feature +--- + +- Added support for the SARIF v2.2 specification in the `github/codeql-action/upload` Action. +- Added a new `sarif-version` input to the `github/codeql-action/upload` Action, allowing users to specify the SARIF version to use when uploading results. +``` + + + ## Resources - [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/) From 63c529979039e72d333b3758905228aa4d227785 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 22 May 2026 13:44:34 +0100 Subject: [PATCH 039/107] Move `isInTestMode` to `environment.ts` --- lib/entry-points.js | 6 +++--- src/environment.ts | 9 +++++++++ src/overlay/caching.test.ts | 3 ++- src/util.ts | 18 +++++++----------- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 93084ea9be..0c14c59476 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -166160,6 +166160,9 @@ var Env = class extends ReadOnlyEnv { function getEnv(env = process.env) { return new Env(env); } +function isInTestMode() { + return process.env["CODEQL_ACTION_TEST_MODE" /* TEST_MODE */] === "true"; +} // src/util.ts var fs = __toESM(require("fs")); @@ -169874,9 +169877,6 @@ async function delay(milliseconds, opts) { function isGoodVersion(versionSpec) { return !BROKEN_VERSIONS.includes(versionSpec); } -function isInTestMode() { - return process.env["CODEQL_ACTION_TEST_MODE" /* TEST_MODE */] === "true"; -} function shouldSkipSarifUpload() { return isInTestMode() || process.env["CODEQL_ACTION_SKIP_SARIF_UPLOAD" /* SKIP_SARIF_UPLOAD */] === "true"; } diff --git a/src/environment.ts b/src/environment.ts index bf4bb4f717..971e1ca8de 100644 --- a/src/environment.ts +++ b/src/environment.ts @@ -317,3 +317,12 @@ export class Env< export function getEnv(env: NodeJS.ProcessEnv = process.env): Env { return new Env(env); } + +/** + * Returns whether we are in test mode. This is used by CodeQL Action PR checks. + * + * In test mode, we skip several uploads (SARIF results, status reports, DBs, ...). + */ +export function isInTestMode(): boolean { + return process.env[EnvVar.TEST_MODE] === "true"; +} diff --git a/src/overlay/caching.test.ts b/src/overlay/caching.test.ts index daf3483ed5..364eeff9c4 100644 --- a/src/overlay/caching.test.ts +++ b/src/overlay/caching.test.ts @@ -8,6 +8,7 @@ import * as sinon from "sinon"; import * as actionsUtil from "../actions-util"; import * as apiClient from "../api-client"; import type { ResolveDatabaseOutput } from "../codeql"; +import * as environment from "../environment"; import * as gitUtils from "../git-utils"; import { BuiltInLanguage } from "../languages"; import { getRunnerLogger } from "../logging"; @@ -82,7 +83,7 @@ const testDownloadOverlayBaseDatabaseFromCache = makeMacro({ sinon.stub(apiClient, "getAutomationID").resolves("test-automation-id/"); - sinon.stub(utils, "isInTestMode").returns(testCase.isInTestMode); + sinon.stub(environment, "isInTestMode").returns(testCase.isInTestMode); if (testCase.restoreCacheResult instanceof Error) { sinon diff --git a/src/util.ts b/src/util.ts index 49a69f0355..26b27e5bad 100644 --- a/src/util.ts +++ b/src/util.ts @@ -14,13 +14,18 @@ import * as apiCompatibility from "./api-compatibility.json"; import type { CodeQL } from "./codeql"; import type { Pack } from "./config/db-config"; import type { Config } from "./config-utils"; -import { EnvVar, getRequiredEnvParam } from "./environment"; +import { EnvVar, getRequiredEnvParam, isInTestMode } from "./environment"; import * as json from "./json"; import { Language } from "./languages"; import { Logger } from "./logging"; // Re-export for backwards compatibility to avoid updating a lot of imports elsewhere. -export { getRequiredEnvParam, getOptionalEnvVar, getEnv } from "./environment"; +export { + getRequiredEnvParam, + getOptionalEnvVar, + getEnv, + isInTestMode, +} from "./environment"; /** * The name of the file containing the base database OIDs, as stored in the @@ -711,15 +716,6 @@ export function isGoodVersion(versionSpec: string) { return !BROKEN_VERSIONS.includes(versionSpec); } -/** - * Returns whether we are in test mode. This is used by CodeQL Action PR checks. - * - * In test mode, we skip several uploads (SARIF results, status reports, DBs, ...). - */ -export function isInTestMode(): boolean { - return process.env[EnvVar.TEST_MODE] === "true"; -} - /** * Returns whether we specifically want to skip uploading SARIF files. */ From 1728f0c676027d01c7e878d19f05b6d7970ff967 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 22 May 2026 13:52:43 +0100 Subject: [PATCH 040/107] Add wrapper around `core.exportVariable` --- lib/entry-points.js | 919 +++++++++++++++++++------------------ src/actions-util.ts | 2 - src/analyze-action.ts | 7 +- src/api-client.ts | 3 +- src/autobuild-action.ts | 8 +- src/autobuild.ts | 12 +- src/codeql.ts | 4 +- src/config-utils.ts | 7 +- src/debug-artifacts.ts | 4 +- src/environment.ts | 63 ++- src/init-action-post.ts | 6 +- src/init-action.ts | 34 +- src/init.test.ts | 19 +- src/init.ts | 5 +- src/setup-codeql-action.ts | 2 +- src/setup-codeql.ts | 5 +- src/status-report.ts | 22 +- src/testing-utils.ts | 10 +- src/upload-lib.ts | 6 +- src/util.ts | 23 +- 20 files changed, 633 insertions(+), 528 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 0c14c59476..258262f2da 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -21641,7 +21641,7 @@ var require_core = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.platform = exports2.toPlatformPath = exports2.toWin32Path = exports2.toPosixPath = exports2.markdownSummary = exports2.summary = exports2.ExitCode = void 0; - exports2.exportVariable = exportVariable17; + exports2.exportVariable = exportVariable3; exports2.setSecret = setSecret2; exports2.addPath = addPath2; exports2.getInput = getInput2; @@ -21673,7 +21673,7 @@ var require_core = __commonJS({ ExitCode2[ExitCode2["Success"] = 0] = "Success"; ExitCode2[ExitCode2["Failure"] = 1] = "Failure"; })(ExitCode || (exports2.ExitCode = ExitCode = {})); - function exportVariable17(name, val) { + function exportVariable3(name, val) { const convertedVal = (0, utils_1.toCommandValue)(val); process.env[name] = convertedVal; const filePath = process.env["GITHUB_ENV"] || ""; @@ -31294,7 +31294,7 @@ var require_internal_glob_options_helper = __commonJS({ })(); Object.defineProperty(exports2, "__esModule", { value: true }); exports2.getOptions = getOptions; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); function getOptions(copy) { const result = { followSymbolicLinks: true, @@ -31306,23 +31306,23 @@ var require_internal_glob_options_helper = __commonJS({ if (copy) { if (typeof copy.followSymbolicLinks === "boolean") { result.followSymbolicLinks = copy.followSymbolicLinks; - core32.debug(`followSymbolicLinks '${result.followSymbolicLinks}'`); + core29.debug(`followSymbolicLinks '${result.followSymbolicLinks}'`); } if (typeof copy.implicitDescendants === "boolean") { result.implicitDescendants = copy.implicitDescendants; - core32.debug(`implicitDescendants '${result.implicitDescendants}'`); + core29.debug(`implicitDescendants '${result.implicitDescendants}'`); } if (typeof copy.matchDirectories === "boolean") { result.matchDirectories = copy.matchDirectories; - core32.debug(`matchDirectories '${result.matchDirectories}'`); + core29.debug(`matchDirectories '${result.matchDirectories}'`); } if (typeof copy.omitBrokenSymbolicLinks === "boolean") { result.omitBrokenSymbolicLinks = copy.omitBrokenSymbolicLinks; - core32.debug(`omitBrokenSymbolicLinks '${result.omitBrokenSymbolicLinks}'`); + core29.debug(`omitBrokenSymbolicLinks '${result.omitBrokenSymbolicLinks}'`); } if (typeof copy.excludeHiddenFiles === "boolean") { result.excludeHiddenFiles = copy.excludeHiddenFiles; - core32.debug(`excludeHiddenFiles '${result.excludeHiddenFiles}'`); + core29.debug(`excludeHiddenFiles '${result.excludeHiddenFiles}'`); } } return result; @@ -33064,7 +33064,7 @@ var require_internal_globber = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DefaultGlobber = void 0; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var fs32 = __importStar2(require("fs")); var globOptionsHelper = __importStar2(require_internal_glob_options_helper()); var path30 = __importStar2(require("path")); @@ -33117,7 +33117,7 @@ var require_internal_globber = __commonJS({ } const stack = []; for (const searchPath of patternHelper.getSearchPaths(patterns)) { - core32.debug(`Search path '${searchPath}'`); + core29.debug(`Search path '${searchPath}'`); try { yield __await2(fs32.promises.lstat(searchPath)); } catch (err) { @@ -33192,7 +33192,7 @@ var require_internal_globber = __commonJS({ } catch (err) { if (err.code === "ENOENT") { if (options.omitBrokenSymbolicLinks) { - core32.debug(`Broken symlink '${item.path}'`); + core29.debug(`Broken symlink '${item.path}'`); return void 0; } throw new Error(`No information found for the path '${item.path}'. This may indicate a broken symbolic link.`); @@ -33208,7 +33208,7 @@ var require_internal_globber = __commonJS({ traversalChain.pop(); } if (traversalChain.some((x) => x === realPath)) { - core32.debug(`Symlink cycle detected for path '${item.path}' and realpath '${realPath}'`); + core29.debug(`Symlink cycle detected for path '${item.path}' and realpath '${realPath}'`); return void 0; } traversalChain.push(realPath); @@ -33311,7 +33311,7 @@ var require_internal_hash_files = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.hashFiles = hashFiles2; var crypto3 = __importStar2(require("crypto")); - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var fs32 = __importStar2(require("fs")); var stream2 = __importStar2(require("stream")); var util4 = __importStar2(require("util")); @@ -33320,7 +33320,7 @@ var require_internal_hash_files = __commonJS({ return __awaiter2(this, arguments, void 0, function* (globber, currentWorkspace, verbose = false) { var _a6, e_1, _b2, _c2; var _d2; - const writeDelegate = verbose ? core32.info : core32.debug; + const writeDelegate = verbose ? core29.info : core29.debug; let hasMatch = false; const githubWorkspace = currentWorkspace ? currentWorkspace : (_d2 = process.env["GITHUB_WORKSPACE"]) !== null && _d2 !== void 0 ? _d2 : process.cwd(); const result = crypto3.createHash("sha256"); @@ -34712,7 +34712,7 @@ var require_cacheUtils = __commonJS({ exports2.assertDefined = assertDefined; exports2.getCacheVersion = getCacheVersion; exports2.getRuntimeToken = getRuntimeToken; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var exec3 = __importStar2(require_exec()); var glob2 = __importStar2(require_glob()); var io9 = __importStar2(require_io()); @@ -34763,7 +34763,7 @@ var require_cacheUtils = __commonJS({ _e2 = false; const file = _c2; const relativeFile = path30.relative(workspace, file).replace(new RegExp(`\\${path30.sep}`, "g"), "/"); - core32.debug(`Matched: ${relativeFile}`); + core29.debug(`Matched: ${relativeFile}`); if (relativeFile === "") { paths.push("."); } else { @@ -34791,7 +34791,7 @@ var require_cacheUtils = __commonJS({ return __awaiter2(this, arguments, void 0, function* (app, additionalArgs = []) { let versionOutput = ""; additionalArgs.push("--version"); - core32.debug(`Checking ${app} ${additionalArgs.join(" ")}`); + core29.debug(`Checking ${app} ${additionalArgs.join(" ")}`); try { yield exec3.exec(`${app}`, additionalArgs, { ignoreReturnCode: true, @@ -34802,10 +34802,10 @@ var require_cacheUtils = __commonJS({ } }); } catch (err) { - core32.debug(err.message); + core29.debug(err.message); } versionOutput = versionOutput.trim(); - core32.debug(versionOutput); + core29.debug(versionOutput); return versionOutput; }); } @@ -34813,7 +34813,7 @@ var require_cacheUtils = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { const versionOutput = yield getVersion("zstd", ["--quiet"]); const version = semver12.clean(versionOutput); - core32.debug(`zstd version: ${version}`); + core29.debug(`zstd version: ${version}`); if (versionOutput === "") { return constants_1.CompressionMethod.Gzip; } else { @@ -99036,7 +99036,7 @@ var require_uploadUtils = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.UploadProgress = void 0; exports2.uploadCacheArchiveSDK = uploadCacheArchiveSDK; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var storage_blob_1 = require_commonjs15(); var errors_1 = require_errors2(); var UploadProgress = class { @@ -99078,7 +99078,7 @@ var require_uploadUtils = __commonJS({ const percentage = (100 * (transferredBytes / this.contentLength)).toFixed(1); const elapsedTime = Date.now() - this.startTime; const uploadSpeed = (transferredBytes / (1024 * 1024) / (elapsedTime / 1e3)).toFixed(1); - core32.info(`Sent ${transferredBytes} of ${this.contentLength} (${percentage}%), ${uploadSpeed} MBs/sec`); + core29.info(`Sent ${transferredBytes} of ${this.contentLength} (${percentage}%), ${uploadSpeed} MBs/sec`); if (this.isDone()) { this.displayedComplete = true; } @@ -99135,14 +99135,14 @@ var require_uploadUtils = __commonJS({ }; try { uploadProgress.startDisplayTimer(); - core32.debug(`BlobClient: ${blobClient.name}:${blobClient.accountName}:${blobClient.containerName}`); + core29.debug(`BlobClient: ${blobClient.name}:${blobClient.accountName}:${blobClient.containerName}`); const response = yield blockBlobClient.uploadFile(archivePath, uploadOptions); if (response._response.status >= 400) { throw new errors_1.InvalidResponseError(`uploadCacheArchiveSDK: upload failed with status code ${response._response.status}`); } return response; } catch (error3) { - core32.warning(`uploadCacheArchiveSDK: internal error uploading cache archive: ${error3.message}`); + core29.warning(`uploadCacheArchiveSDK: internal error uploading cache archive: ${error3.message}`); throw error3; } finally { uploadProgress.stopDisplayTimer(); @@ -99227,7 +99227,7 @@ var require_requestUtils = __commonJS({ exports2.retry = retry2; exports2.retryTypedResponse = retryTypedResponse; exports2.retryHttpClientResponse = retryHttpClientResponse; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var http_client_1 = require_lib(); var constants_1 = require_constants7(); function isSuccessStatusCode(statusCode) { @@ -99285,9 +99285,9 @@ var require_requestUtils = __commonJS({ isRetryable = isRetryableStatusCode(statusCode); errorMessage = `Cache service responded with ${statusCode}`; } - core32.debug(`${name} - Attempt ${attempt} of ${maxAttempts} failed with error: ${errorMessage}`); + core29.debug(`${name} - Attempt ${attempt} of ${maxAttempts} failed with error: ${errorMessage}`); if (!isRetryable) { - core32.debug(`${name} - Error is not retryable`); + core29.debug(`${name} - Error is not retryable`); break; } yield sleep(delay2); @@ -99546,7 +99546,7 @@ var require_downloadUtils = __commonJS({ exports2.downloadCacheHttpClient = downloadCacheHttpClient; exports2.downloadCacheHttpClientConcurrent = downloadCacheHttpClientConcurrent; exports2.downloadCacheStorageSDK = downloadCacheStorageSDK; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var http_client_1 = require_lib(); var storage_blob_1 = require_commonjs15(); var buffer = __importStar2(require("buffer")); @@ -99584,7 +99584,7 @@ var require_downloadUtils = __commonJS({ this.segmentIndex = this.segmentIndex + 1; this.segmentSize = segmentSize; this.receivedBytes = 0; - core32.debug(`Downloading segment at offset ${this.segmentOffset} with length ${this.segmentSize}...`); + core29.debug(`Downloading segment at offset ${this.segmentOffset} with length ${this.segmentSize}...`); } /** * Sets the number of bytes received for the current segment. @@ -99618,7 +99618,7 @@ var require_downloadUtils = __commonJS({ const percentage = (100 * (transferredBytes / this.contentLength)).toFixed(1); const elapsedTime = Date.now() - this.startTime; const downloadSpeed = (transferredBytes / (1024 * 1024) / (elapsedTime / 1e3)).toFixed(1); - core32.info(`Received ${transferredBytes} of ${this.contentLength} (${percentage}%), ${downloadSpeed} MBs/sec`); + core29.info(`Received ${transferredBytes} of ${this.contentLength} (${percentage}%), ${downloadSpeed} MBs/sec`); if (this.isDone()) { this.displayedComplete = true; } @@ -99668,7 +99668,7 @@ var require_downloadUtils = __commonJS({ })); downloadResponse.message.socket.setTimeout(constants_1.SocketTimeout, () => { downloadResponse.message.destroy(); - core32.debug(`Aborting download, socket timed out after ${constants_1.SocketTimeout} ms`); + core29.debug(`Aborting download, socket timed out after ${constants_1.SocketTimeout} ms`); }); yield pipeResponseToStream(downloadResponse, writeStream); const contentLengthHeader = downloadResponse.message.headers["content-length"]; @@ -99679,7 +99679,7 @@ var require_downloadUtils = __commonJS({ throw new Error(`Incomplete download. Expected file size: ${expectedLength}, actual file size: ${actualLength}`); } } else { - core32.debug("Unable to validate download, no Content-Length header"); + core29.debug("Unable to validate download, no Content-Length header"); } }); } @@ -99797,7 +99797,7 @@ var require_downloadUtils = __commonJS({ const properties = yield client.getProperties(); const contentLength = (_a6 = properties.contentLength) !== null && _a6 !== void 0 ? _a6 : -1; if (contentLength < 0) { - core32.debug("Unable to determine content length, downloading file with http-client..."); + core29.debug("Unable to determine content length, downloading file with http-client..."); yield downloadCacheHttpClient(archiveLocation, archivePath); } else { const maxSegmentSize = Math.min(134217728, buffer.constants.MAX_LENGTH); @@ -99887,7 +99887,7 @@ var require_options = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.getUploadOptions = getUploadOptions; exports2.getDownloadOptions = getDownloadOptions; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); function getUploadOptions(copy) { const result = { useAzureSdk: false, @@ -99907,9 +99907,9 @@ var require_options = __commonJS({ } result.uploadConcurrency = !isNaN(Number(process.env["CACHE_UPLOAD_CONCURRENCY"])) ? Math.min(32, Number(process.env["CACHE_UPLOAD_CONCURRENCY"])) : result.uploadConcurrency; result.uploadChunkSize = !isNaN(Number(process.env["CACHE_UPLOAD_CHUNK_SIZE"])) ? Math.min(128 * 1024 * 1024, Number(process.env["CACHE_UPLOAD_CHUNK_SIZE"]) * 1024 * 1024) : result.uploadChunkSize; - core32.debug(`Use Azure SDK: ${result.useAzureSdk}`); - core32.debug(`Upload concurrency: ${result.uploadConcurrency}`); - core32.debug(`Upload chunk size: ${result.uploadChunkSize}`); + core29.debug(`Use Azure SDK: ${result.useAzureSdk}`); + core29.debug(`Upload concurrency: ${result.uploadConcurrency}`); + core29.debug(`Upload chunk size: ${result.uploadChunkSize}`); return result; } function getDownloadOptions(copy) { @@ -99945,12 +99945,12 @@ var require_options = __commonJS({ if (segmentDownloadTimeoutMins && !isNaN(Number(segmentDownloadTimeoutMins)) && isFinite(Number(segmentDownloadTimeoutMins))) { result.segmentTimeoutInMs = Number(segmentDownloadTimeoutMins) * 60 * 1e3; } - core32.debug(`Use Azure SDK: ${result.useAzureSdk}`); - core32.debug(`Download concurrency: ${result.downloadConcurrency}`); - core32.debug(`Request timeout (ms): ${result.timeoutInMs}`); - core32.debug(`Cache segment download timeout mins env var: ${process.env["SEGMENT_DOWNLOAD_TIMEOUT_MINS"]}`); - core32.debug(`Segment download timeout (ms): ${result.segmentTimeoutInMs}`); - core32.debug(`Lookup only: ${result.lookupOnly}`); + core29.debug(`Use Azure SDK: ${result.useAzureSdk}`); + core29.debug(`Download concurrency: ${result.downloadConcurrency}`); + core29.debug(`Request timeout (ms): ${result.timeoutInMs}`); + core29.debug(`Cache segment download timeout mins env var: ${process.env["SEGMENT_DOWNLOAD_TIMEOUT_MINS"]}`); + core29.debug(`Segment download timeout (ms): ${result.segmentTimeoutInMs}`); + core29.debug(`Lookup only: ${result.lookupOnly}`); return result; } } @@ -100161,7 +100161,7 @@ var require_cacheHttpClient = __commonJS({ exports2.downloadCache = downloadCache; exports2.reserveCache = reserveCache; exports2.saveCache = saveCache5; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var http_client_1 = require_lib(); var auth_1 = require_auth(); var fs32 = __importStar2(require("fs")); @@ -100180,7 +100180,7 @@ var require_cacheHttpClient = __commonJS({ throw new Error("Cache Service Url not found, unable to restore cache."); } const url2 = `${baseUrl}_apis/artifactcache/${resource}`; - core32.debug(`Resource Url: ${url2}`); + core29.debug(`Resource Url: ${url2}`); return url2; } function createAcceptHeader(type, apiVersion) { @@ -100209,7 +100209,7 @@ var require_cacheHttpClient = __commonJS({ return httpClient.getJson(getCacheApiUrl(resource)); })); if (response.statusCode === 204) { - if (core32.isDebug()) { + if (core29.isDebug()) { yield printCachesListForDiagnostics(keys[0], httpClient, version); } return null; @@ -100226,9 +100226,9 @@ var require_cacheHttpClient = __commonJS({ if (!cacheDownloadUrl) { throw new Error("Cache not found."); } - core32.setSecret(cacheDownloadUrl); - core32.debug(`Cache Result:`); - core32.debug(JSON.stringify(cacheResult)); + core29.setSecret(cacheDownloadUrl); + core29.debug(`Cache Result:`); + core29.debug(JSON.stringify(cacheResult)); return cacheResult; }); } @@ -100242,10 +100242,10 @@ var require_cacheHttpClient = __commonJS({ const cacheListResult = response.result; const totalCount = cacheListResult === null || cacheListResult === void 0 ? void 0 : cacheListResult.totalCount; if (totalCount && totalCount > 0) { - core32.debug(`No matching cache found for cache key '${key}', version '${version} and scope ${process.env["GITHUB_REF"]}. There exist one or more cache(s) with similar key but they have different version or scope. See more info on cache matching here: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key + core29.debug(`No matching cache found for cache key '${key}', version '${version} and scope ${process.env["GITHUB_REF"]}. There exist one or more cache(s) with similar key but they have different version or scope. See more info on cache matching here: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key Other caches with similar key:`); for (const cacheEntry of (cacheListResult === null || cacheListResult === void 0 ? void 0 : cacheListResult.artifactCaches) || []) { - core32.debug(`Cache Key: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheKey}, Cache Version: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheVersion}, Cache Scope: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.scope}, Cache Created: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.creationTime}`); + core29.debug(`Cache Key: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheKey}, Cache Version: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.cacheVersion}, Cache Scope: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.scope}, Cache Created: ${cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.creationTime}`); } } } @@ -100288,7 +100288,7 @@ Other caches with similar key:`); } function uploadChunk(httpClient, resourceUrl, openStream, start, end) { return __awaiter2(this, void 0, void 0, function* () { - core32.debug(`Uploading chunk of size ${end - start + 1} bytes at offset ${start} with content range: ${getContentRange(start, end)}`); + core29.debug(`Uploading chunk of size ${end - start + 1} bytes at offset ${start} with content range: ${getContentRange(start, end)}`); const additionalHeaders = { "Content-Type": "application/octet-stream", "Content-Range": getContentRange(start, end) @@ -100310,7 +100310,7 @@ Other caches with similar key:`); const concurrency = utils.assertDefined("uploadConcurrency", uploadOptions.uploadConcurrency); const maxChunkSize = utils.assertDefined("uploadChunkSize", uploadOptions.uploadChunkSize); const parallelUploads = [...new Array(concurrency).keys()]; - core32.debug("Awaiting all uploads"); + core29.debug("Awaiting all uploads"); let offset = 0; try { yield Promise.all(parallelUploads.map(() => __awaiter2(this, void 0, void 0, function* () { @@ -100353,16 +100353,16 @@ Other caches with similar key:`); yield (0, uploadUtils_1.uploadCacheArchiveSDK)(signedUploadURL, archivePath, options); } else { const httpClient = createHttpClient(); - core32.debug("Upload cache"); + core29.debug("Upload cache"); yield uploadFile(httpClient, cacheId, archivePath, options); - core32.debug("Commiting cache"); + core29.debug("Commiting cache"); const cacheSize = utils.getArchiveFileSizeInBytes(archivePath); - core32.info(`Cache Size: ~${Math.round(cacheSize / (1024 * 1024))} MB (${cacheSize} B)`); + core29.info(`Cache Size: ~${Math.round(cacheSize / (1024 * 1024))} MB (${cacheSize} B)`); const commitCacheResponse = yield commitCache(httpClient, cacheId, cacheSize); if (!(0, requestUtils_1.isSuccessStatusCode)(commitCacheResponse.statusCode)) { throw new Error(`Cache service responded with ${commitCacheResponse.statusCode} during commit cache.`); } - core32.info("Cache saved successfully"); + core29.info("Cache saved successfully"); } }); } @@ -105845,7 +105845,7 @@ var require_cache4 = __commonJS({ exports2.isFeatureAvailable = isFeatureAvailable; exports2.restoreCache = restoreCache5; exports2.saveCache = saveCache5; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var path30 = __importStar2(require("path")); var utils = __importStar2(require_cacheUtils()); var cacheHttpClient = __importStar2(require_cacheHttpClient()); @@ -105923,12 +105923,12 @@ var require_cache4 = __commonJS({ function restoreCache5(paths_1, primaryKey_1, restoreKeys_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); - core32.debug(`Cache service version: ${cacheServiceVersion}`); + core29.debug(`Cache service version: ${cacheServiceVersion}`); checkPaths(paths); const cacheMode = (0, config_1.getCacheMode)(); if (!(0, config_1.isCacheReadable)(cacheMode)) { - core32.info(`Cache restore skipped: the effective cache-mode '${cacheMode}' does not permit reads.`); - core32.debug(`Skipped restore for paths [${paths.join(", ")}] with primary key '${primaryKey}'.`); + core29.info(`Cache restore skipped: the effective cache-mode '${cacheMode}' does not permit reads.`); + core29.debug(`Skipped restore for paths [${paths.join(", ")}] with primary key '${primaryKey}'.`); return void 0; } switch (cacheServiceVersion) { @@ -105945,8 +105945,8 @@ var require_cache4 = __commonJS({ var _a6; restoreKeys = restoreKeys || []; const keys = [primaryKey, ...restoreKeys]; - core32.debug("Resolved Keys:"); - core32.debug(JSON.stringify(keys)); + core29.debug("Resolved Keys:"); + core29.debug(JSON.stringify(keys)); if (keys.length > 10) { throw new ValidationError(`Key Validation Error: Keys are limited to a maximum of 10.`); } @@ -105973,19 +105973,19 @@ var require_cache4 = __commonJS({ return void 0; } if (options === null || options === void 0 ? void 0 : options.lookupOnly) { - core32.info("Lookup only - skipping download"); + core29.info("Lookup only - skipping download"); return cacheEntry.cacheKey; } archivePath = path30.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); - core32.debug(`Archive Path: ${archivePath}`); + core29.debug(`Archive Path: ${archivePath}`); yield cacheHttpClient.downloadCache(cacheEntry.archiveLocation, archivePath, options); - if (core32.isDebug()) { + if (core29.isDebug()) { yield (0, tar_1.listTar)(archivePath, compressionMethod); } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); - core32.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); + core29.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); yield (0, tar_1.extractTar)(archivePath, compressionMethod); - core32.info("Cache restored successfully"); + core29.info("Cache restored successfully"); return cacheEntry.cacheKey; } catch (error3) { const typedError = error3; @@ -105993,16 +105993,16 @@ var require_cache4 = __commonJS({ throw error3; } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { - core32.error(`Failed to restore: ${error3.message}`); + core29.error(`Failed to restore: ${error3.message}`); } else { - core32.warning(`Failed to restore: ${error3.message}`); + core29.warning(`Failed to restore: ${error3.message}`); } } } finally { try { yield utils.unlinkFile(archivePath); } catch (error3) { - core32.debug(`Failed to delete archive: ${error3}`); + core29.debug(`Failed to delete archive: ${error3}`); } } return void 0; @@ -106014,8 +106014,8 @@ var require_cache4 = __commonJS({ options = Object.assign(Object.assign({}, options), { useAzureSdk: true }); restoreKeys = restoreKeys || []; const keys = [primaryKey, ...restoreKeys]; - core32.debug("Resolved Keys:"); - core32.debug(JSON.stringify(keys)); + core29.debug("Resolved Keys:"); + core29.debug(JSON.stringify(keys)); if (keys.length > 10) { throw new ValidationError(`Key Validation Error: Keys are limited to a maximum of 10.`); } @@ -106042,30 +106042,30 @@ var require_cache4 = __commonJS({ throw error3; } if (!response.ok) { - core32.debug(`Cache not found for version ${request3.version} of keys: ${keys.join(", ")}`); + core29.debug(`Cache not found for version ${request3.version} of keys: ${keys.join(", ")}`); return void 0; } const isRestoreKeyMatch = request3.key !== response.matchedKey; if (isRestoreKeyMatch) { - core32.info(`Cache hit for restore-key: ${response.matchedKey}`); + core29.info(`Cache hit for restore-key: ${response.matchedKey}`); } else { - core32.info(`Cache hit for: ${response.matchedKey}`); + core29.info(`Cache hit for: ${response.matchedKey}`); } if (options === null || options === void 0 ? void 0 : options.lookupOnly) { - core32.info("Lookup only - skipping download"); + core29.info("Lookup only - skipping download"); return response.matchedKey; } archivePath = path30.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); - core32.debug(`Archive path: ${archivePath}`); - core32.debug(`Starting download of archive to: ${archivePath}`); + core29.debug(`Archive path: ${archivePath}`); + core29.debug(`Starting download of archive to: ${archivePath}`); yield cacheHttpClient.downloadCache(response.signedDownloadUrl, archivePath, options); const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); - core32.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); - if (core32.isDebug()) { + core29.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); + if (core29.isDebug()) { yield (0, tar_1.listTar)(archivePath, compressionMethod); } yield (0, tar_1.extractTar)(archivePath, compressionMethod); - core32.info("Cache restored successfully"); + core29.info("Cache restored successfully"); return response.matchedKey; } catch (error3) { const typedError = error3; @@ -106073,9 +106073,9 @@ var require_cache4 = __commonJS({ throw error3; } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { - core32.error(`Failed to restore: ${error3.message}`); + core29.error(`Failed to restore: ${error3.message}`); } else { - core32.warning(`Failed to restore: ${error3.message}`); + core29.warning(`Failed to restore: ${error3.message}`); } } } finally { @@ -106084,7 +106084,7 @@ var require_cache4 = __commonJS({ yield utils.unlinkFile(archivePath); } } catch (error3) { - core32.debug(`Failed to delete archive: ${error3}`); + core29.debug(`Failed to delete archive: ${error3}`); } } return void 0; @@ -106093,13 +106093,13 @@ var require_cache4 = __commonJS({ function saveCache5(paths_1, key_1, options_1) { return __awaiter2(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) { const cacheServiceVersion = (0, config_1.getCacheServiceVersion)(); - core32.debug(`Cache service version: ${cacheServiceVersion}`); + core29.debug(`Cache service version: ${cacheServiceVersion}`); checkPaths(paths); checkKey(key); const cacheMode = (0, config_1.getCacheMode)(); if (!(0, config_1.isCacheWritable)(cacheMode)) { - core32.info(`Cache save skipped: the effective cache-mode '${cacheMode}' does not permit writes.`); - core32.debug(`Skipped save for paths [${paths.join(", ")}] with key '${key}'.`); + core29.info(`Cache save skipped: the effective cache-mode '${cacheMode}' does not permit writes.`); + core29.debug(`Skipped save for paths [${paths.join(", ")}] with key '${key}'.`); return -1; } switch (cacheServiceVersion) { @@ -106117,26 +106117,26 @@ var require_cache4 = __commonJS({ const compressionMethod = yield utils.getCompressionMethod(); let cacheId = -1; const cachePaths = yield utils.resolvePaths(paths); - core32.debug("Cache Paths:"); - core32.debug(`${JSON.stringify(cachePaths)}`); + core29.debug("Cache Paths:"); + core29.debug(`${JSON.stringify(cachePaths)}`); if (cachePaths.length === 0) { throw new Error(`Path Validation Error: Path(s) specified in the action for caching do(es) not exist, hence no cache is being saved.`); } const archiveFolder = yield utils.createTempDirectory(); const archivePath = path30.join(archiveFolder, utils.getCacheFileName(compressionMethod)); - core32.debug(`Archive Path: ${archivePath}`); + core29.debug(`Archive Path: ${archivePath}`); try { yield (0, tar_1.createTar)(archiveFolder, cachePaths, compressionMethod); - if (core32.isDebug()) { + if (core29.isDebug()) { yield (0, tar_1.listTar)(archivePath, compressionMethod); } const fileSizeLimit = 10 * 1024 * 1024 * 1024; const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); - core32.debug(`File Size: ${archiveFileSize}`); + core29.debug(`File Size: ${archiveFileSize}`); if (archiveFileSize > fileSizeLimit && !(0, config_1.isGhes)()) { throw new Error(`Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`); } - core32.debug("Reserving Cache"); + core29.debug("Reserving Cache"); const reserveCacheResponse = yield cacheHttpClient.reserveCache(key, paths, { compressionMethod, enableCrossOsArchive, @@ -106153,28 +106153,28 @@ var require_cache4 = __commonJS({ } throw new ReserveCacheError2(`Unable to reserve cache with key ${key}, another job may be creating this cache. More details: ${detailMessage}`); } - core32.debug(`Saving Cache (ID: ${cacheId})`); + core29.debug(`Saving Cache (ID: ${cacheId})`); yield cacheHttpClient.saveCache(cacheId, archivePath, "", options); } catch (error3) { const typedError = error3; if (typedError.name === ValidationError.name) { throw error3; } else if (typedError.name === CacheWriteDeniedError.name) { - core32.warning(`Failed to save: ${typedError.message}`); + core29.warning(`Failed to save: ${typedError.message}`); } else if (typedError.name === ReserveCacheError2.name) { - core32.info(`Failed to save: ${typedError.message}`); + core29.info(`Failed to save: ${typedError.message}`); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { - core32.error(`Failed to save: ${typedError.message}`); + core29.error(`Failed to save: ${typedError.message}`); } else { - core32.warning(`Failed to save: ${typedError.message}`); + core29.warning(`Failed to save: ${typedError.message}`); } } } finally { try { yield utils.unlinkFile(archivePath); } catch (error3) { - core32.debug(`Failed to delete archive: ${error3}`); + core29.debug(`Failed to delete archive: ${error3}`); } } return cacheId; @@ -106188,23 +106188,23 @@ var require_cache4 = __commonJS({ const twirpClient = cacheTwirpClient.internalCacheTwirpClient(); let cacheId = -1; const cachePaths = yield utils.resolvePaths(paths); - core32.debug("Cache Paths:"); - core32.debug(`${JSON.stringify(cachePaths)}`); + core29.debug("Cache Paths:"); + core29.debug(`${JSON.stringify(cachePaths)}`); if (cachePaths.length === 0) { throw new Error(`Path Validation Error: Path(s) specified in the action for caching do(es) not exist, hence no cache is being saved.`); } const archiveFolder = yield utils.createTempDirectory(); const archivePath = path30.join(archiveFolder, utils.getCacheFileName(compressionMethod)); - core32.debug(`Archive Path: ${archivePath}`); + core29.debug(`Archive Path: ${archivePath}`); try { yield (0, tar_1.createTar)(archiveFolder, cachePaths, compressionMethod); - if (core32.isDebug()) { + if (core29.isDebug()) { yield (0, tar_1.listTar)(archivePath, compressionMethod); } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); - core32.debug(`File Size: ${archiveFileSize}`); + core29.debug(`File Size: ${archiveFileSize}`); options.archiveSizeBytes = archiveFileSize; - core32.debug("Reserving Cache"); + core29.debug("Reserving Cache"); const version = utils.getCacheVersion(paths, compressionMethod, enableCrossOsArchive); const request3 = { key, @@ -106215,20 +106215,20 @@ var require_cache4 = __commonJS({ const response = yield twirpClient.CreateCacheEntry(request3); if (!response.ok) { if (response.message && !response.message.startsWith(exports2.CACHE_WRITE_DENIED_PREFIX)) { - core32.warning(`Cache reservation failed: ${response.message}`); + core29.warning(`Cache reservation failed: ${response.message}`); } throw new Error(response.message || "Response was not ok"); } signedUploadUrl = response.signedUploadUrl; } catch (error3) { - core32.debug(`Failed to reserve cache: ${error3}`); + core29.debug(`Failed to reserve cache: ${error3}`); const errorMessage = (_a6 = error3 === null || error3 === void 0 ? void 0 : error3.message) !== null && _a6 !== void 0 ? _a6 : ""; if (errorMessage.startsWith(exports2.CACHE_WRITE_DENIED_PREFIX)) { throw new CacheWriteDeniedError(`Unable to reserve cache with key ${key}. More details: ${errorMessage}`); } throw new ReserveCacheError2(`Unable to reserve cache with key ${key}, another job may be creating this cache.`); } - core32.debug(`Attempting to upload cache located at: ${archivePath}`); + core29.debug(`Attempting to upload cache located at: ${archivePath}`); yield cacheHttpClient.saveCache(cacheId, archivePath, signedUploadUrl, options); const finalizeRequest = { key, @@ -106236,7 +106236,7 @@ var require_cache4 = __commonJS({ sizeBytes: `${archiveFileSize}` }; const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest); - core32.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); + core29.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); if (!finalizeResponse.ok) { if (finalizeResponse.message) { throw new FinalizeCacheError(finalizeResponse.message); @@ -106249,23 +106249,23 @@ var require_cache4 = __commonJS({ if (typedError.name === ValidationError.name) { throw error3; } else if (typedError.name === CacheWriteDeniedError.name) { - core32.warning(`Failed to save: ${typedError.message}`); + core29.warning(`Failed to save: ${typedError.message}`); } else if (typedError.name === ReserveCacheError2.name) { - core32.info(`Failed to save: ${typedError.message}`); + core29.info(`Failed to save: ${typedError.message}`); } else if (typedError.name === FinalizeCacheError.name) { - core32.warning(typedError.message); + core29.warning(typedError.message); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { - core32.error(`Failed to save: ${typedError.message}`); + core29.error(`Failed to save: ${typedError.message}`); } else { - core32.warning(`Failed to save: ${typedError.message}`); + core29.warning(`Failed to save: ${typedError.message}`); } } } finally { try { yield utils.unlinkFile(archivePath); } catch (error3) { - core32.debug(`Failed to delete archive: ${error3}`); + core29.debug(`Failed to delete archive: ${error3}`); } } return cacheId; @@ -106492,7 +106492,7 @@ var require_retry_helper = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.RetryHelper = void 0; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var RetryHelper = class { constructor(maxAttempts, minSeconds, maxSeconds) { if (maxAttempts < 1) { @@ -106515,10 +106515,10 @@ var require_retry_helper = __commonJS({ if (isRetryable && !isRetryable(err)) { throw err; } - core32.info(err.message); + core29.info(err.message); } const seconds = this.getSleepAmount(); - core32.info(`Waiting ${seconds} seconds before trying again`); + core29.info(`Waiting ${seconds} seconds before trying again`); yield this.sleep(seconds); attempt++; } @@ -106621,7 +106621,7 @@ var require_tool_cache = __commonJS({ exports2.findFromManifest = findFromManifest; exports2.isExplicitVersion = isExplicitVersion; exports2.evaluateVersions = evaluateVersions; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var io9 = __importStar2(require_io()); var crypto3 = __importStar2(require("crypto")); var fs32 = __importStar2(require("fs")); @@ -106650,8 +106650,8 @@ var require_tool_cache = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { dest = dest || path30.join(_getTempDirectory(), crypto3.randomUUID()); yield io9.mkdirP(path30.dirname(dest)); - core32.debug(`Downloading ${url2}`); - core32.debug(`Destination ${dest}`); + core29.debug(`Downloading ${url2}`); + core29.debug(`Destination ${dest}`); const maxAttempts = 3; const minSeconds = _getGlobal("TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS", 10); const maxSeconds = _getGlobal("TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS", 20); @@ -106677,7 +106677,7 @@ var require_tool_cache = __commonJS({ allowRetries: false }); if (auth2) { - core32.debug("set auth"); + core29.debug("set auth"); if (headers === void 0) { headers = {}; } @@ -106686,7 +106686,7 @@ var require_tool_cache = __commonJS({ const response = yield http.get(url2, headers); if (response.message.statusCode !== 200) { const err = new HTTPError2(response.message.statusCode); - core32.debug(`Failed to download from "${url2}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); + core29.debug(`Failed to download from "${url2}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); throw err; } const pipeline2 = util4.promisify(stream2.pipeline); @@ -106695,16 +106695,16 @@ var require_tool_cache = __commonJS({ let succeeded = false; try { yield pipeline2(readStream, fs32.createWriteStream(dest)); - core32.debug("download complete"); + core29.debug("download complete"); succeeded = true; return dest; } finally { if (!succeeded) { - core32.debug("download failed"); + core29.debug("download failed"); try { yield io9.rmRF(dest); } catch (err) { - core32.debug(`Failed to delete '${dest}'. ${err.message}`); + core29.debug(`Failed to delete '${dest}'. ${err.message}`); } } } @@ -106719,7 +106719,7 @@ var require_tool_cache = __commonJS({ process.chdir(dest); if (_7zPath) { try { - const logLevel = core32.isDebug() ? "-bb1" : "-bb0"; + const logLevel = core29.isDebug() ? "-bb1" : "-bb0"; const args = [ "x", // eXtract files with full paths @@ -106772,7 +106772,7 @@ var require_tool_cache = __commonJS({ throw new Error("parameter 'file' is required"); } dest = yield _createExtractFolder(dest); - core32.debug("Checking tar --version"); + core29.debug("Checking tar --version"); let versionOutput = ""; yield (0, exec_1.exec)("tar --version", [], { ignoreReturnCode: true, @@ -106782,7 +106782,7 @@ var require_tool_cache = __commonJS({ stderr: (data) => versionOutput += data.toString() } }); - core32.debug(versionOutput.trim()); + core29.debug(versionOutput.trim()); const isGnuTar = versionOutput.toUpperCase().includes("GNU TAR"); let args; if (flags instanceof Array) { @@ -106790,7 +106790,7 @@ var require_tool_cache = __commonJS({ } else { args = [flags]; } - if (core32.isDebug() && !flags.includes("v")) { + if (core29.isDebug() && !flags.includes("v")) { args.push("-v"); } let destArg = dest; @@ -106821,7 +106821,7 @@ var require_tool_cache = __commonJS({ args = [flags]; } args.push("-x", "-C", dest, "-f", file); - if (core32.isDebug()) { + if (core29.isDebug()) { args.push("-v"); } const xarPath = yield io9.which("xar", true); @@ -106864,7 +106864,7 @@ var require_tool_cache = __commonJS({ "-Command", pwshCommand ]; - core32.debug(`Using pwsh at path: ${pwshPath}`); + core29.debug(`Using pwsh at path: ${pwshPath}`); yield (0, exec_1.exec)(`"${pwshPath}"`, args); } else { const powershellCommand = [ @@ -106884,7 +106884,7 @@ var require_tool_cache = __commonJS({ powershellCommand ]; const powershellPath = yield io9.which("powershell", true); - core32.debug(`Using powershell at path: ${powershellPath}`); + core29.debug(`Using powershell at path: ${powershellPath}`); yield (0, exec_1.exec)(`"${powershellPath}"`, args); } }); @@ -106893,7 +106893,7 @@ var require_tool_cache = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { const unzipPath = yield io9.which("unzip", true); const args = [file]; - if (!core32.isDebug()) { + if (!core29.isDebug()) { args.unshift("-q"); } args.unshift("-o"); @@ -106904,8 +106904,8 @@ var require_tool_cache = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { version = semver12.clean(version) || version; arch2 = arch2 || os7.arch(); - core32.debug(`Caching tool ${tool} ${version} ${arch2}`); - core32.debug(`source dir: ${sourceDir}`); + core29.debug(`Caching tool ${tool} ${version} ${arch2}`); + core29.debug(`source dir: ${sourceDir}`); if (!fs32.statSync(sourceDir).isDirectory()) { throw new Error("sourceDir is not a directory"); } @@ -106922,14 +106922,14 @@ var require_tool_cache = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { version = semver12.clean(version) || version; arch2 = arch2 || os7.arch(); - core32.debug(`Caching tool ${tool} ${version} ${arch2}`); - core32.debug(`source file: ${sourceFile}`); + core29.debug(`Caching tool ${tool} ${version} ${arch2}`); + core29.debug(`source file: ${sourceFile}`); if (!fs32.statSync(sourceFile).isFile()) { throw new Error("sourceFile is not a file"); } const destFolder = yield _createToolPath(tool, version, arch2); const destPath = path30.join(destFolder, targetFile); - core32.debug(`destination file ${destPath}`); + core29.debug(`destination file ${destPath}`); yield io9.cp(sourceFile, destPath); _completeToolPath(tool, version, arch2); return destFolder; @@ -106952,12 +106952,12 @@ var require_tool_cache = __commonJS({ if (versionSpec) { versionSpec = semver12.clean(versionSpec) || ""; const cachePath = path30.join(_getCacheDirectory(), toolName, versionSpec, arch2); - core32.debug(`checking cache: ${cachePath}`); + core29.debug(`checking cache: ${cachePath}`); if (fs32.existsSync(cachePath) && fs32.existsSync(`${cachePath}.complete`)) { - core32.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch2}`); + core29.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch2}`); toolPath = cachePath; } else { - core32.debug("not found"); + core29.debug("not found"); } } return toolPath; @@ -106986,7 +106986,7 @@ var require_tool_cache = __commonJS({ const http = new httpm.HttpClient("tool-cache"); const headers = {}; if (auth2) { - core32.debug("set auth"); + core29.debug("set auth"); headers.authorization = auth2; } const response = yield http.getJson(treeUrl, headers); @@ -107007,7 +107007,7 @@ var require_tool_cache = __commonJS({ try { releases = JSON.parse(versionsRaw); } catch (_a6) { - core32.debug("Invalid json"); + core29.debug("Invalid json"); } } return releases; @@ -107031,7 +107031,7 @@ var require_tool_cache = __commonJS({ function _createToolPath(tool, version, arch2) { return __awaiter2(this, void 0, void 0, function* () { const folderPath = path30.join(_getCacheDirectory(), tool, semver12.clean(version) || version, arch2 || ""); - core32.debug(`destination ${folderPath}`); + core29.debug(`destination ${folderPath}`); const markerPath = `${folderPath}.complete`; yield io9.rmRF(folderPath); yield io9.rmRF(markerPath); @@ -107043,18 +107043,18 @@ var require_tool_cache = __commonJS({ const folderPath = path30.join(_getCacheDirectory(), tool, semver12.clean(version) || version, arch2 || ""); const markerPath = `${folderPath}.complete`; fs32.writeFileSync(markerPath, ""); - core32.debug("finished caching tool"); + core29.debug("finished caching tool"); } function isExplicitVersion(versionSpec) { const c = semver12.clean(versionSpec) || ""; - core32.debug(`isExplicit: ${c}`); + core29.debug(`isExplicit: ${c}`); const valid4 = semver12.valid(c) != null; - core32.debug(`explicit? ${valid4}`); + core29.debug(`explicit? ${valid4}`); return valid4; } function evaluateVersions(versions, versionSpec) { let version = ""; - core32.debug(`evaluating ${versions.length} versions`); + core29.debug(`evaluating ${versions.length} versions`); versions = versions.sort((a, b) => { if (semver12.gt(a, b)) { return 1; @@ -107070,9 +107070,9 @@ var require_tool_cache = __commonJS({ } } if (version) { - core32.debug(`matched: ${version}`); + core29.debug(`matched: ${version}`); } else { - core32.debug("match not found"); + core29.debug("match not found"); } return version; } @@ -112665,14 +112665,14 @@ var require_retention = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.getExpiration = void 0; var generated_1 = require_generated(); - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); function getExpiration(retentionDays) { if (!retentionDays) { return void 0; } const maxRetentionDays = getRetentionDays(); if (maxRetentionDays && maxRetentionDays < retentionDays) { - core32.warning(`Retention days cannot be greater than the maximum allowed retention set within the repository. Using ${maxRetentionDays} instead.`); + core29.warning(`Retention days cannot be greater than the maximum allowed retention set within the repository. Using ${maxRetentionDays} instead.`); retentionDays = maxRetentionDays; } const expirationDate = /* @__PURE__ */ new Date(); @@ -113010,7 +113010,7 @@ var require_util11 = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.maskSecretUrls = exports2.maskSigUrl = exports2.getBackendIdsFromToken = void 0; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var config_1 = require_config2(); var jwt_decode_1 = __importDefault2(require_jwt_decode_cjs()); var core_1 = require_core(); @@ -113037,8 +113037,8 @@ var require_util11 = __commonJS({ workflowRunBackendId: scopeParts[1], workflowJobRunBackendId: scopeParts[2] }; - core32.debug(`Workflow Run Backend ID: ${ids.workflowRunBackendId}`); - core32.debug(`Workflow Job Run Backend ID: ${ids.workflowJobRunBackendId}`); + core29.debug(`Workflow Run Backend ID: ${ids.workflowRunBackendId}`); + core29.debug(`Workflow Job Run Backend ID: ${ids.workflowJobRunBackendId}`); return ids; } throw InvalidJwtError; @@ -113398,7 +113398,7 @@ var require_blob_upload = __commonJS({ exports2.uploadZipToBlobStorage = void 0; var storage_blob_1 = require_commonjs15(); var config_1 = require_config2(); - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var crypto3 = __importStar2(require("crypto")); var stream2 = __importStar2(require("stream")); var errors_1 = require_errors3(); @@ -113424,9 +113424,9 @@ var require_blob_upload = __commonJS({ const bufferSize = (0, config_1.getUploadChunkSize)(); const blobClient = new storage_blob_1.BlobClient(authenticatedUploadURL); const blockBlobClient = blobClient.getBlockBlobClient(); - core32.debug(`Uploading artifact zip to blob storage with maxConcurrency: ${maxConcurrency}, bufferSize: ${bufferSize}`); + core29.debug(`Uploading artifact zip to blob storage with maxConcurrency: ${maxConcurrency}, bufferSize: ${bufferSize}`); const uploadCallback = (progress) => { - core32.info(`Uploaded bytes ${progress.loadedBytes}`); + core29.info(`Uploaded bytes ${progress.loadedBytes}`); uploadByteCount = progress.loadedBytes; lastProgressTime = Date.now(); }; @@ -113440,7 +113440,7 @@ var require_blob_upload = __commonJS({ const hashStream = crypto3.createHash("sha256"); zipUploadStream.pipe(uploadStream); zipUploadStream.pipe(hashStream).setEncoding("hex"); - core32.info("Beginning upload of artifact content to blob storage"); + core29.info("Beginning upload of artifact content to blob storage"); try { yield Promise.race([ blockBlobClient.uploadStream(uploadStream, bufferSize, maxConcurrency, options), @@ -113454,12 +113454,12 @@ var require_blob_upload = __commonJS({ } finally { abortController.abort(); } - core32.info("Finished uploading artifact content to blob storage!"); + core29.info("Finished uploading artifact content to blob storage!"); hashStream.end(); sha256Hash = hashStream.read(); - core32.info(`SHA256 digest of uploaded artifact zip is ${sha256Hash}`); + core29.info(`SHA256 digest of uploaded artifact zip is ${sha256Hash}`); if (uploadByteCount === 0) { - core32.warning(`No data was uploaded to blob storage. Reported upload byte count is 0.`); + core29.warning(`No data was uploaded to blob storage. Reported upload byte count is 0.`); } return { uploadSize: uploadByteCount, @@ -135113,7 +135113,7 @@ var require_zip2 = __commonJS({ var stream2 = __importStar2(require("stream")); var promises_1 = require("fs/promises"); var archiver = __importStar2(require_archiver()); - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var config_1 = require_config2(); exports2.DEFAULT_COMPRESSION_LEVEL = 6; var ZipUploadStream = class extends stream2.Transform { @@ -135130,7 +135130,7 @@ var require_zip2 = __commonJS({ exports2.ZipUploadStream = ZipUploadStream; function createZipUploadStream(uploadSpecification_1) { return __awaiter2(this, arguments, void 0, function* (uploadSpecification, compressionLevel = exports2.DEFAULT_COMPRESSION_LEVEL) { - core32.debug(`Creating Artifact archive with compressionLevel: ${compressionLevel}`); + core29.debug(`Creating Artifact archive with compressionLevel: ${compressionLevel}`); const zip = archiver.create("zip", { highWaterMark: (0, config_1.getUploadChunkSize)(), zlib: { level: compressionLevel } @@ -135154,8 +135154,8 @@ var require_zip2 = __commonJS({ } const bufferSize = (0, config_1.getUploadChunkSize)(); const zipUploadStream = new ZipUploadStream(bufferSize); - core32.debug(`Zip write high watermark value ${zipUploadStream.writableHighWaterMark}`); - core32.debug(`Zip read high watermark value ${zipUploadStream.readableHighWaterMark}`); + core29.debug(`Zip write high watermark value ${zipUploadStream.writableHighWaterMark}`); + core29.debug(`Zip read high watermark value ${zipUploadStream.readableHighWaterMark}`); zip.pipe(zipUploadStream); zip.finalize(); return zipUploadStream; @@ -135163,24 +135163,24 @@ var require_zip2 = __commonJS({ } exports2.createZipUploadStream = createZipUploadStream; var zipErrorCallback = (error3) => { - core32.error("An error has occurred while creating the zip file for upload"); - core32.info(error3); + core29.error("An error has occurred while creating the zip file for upload"); + core29.info(error3); throw new Error("An error has occurred during zip creation for the artifact"); }; var zipWarningCallback = (error3) => { if (error3.code === "ENOENT") { - core32.warning("ENOENT warning during artifact zip creation. No such file or directory"); - core32.info(error3); + core29.warning("ENOENT warning during artifact zip creation. No such file or directory"); + core29.info(error3); } else { - core32.warning(`A non-blocking warning has occurred during artifact zip creation: ${error3.code}`); - core32.info(error3); + core29.warning(`A non-blocking warning has occurred during artifact zip creation: ${error3.code}`); + core29.info(error3); } }; var zipFinishCallback = () => { - core32.debug("Zip stream for upload has finished."); + core29.debug("Zip stream for upload has finished."); }; var zipEndCallback = () => { - core32.debug("Zip stream for upload has ended."); + core29.debug("Zip stream for upload has ended."); }; } }); @@ -135245,7 +135245,7 @@ var require_upload_artifact = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.uploadArtifact = void 0; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var retention_1 = require_retention(); var path_and_artifact_name_validation_1 = require_path_and_artifact_name_validation(); var artifact_twirp_client_1 = require_artifact_twirp_client2(); @@ -135292,13 +135292,13 @@ var require_upload_artifact = __commonJS({ value: `sha256:${uploadResult.sha256Hash}` }); } - core32.info(`Finalizing artifact upload`); + core29.info(`Finalizing artifact upload`); const finalizeArtifactResp = yield artifactClient.FinalizeArtifact(finalizeArtifactReq); if (!finalizeArtifactResp.ok) { throw new errors_1.InvalidResponseError("FinalizeArtifact: response from backend was not ok"); } const artifactId = BigInt(finalizeArtifactResp.artifactId); - core32.info(`Artifact ${name}.zip successfully finalized. Artifact ID ${artifactId}`); + core29.info(`Artifact ${name}.zip successfully finalized. Artifact ID ${artifactId}`); return { size: uploadResult.uploadSize, digest: uploadResult.sha256Hash, @@ -142022,7 +142022,7 @@ var require_download_artifact = __commonJS({ var crypto3 = __importStar2(require("crypto")); var stream2 = __importStar2(require("stream")); var github5 = __importStar2(require_github2()); - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var httpClient = __importStar2(require_lib()); var unzip_stream_1 = __importDefault2(require_unzip()); var user_agent_1 = require_user_agent2(); @@ -142058,7 +142058,7 @@ var require_download_artifact = __commonJS({ return yield streamExtractExternal(url2, directory); } catch (error3) { retryCount++; - core32.debug(`Failed to download artifact after ${retryCount} retries due to ${error3.message}. Retrying in 5 seconds...`); + core29.debug(`Failed to download artifact after ${retryCount} retries due to ${error3.message}. Retrying in 5 seconds...`); yield new Promise((resolve14) => setTimeout(resolve14, 5e3)); } } @@ -142088,7 +142088,7 @@ var require_download_artifact = __commonJS({ extractStream.on("data", () => { timer.refresh(); }).on("error", (error3) => { - core32.debug(`response.message: Artifact download failed: ${error3.message}`); + core29.debug(`response.message: Artifact download failed: ${error3.message}`); clearTimeout(timer); reject(error3); }).pipe(unzip_stream_1.default.Extract({ path: directory })).on("close", () => { @@ -142096,7 +142096,7 @@ var require_download_artifact = __commonJS({ if (hashStream) { hashStream.end(); sha256Digest = hashStream.read(); - core32.info(`SHA256 digest of downloaded artifact is ${sha256Digest}`); + core29.info(`SHA256 digest of downloaded artifact is ${sha256Digest}`); } resolve14({ sha256Digest: `sha256:${sha256Digest}` }); }).on("error", (error3) => { @@ -142111,7 +142111,7 @@ var require_download_artifact = __commonJS({ const downloadPath = yield resolveOrCreateDirectory(options === null || options === void 0 ? void 0 : options.path); const api = github5.getOctokit(token); let digestMismatch = false; - core32.info(`Downloading artifact '${artifactId}' from '${repositoryOwner}/${repositoryName}'`); + core29.info(`Downloading artifact '${artifactId}' from '${repositoryOwner}/${repositoryName}'`); const { headers, status } = yield api.rest.actions.downloadArtifact({ owner: repositoryOwner, repo: repositoryName, @@ -142128,16 +142128,16 @@ var require_download_artifact = __commonJS({ if (!location) { throw new Error(`Unable to redirect to artifact download url`); } - core32.info(`Redirecting to blob download url: ${scrubQueryParameters(location)}`); + core29.info(`Redirecting to blob download url: ${scrubQueryParameters(location)}`); try { - core32.info(`Starting download of artifact to: ${downloadPath}`); + core29.info(`Starting download of artifact to: ${downloadPath}`); const extractResponse = yield streamExtract(location, downloadPath); - core32.info(`Artifact download completed successfully.`); + core29.info(`Artifact download completed successfully.`); if (options === null || options === void 0 ? void 0 : options.expectedHash) { if ((options === null || options === void 0 ? void 0 : options.expectedHash) !== extractResponse.sha256Digest) { digestMismatch = true; - core32.debug(`Computed digest: ${extractResponse.sha256Digest}`); - core32.debug(`Expected digest: ${options.expectedHash}`); + core29.debug(`Computed digest: ${extractResponse.sha256Digest}`); + core29.debug(`Expected digest: ${options.expectedHash}`); } } } catch (error3) { @@ -142164,7 +142164,7 @@ var require_download_artifact = __commonJS({ Are you trying to download from a different run? Try specifying a github-token with \`actions:read\` scope.`); } if (artifacts.length > 1) { - core32.warning("Multiple artifacts found, defaulting to first."); + core29.warning("Multiple artifacts found, defaulting to first."); } const signedReq = { workflowRunBackendId: artifacts[0].workflowRunBackendId, @@ -142172,16 +142172,16 @@ Are you trying to download from a different run? Try specifying a github-token w name: artifacts[0].name }; const { signedUrl } = yield artifactClient.GetSignedArtifactURL(signedReq); - core32.info(`Redirecting to blob download url: ${scrubQueryParameters(signedUrl)}`); + core29.info(`Redirecting to blob download url: ${scrubQueryParameters(signedUrl)}`); try { - core32.info(`Starting download of artifact to: ${downloadPath}`); + core29.info(`Starting download of artifact to: ${downloadPath}`); const extractResponse = yield streamExtract(signedUrl, downloadPath); - core32.info(`Artifact download completed successfully.`); + core29.info(`Artifact download completed successfully.`); if (options === null || options === void 0 ? void 0 : options.expectedHash) { if ((options === null || options === void 0 ? void 0 : options.expectedHash) !== extractResponse.sha256Digest) { digestMismatch = true; - core32.debug(`Computed digest: ${extractResponse.sha256Digest}`); - core32.debug(`Expected digest: ${options.expectedHash}`); + core29.debug(`Computed digest: ${extractResponse.sha256Digest}`); + core29.debug(`Expected digest: ${options.expectedHash}`); } } } catch (error3) { @@ -142194,10 +142194,10 @@ Are you trying to download from a different run? Try specifying a github-token w function resolveOrCreateDirectory() { return __awaiter2(this, arguments, void 0, function* (downloadPath = (0, config_1.getGitHubWorkspaceDir)()) { if (!(yield exists(downloadPath))) { - core32.debug(`Artifact destination folder does not exist, creating: ${downloadPath}`); + core29.debug(`Artifact destination folder does not exist, creating: ${downloadPath}`); yield promises_1.default.mkdir(downloadPath, { recursive: true }); } else { - core32.debug(`Artifact destination folder already exists: ${downloadPath}`); + core29.debug(`Artifact destination folder already exists: ${downloadPath}`); } return downloadPath; }); @@ -142238,7 +142238,7 @@ var require_retry_options = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.getRetryOptions = void 0; - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var defaultMaxRetryNumber = 5; var defaultExemptStatusCodes = [400, 401, 403, 404, 422]; function getRetryOptions(defaultOptions, retries = defaultMaxRetryNumber, exemptStatusCodes = defaultExemptStatusCodes) { @@ -142253,7 +142253,7 @@ var require_retry_options = __commonJS({ retryOptions.doNotRetry = exemptStatusCodes; } const requestOptions = Object.assign(Object.assign({}, defaultOptions.request), { retries }); - core32.debug(`GitHub client configured with: (retries: ${requestOptions.retries}, retry-exempt-status-code: ${(_a6 = retryOptions.doNotRetry) !== null && _a6 !== void 0 ? _a6 : "octokit default: [400, 401, 403, 404, 422]"})`); + core29.debug(`GitHub client configured with: (retries: ${requestOptions.retries}, retry-exempt-status-code: ${(_a6 = retryOptions.doNotRetry) !== null && _a6 !== void 0 ? _a6 : "octokit default: [400, 401, 403, 404, 422]"})`); return [retryOptions, requestOptions]; } exports2.getRetryOptions = getRetryOptions; @@ -142410,7 +142410,7 @@ var require_get_artifact = __commonJS({ exports2.getArtifactInternal = exports2.getArtifactPublic = void 0; var github_1 = require_github2(); var plugin_retry_1 = require_dist_node12(); - var core32 = __importStar2(require_core()); + var core29 = __importStar2(require_core()); var utils_1 = require_utils10(); var retry_options_1 = require_retry_options(); var plugin_request_log_1 = require_dist_node11(); @@ -142448,7 +142448,7 @@ var require_get_artifact = __commonJS({ let artifact2 = getArtifactResp.data.artifacts[0]; if (getArtifactResp.data.artifacts.length > 1) { artifact2 = getArtifactResp.data.artifacts.sort((a, b) => b.id - a.id)[0]; - core32.debug(`More than one artifact found for a single name, returning newest (id: ${artifact2.id})`); + core29.debug(`More than one artifact found for a single name, returning newest (id: ${artifact2.id})`); } return { artifact: { @@ -142481,7 +142481,7 @@ var require_get_artifact = __commonJS({ let artifact2 = res.artifacts[0]; if (res.artifacts.length > 1) { artifact2 = res.artifacts.sort((a, b) => Number(b.databaseId) - Number(a.databaseId))[0]; - core32.debug(`More than one artifact found for a single name, returning newest (id: ${artifact2.databaseId})`); + core29.debug(`More than one artifact found for a single name, returning newest (id: ${artifact2.databaseId})`); } return { artifact: { @@ -145589,7 +145589,7 @@ var require_core3 = __commonJS({ ExitCode2[ExitCode2["Success"] = 0] = "Success"; ExitCode2[ExitCode2["Failure"] = 1] = "Failure"; })(ExitCode || (exports2.ExitCode = ExitCode = {})); - function exportVariable17(name, val) { + function exportVariable3(name, val) { const convertedVal = (0, utils_1.toCommandValue)(val); process.env[name] = convertedVal; const filePath = process.env["GITHUB_ENV"] || ""; @@ -145598,7 +145598,7 @@ var require_core3 = __commonJS({ } (0, command_1.issueCommand)("set-env", { name }, convertedVal); } - exports2.exportVariable = exportVariable17; + exports2.exportVariable = exportVariable3; function setSecret2(secret) { (0, command_1.issueCommand)("add-mask", {}, secret); } @@ -147235,7 +147235,7 @@ var require_requestUtils2 = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.retryHttpClientRequest = exports2.retry = void 0; var utils_1 = require_utils12(); - var core32 = __importStar2(require_core3()); + var core29 = __importStar2(require_core3()); var config_variables_1 = require_config_variables(); function retry2(name, operation, customErrorMessages, maxAttempts) { return __awaiter2(this, void 0, void 0, function* () { @@ -147262,13 +147262,13 @@ var require_requestUtils2 = __commonJS({ errorMessage = error3.message; } if (!isRetryable) { - core32.info(`${name} - Error is not retryable`); + core29.info(`${name} - Error is not retryable`); if (response) { (0, utils_1.displayHttpDiagnostics)(response); } break; } - core32.info(`${name} - Attempt ${attempt} of ${maxAttempts} failed with error: ${errorMessage}`); + core29.info(`${name} - Attempt ${attempt} of ${maxAttempts} failed with error: ${errorMessage}`); yield (0, utils_1.sleep)((0, utils_1.getExponentialRetryTimeInMilliseconds)(attempt)); attempt++; } @@ -147352,7 +147352,7 @@ var require_upload_http_client = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.UploadHttpClient = void 0; var fs32 = __importStar2(require("fs")); - var core32 = __importStar2(require_core3()); + var core29 = __importStar2(require_core3()); var tmp2 = __importStar2(require_tmp_promise()); var stream2 = __importStar2(require("stream")); var utils_1 = require_utils12(); @@ -147417,7 +147417,7 @@ var require_upload_http_client = __commonJS({ return __awaiter2(this, void 0, void 0, function* () { const FILE_CONCURRENCY = (0, config_variables_1.getUploadFileConcurrency)(); const MAX_CHUNK_SIZE = (0, config_variables_1.getUploadChunkSize)(); - core32.debug(`File Concurrency: ${FILE_CONCURRENCY}, and Chunk Size: ${MAX_CHUNK_SIZE}`); + core29.debug(`File Concurrency: ${FILE_CONCURRENCY}, and Chunk Size: ${MAX_CHUNK_SIZE}`); const parameters = []; let continueOnError = true; if (options) { @@ -147454,15 +147454,15 @@ var require_upload_http_client = __commonJS({ } const startTime = perf_hooks_1.performance.now(); const uploadFileResult = yield this.uploadFileAsync(index2, currentFileParameters); - if (core32.isDebug()) { - core32.debug(`File: ${++completedFiles}/${filesToUpload.length}. ${currentFileParameters.file} took ${(perf_hooks_1.performance.now() - startTime).toFixed(3)} milliseconds to finish upload`); + if (core29.isDebug()) { + core29.debug(`File: ${++completedFiles}/${filesToUpload.length}. ${currentFileParameters.file} took ${(perf_hooks_1.performance.now() - startTime).toFixed(3)} milliseconds to finish upload`); } uploadFileSize += uploadFileResult.successfulUploadSize; totalFileSize += uploadFileResult.totalSize; if (uploadFileResult.isSuccess === false) { failedItemsToReport.push(currentFileParameters.file); if (!continueOnError) { - core32.error(`aborting artifact upload`); + core29.error(`aborting artifact upload`); abortPendingFileUploads = true; } } @@ -147471,7 +147471,7 @@ var require_upload_http_client = __commonJS({ }))); this.statusReporter.stop(); this.uploadHttpManager.disposeAndReplaceAllClients(); - core32.info(`Total size of all the files uploaded is ${uploadFileSize} bytes`); + core29.info(`Total size of all the files uploaded is ${uploadFileSize} bytes`); return { uploadSize: uploadFileSize, totalSize: totalFileSize, @@ -147497,16 +147497,16 @@ var require_upload_http_client = __commonJS({ let uploadFileSize = 0; let isGzip = true; if (!isFIFO && totalFileSize < 65536) { - core32.debug(`${parameters.file} is less than 64k in size. Creating a gzip file in-memory to potentially reduce the upload size`); + core29.debug(`${parameters.file} is less than 64k in size. Creating a gzip file in-memory to potentially reduce the upload size`); const buffer = yield (0, upload_gzip_1.createGZipFileInBuffer)(parameters.file); let openUploadStream; if (totalFileSize < buffer.byteLength) { - core32.debug(`The gzip file created for ${parameters.file} did not help with reducing the size of the file. The original file will be uploaded as-is`); + core29.debug(`The gzip file created for ${parameters.file} did not help with reducing the size of the file. The original file will be uploaded as-is`); openUploadStream = () => fs32.createReadStream(parameters.file); isGzip = false; uploadFileSize = totalFileSize; } else { - core32.debug(`A gzip file created for ${parameters.file} helped with reducing the size of the original file. The file will be uploaded using gzip.`); + core29.debug(`A gzip file created for ${parameters.file} helped with reducing the size of the original file. The file will be uploaded using gzip.`); openUploadStream = () => { const passThrough = new stream2.PassThrough(); passThrough.end(buffer); @@ -147518,7 +147518,7 @@ var require_upload_http_client = __commonJS({ if (!result) { isUploadSuccessful = false; failedChunkSizes += uploadFileSize; - core32.warning(`Aborting upload for ${parameters.file} due to failure`); + core29.warning(`Aborting upload for ${parameters.file} due to failure`); } return { isSuccess: isUploadSuccessful, @@ -147527,16 +147527,16 @@ var require_upload_http_client = __commonJS({ }; } else { const tempFile = yield tmp2.file(); - core32.debug(`${parameters.file} is greater than 64k in size. Creating a gzip file on-disk ${tempFile.path} to potentially reduce the upload size`); + core29.debug(`${parameters.file} is greater than 64k in size. Creating a gzip file on-disk ${tempFile.path} to potentially reduce the upload size`); uploadFileSize = yield (0, upload_gzip_1.createGZipFileOnDisk)(parameters.file, tempFile.path); let uploadFilePath = tempFile.path; if (!isFIFO && totalFileSize < uploadFileSize) { - core32.debug(`The gzip file created for ${parameters.file} did not help with reducing the size of the file. The original file will be uploaded as-is`); + core29.debug(`The gzip file created for ${parameters.file} did not help with reducing the size of the file. The original file will be uploaded as-is`); uploadFileSize = totalFileSize; uploadFilePath = parameters.file; isGzip = false; } else { - core32.debug(`The gzip file created for ${parameters.file} is smaller than the original file. The file will be uploaded using gzip.`); + core29.debug(`The gzip file created for ${parameters.file} is smaller than the original file. The file will be uploaded using gzip.`); } let abortFileUpload = false; while (offset < uploadFileSize) { @@ -147556,7 +147556,7 @@ var require_upload_http_client = __commonJS({ if (!result) { isUploadSuccessful = false; failedChunkSizes += chunkSize; - core32.warning(`Aborting upload for ${parameters.file} due to failure`); + core29.warning(`Aborting upload for ${parameters.file} due to failure`); abortFileUpload = true; } else { if (uploadFileSize > 8388608) { @@ -147564,7 +147564,7 @@ var require_upload_http_client = __commonJS({ } } } - core32.debug(`deleting temporary gzip file ${tempFile.path}`); + core29.debug(`deleting temporary gzip file ${tempFile.path}`); yield tempFile.cleanup(); return { isSuccess: isUploadSuccessful, @@ -147603,7 +147603,7 @@ var require_upload_http_client = __commonJS({ if (response) { (0, utils_1.displayHttpDiagnostics)(response); } - core32.info(`Retry limit has been reached for chunk at offset ${start} to ${resourceUrl}`); + core29.info(`Retry limit has been reached for chunk at offset ${start} to ${resourceUrl}`); return true; } return false; @@ -147611,14 +147611,14 @@ var require_upload_http_client = __commonJS({ const backOff = (retryAfterValue) => __awaiter2(this, void 0, void 0, function* () { this.uploadHttpManager.disposeAndReplaceClient(httpClientIndex); if (retryAfterValue) { - core32.info(`Backoff due to too many requests, retry #${retryCount}. Waiting for ${retryAfterValue} milliseconds before continuing the upload`); + core29.info(`Backoff due to too many requests, retry #${retryCount}. Waiting for ${retryAfterValue} milliseconds before continuing the upload`); yield (0, utils_1.sleep)(retryAfterValue); } else { const backoffTime = (0, utils_1.getExponentialRetryTimeInMilliseconds)(retryCount); - core32.info(`Exponential backoff for retry #${retryCount}. Waiting for ${backoffTime} milliseconds before continuing the upload at offset ${start}`); + core29.info(`Exponential backoff for retry #${retryCount}. Waiting for ${backoffTime} milliseconds before continuing the upload at offset ${start}`); yield (0, utils_1.sleep)(backoffTime); } - core32.info(`Finished backoff for retry #${retryCount}, continuing with upload`); + core29.info(`Finished backoff for retry #${retryCount}, continuing with upload`); return; }); while (retryCount <= retryLimit) { @@ -147626,7 +147626,7 @@ var require_upload_http_client = __commonJS({ try { response = yield uploadChunkRequest(); } catch (error3) { - core32.info(`An error has been caught http-client index ${httpClientIndex}, retrying the upload`); + core29.info(`An error has been caught http-client index ${httpClientIndex}, retrying the upload`); console.log(error3); if (incrementAndCheckRetryLimit()) { return false; @@ -147638,13 +147638,13 @@ var require_upload_http_client = __commonJS({ if ((0, utils_1.isSuccessStatusCode)(response.message.statusCode)) { return true; } else if ((0, utils_1.isRetryableStatusCode)(response.message.statusCode)) { - core32.info(`A ${response.message.statusCode} status code has been received, will attempt to retry the upload`); + core29.info(`A ${response.message.statusCode} status code has been received, will attempt to retry the upload`); if (incrementAndCheckRetryLimit(response)) { return false; } (0, utils_1.isThrottledStatusCode)(response.message.statusCode) ? yield backOff((0, utils_1.tryGetRetryAfterValueTimeInMilliseconds)(response.message.headers)) : yield backOff(); } else { - core32.error(`Unexpected response. Unable to upload chunk to ${resourceUrl}`); + core29.error(`Unexpected response. Unable to upload chunk to ${resourceUrl}`); (0, utils_1.displayHttpDiagnostics)(response); return false; } @@ -147662,7 +147662,7 @@ var require_upload_http_client = __commonJS({ resourceUrl.searchParams.append("artifactName", artifactName); const parameters = { Size: size }; const data = JSON.stringify(parameters, null, 2); - core32.debug(`URL is ${resourceUrl.toString()}`); + core29.debug(`URL is ${resourceUrl.toString()}`); const client = this.uploadHttpManager.getClient(0); const headers = (0, utils_1.getUploadHeaders)("application/json", false); const customErrorMessages = /* @__PURE__ */ new Map([ @@ -147675,7 +147675,7 @@ var require_upload_http_client = __commonJS({ return client.patch(resourceUrl.toString(), data, headers); }), customErrorMessages); yield response.readBody(); - core32.debug(`Artifact ${artifactName} has been successfully uploaded, total size in bytes: ${size}`); + core29.debug(`Artifact ${artifactName} has been successfully uploaded, total size in bytes: ${size}`); }); } }; @@ -147744,7 +147744,7 @@ var require_download_http_client = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DownloadHttpClient = void 0; var fs32 = __importStar2(require("fs")); - var core32 = __importStar2(require_core3()); + var core29 = __importStar2(require_core3()); var zlib3 = __importStar2(require("zlib")); var utils_1 = require_utils12(); var url_1 = require("url"); @@ -147798,11 +147798,11 @@ var require_download_http_client = __commonJS({ downloadSingleArtifact(downloadItems) { return __awaiter2(this, void 0, void 0, function* () { const DOWNLOAD_CONCURRENCY = (0, config_variables_1.getDownloadFileConcurrency)(); - core32.debug(`Download file concurrency is set to ${DOWNLOAD_CONCURRENCY}`); + core29.debug(`Download file concurrency is set to ${DOWNLOAD_CONCURRENCY}`); const parallelDownloads = [...new Array(DOWNLOAD_CONCURRENCY).keys()]; let currentFile = 0; let downloadedFiles = 0; - core32.info(`Total number of files that will be downloaded: ${downloadItems.length}`); + core29.info(`Total number of files that will be downloaded: ${downloadItems.length}`); this.statusReporter.setTotalNumberOfFilesToProcess(downloadItems.length); this.statusReporter.start(); yield Promise.all(parallelDownloads.map((index2) => __awaiter2(this, void 0, void 0, function* () { @@ -147811,8 +147811,8 @@ var require_download_http_client = __commonJS({ currentFile += 1; const startTime = perf_hooks_1.performance.now(); yield this.downloadIndividualFile(index2, currentFileToDownload.sourceLocation, currentFileToDownload.targetPath); - if (core32.isDebug()) { - core32.debug(`File: ${++downloadedFiles}/${downloadItems.length}. ${currentFileToDownload.targetPath} took ${(perf_hooks_1.performance.now() - startTime).toFixed(3)} milliseconds to finish downloading`); + if (core29.isDebug()) { + core29.debug(`File: ${++downloadedFiles}/${downloadItems.length}. ${currentFileToDownload.targetPath} took ${(perf_hooks_1.performance.now() - startTime).toFixed(3)} milliseconds to finish downloading`); } this.statusReporter.incrementProcessedCount(); } @@ -147850,19 +147850,19 @@ var require_download_http_client = __commonJS({ } else { this.downloadHttpManager.disposeAndReplaceClient(httpClientIndex); if (retryAfterValue) { - core32.info(`Backoff due to too many requests, retry #${retryCount}. Waiting for ${retryAfterValue} milliseconds before continuing the download`); + core29.info(`Backoff due to too many requests, retry #${retryCount}. Waiting for ${retryAfterValue} milliseconds before continuing the download`); yield (0, utils_1.sleep)(retryAfterValue); } else { const backoffTime = (0, utils_1.getExponentialRetryTimeInMilliseconds)(retryCount); - core32.info(`Exponential backoff for retry #${retryCount}. Waiting for ${backoffTime} milliseconds before continuing the download`); + core29.info(`Exponential backoff for retry #${retryCount}. Waiting for ${backoffTime} milliseconds before continuing the download`); yield (0, utils_1.sleep)(backoffTime); } - core32.info(`Finished backoff for retry #${retryCount}, continuing with download`); + core29.info(`Finished backoff for retry #${retryCount}, continuing with download`); } }); const isAllBytesReceived = (expected, received) => { if (!expected || !received || process.env["ACTIONS_ARTIFACT_SKIP_DOWNLOAD_VALIDATION"]) { - core32.info("Skipping download validation."); + core29.info("Skipping download validation."); return true; } return parseInt(expected) === received; @@ -147883,7 +147883,7 @@ var require_download_http_client = __commonJS({ try { response = yield makeDownloadRequest(); } catch (error3) { - core32.info("An error occurred while attempting to download a file"); + core29.info("An error occurred while attempting to download a file"); console.log(error3); yield backOff(); continue; @@ -147903,7 +147903,7 @@ var require_download_http_client = __commonJS({ } } if (forceRetry || (0, utils_1.isRetryableStatusCode)(response.message.statusCode)) { - core32.info(`A ${response.message.statusCode} response code has been received while attempting to download an artifact`); + core29.info(`A ${response.message.statusCode} response code has been received while attempting to download an artifact`); resetDestinationStream(downloadPath); (0, utils_1.isThrottledStatusCode)(response.message.statusCode) ? yield backOff((0, utils_1.tryGetRetryAfterValueTimeInMilliseconds)(response.message.headers)) : yield backOff(); } else { @@ -147925,29 +147925,29 @@ var require_download_http_client = __commonJS({ if (isGzip) { const gunzip = zlib3.createGunzip(); response.message.on("error", (error3) => { - core32.info(`An error occurred while attempting to read the response stream`); + core29.info(`An error occurred while attempting to read the response stream`); gunzip.close(); destinationStream.close(); reject(error3); }).pipe(gunzip).on("error", (error3) => { - core32.info(`An error occurred while attempting to decompress the response stream`); + core29.info(`An error occurred while attempting to decompress the response stream`); destinationStream.close(); reject(error3); }).pipe(destinationStream).on("close", () => { resolve14(); }).on("error", (error3) => { - core32.info(`An error occurred while writing a downloaded file to ${destinationStream.path}`); + core29.info(`An error occurred while writing a downloaded file to ${destinationStream.path}`); reject(error3); }); } else { response.message.on("error", (error3) => { - core32.info(`An error occurred while attempting to read the response stream`); + core29.info(`An error occurred while attempting to read the response stream`); destinationStream.close(); reject(error3); }).pipe(destinationStream).on("close", () => { resolve14(); }).on("error", (error3) => { - core32.info(`An error occurred while writing a downloaded file to ${destinationStream.path}`); + core29.info(`An error occurred while writing a downloaded file to ${destinationStream.path}`); reject(error3); }); } @@ -148086,7 +148086,7 @@ var require_artifact_client = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DefaultArtifactClient = void 0; - var core32 = __importStar2(require_core3()); + var core29 = __importStar2(require_core3()); var upload_specification_1 = require_upload_specification(); var upload_http_client_1 = require_upload_http_client(); var utils_1 = require_utils12(); @@ -148107,7 +148107,7 @@ var require_artifact_client = __commonJS({ */ uploadArtifact(name, files, rootDirectory, options) { return __awaiter2(this, void 0, void 0, function* () { - core32.info(`Starting artifact upload + core29.info(`Starting artifact upload For more detailed logs during the artifact upload process, enable step-debugging: https://docs.github.com/actions/monitoring-and-troubleshooting-workflows/enabling-debug-logging#enabling-step-debug-logging`); (0, path_and_artifact_name_validation_1.checkArtifactName)(name); const uploadSpecification = (0, upload_specification_1.getUploadSpecification)(name, rootDirectory, files); @@ -148119,24 +148119,24 @@ For more detailed logs during the artifact upload process, enable step-debugging }; const uploadHttpClient = new upload_http_client_1.UploadHttpClient(); if (uploadSpecification.length === 0) { - core32.warning(`No files found that can be uploaded`); + core29.warning(`No files found that can be uploaded`); } else { const response = yield uploadHttpClient.createArtifactInFileContainer(name, options); if (!response.fileContainerResourceUrl) { - core32.debug(response.toString()); + core29.debug(response.toString()); throw new Error("No URL provided by the Artifact Service to upload an artifact to"); } - core32.debug(`Upload Resource URL: ${response.fileContainerResourceUrl}`); - core32.info(`Container for artifact "${name}" successfully created. Starting upload of file(s)`); + core29.debug(`Upload Resource URL: ${response.fileContainerResourceUrl}`); + core29.info(`Container for artifact "${name}" successfully created. Starting upload of file(s)`); const uploadResult = yield uploadHttpClient.uploadArtifactToFileContainer(response.fileContainerResourceUrl, uploadSpecification, options); - core32.info(`File upload process has finished. Finalizing the artifact upload`); + core29.info(`File upload process has finished. Finalizing the artifact upload`); yield uploadHttpClient.patchArtifactSize(uploadResult.totalSize, name); if (uploadResult.failedItems.length > 0) { - core32.info(`Upload finished. There were ${uploadResult.failedItems.length} items that failed to upload`); + core29.info(`Upload finished. There were ${uploadResult.failedItems.length} items that failed to upload`); } else { - core32.info(`Artifact has been finalized. All files have been successfully uploaded!`); + core29.info(`Artifact has been finalized. All files have been successfully uploaded!`); } - core32.info(` + core29.info(` The raw size of all the files that were specified for upload is ${uploadResult.totalSize} bytes The size of all the files that were uploaded is ${uploadResult.uploadSize} bytes. This takes into account any gzip compression used to reduce the upload size, time and storage @@ -148170,10 +148170,10 @@ Note: The size of downloaded zips can differ significantly from the reported siz path30 = (0, path_1.resolve)(path30); const downloadSpecification = (0, download_specification_1.getDownloadSpecification)(name, items.value, path30, (options === null || options === void 0 ? void 0 : options.createArtifactFolder) || false); if (downloadSpecification.filesToDownload.length === 0) { - core32.info(`No downloadable files were found for the artifact: ${artifactToDownload.name}`); + core29.info(`No downloadable files were found for the artifact: ${artifactToDownload.name}`); } else { yield (0, utils_1.createDirectoriesForArtifact)(downloadSpecification.directoryStructure); - core32.info("Directory structure has been set up for the artifact"); + core29.info("Directory structure has been set up for the artifact"); yield (0, utils_1.createEmptyFilesForArtifact)(downloadSpecification.emptyFilesToCreate); yield downloadHttpClient.downloadSingleArtifact(downloadSpecification.filesToDownload); } @@ -148189,7 +148189,7 @@ Note: The size of downloaded zips can differ significantly from the reported siz const response = []; const artifacts = yield downloadHttpClient.listArtifacts(); if (artifacts.count === 0) { - core32.info("Unable to find any artifacts for the associated workflow"); + core29.info("Unable to find any artifacts for the associated workflow"); return response; } if (!path30) { @@ -148201,11 +148201,11 @@ Note: The size of downloaded zips can differ significantly from the reported siz while (downloadedArtifacts < artifacts.count) { const currentArtifactToDownload = artifacts.value[downloadedArtifacts]; downloadedArtifacts += 1; - core32.info(`starting download of artifact ${currentArtifactToDownload.name} : ${downloadedArtifacts}/${artifacts.count}`); + core29.info(`starting download of artifact ${currentArtifactToDownload.name} : ${downloadedArtifacts}/${artifacts.count}`); const items = yield downloadHttpClient.getContainerItems(currentArtifactToDownload.name, currentArtifactToDownload.fileContainerResourceUrl); const downloadSpecification = (0, download_specification_1.getDownloadSpecification)(currentArtifactToDownload.name, items.value, path30, true); if (downloadSpecification.filesToDownload.length === 0) { - core32.info(`No downloadable files were found for any artifact ${currentArtifactToDownload.name}`); + core29.info(`No downloadable files were found for any artifact ${currentArtifactToDownload.name}`); } else { yield (0, utils_1.createDirectoriesForArtifact)(downloadSpecification.directoryStructure); yield (0, utils_1.createEmptyFilesForArtifact)(downloadSpecification.emptyFilesToCreate); @@ -166085,20 +166085,21 @@ module.exports = __toCommonJS(entry_points_exports); var fs23 = __toESM(require("fs")); var import_path5 = __toESM(require("path")); var import_perf_hooks6 = require("perf_hooks"); -var core17 = __toESM(require_core()); +var core14 = __toESM(require_core()); // src/action-common.ts -var core8 = __toESM(require_core()); +var core9 = __toESM(require_core()); // src/actions-util.ts var fs2 = __toESM(require("fs")); var path2 = __toESM(require("path")); -var core3 = __toESM(require_core()); +var core4 = __toESM(require_core()); var toolrunner = __toESM(require_toolrunner()); var github = __toESM(require_github()); var io2 = __toESM(require_io()); // src/environment.ts +var core = __toESM(require_core()); function getRequiredEnvVar(env, paramName) { const value = env[paramName]; if (value === void 0 || value.length === 0) { @@ -166144,6 +166145,15 @@ var ReadOnlyEnv = class { entries() { return Object.entries(this.vars); } + /** + * Gets a value indicative of whether we are in a testing environment + * by testing whether the value of the `NODE_ENV` variable is "test". + * This is expected to be the case if e.g. `ava` is running the tests + * or if this instance was constructed by `getTestEnv`. + */ + isTestingEnv() { + return this.getOptional("NODE_ENV" /* NODE_ENV */) === "test"; + } }; var Env = class extends ReadOnlyEnv { changed = false; @@ -166152,6 +166162,20 @@ var Env = class extends ReadOnlyEnv { this.vars[name] = value; this.changed = true; } + /** + * Wrapper around `core.exportVariable` which does not call `core.exportVariable` + * when running unit tests. This is important, because otherwise `core.exportVariable` + * sets environment variables for other steps in a workflow when we run unit tests in CI. + * + * @param name The name of the environment variable to set and export. + * @param val The value to set and export for the environment variable. + */ + export(name, val) { + this.set(name, val); + if (!this.isTestingEnv()) { + core.exportVariable(name, val); + } + } /** Gets a value indicating whether `set` was called at least once. */ hasChanged() { return this.changed; @@ -166163,6 +166187,14 @@ function getEnv(env = process.env) { function isInTestMode() { return process.env["CODEQL_ACTION_TEST_MODE" /* TEST_MODE */] === "true"; } +function exportVariable2(name, val) { + const env = getEnv(); + if (typeof val === "string") { + env.export(name, val); + } else { + env.export(name, JSON.stringify(val)); + } +} // src/util.ts var fs = __toESM(require("fs")); @@ -166170,17 +166202,17 @@ var fsPromises = __toESM(require("fs/promises")); var os = __toESM(require("os")); var path = __toESM(require("path")); var import_perf_hooks = require("perf_hooks"); -var core2 = __toESM(require_core()); +var core3 = __toESM(require_core()); var io = __toESM(require_io()); // node_modules/get-folder-size/index.js var import_node_path = require("node:path"); async function getFolderSize(itemPath, options) { - return await core(itemPath, options, { errors: true }); + return await core2(itemPath, options, { errors: true }); } -getFolderSize.loose = async (itemPath, options) => await core(itemPath, options); -getFolderSize.strict = async (itemPath, options) => await core(itemPath, options, { strict: true }); -async function core(rootItemPath, options = {}, returnType = {}) { +getFolderSize.loose = async (itemPath, options) => await core2(itemPath, options); +getFolderSize.strict = async (itemPath, options) => await core2(itemPath, options, { strict: true }); +async function core2(rootItemPath, options = {}, returnType = {}) { const fs32 = options.fs || await import("node:fs/promises"); let folderSize = 0n; const foundInos = /* @__PURE__ */ new Set(); @@ -169783,7 +169815,7 @@ function checkGitHubVersionInRange(version, logger2) { ); } hasBeenWarnedAboutVersion = true; - core2.exportVariable(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true); + exportVariable2(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true); } function apiVersionInRange(version, minimumVersion2, maximumVersion2) { if (!semver.satisfies(version, `>=${minimumVersion2}`)) { @@ -169805,11 +169837,11 @@ function assertNever(value) { throw new ExhaustivityCheckingError(value); } function initializeEnvironment(version) { - core2.exportVariable("CODEQL_ACTION_FEATURE_MULTI_LANGUAGE" /* FEATURE_MULTI_LANGUAGE */, "false"); - core2.exportVariable("CODEQL_ACTION_FEATURE_SANDWICH" /* FEATURE_SANDWICH */, "false"); - core2.exportVariable("CODEQL_ACTION_FEATURE_SARIF_COMBINE" /* FEATURE_SARIF_COMBINE */, "true"); - core2.exportVariable("CODEQL_ACTION_FEATURE_WILL_UPLOAD" /* FEATURE_WILL_UPLOAD */, "true"); - core2.exportVariable("CODEQL_ACTION_VERSION" /* VERSION */, version); + exportVariable2("CODEQL_ACTION_FEATURE_MULTI_LANGUAGE" /* FEATURE_MULTI_LANGUAGE */, "false"); + exportVariable2("CODEQL_ACTION_FEATURE_SANDWICH" /* FEATURE_SANDWICH */, "false"); + exportVariable2("CODEQL_ACTION_FEATURE_SARIF_COMBINE" /* FEATURE_SARIF_COMBINE */, "true"); + exportVariable2("CODEQL_ACTION_FEATURE_WILL_UPLOAD" /* FEATURE_WILL_UPLOAD */, "true"); + exportVariable2("CODEQL_ACTION_VERSION" /* VERSION */, version); } var HTTPError = class extends Error { status; @@ -169942,7 +169974,7 @@ async function waitForResultWithTimeLimit(timeoutMs, promise, onTimeout) { } async function checkForTimeout() { if (hadTimeout === true) { - core2.info( + core3.info( "A timeout occurred, force exiting the process after 30 seconds to prevent hanging." ); await delay(3e4, { allowProcessExit: true }); @@ -169993,7 +170025,7 @@ async function checkDiskUsage(logger2) { } else { logger2.debug(message); } - core2.exportVariable("CODEQL_ACTION_HAS_WARNED_ABOUT_DISK_SPACE" /* HAS_WARNED_ABOUT_DISK_SPACE */, "true"); + exportVariable2("CODEQL_ACTION_HAS_WARNED_ABOUT_DISK_SPACE" /* HAS_WARNED_ABOUT_DISK_SPACE */, "true"); } return { numAvailableBytes: diskUsage.bavail * blockSizeInBytes, @@ -170013,10 +170045,10 @@ function checkActionVersion(version, githubVersion) { semver.coerce(githubVersion.version) ?? "0.0.0", ">=3.20" )) { - core2.warning( + core3.warning( "CodeQL Action v3 will be deprecated in December 2026. Please update all occurrences of the CodeQL Action in your workflow files to v4. For more information, see https://github.blog/changelog/2025-10-28-upcoming-deprecation-of-codeql-action-v3/" ); - core2.exportVariable("CODEQL_ACTION_DID_LOG_VERSION_DEPRECATION" /* LOG_VERSION_DEPRECATION */, "true"); + exportVariable2("CODEQL_ACTION_DID_LOG_VERSION_DEPRECATION" /* LOG_VERSION_DEPRECATION */, "true"); } } } @@ -170120,19 +170152,18 @@ var Failure = class { function getActionsEnv() { return { getRequiredInput, - getOptionalInput, - exportVariable: core3.exportVariable + getOptionalInput }; } var getRequiredInput = function(name) { - const value = core3.getInput(name); + const value = core4.getInput(name); if (!value) { throw new ConfigurationError(`Input required and not supplied: ${name}`); } return value; }; var getOptionalInput = function(name) { - const value = core3.getInput(name); + const value = core4.getInput(name); return value.length > 0 ? value : void 0; }; function getTemporaryDirectory(env = getEnv()) { @@ -170172,22 +170203,22 @@ async function printDebugLogs(config) { const databaseDirectory = getCodeQLDatabasePath(config, language); const logsDirectory = path2.join(databaseDirectory, "log"); if (!doesDirectoryExist(logsDirectory)) { - core3.info(`Directory ${logsDirectory} does not exist.`); + core4.info(`Directory ${logsDirectory} does not exist.`); continue; } const walkLogFiles = (dir) => { const entries = fs2.readdirSync(dir, { withFileTypes: true }); if (entries.length === 0) { - core3.info(`No debug logs found at directory ${logsDirectory}.`); + core4.info(`No debug logs found at directory ${logsDirectory}.`); } for (const entry of entries) { if (entry.isFile()) { const absolutePath = path2.resolve(dir, entry.name); - core3.startGroup( + core4.startGroup( `CodeQL Debug Logs - ${language} - ${entry.name} from file at path ${absolutePath}` ); process.stdout.write(fs2.readFileSync(absolutePath)); - core3.endGroup(); + core4.endGroup(); } else if (entry.isDirectory()) { walkLogFiles(path2.resolve(dir, entry.name)); } @@ -170208,7 +170239,7 @@ function getUploadValue(input) { case "never": return "never"; default: - core3.warning( + core4.warning( `Unrecognized 'upload' input to 'analyze' Action: ${input}. Defaulting to 'always'.` ); return "always"; @@ -170277,7 +170308,7 @@ var getFileType = async (filePath) => { }).exec(); return stdout.trim(); } catch (e) { - core3.info( + core4.info( `Could not determine type of ${filePath} from ${stdout}. ${stderr}` ); throw e; @@ -170362,11 +170393,11 @@ var persistInputs = function(env = getEnv()) { const inputEnvironmentVariables = entries.filter( ([name]) => name.startsWith("INPUT_") ); - core3.saveState(persistedInputsKey, JSON.stringify(inputEnvironmentVariables)); + core4.saveState(persistedInputsKey, JSON.stringify(inputEnvironmentVariables)); }; function restoreInputs(logger2) { try { - const persistedInputsValue = core3.getState(persistedInputsKey); + const persistedInputsValue = core4.getState(persistedInputsKey); if (persistedInputsValue) { const persistedInputs = JSON.parse(persistedInputsValue); for (const [name, value] of persistedInputs) { @@ -170434,32 +170465,32 @@ function fixCodeQualityCategory(logger2, category, env = getEnv()) { } // src/logging.ts -var core4 = __toESM(require_core()); +var core5 = __toESM(require_core()); function getActionsLogger() { return { - debug: core4.debug, - info: core4.info, - warning: core4.warning, - error: core4.error, - isDebug: core4.isDebug, - startGroup: core4.startGroup, - endGroup: core4.endGroup + debug: core5.debug, + info: core5.info, + warning: core5.warning, + error: core5.error, + isDebug: core5.isDebug, + startGroup: core5.startGroup, + endGroup: core5.endGroup }; } function withGroup(groupName, f) { - core4.startGroup(groupName); + core5.startGroup(groupName); try { return f(); } finally { - core4.endGroup(); + core5.endGroup(); } } async function withGroupAsync(groupName, f) { - core4.startGroup(groupName); + core5.startGroup(groupName); try { return await f(); } finally { - core4.endGroup(); + core5.endGroup(); } } function formatDuration(durationMs) { @@ -170476,7 +170507,7 @@ function formatDuration(durationMs) { // src/status-report.ts var os3 = __toESM(require("os")); -var core7 = __toESM(require_core()); +var core8 = __toESM(require_core()); // node_modules/uuid/dist-node/regex.js var regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i; @@ -170532,7 +170563,7 @@ function _v4(options, buf, offset) { var v4_default = v4; // src/api-client.ts -var core5 = __toESM(require_core()); +var core6 = __toESM(require_core()); var githubUtils = __toESM(require_utils4()); // node_modules/@octokit/plugin-retry/dist-bundle/index.js @@ -170683,10 +170714,10 @@ function createApiClientWithDetails(apiDetails, { allowExternal = false, proxy = baseUrl: apiDetails.apiURL, userAgent: `CodeQL-Action/${getActionVersion()}`, log: { - debug: core5.debug, - info: core5.info, - warn: core5.warning, - error: core5.error + debug: core6.debug, + info: core6.info, + warn: core6.warning, + error: core6.error }, request: requestOptions, retry: { @@ -170773,7 +170804,7 @@ async function getAnalysisKey() { const workflowPath = await getWorkflowRelativePath(); const jobName = getRequiredEnvParam("GITHUB_JOB"); analysisKey = `${workflowPath}:${jobName}`; - core5.exportVariable("CODEQL_ACTION_ANALYSIS_KEY" /* ANALYSIS_KEY */, analysisKey); + exportVariable2("CODEQL_ACTION_ANALYSIS_KEY" /* ANALYSIS_KEY */, analysisKey); return analysisKey; } async function getAutomationID() { @@ -170952,7 +170983,7 @@ function parseRegistriesWithoutCredentials(registriesInput) { var fs4 = __toESM(require("fs")); var os2 = __toESM(require("os")); var path4 = __toESM(require("path")); -var core6 = __toESM(require_core()); +var core7 = __toESM(require_core()); var toolrunner2 = __toESM(require_toolrunner()); var io3 = __toESM(require_io()); var semver2 = __toESM(require_semver2()); @@ -170983,7 +171014,7 @@ async function getGitVersionOrThrow() { var runGitCommand = async function(workingDirectory, args, customErrorMessage, options) { let stdout = ""; let stderr = ""; - core6.debug(`Running git command: git ${args.join(" ")}`); + core7.debug(`Running git command: git ${args.join(" ")}`); try { await new toolrunner2.ToolRunner(await io3.which("git", true), args, { silent: true, @@ -171004,7 +171035,7 @@ var runGitCommand = async function(workingDirectory, args, customErrorMessage, o if (stderr.includes("not a git repository")) { reason = "The checkout path provided to the action does not appear to be a git repository."; } - core6.info(`git call failed. ${customErrorMessage} Error: ${reason}`); + core7.info(`git call failed. ${customErrorMessage} Error: ${reason}`); throw error3; } }; @@ -171167,7 +171198,7 @@ async function getRef() { ) !== head; if (hasChangedRef) { const newRef = ref.replace(pull_ref_regex, "refs/pull/$1/head"); - core6.debug( + core7.debug( `No longer on merge commit, rewriting ref from ${ref} to ${newRef}.` ); return newRef; @@ -171375,7 +171406,7 @@ function getJobUUID(action) { } const jobRunUuid = v4_default(); action.logger.info(`Job run UUID is ${jobRunUuid}.`); - action.actions.exportVariable("CODEQL_ACTION_JOB_RUN_UUID" /* JOB_RUN_UUID */, jobRunUuid); + action.env.export("CODEQL_ACTION_JOB_RUN_UUID" /* JOB_RUN_UUID */, jobRunUuid); return jobRunUuid; } function isFirstPartyAnalysis(actionName) { @@ -171417,12 +171448,12 @@ function getJobStatusDisplayName(status) { } function setJobStatusIfUnsuccessful(actionStatus) { if (actionStatus === "user-error") { - core7.exportVariable( + exportVariable2( "CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, process.env["CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */] ?? "JOB_STATUS_CONFIGURATION_ERROR" /* ConfigErrorStatus */ ); } else if (actionStatus === "failure" || actionStatus === "aborted") { - core7.exportVariable( + exportVariable2( "CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, process.env["CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */] ?? "JOB_STATUS_FAILURE" /* FailureStatus */ ); @@ -171469,7 +171500,7 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi let workflowStartedAt = process.env["CODEQL_WORKFLOW_STARTED_AT" /* WORKFLOW_STARTED_AT */]; if (workflowStartedAt === void 0) { workflowStartedAt = actionStartedAt.toISOString(); - core7.exportVariable("CODEQL_WORKFLOW_STARTED_AT" /* WORKFLOW_STARTED_AT */, workflowStartedAt); + exportVariable2("CODEQL_WORKFLOW_STARTED_AT" /* WORKFLOW_STARTED_AT */, workflowStartedAt); } const runnerOs = getRequiredEnvParam("RUNNER_OS"); const codeQlCliVersion = getCachedCodeQlVersion( @@ -171479,7 +171510,7 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi const actionRef = process.env["GITHUB_ACTION_REF"] || ""; const testingEnvironment = getTestingEnvironment(); if (testingEnvironment) { - core7.exportVariable("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment); + exportVariable2("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment); } const isSteadyStateDefaultSetupRun = process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true"; const statusReport = { @@ -171564,9 +171595,9 @@ var INCOMPATIBLE_MSG = "CodeQL Action version is incompatible with the API endpo async function sendStatusReport(statusReport) { setJobStatusIfUnsuccessful(statusReport.status); const statusReportJSON = JSON.stringify(statusReport); - core7.debug(`Sending status report: ${statusReportJSON}`); + core8.debug(`Sending status report: ${statusReportJSON}`); if (isInTestMode()) { - core7.debug("In test mode. Status reports are not uploaded."); + core8.debug("In test mode. Status reports are not uploaded."); return; } const nwo = getRepositoryNwo(); @@ -171586,28 +171617,28 @@ async function sendStatusReport(statusReport) { switch (httpError.status) { case 403: if (getWorkflowEventName() === "push" && process.env["GITHUB_ACTOR"] === "dependabot[bot]") { - core7.warning( + core8.warning( `Workflows triggered by Dependabot on the "push" event run with read-only access. Uploading CodeQL results requires write access. To use CodeQL with Dependabot, please ensure you are using the "pull_request" event for this workflow and avoid triggering on the "push" event for Dependabot branches. See ${"https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning#scanning-on-push" /* SCANNING_ON_PUSH */} for more information on how to configure these events.` ); } else { - core7.warning( + core8.warning( `This run of the CodeQL Action does not have permission to access the CodeQL Action API endpoints. This could be because the Action is running on a pull request from a fork. If not, please ensure the workflow has at least the 'security-events: read' permission. Details: ${httpError.message}` ); } return; case 404: - core7.warning(httpError.message); + core8.warning(httpError.message); return; case 422: if (getRequiredEnvParam("GITHUB_SERVER_URL") !== GITHUB_DOTCOM_URL) { - core7.debug(INCOMPATIBLE_MSG); + core8.debug(INCOMPATIBLE_MSG); } else { - core7.debug(OUT_OF_DATE_MSG); + core8.debug(OUT_OF_DATE_MSG); } return; } } - core7.warning( + core8.warning( `An unexpected error occurred when sending a status report: ${getErrorMessage( e )}` @@ -171704,7 +171735,7 @@ async function runInActions(action) { getJobUUID(actionState); await action.run(actionState); } catch (error3) { - core8.setFailed( + core9.setFailed( `${getDisplayActionName(action.name)} action failed: ${getErrorMessage(error3)}` ); const statusReportError = action.transformTelemetryError !== void 0 ? action.transformTelemetryError(wrapError(error3)) : error3; @@ -172609,13 +172640,10 @@ var path16 = __toESM(require("path")); var import_perf_hooks5 = require("perf_hooks"); var io5 = __toESM(require_io()); -// src/autobuild.ts -var core14 = __toESM(require_core()); - // src/codeql.ts var fs16 = __toESM(require("fs")); var path15 = __toESM(require("path")); -var core13 = __toESM(require_core()); +var core12 = __toESM(require_core()); var toolrunner3 = __toESM(require_toolrunner()); // src/cli-errors.ts @@ -172871,11 +172899,10 @@ function wrapCliConfigurationError(cliError) { var fs10 = __toESM(require("fs")); var path11 = __toESM(require("path")); var import_perf_hooks2 = require("perf_hooks"); -var core10 = __toESM(require_core()); // src/caching-utils.ts var crypto2 = __toESM(require("crypto")); -var core9 = __toESM(require_core()); +var core10 = __toESM(require_core()); async function getTotalCacheSize(paths, logger2, quiet = false) { const sizes = await Promise.all( paths.map((cacheDir2) => tryGetFolderBytes(cacheDir2, logger2, quiet)) @@ -172904,7 +172931,7 @@ function getCachingKind(input) { case "restore": return "restore" /* Restore */; default: - core9.warning( + core10.warning( `Unrecognized 'dependency-caching' input: ${input}. Defaulting to 'none'.` ); return "none" /* None */; @@ -174786,10 +174813,10 @@ async function setCppTrapCachingEnvironmentVariables(config, logger2) { ); } else if (config.trapCaches["cpp" /* cpp */]) { logger2.info("Enabling TRAP caching for C/C++."); - core10.exportVariable(envVar, "true"); + exportVariable2(envVar, "true"); } else { logger2.debug(`Disabling TRAP caching for C/C++.`); - core10.exportVariable(envVar, "false"); + exportVariable2(envVar, "false"); } } } @@ -175193,7 +175220,6 @@ async function logGeneratedFilesTelemetry(config, duration, generatedFilesCount) var fs14 = __toESM(require("fs")); var path13 = __toESM(require("path")); var import_perf_hooks4 = require("perf_hooks"); -var core12 = __toESM(require_core()); var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); var semver10 = __toESM(require_semver2()); @@ -176681,7 +176707,7 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau default: assertNever(source); } - core12.exportVariable("CODEQL_ACTION_HAS_SET_UP_CODEQL" /* HAS_SET_UP_CODEQL */, "true"); + exportVariable2("CODEQL_ACTION_HAS_SET_UP_CODEQL" /* HAS_SET_UP_CODEQL */, "true"); return { codeqlFolder, toolsDownloadStatusReport, @@ -176962,7 +176988,7 @@ async function getCodeQLForCmd(logger2, cmd, checkVersion) { return result; }, async printVersion() { - core13.info(JSON.stringify(await this.getVersion(), null, 2)); + core12.info(JSON.stringify(await this.getVersion(), null, 2)); }, async supportsFeature(feature) { return isSupportedToolsFeature(await this.getVersion(), feature); @@ -177355,12 +177381,12 @@ Output was: ${extractorPath}` ); } else if (checkVersion && process.env["CODEQL_ACTION_SUPPRESS_DEPRECATED_SOON_WARNING" /* SUPPRESS_DEPRECATED_SOON_WARNING */] !== "true" && !await codeQlVersionAtLeast(codeql, CODEQL_NEXT_MINIMUM_VERSION)) { const result = await codeql.getVersion(); - core13.warning( + core12.warning( `CodeQL CLI version ${result.version} was discontinued on ${GHES_MOST_RECENT_DEPRECATION_DATE} alongside GitHub Enterprise Server ${GHES_VERSION_MOST_RECENTLY_DEPRECATED} and will not be supported by the next minor release of the CodeQL Action. Please update to CodeQL CLI version ${CODEQL_NEXT_MINIMUM_VERSION} or later. For instance, if you have specified a custom version of the CLI using the 'tools' input to the 'init' Action, you can remove this input to use the default version. Alternatively, if you want to continue using CodeQL CLI version ${result.version}, you can replace 'github/codeql-action/*@v${getActionVersion().split(".")[0]}' by 'github/codeql-action/*@v${getActionVersion()}' in your code scanning workflow to continue using this version of the CodeQL Action.` ); - core13.exportVariable("CODEQL_ACTION_SUPPRESS_DEPRECATED_SOON_WARNING" /* SUPPRESS_DEPRECATED_SOON_WARNING */, "true"); + exportVariable2("CODEQL_ACTION_SUPPRESS_DEPRECATED_SOON_WARNING" /* SUPPRESS_DEPRECATED_SOON_WARNING */, "true"); } return codeql; } @@ -177529,16 +177555,16 @@ async function setupCppAutobuild(codeql, logger2) { logger2.info( `Disabling ${featureName} as we are on a self-hosted runner.${getWorkflowEventName() !== "dynamic" ? ` To override this, set the ${envVar} environment variable to 'true' in your workflow. See ${"https://docs.github.com/en/actions/learn-github-actions/variables#defining-environment-variables-for-a-single-workflow" /* DEFINE_ENV_VARIABLES */} for more information.` : ""}` ); - core14.exportVariable(envVar, "false"); + exportVariable2(envVar, "false"); } else { logger2.info( `Enabling ${featureName}. This can be disabled by setting the ${envVar} environment variable to 'false'. See ${"https://docs.github.com/en/actions/learn-github-actions/variables#defining-environment-variables-for-a-single-workflow" /* DEFINE_ENV_VARIABLES */} for more information.` ); - core14.exportVariable(envVar, "true"); + exportVariable2(envVar, "true"); } } else { logger2.info(`Disabling ${featureName}.`); - core14.exportVariable(envVar, "false"); + exportVariable2(envVar, "false"); } } async function runAutobuild(config, language, logger2) { @@ -177553,7 +177579,7 @@ async function runAutobuild(config, language, logger2) { await codeQL.runAutobuild(config, language); } if (language === "go" /* go */) { - core14.exportVariable("CODEQL_ACTION_DID_AUTOBUILD_GOLANG" /* DID_AUTOBUILD_GOLANG */, "true"); + exportVariable2("CODEQL_ACTION_DID_AUTOBUILD_GOLANG" /* DID_AUTOBUILD_GOLANG */, "true"); } logger2.endGroup(); } @@ -178401,7 +178427,7 @@ var fs22 = __toESM(require("fs")); var path19 = __toESM(require("path")); var url = __toESM(require("url")); var import_zlib = __toESM(require("zlib")); -var core16 = __toESM(require_core()); +var core13 = __toESM(require_core()); var jsonschema2 = __toESM(require_lib2()); // src/fingerprints.ts @@ -179529,7 +179555,6 @@ async function addFingerprints(sarifLog, sourceRoot, logger2) { // src/init.ts var fs20 = __toESM(require("fs")); var path18 = __toESM(require("path")); -var core15 = __toESM(require_core()); var toolrunner4 = __toESM(require_toolrunner()); var github3 = __toESM(require_github()); var io6 = __toESM(require_io()); @@ -179752,7 +179777,7 @@ To opt out of this change, switch to an advanced setup workflow and ${envVarOptO To opt out of this change, ${envVarOptOut}`; } logger2.warning(message); - core15.exportVariable("CODEQL_ACTION_DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION" /* DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION */, "true"); + exportVariable2("CODEQL_ACTION_DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION" /* DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION */, "true"); } // src/sarif/index.ts @@ -179872,7 +179897,7 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo logger2.warning( `Uploading multiple SARIF runs with the same category is deprecated ${deprecationWarningMessage}. Please update your workflow to upload a single run per category. ${deprecationMoreInformationMessage}` ); - core16.exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true"); + exportVariable2("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true"); } return combineSarifFiles(sarifFiles, logger2); } @@ -179975,13 +180000,13 @@ async function uploadPayload(payload, repositoryNwo, logger2, analysis) { if (httpError !== void 0) { switch (httpError.status) { case 403: - core16.warning(httpError.message || GENERIC_403_MSG); + core13.warning(httpError.message || GENERIC_403_MSG); break; case 404: - core16.warning(httpError.message || GENERIC_404_MSG); + core13.warning(httpError.message || GENERIC_404_MSG); break; default: - core16.warning(httpError.message); + core13.warning(httpError.message); break; } } @@ -180419,7 +180444,7 @@ function validateUniqueCategory(sarifLog, sentinelPrefix) { `Aborting upload: only one run of the codeql/analyze or codeql/upload-sarif actions is allowed per job per tool/category. The easiest fix is to specify a unique value for the \`category\` input. If .runs[].automationDetails.id is specified in the sarif file, that will take precedence over your configured \`category\`. Category: (${id ? id : "none"}) Tool: (${tool ? tool : "none"})` ); } - core16.exportVariable(sentinelEnvVar, sentinelEnvVar); + exportVariable2(sentinelEnvVar, sentinelEnvVar); } } function sanitize(str) { @@ -180591,6 +180616,7 @@ async function runAutobuildIfLegacyGoWorkflow(config, logger2) { } async function run({ startedAt, + env, logger: logger2, actions }) { @@ -180641,7 +180667,7 @@ async function run({ } const apiDetails = getApiDetails(); const outputDir = getRequiredInput("output"); - core17.exportVariable("CODEQL_ACTION_SARIF_RESULTS_OUTPUT_DIR" /* SARIF_RESULTS_OUTPUT_DIR */, outputDir); + env.export("CODEQL_ACTION_SARIF_RESULTS_OUTPUT_DIR" /* SARIF_RESULTS_OUTPUT_DIR */, outputDir); const threads = getThreadsFlag( getOptionalInput("threads") || process.env["CODEQL_THREADS"], logger2 @@ -180697,8 +180723,8 @@ async function run({ for (const language of config.languages) { dbLocations[language] = getCodeQLDatabasePath(config, language); } - core17.setOutput("db-locations", dbLocations); - core17.setOutput("sarif-output", import_path5.default.resolve(outputDir)); + core14.setOutput("db-locations", dbLocations); + core14.setOutput("sarif-output", import_path5.default.resolve(outputDir)); const uploadKind = getUploadValue( getOptionalInput("upload") ); @@ -180714,13 +180740,13 @@ async function run({ getOptionalInput("post-processed-sarif-path") ); if (uploadResults["code-scanning" /* CodeScanning */] !== void 0) { - core17.setOutput( + core14.setOutput( "sarif-id", uploadResults["code-scanning" /* CodeScanning */].sarifID ); } if (uploadResults["code-quality" /* CodeQuality */] !== void 0) { - core17.setOutput( + core14.setOutput( "quality-sarif-id", uploadResults["code-quality" /* CodeQuality */].sarifID ); @@ -180768,15 +180794,15 @@ async function run({ ); } if (getOptionalInput("expect-error") === "true") { - core17.setFailed( + core14.setFailed( `expect-error input was set to true but no error was thrown.` ); } - core17.exportVariable("CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */, "true"); + env.export("CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */, "true"); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); if (getOptionalInput("expect-error") !== "true" || hasBadExpectErrorInput()) { - core17.setFailed(error3.message); + core14.setFailed(error3.message); } await sendStatusReport2( startedAt, @@ -180851,14 +180877,14 @@ async function runWrapper() { // src/analyze-action-post.ts var fs27 = __toESM(require("fs")); -var core19 = __toESM(require_core()); +var core16 = __toESM(require_core()); // src/debug-artifacts.ts var fs26 = __toESM(require("fs")); var path23 = __toESM(require("path")); var artifact = __toESM(require_artifact2()); var artifactLegacy = __toESM(require_artifact_client2()); -var core18 = __toESM(require_core()); +var core15 = __toESM(require_core()); // node_modules/archiver/lib/core.js var import_fs2 = require("fs"); @@ -185659,10 +185685,10 @@ function getArtifactSuffix(matrix) { for (const matrixKey of Object.keys(matrixObject).sort()) suffix += `-${matrixObject[matrixKey]}`; } else { - core18.warning("User-specified `matrix` input is not an object."); + core15.warning("User-specified `matrix` input is not an object."); } } catch { - core18.warning( + core15.warning( "Could not parse user-specified `matrix` input into JSON. The debug artifact will not be named with the user's `matrix` input." ); } @@ -185672,7 +185698,7 @@ function getArtifactSuffix(matrix) { async function uploadDebugArtifacts(logger2, toUpload, rootDir, artifactName, ghVariant, codeQlVersion) { const uploadSupported = isSafeArtifactUpload(codeQlVersion); if (!uploadSupported) { - core18.info( + core15.info( `Skipping debug artifact upload because the current CLI does not support safe upload. Please upgrade to CLI v${SafeArtifactUploadVersion} or later.` ); return "upload-not-supported"; @@ -185685,7 +185711,7 @@ async function uploadArtifacts(logger2, toUpload, rootDir, artifactName, ghVaria } if (isInTestMode()) { await scanArtifactsForTokens(toUpload, logger2); - core18.exportVariable("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true"); + exportVariable2("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true"); } const suffix = getArtifactSuffix(getOptionalInput("matrix")); const artifactUploader = await getArtifactUploaderClient(logger2, ghVariant); @@ -185701,7 +185727,7 @@ async function uploadArtifacts(logger2, toUpload, rootDir, artifactName, ghVaria ); return "upload-successful"; } catch (e) { - core18.warning(`Failed to upload debug artifacts: ${e}`); + core15.warning(`Failed to upload debug artifacts: ${e}`); return "upload-failed"; } } @@ -185724,7 +185750,7 @@ async function createPartialDatabaseBundle(config, language) { config.dbLocation, `${config.debugDatabaseName}-${language}-partial.zip` ); - core18.info( + core15.info( `${config.debugDatabaseName}-${language} is not finalized. Uploading partial database bundle at ${databaseBundlePath}...` ); if (fs26.existsSync(databaseBundlePath)) { @@ -185794,14 +185820,14 @@ async function runWrapper2() { } } } catch (error3) { - core19.setFailed( + core16.setFailed( `analyze post-action step failed: ${getErrorMessage(error3)}` ); } } // src/autobuild-action.ts -var core20 = __toESM(require_core()); +var core17 = __toESM(require_core()); async function sendCompletedStatusReport(config, logger2, startedAt, allLanguages, failingLanguage, cause) { initializeEnvironment(getActionVersion()); const status = getActionsStatus(cause, failingLanguage); @@ -185824,7 +185850,11 @@ async function sendCompletedStatusReport(config, logger2, startedAt, allLanguage await sendStatusReport(statusReport); } } -async function run2({ startedAt, logger: logger2 }) { +async function run2({ + startedAt, + env, + logger: logger2 +}) { let config; let currentLanguage; let languages; @@ -185867,7 +185897,7 @@ async function run2({ startedAt, logger: logger2 }) { await endTracingForCluster(codeql, config, logger2); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); - core20.setFailed( + core17.setFailed( `We were unable to automatically build your code. Please replace the call to the autobuild action with your custom build steps. ${error3.message}` ); await sendCompletedStatusReport( @@ -185880,7 +185910,7 @@ async function run2({ startedAt, logger: logger2 }) { ); return; } - core20.exportVariable("CODEQL_ACTION_AUTOBUILD_DID_COMPLETE_SUCCESSFULLY" /* AUTOBUILD_DID_COMPLETE_SUCCESSFULLY */, "true"); + env.export("CODEQL_ACTION_AUTOBUILD_DID_COMPLETE_SUCCESSFULLY" /* AUTOBUILD_DID_COMPLETE_SUCCESSFULLY */, "true"); await sendCompletedStatusReport(config, logger2, startedAt, languages ?? []); } var autobuild = { @@ -185894,7 +185924,7 @@ async function runWrapper3() { // src/init-action.ts var fs29 = __toESM(require("fs")); var path25 = __toESM(require("path")); -var core22 = __toESM(require_core()); +var core19 = __toESM(require_core()); var io7 = __toESM(require_io()); var semver11 = __toESM(require_semver2()); @@ -185954,7 +185984,7 @@ function createInitToolsDownloadFields(report, toolsFeatureFlagsValid) { var fs28 = __toESM(require("fs")); var path24 = __toESM(require("path")); var import_zlib3 = __toESM(require("zlib")); -var core21 = __toESM(require_core()); +var core18 = __toESM(require_core()); function toCodedErrors(errors) { return Object.entries(errors).reduce( (acc, [code, message]) => { @@ -186077,7 +186107,7 @@ async function validateWorkflow(codeql, logger2) { } catch (e) { return `error: formatWorkflowErrors() failed: ${String(e)}`; } - core21.warning(message); + core18.warning(message); } return formatWorkflowCause(workflowErrors); } @@ -186206,7 +186236,7 @@ function getCheckoutPathInputOrThrow(workflow, jobName, matrixVars) { } async function checkWorkflow(logger2, codeql) { if (!isDynamicWorkflow() && process.env["CODEQL_ACTION_SKIP_WORKFLOW_VALIDATION" /* SKIP_WORKFLOW_VALIDATION */] !== "true") { - core21.startGroup("Validating workflow"); + core18.startGroup("Validating workflow"); const validateWorkflowResult = await internal2.validateWorkflow( codeql, logger2 @@ -186218,7 +186248,7 @@ async function checkWorkflow(logger2, codeql) { `Unable to validate code scanning workflow: ${validateWorkflowResult}` ); } - core21.endGroup(); + core18.endGroup(); } } var internal2 = { @@ -186326,7 +186356,7 @@ async function run3(actionState) { logger2 ); const repositoryProperties = repositoryPropertiesResult.orElse({}); - core22.exportVariable("CODEQL_ACTION_INIT_HAS_RUN" /* INIT_ACTION_HAS_RUN */, "true"); + actionState.env.export("CODEQL_ACTION_INIT_HAS_RUN" /* INIT_ACTION_HAS_RUN */, "true"); sourceRoot = path25.resolve( actionState.env.getRequired("GITHUB_WORKSPACE" /* GITHUB_WORKSPACE */), getOptionalInput("source-root") || "" @@ -186406,12 +186436,12 @@ async function run3(actionState) { ); } if (semver11.lt(actualVer, publicPreview)) { - core22.exportVariable("CODEQL_ENABLE_EXPERIMENTAL_FEATURES" /* EXPERIMENTAL_FEATURES */, "true"); + actionState.env.export("CODEQL_ENABLE_EXPERIMENTAL_FEATURES" /* EXPERIMENTAL_FEATURES */, "true"); logger2.info("Experimental Rust analysis enabled"); } } analysisKinds = await getAnalysisKinds(logger2, features); - const debugMode = getOptionalInput("debug") === "true" || core22.isDebug(); + const debugMode = getOptionalInput("debug") === "true" || core19.isDebug(); const fileCoverageResult = await getFileCoverageInformationEnabled( debugMode, codeql, @@ -186483,7 +186513,7 @@ async function run3(actionState) { await checkInstallPython311(config.languages, codeql); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); - core22.setFailed(error3.message); + core19.setFailed(error3.message); const statusReportBase = await createStatusReportBase( "init" /* Init */, error3 instanceof ConfigurationError ? "user-error" : "aborted", @@ -186523,10 +186553,10 @@ async function run3(actionState) { if (config.overlayDatabaseMode !== "overlay" /* Overlay */) { cleanupDatabaseClusterDirectory(config, logger2); } - const goFlags = process.env["GOFLAGS"]; + const goFlags = actionState.env.getOptional("GOFLAGS"); if (goFlags) { - core22.exportVariable("GOFLAGS", goFlags); - core22.warning( + actionState.env.export("GOFLAGS", goFlags); + core19.warning( "Passing the GOFLAGS env parameter to the init action is deprecated. Please move this to the analyze action." ); } @@ -186545,7 +186575,7 @@ async function run3(actionState) { "bin" ); fs29.mkdirSync(tempBinPath, { recursive: true }); - core22.addPath(tempBinPath); + core19.addPath(tempBinPath); const goWrapperPath = path25.resolve(tempBinPath, "go"); fs29.writeFileSync( goWrapperPath, @@ -186554,14 +186584,14 @@ async function run3(actionState) { exec ${goBinaryPath} "$@"` ); fs29.chmodSync(goWrapperPath, "755"); - core22.exportVariable("CODEQL_ACTION_GO_BINARY" /* GO_BINARY_LOCATION */, goWrapperPath); + actionState.env.export("CODEQL_ACTION_GO_BINARY" /* GO_BINARY_LOCATION */, goWrapperPath); } catch (e) { logger2.warning( `Analyzing Go on Linux, but failed to install wrapper script. Tracing custom builds may fail: ${e}` ); } } else { - core22.exportVariable("CODEQL_ACTION_GO_BINARY" /* GO_BINARY_LOCATION */, goBinaryPath); + actionState.env.export("CODEQL_ACTION_GO_BINARY" /* GO_BINARY_LOCATION */, goBinaryPath); } } catch (e) { logger2.warning( @@ -186588,23 +186618,26 @@ exec ${goBinaryPath} "$@"` } } } - core22.exportVariable( + actionState.env.export( "CODEQL_RAM", process.env["CODEQL_RAM"] || getCodeQLMemoryLimit(getOptionalInput("ram"), logger2).toString() ); - core22.exportVariable( + actionState.env.export( "CODEQL_THREADS", process.env["CODEQL_THREADS"] || getThreadsFlagValue(getOptionalInput("threads"), logger2).toString() ); if (await features.getValue("disable_kotlin_analysis_enabled" /* DisableKotlinAnalysisEnabled */)) { - core22.exportVariable("CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN", "true"); + actionState.env.export( + "CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN", + "true" + ); } if (await features.getValue("force_jgit" /* ForceJGit */)) { - core22.exportVariable("CODEQL_GIT_BACKEND", "jgit"); + actionState.env.export("CODEQL_GIT_BACKEND", "jgit"); } const kotlinLimitVar = "CODEQL_EXTRACTOR_KOTLIN_OVERRIDE_MAXIMUM_VERSION_LIMIT"; if (await codeQlVersionAtLeast(codeql, "2.20.3") && !await codeQlVersionAtLeast(codeql, "2.20.4")) { - core22.exportVariable(kotlinLimitVar, "2.1.20"); + actionState.env.export(kotlinLimitVar, "2.1.20"); } if (shouldRestoreCache(config.dependencyCachingEnabled)) { const dependencyCachingResult = await downloadDependencyCaches( @@ -186631,7 +186664,7 @@ exec ${goBinaryPath} "$@"` `${"CODEQL_EXTRACTOR_JAVA_OPTION_MINIMIZE_DEPENDENCY_JARS" /* JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS */} is already set to '${process.env["CODEQL_EXTRACTOR_JAVA_OPTION_MINIMIZE_DEPENDENCY_JARS" /* JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS */]}', so the Action will not override it.` ); } else if (await codeQlVersionAtLeast(codeql, CODEQL_VERSION_JAR_MINIMIZATION) && config.dependencyCachingEnabled && config.buildMode === "none" /* None */ && config.languages.includes("java" /* java */)) { - core22.exportVariable( + actionState.env.export( "CODEQL_EXTRACTOR_JAVA_OPTION_MINIMIZE_DEPENDENCY_JARS" /* JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS */, "true" ); @@ -186673,23 +186706,23 @@ exec ${goBinaryPath} "$@"` const tracerConfig = await getCombinedTracerConfig(logger2, codeql, config); if (tracerConfig !== void 0) { for (const [key, value] of Object.entries(tracerConfig.env)) { - core22.exportVariable(key, value); + actionState.env.export(key, value); } } if (await features.getValue("java_network_debugging" /* JavaNetworkDebugging */)) { - const existingJavaToolOptions = getOptionalEnvVar("JAVA_TOOL_OPTIONS" /* JAVA_TOOL_OPTIONS */) || ""; - core22.exportVariable( + const existingJavaToolOptions = actionState.env.getOptional("JAVA_TOOL_OPTIONS" /* JAVA_TOOL_OPTIONS */) ?? ""; + actionState.env.export( "JAVA_TOOL_OPTIONS" /* JAVA_TOOL_OPTIONS */, `${existingJavaToolOptions} -Djavax.net.debug=all` ); } flushDiagnostics(config); await saveConfig(config, logger2); - core22.setOutput("codeql-path", config.codeQLCmd); - core22.setOutput("codeql-version", (await codeql.getVersion()).version); + core19.setOutput("codeql-path", config.codeQLCmd); + core19.setOutput("codeql-version", (await codeql.getVersion()).version); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); - core22.setFailed(error3.message); + core19.setFailed(error3.message); await sendCompletedStatusReport2( startedAt, config, @@ -186733,7 +186766,7 @@ async function runWrapper4() { } // src/init-action-post.ts -var core23 = __toESM(require_core()); +var core20 = __toESM(require_core()); // src/init-action-post-helper.ts var fs30 = __toESM(require("fs")); @@ -187105,7 +187138,7 @@ async function run4(startedAt) { } } catch (unwrappedError) { const error3 = wrapApiConfigurationError(wrapError(unwrappedError)); - core23.setFailed(error3.message); + core20.setFailed(error3.message); const statusReportBase2 = await createStatusReportBase( "init-post" /* InitPost */, getActionsStatus(error3), @@ -187150,14 +187183,14 @@ function getFinalJobStatus(config) { } let jobStatus; if (process.env["CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */] === "true") { - core23.exportVariable("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, "JOB_STATUS_SUCCESS" /* SuccessStatus */); + exportVariable2("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, "JOB_STATUS_SUCCESS" /* SuccessStatus */); jobStatus = "JOB_STATUS_SUCCESS" /* SuccessStatus */; } else if (config !== void 0) { jobStatus = "JOB_STATUS_CONFIGURATION_ERROR" /* ConfigErrorStatus */; } else { jobStatus = "JOB_STATUS_UNKNOWN" /* UnknownStatus */; } - core23.exportVariable("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, jobStatus); + exportVariable2("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, jobStatus); return jobStatus; } function getJobStatusFromEnvironment() { @@ -187176,7 +187209,7 @@ async function runWrapper5() { try { await run4(startedAt); } catch (error3) { - core23.setFailed(`init post action failed: ${wrapError(error3).message}`); + core20.setFailed(`init post action failed: ${wrapError(error3).message}`); await sendUnhandledErrorStatusReport( "init-post" /* InitPost */, startedAt, @@ -187187,7 +187220,7 @@ async function runWrapper5() { } // src/resolve-environment-action.ts -var core24 = __toESM(require_core()); +var core21 = __toESM(require_core()); // src/resolve-environment.ts async function runResolveBuildEnvironment(cmd, logger2, workingDir, language) { @@ -187234,16 +187267,16 @@ async function run5(startedAt) { workingDirectory, getRequiredInput("language") ); - core24.setOutput(ENVIRONMENT_OUTPUT_NAME, result); + core21.setOutput(ENVIRONMENT_OUTPUT_NAME, result); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); if (error3 instanceof CliError) { - core24.setOutput(ENVIRONMENT_OUTPUT_NAME, {}); + core21.setOutput(ENVIRONMENT_OUTPUT_NAME, {}); logger2.warning( `Failed to resolve a build environment suitable for automatically building your code. ${error3.message}` ); } else { - core24.setFailed( + core21.setFailed( `Failed to resolve a build environment suitable for automatically building your code. ${error3.message}` ); const statusReportBase2 = await createStatusReportBase( @@ -187280,7 +187313,7 @@ async function runWrapper6() { try { await run5(startedAt); } catch (error3) { - core24.setFailed( + core21.setFailed( `${"resolve-environment" /* ResolveEnvironment */} action failed: ${getErrorMessage( error3 )}` @@ -187296,7 +187329,7 @@ async function runWrapper6() { } // src/setup-codeql-action.ts -var core25 = __toESM(require_core()); +var core22 = __toESM(require_core()); async function sendCompletedStatusReport3(startedAt, toolsInput, toolsDownloadStatusReport, toolsFeatureFlagsValid, toolsSource, toolsVersion, logger2, error3) { const statusReportBase = await createStatusReportBase( "setup-codeql" /* SetupCodeQL */, @@ -187400,12 +187433,12 @@ async function run6(actionState) { toolsDownloadStatusReport = initCodeQLResult.toolsDownloadStatusReport; toolsVersion = initCodeQLResult.toolsVersion; toolsSource = initCodeQLResult.toolsSource; - core25.setOutput("codeql-path", codeql.getPath()); - core25.setOutput("codeql-version", (await codeql.getVersion()).version); - core25.exportVariable("CODEQL_ACTION_SETUP_CODEQL_HAS_RUN" /* SETUP_CODEQL_ACTION_HAS_RUN */, "true"); + core22.setOutput("codeql-path", codeql.getPath()); + core22.setOutput("codeql-version", (await codeql.getVersion()).version); + actionState.env.export("CODEQL_ACTION_SETUP_CODEQL_HAS_RUN" /* SETUP_CODEQL_ACTION_HAS_RUN */, "true"); } catch (unwrappedError) { const error3 = wrapError(unwrappedError); - core25.setFailed(error3.message); + core22.setFailed(error3.message); const statusReportBase = await createStatusReportBase( "setup-codeql" /* SetupCodeQL */, error3 instanceof ConfigurationError ? "user-error" : "failure", @@ -187443,15 +187476,15 @@ async function runWrapper7() { // src/start-proxy-action.ts var import_child_process2 = require("child_process"); var path29 = __toESM(require("path")); -var core28 = __toESM(require_core()); +var core25 = __toESM(require_core()); // src/start-proxy.ts var path27 = __toESM(require("path")); -var core27 = __toESM(require_core()); +var core24 = __toESM(require_core()); var toolcache4 = __toESM(require_tool_cache()); // src/start-proxy/validation.ts -var core26 = __toESM(require_core()); +var core23 = __toESM(require_core()); function cloneCredential(schema, obj) { const result = {}; for (const key of Object.keys(schema)) { @@ -187470,14 +187503,14 @@ function getAuthConfig(config) { } if (isToken(config)) { if (isDefined2(config.token)) { - core26.setSecret(config.token); + core23.setSecret(config.token); } return cloneCredential(tokenSchema, config); } else { let username = void 0; let password = void 0; if ("password" in config && isString(config.password)) { - core26.setSecret(config.password); + core23.setSecret(config.password); password = config.password; } if ("username" in config && isString(config.username)) { @@ -187533,7 +187566,7 @@ function getSafeErrorMessage(error3) { } async function sendFailedStatusReport(logger2, startedAt, language, unwrappedError) { const error3 = wrapError(unwrappedError); - core27.setFailed(`start-proxy action failed: ${error3.message}`); + core24.setFailed(`start-proxy action failed: ${error3.message}`); const statusReportMessage = getSafeErrorMessage(error3); const errorStatusReportBase = await createStatusReportBase( "start-proxy" /* StartProxy */, @@ -188114,7 +188147,7 @@ async function run7(action) { persistInputs(); const tempDir = getTemporaryDirectory(); const proxyLogFilePath = path29.resolve(tempDir, "proxy.log"); - core28.saveState("proxy-log-file", proxyLogFilePath); + core25.saveState("proxy-log-file", proxyLogFilePath); const repositoryNwo = getRepositoryNwo(); const gitHubVersion = await getGitHubVersion(); features = initFeatures( @@ -188139,7 +188172,7 @@ async function run7(action) { `Credentials loaded for the following registries: ${credentials.map((c) => credentialToStr(c)).join("\n")}` ); - if (core28.isDebug() || isInTestMode()) { + if (core25.isDebug() || isInTestMode()) { try { await checkProxyEnvironment(logger2, language); } catch (err) { @@ -188198,7 +188231,7 @@ async function startProxy(binPath, config, logFilePath, logger2) { ); subprocess.unref(); if (subprocess.pid) { - core28.saveState("proxy-process-pid", `${subprocess.pid}`); + core25.saveState("proxy-process-pid", `${subprocess.pid}`); } subprocess.on("error", (error3) => { subprocessError = error3; @@ -188217,25 +188250,25 @@ async function startProxy(binPath, config, logFilePath, logger2) { throw subprocessError; } logger2.info(`Proxy started on ${host}:${port}`); - core28.setOutput("proxy_host", host); - core28.setOutput("proxy_port", port.toString()); - core28.setOutput("proxy_ca_certificate", config.ca.cert); + core25.setOutput("proxy_host", host); + core25.setOutput("proxy_port", port.toString()); + core25.setOutput("proxy_ca_certificate", config.ca.cert); const registry_urls = config.all_credentials.filter((credential) => credential.url !== void 0).map((credential) => ({ type: credential.type, url: credential.url, "replaces-base": credential["replaces-base"] })); - core28.setOutput("proxy_urls", JSON.stringify(registry_urls)); + core25.setOutput("proxy_urls", JSON.stringify(registry_urls)); return { host, port, cert: config.ca.cert, registries: registry_urls }; } // src/start-proxy-action-post.ts -var core29 = __toESM(require_core()); +var core26 = __toESM(require_core()); async function runWrapper9() { const logger2 = getActionsLogger(); try { restoreInputs(logger2); - const pid = core29.getState("proxy-process-pid"); + const pid = core26.getState("proxy-process-pid"); if (pid) { process.kill(Number(pid)); } @@ -188243,8 +188276,8 @@ async function runWrapper9() { getTemporaryDirectory(), logger2 ); - if (config?.debugMode || core29.isDebug()) { - const logFilePath = core29.getState("proxy-log-file"); + if (config?.debugMode || core26.isDebug()) { + const logFilePath = core26.getState("proxy-log-file"); logger2.info( "Debug mode is on. Uploading proxy log as Actions debugging artifact..." ); @@ -188266,7 +188299,7 @@ async function runWrapper9() { } // src/upload-sarif-action.ts -var core30 = __toESM(require_core()); +var core27 = __toESM(require_core()); async function sendSuccessStatusReport2(startedAt, uploadStats, logger2) { const statusReportBase = await createStatusReportBase( "upload-sarif" /* UploadSarif */, @@ -188326,11 +188359,11 @@ async function run8({ startedAt, logger: logger2 }) { } const codeScanningResult = uploadResults["code-scanning" /* CodeScanning */]; if (codeScanningResult !== void 0) { - core30.setOutput("sarif-id", codeScanningResult.sarifID); + core27.setOutput("sarif-id", codeScanningResult.sarifID); } - core30.setOutput("sarif-ids", JSON.stringify(uploadResults)); + core27.setOutput("sarif-ids", JSON.stringify(uploadResults)); if (shouldSkipSarifUpload()) { - core30.debug( + core27.debug( "SARIF upload disabled by an environment variable. Waiting for processing is disabled." ); } else if (getRequiredInput("wait-for-processing") === "true") { @@ -188350,7 +188383,7 @@ async function run8({ startedAt, logger: logger2 }) { } catch (unwrappedError) { const error3 = isThirdPartyAnalysis("upload-sarif" /* UploadSarif */) && unwrappedError instanceof InvalidSarifUploadError ? new ConfigurationError(unwrappedError.message) : wrapError(unwrappedError); const message = error3.message; - core30.setFailed(message); + core27.setFailed(message); const errorStatusReportBase = await createStatusReportBase( "upload-sarif" /* UploadSarif */, getActionsStatus(error3), @@ -188376,7 +188409,7 @@ async function runWrapper10() { } // src/upload-sarif-action-post.ts -var core31 = __toESM(require_core()); +var core28 = __toESM(require_core()); async function runWrapper11() { try { const logger2 = getActionsLogger(); @@ -188385,7 +188418,7 @@ async function runWrapper11() { checkGitHubVersionInRange(gitHubVersion, logger2); if (process.env["CODEQL_ACTION_INIT_HAS_RUN" /* INIT_ACTION_HAS_RUN */] !== "true") { if (gitHubVersion.type === void 0) { - core31.warning( + core28.warning( `Did not upload debug artifacts because cannot determine the GitHub variant running.` ); return; @@ -188402,7 +188435,7 @@ async function runWrapper11() { ); } } catch (error3) { - core31.setFailed( + core28.setFailed( `upload-sarif post-action step failed: ${getErrorMessage(error3)}` ); } diff --git a/src/actions-util.ts b/src/actions-util.ts index 6c7d6a78d2..ea9a119ed4 100644 --- a/src/actions-util.ts +++ b/src/actions-util.ts @@ -30,7 +30,6 @@ declare const __CODEQL_ACTION_VERSION__: string; export interface ActionsEnv { getRequiredInput: (name: string) => string; getOptionalInput: (name: string) => string | undefined; - exportVariable: (name: string, value: string) => void; } /** @@ -40,7 +39,6 @@ export function getActionsEnv(): ActionsEnv { return { getRequiredInput, getOptionalInput, - exportVariable: core.exportVariable, }; } diff --git a/src/analyze-action.ts b/src/analyze-action.ts index 7963fa52bf..a019332858 100644 --- a/src/analyze-action.ts +++ b/src/analyze-action.ts @@ -214,9 +214,10 @@ async function runAutobuildIfLegacyGoWorkflow(config: Config, logger: Logger) { async function run({ startedAt, + env, logger, actions, -}: ActionState<["Base", "Logger", "Actions"]>) { +}: ActionState<["Base", "Env", "Logger", "Actions"]>) { // To capture errors appropriately, keep as much code within the try-catch as // possible, and only use safe functions outside. @@ -287,7 +288,7 @@ async function run({ const apiDetails = getApiDetails(); const outputDir = actionsUtil.getRequiredInput("output"); - core.exportVariable(EnvVar.SARIF_RESULTS_OUTPUT_DIR, outputDir); + env.export(EnvVar.SARIF_RESULTS_OUTPUT_DIR, outputDir); const threads = util.getThreadsFlag( actionsUtil.getOptionalInput("threads") || process.env["CODEQL_THREADS"], logger, @@ -456,7 +457,7 @@ async function run({ `expect-error input was set to true but no error was thrown.`, ); } - core.exportVariable(EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY, "true"); + env.export(EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY, "true"); } catch (unwrappedError) { const error = util.wrapError(unwrappedError); if ( diff --git a/src/api-client.ts b/src/api-client.ts index de62f4db44..0a6e16b679 100644 --- a/src/api-client.ts +++ b/src/api-client.ts @@ -17,6 +17,7 @@ import { ReadOnlyEnv, RegistryProxyVars, getEnv, + exportVariable, } from "./environment"; import { Logger } from "./logging"; import { getRepositoryNwo, RepositoryNwo } from "./repository"; @@ -316,7 +317,7 @@ export async function getAnalysisKey(): Promise { const jobName = getRequiredEnvParam("GITHUB_JOB"); analysisKey = `${workflowPath}:${jobName}`; - core.exportVariable(EnvVar.ANALYSIS_KEY, analysisKey); + exportVariable(EnvVar.ANALYSIS_KEY, analysisKey); return analysisKey; } diff --git a/src/autobuild-action.ts b/src/autobuild-action.ts index 9fa8016578..18aad11855 100644 --- a/src/autobuild-action.ts +++ b/src/autobuild-action.ts @@ -68,7 +68,11 @@ async function sendCompletedStatusReport( } } -async function run({ startedAt, logger }: ActionState<["Base", "Logger"]>) { +async function run({ + startedAt, + env, + logger, +}: ActionState<["Base", "Env", "Logger"]>) { // To capture errors appropriately, keep as much code within the try-catch as // possible, and only use safe functions outside. @@ -135,7 +139,7 @@ async function run({ startedAt, logger }: ActionState<["Base", "Logger"]>) { return; } - core.exportVariable(EnvVar.AUTOBUILD_DID_COMPLETE_SUCCESSFULLY, "true"); + env.export(EnvVar.AUTOBUILD_DID_COMPLETE_SUCCESSFULLY, "true"); await sendCompletedStatusReport(config, logger, startedAt, languages ?? []); } diff --git a/src/autobuild.ts b/src/autobuild.ts index 49b790102d..6a2c5aa542 100644 --- a/src/autobuild.ts +++ b/src/autobuild.ts @@ -1,11 +1,9 @@ -import * as core from "@actions/core"; - import { getTemporaryDirectory, getWorkflowEventName } from "./actions-util"; import { getGitHubVersion } from "./api-client"; import { CodeQL, getCodeQL } from "./codeql"; import * as configUtils from "./config-utils"; import { DocUrl } from "./doc-url"; -import { ActionsEnvVars, EnvVar } from "./environment"; +import { ActionsEnvVars, EnvVar, exportVariable } from "./environment"; import { Feature, featureConfig, initFeatures } from "./feature-flags"; import { BuiltInLanguage, Language } from "./languages"; import { Logger } from "./logging"; @@ -136,16 +134,16 @@ export async function setupCppAutobuild(codeql: CodeQL, logger: Logger) { : "" }`, ); - core.exportVariable(envVar, "false"); + exportVariable(envVar, "false"); } else { logger.info( `Enabling ${featureName}. This can be disabled by setting the ${envVar} environment variable to 'false'. See ${DocUrl.DEFINE_ENV_VARIABLES} for more information.`, ); - core.exportVariable(envVar, "true"); + exportVariable(envVar, "true"); } } else { logger.info(`Disabling ${featureName}.`); - core.exportVariable(envVar, "false"); + exportVariable(envVar, "false"); } } @@ -165,7 +163,7 @@ export async function runAutobuild( await codeQL.runAutobuild(config, language); } if (language === BuiltInLanguage.go) { - core.exportVariable(EnvVar.DID_AUTOBUILD_GOLANG, "true"); + exportVariable(EnvVar.DID_AUTOBUILD_GOLANG, "true"); } logger.endGroup(); } diff --git a/src/codeql.ts b/src/codeql.ts index 4d4e4a091d..58d0a9cf69 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -17,7 +17,7 @@ import type { VersionInfo } from "./cli/types"; import { CliError, wrapCliConfigurationError } from "./cli-errors"; import { appendExtraQueryExclusions, type Config } from "./config-utils"; import { DocUrl } from "./doc-url"; -import { EnvVar, getEnv } from "./environment"; +import { EnvVar, getEnv, exportVariable } from "./environment"; import { CodeQLDefaultVersionInfo, Feature, @@ -1054,7 +1054,7 @@ async function getCodeQLForCmd( }' by 'github/codeql-action/*@v${getActionVersion()}' in your code scanning workflow to ` + "continue using this version of the CodeQL Action.", ); - core.exportVariable(EnvVar.SUPPRESS_DEPRECATED_SOON_WARNING, "true"); + exportVariable(EnvVar.SUPPRESS_DEPRECATED_SOON_WARNING, "true"); } return codeql; } diff --git a/src/config-utils.ts b/src/config-utils.ts index 46640c3449..54843951ac 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -2,7 +2,6 @@ import * as fs from "fs"; import * as path from "path"; import { performance } from "perf_hooks"; -import * as core from "@actions/core"; import * as yaml from "js-yaml"; import { ActionState } from "./action-common"; @@ -46,7 +45,7 @@ import { makeTelemetryDiagnostic, } from "./diagnostics"; import { prepareDiffInformedAnalysis } from "./diff-informed-analysis-utils"; -import { EnvVar } from "./environment"; +import { EnvVar, exportVariable } from "./environment"; import * as errorMessages from "./error-messages"; import { Feature, FeatureEnablement, FeatureWithoutCLI } from "./feature-flags"; import { @@ -965,10 +964,10 @@ async function setCppTrapCachingEnvironmentVariables( ); } else if (config.trapCaches[BuiltInLanguage.cpp]) { logger.info("Enabling TRAP caching for C/C++."); - core.exportVariable(envVar, "true"); + exportVariable(envVar, "true"); } else { logger.debug(`Disabling TRAP caching for C/C++.`); - core.exportVariable(envVar, "false"); + exportVariable(envVar, "false"); } } } diff --git a/src/debug-artifacts.ts b/src/debug-artifacts.ts index 9f5f1775d4..4563a90368 100644 --- a/src/debug-artifacts.ts +++ b/src/debug-artifacts.ts @@ -11,7 +11,7 @@ import { dbIsFinalized } from "./analyze"; import { scanArtifactsForTokens } from "./artifact-scanner"; import { type CodeQL } from "./codeql"; import { Config } from "./config-utils"; -import { EnvVar } from "./environment"; +import { EnvVar, exportVariable } from "./environment"; import * as json from "./json"; import { Language } from "./languages"; import { Logger, withGroup } from "./logging"; @@ -330,7 +330,7 @@ export async function uploadArtifacts( // some issues early. if (isInTestMode()) { await scanArtifactsForTokens(toUpload, logger); - core.exportVariable("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true"); + exportVariable("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true"); } const suffix = getArtifactSuffix(getOptionalInput("matrix")); diff --git a/src/environment.ts b/src/environment.ts index 971e1ca8de..4a68e76be1 100644 --- a/src/environment.ts +++ b/src/environment.ts @@ -1,3 +1,5 @@ +import * as core from "@actions/core"; + /** * Environment variables used by Default Setup to communicate the private registry proxy configuration. */ @@ -211,8 +213,20 @@ export enum ActionsEnvVars { RUNNER_TOOL_CACHE = "RUNNER_TOOL_CACHE", } +/** Environment variables which are not specific to CodeQL. */ +export enum SystemEnvVar { + /** + * Used by Node and related tools to indicate what kind of environment we are running in. + */ + NODE_ENV = "NODE_ENV", +} + /** A type representing all known environment variables. */ -export type KnownEnvVar = EnvVar | ActionsEnvVars | RegistryProxyVars; +export type KnownEnvVar = + | EnvVar + | ActionsEnvVars + | RegistryProxyVars + | SystemEnvVar; /** * Gets an environment variable, but throws an error if it is not set. @@ -289,6 +303,16 @@ export class ReadOnlyEnv { public entries(): Array<[string, T]> { return Object.entries(this.vars); } + + /** + * Gets a value indicative of whether we are in a testing environment + * by testing whether the value of the `NODE_ENV` variable is "test". + * This is expected to be the case if e.g. `ava` is running the tests + * or if this instance was constructed by `getTestEnv`. + */ + public isTestingEnv(): boolean { + return this.getOptional(SystemEnvVar.NODE_ENV) === "test"; + } } /** @@ -307,6 +331,26 @@ export class Env< this.changed = true; } + /** + * Wrapper around `core.exportVariable` which does not call `core.exportVariable` + * when running unit tests. This is important, because otherwise `core.exportVariable` + * sets environment variables for other steps in a workflow when we run unit tests in CI. + * + * @param name The name of the environment variable to set and export. + * @param val The value to set and export for the environment variable. + */ + public export(name: string, val: T): void { + // Setting the environment variable for this instance is always OK, including + // in tests, since we use fresh `Env` instances whenever needed. This allows + // tests to pass that rely on that part of the `core.exportVariable` behaviour. + this.set(name, val); + + // Call `core.exportVariable` whenever we are not in a test environment. + if (!this.isTestingEnv()) { + core.exportVariable(name, val); + } + } + /** Gets a value indicating whether `set` was called at least once. */ public hasChanged(): boolean { return this.changed; @@ -326,3 +370,20 @@ export function getEnv(env: NodeJS.ProcessEnv = process.env): Env { export function isInTestMode(): boolean { return process.env[EnvVar.TEST_MODE] === "true"; } + +/** + * Wrapper around `core.exportVariable` which does not call `core.exportVariable` + * when running unit tests. This is important, because otherwise `core.exportVariable` + * sets environment variables for other steps in a workflow when we run unit tests in CI. + * + * @deprecated Use `export` on an `Env` instance instead. + */ +export function exportVariable(name: string, val: any): void { + const env = getEnv(); + + if (typeof val === "string") { + env.export(name, val); + } else { + env.export(name, JSON.stringify(val)); + } +} diff --git a/src/init-action-post.ts b/src/init-action-post.ts index a2bba6d7a4..90f67ea61b 100644 --- a/src/init-action-post.ts +++ b/src/init-action-post.ts @@ -21,7 +21,7 @@ import { DependencyCachingUsageReport, getDependencyCacheUsage, } from "./dependency-caching"; -import { EnvVar, getEnv } from "./environment"; +import { EnvVar, getEnv, exportVariable } from "./environment"; import { initFeatures } from "./feature-flags"; import * as gitUtils from "./git-utils"; import * as initActionPostHelper from "./init-action-post-helper"; @@ -166,7 +166,7 @@ function getFinalJobStatus(config: Config | undefined): JobStatus { let jobStatus: JobStatus; if (process.env[EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY] === "true") { - core.exportVariable(EnvVar.JOB_STATUS, JobStatus.SuccessStatus); + exportVariable(EnvVar.JOB_STATUS, JobStatus.SuccessStatus); jobStatus = JobStatus.SuccessStatus; } else if (config !== undefined) { // - We have computed a CodeQL config @@ -191,7 +191,7 @@ function getFinalJobStatus(config: Config | undefined): JobStatus { // This shouldn't be necessary, but in the odd case that we run more than one // `init` post step, ensure the job status is consistent between them. - core.exportVariable(EnvVar.JOB_STATUS, jobStatus); + exportVariable(EnvVar.JOB_STATUS, jobStatus); return jobStatus; } diff --git a/src/init-action.ts b/src/init-action.ts index 31414bd80b..ab8591f488 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -93,7 +93,6 @@ import { checkActionVersion, getErrorMessage, BuildMode, - getOptionalEnvVar, } from "./util"; import { checkWorkflow } from "./workflow"; @@ -253,7 +252,7 @@ async function run( ); const repositoryProperties = repositoryPropertiesResult.orElse({}); - core.exportVariable(EnvVar.INIT_ACTION_HAS_RUN, "true"); + actionState.env.export(EnvVar.INIT_ACTION_HAS_RUN, "true"); // path.resolve() respects the intended semantics of source-root. If // source-root is relative, it is relative to the GITHUB_WORKSPACE. If @@ -369,7 +368,7 @@ async function run( ); } if (semver.lt(actualVer, publicPreview)) { - core.exportVariable(EnvVar.EXPERIMENTAL_FEATURES, "true"); + actionState.env.export(EnvVar.EXPERIMENTAL_FEATURES, "true"); logger.info("Experimental Rust analysis enabled"); } } @@ -517,9 +516,9 @@ async function run( } // Forward Go flags - const goFlags = process.env["GOFLAGS"]; + const goFlags = actionState.env.getOptional("GOFLAGS"); if (goFlags) { - core.exportVariable("GOFLAGS", goFlags); + actionState.env.export("GOFLAGS", goFlags); core.warning( "Passing the GOFLAGS env parameter to the init action is deprecated. Please move this to the analyze action.", ); @@ -565,7 +564,7 @@ async function run( // Store the original location of our wrapper script somewhere where we can // later retrieve it from and cross-check that it hasn't been changed. - core.exportVariable(EnvVar.GO_BINARY_LOCATION, goWrapperPath); + actionState.env.export(EnvVar.GO_BINARY_LOCATION, goWrapperPath); } catch (e) { logger.warning( `Analyzing Go on Linux, but failed to install wrapper script. Tracing custom builds may fail: ${e}`, @@ -574,7 +573,7 @@ async function run( } else { // Store the location of the original Go binary, so we can check that no setup tasks were performed after the // `init` Action ran. - core.exportVariable(EnvVar.GO_BINARY_LOCATION, goBinaryPath); + actionState.env.export(EnvVar.GO_BINARY_LOCATION, goBinaryPath); } } catch (e) { logger.warning( @@ -609,12 +608,12 @@ async function run( // threads it would ask extractors to use. See help text for the "--ram" and "--threads" // options at https://codeql.github.com/docs/codeql-cli/manual/database-trace-command/ // for details. - core.exportVariable( + actionState.env.export( "CODEQL_RAM", process.env["CODEQL_RAM"] || getCodeQLMemoryLimit(getOptionalInput("ram"), logger).toString(), ); - core.exportVariable( + actionState.env.export( "CODEQL_THREADS", process.env["CODEQL_THREADS"] || getThreadsFlagValue(getOptionalInput("threads"), logger).toString(), @@ -622,12 +621,15 @@ async function run( // Disable Kotlin extractor if feature flag set if (await features.getValue(Feature.DisableKotlinAnalysisEnabled)) { - core.exportVariable("CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN", "true"); + actionState.env.export( + "CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN", + "true", + ); } // Emergency override to force the CodeQL CLI back to the JGit-based Git backend. if (await features.getValue(Feature.ForceJGit)) { - core.exportVariable("CODEQL_GIT_BACKEND", "jgit"); + actionState.env.export("CODEQL_GIT_BACKEND", "jgit"); } const kotlinLimitVar = @@ -636,7 +638,7 @@ async function run( (await codeQlVersionAtLeast(codeql, "2.20.3")) && !(await codeQlVersionAtLeast(codeql, "2.20.4")) ) { - core.exportVariable(kotlinLimitVar, "2.1.20"); + actionState.env.export(kotlinLimitVar, "2.1.20"); } // Restore dependency cache(s), if they exist. @@ -685,7 +687,7 @@ async function run( config.buildMode === BuildMode.None && config.languages.includes(BuiltInLanguage.java) ) { - core.exportVariable( + actionState.env.export( EnvVar.JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS, "true", ); @@ -743,7 +745,7 @@ async function run( const tracerConfig = await getCombinedTracerConfig(logger, codeql, config); if (tracerConfig !== undefined) { for (const [key, value] of Object.entries(tracerConfig.env)) { - core.exportVariable(key, value); + actionState.env.export(key, value); } } @@ -751,10 +753,10 @@ async function run( if (await features.getValue(Feature.JavaNetworkDebugging)) { // Get the existing value of `JAVA_TOOL_OPTIONS`, if any. const existingJavaToolOptions = - getOptionalEnvVar(JavaEnvVars.JAVA_TOOL_OPTIONS) || ""; + actionState.env.getOptional(JavaEnvVars.JAVA_TOOL_OPTIONS) ?? ""; // Add the network debugging options. - core.exportVariable( + actionState.env.export( JavaEnvVars.JAVA_TOOL_OPTIONS, `${existingJavaToolOptions} -Djavax.net.debug=all`, ); diff --git a/src/init.test.ts b/src/init.test.ts index 1f0d2c701c..b40f9611d7 100644 --- a/src/init.test.ts +++ b/src/init.test.ts @@ -1,14 +1,13 @@ import * as fs from "fs"; import path from "path"; -import * as core from "@actions/core"; import * as github from "@actions/github"; import test, { ExecutionContext } from "ava"; import * as sinon from "sinon"; import * as actionsUtil from "./actions-util"; import { createStubCodeQL } from "./codeql"; -import { ActionsEnvVars } from "./environment"; +import * as environment from "./environment"; import { Feature } from "./feature-flags"; import { checkPacksForOverlayCompatibility, @@ -85,7 +84,7 @@ for (const { runnerEnv, ErrorConstructor, message } of [ `cleanupDatabaseClusterDirectory throws a ${ErrorConstructor.name} when cleanup fails on ${runnerEnv} runner`, async (t) => { await withTmpDir(async (tmpDir: string) => { - process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] = runnerEnv; + process.env[environment.ActionsEnvVars.RUNNER_ENVIRONMENT] = runnerEnv; const dbLocation = path.resolve(tmpDir, "dbs"); fs.mkdirSync(dbLocation, { recursive: true }); @@ -546,7 +545,7 @@ test.serial( test.serial( "file coverage deprecation warning for org-owned repo with default setup recommends repo property", (t) => { - const exportVariableStub = sinon.stub(core, "exportVariable"); + const exportVariableStub = sinon.stub(environment, "exportVariable"); sinon.stub(actionsUtil, "isDefaultSetup").returns(true); github.context.payload = { repository: { @@ -573,7 +572,7 @@ test.serial( test.serial( "file coverage deprecation warning for org-owned repo with advanced setup recommends env var and repo property", (t) => { - const exportVariableStub = sinon.stub(core, "exportVariable"); + const exportVariableStub = sinon.stub(environment, "exportVariable"); sinon.stub(actionsUtil, "isDefaultSetup").returns(false); github.context.payload = { repository: { @@ -601,7 +600,7 @@ test.serial( test.serial( "file coverage deprecation warning for user-owned repo with default setup recommends advanced setup", (t) => { - const exportVariableStub = sinon.stub(core, "exportVariable"); + const exportVariableStub = sinon.stub(environment, "exportVariable"); sinon.stub(actionsUtil, "isDefaultSetup").returns(true); github.context.payload = { repository: { @@ -627,7 +626,7 @@ test.serial( test.serial( "file coverage deprecation warning for user-owned repo with advanced setup recommends env var", (t) => { - const exportVariableStub = sinon.stub(core, "exportVariable"); + const exportVariableStub = sinon.stub(environment, "exportVariable"); sinon.stub(actionsUtil, "isDefaultSetup").returns(false); github.context.payload = { repository: { @@ -652,7 +651,7 @@ test.serial( test.serial( "file coverage deprecation warning for unknown owner type with default setup recommends advanced setup", (t) => { - const exportVariableStub = sinon.stub(core, "exportVariable"); + const exportVariableStub = sinon.stub(environment, "exportVariable"); sinon.stub(actionsUtil, "isDefaultSetup").returns(true); github.context.payload = { repository: undefined }; const messages: LoggedMessage[] = []; @@ -673,7 +672,7 @@ test.serial( test.serial( "file coverage deprecation warning for unknown owner type with advanced setup recommends env var", (t) => { - const exportVariableStub = sinon.stub(core, "exportVariable"); + const exportVariableStub = sinon.stub(environment, "exportVariable"); sinon.stub(actionsUtil, "isDefaultSetup").returns(false); github.context.payload = { repository: undefined }; const messages: LoggedMessage[] = []; @@ -695,7 +694,7 @@ test.serial( (t) => { process.env["CODEQL_ACTION_DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION"] = "true"; - const exportVariableStub = sinon.stub(core, "exportVariable"); + const exportVariableStub = sinon.stub(environment, "exportVariable"); const messages: LoggedMessage[] = []; logFileCoverageOnPrsDeprecationWarning(getRecordingLogger(messages)); t.is(messages.length, 0); diff --git a/src/init.ts b/src/init.ts index d757e29976..06314acf2a 100644 --- a/src/init.ts +++ b/src/init.ts @@ -1,7 +1,6 @@ import * as fs from "fs"; import * as path from "path"; -import * as core from "@actions/core"; import * as toolrunner from "@actions/exec/lib/toolrunner"; import * as github from "@actions/github"; import * as io from "@actions/io"; @@ -17,7 +16,7 @@ import { import { GitHubApiDetails } from "./api-client"; import { CodeQL, setupCodeQL } from "./codeql"; import * as configUtils from "./config-utils"; -import { EnvVar } from "./environment"; +import { EnvVar, exportVariable } from "./environment"; import { CodeQLDefaultVersionInfo, Feature, @@ -411,5 +410,5 @@ export function logFileCoverageOnPrsDeprecationWarning(logger: Logger): void { } logger.warning(message); - core.exportVariable(EnvVar.DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION, "true"); + exportVariable(EnvVar.DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION, "true"); } diff --git a/src/setup-codeql-action.ts b/src/setup-codeql-action.ts index 23a9c65ebd..ccd68288d3 100644 --- a/src/setup-codeql-action.ts +++ b/src/setup-codeql-action.ts @@ -184,7 +184,7 @@ async function run( core.setOutput("codeql-path", codeql.getPath()); core.setOutput("codeql-version", (await codeql.getVersion()).version); - core.exportVariable(EnvVar.SETUP_CODEQL_ACTION_HAS_RUN, "true"); + actionState.env.export(EnvVar.SETUP_CODEQL_ACTION_HAS_RUN, "true"); } catch (unwrappedError) { const error = wrapError(unwrappedError); core.setFailed(error.message); diff --git a/src/setup-codeql.ts b/src/setup-codeql.ts index f2ce959a8d..0c25bbe08d 100644 --- a/src/setup-codeql.ts +++ b/src/setup-codeql.ts @@ -3,7 +3,6 @@ import { OutgoingHttpHeaders } from "http"; import * as path from "path"; import { performance } from "perf_hooks"; -import * as core from "@actions/core"; import * as toolcache from "@actions/tool-cache"; import { default as deepEqual } from "fast-deep-equal"; import * as semver from "semver"; @@ -29,7 +28,7 @@ import { makeDiagnostic, makeTelemetryDiagnostic, } from "./diagnostics"; -import { EnvVar, getEnv } from "./environment"; +import { EnvVar, exportVariable, getEnv } from "./environment"; import { CODEQL_VERSION_ZSTD_BUNDLE, CodeQLDefaultVersionInfo, @@ -1071,7 +1070,7 @@ export async function setupCodeQLBundle( // Record that this job now has a copy of the CodeQL tools, so that a later step doesn't delete // the toolcache out from under the path we are about to return. - core.exportVariable(EnvVar.HAS_SET_UP_CODEQL, "true"); + exportVariable(EnvVar.HAS_SET_UP_CODEQL, "true"); return { codeqlFolder, diff --git a/src/status-report.ts b/src/status-report.ts index c392b51922..43e52f67fb 100644 --- a/src/status-report.ts +++ b/src/status-report.ts @@ -23,7 +23,13 @@ import type { ComputedInput, InputName } from "./config/inputs"; import { parseRegistriesWithoutCredentials } from "./config/pack-registries"; import type { DependencyCacheRestoreStatusReport } from "./dependency-caching"; import { DocUrl } from "./doc-url"; -import { EnvVar, getEnv, ReadOnlyEnv, RegistryProxyVars } from "./environment"; +import { + EnvVar, + getEnv, + ReadOnlyEnv, + RegistryProxyVars, + exportVariable, +} from "./environment"; import { getRef } from "./git-utils"; import * as json from "./json"; import type { Logger } from "./logging"; @@ -71,9 +77,7 @@ export function getDisplayActionName(actionName: ActionName): string { * environment and returns it. * If a new UUID is generated, it is also exported as an environment variable. */ -export function getJobUUID( - action: ActionState<["Logger", "ReadOnlyEnv", "Actions"]>, -) { +export function getJobUUID(action: ActionState<["Logger", "Env", "Actions"]>) { // Check if we already have a UUID for the analysis and return it if so. const existingJobRunUuid = action.env.getOptional(EnvVar.JOB_RUN_UUID); @@ -86,7 +90,7 @@ export function getJobUUID( const jobRunUuid = uuid.v4(); action.logger.info(`Job run UUID is ${jobRunUuid}.`); - action.actions.exportVariable(EnvVar.JOB_RUN_UUID, jobRunUuid); + action.env.export(EnvVar.JOB_RUN_UUID, jobRunUuid); return jobRunUuid; } @@ -268,12 +272,12 @@ export function getJobStatusDisplayName(status: JobStatus): string { */ function setJobStatusIfUnsuccessful(actionStatus: ActionStatus) { if (actionStatus === "user-error") { - core.exportVariable( + exportVariable( EnvVar.JOB_STATUS, process.env[EnvVar.JOB_STATUS] ?? JobStatus.ConfigErrorStatus, ); } else if (actionStatus === "failure" || actionStatus === "aborted") { - core.exportVariable( + exportVariable( EnvVar.JOB_STATUS, process.env[EnvVar.JOB_STATUS] ?? JobStatus.FailureStatus, ); @@ -376,7 +380,7 @@ export async function createStatusReportBase( let workflowStartedAt = process.env[EnvVar.WORKFLOW_STARTED_AT]; if (workflowStartedAt === undefined) { workflowStartedAt = actionStartedAt.toISOString(); - core.exportVariable(EnvVar.WORKFLOW_STARTED_AT, workflowStartedAt); + exportVariable(EnvVar.WORKFLOW_STARTED_AT, workflowStartedAt); } const runnerOs = getRequiredEnvParam("RUNNER_OS"); const codeQlCliVersion = getCachedCodeQlVersion( @@ -388,7 +392,7 @@ export async function createStatusReportBase( // re-export the testing environment variable so that it is available to subsequent steps, // even if it was only set for this step if (testingEnvironment) { - core.exportVariable(EnvVar.TESTING_ENVIRONMENT, testingEnvironment); + exportVariable(EnvVar.TESTING_ENVIRONMENT, testingEnvironment); } const isSteadyStateDefaultSetupRun = process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true"; diff --git a/src/testing-utils.ts b/src/testing-utils.ts index a5ba50554c..2011b56e00 100644 --- a/src/testing-utils.ts +++ b/src/testing-utils.ts @@ -184,6 +184,12 @@ export function makeMacro( } export function getTestEnv(testEnv: NodeJS.ProcessEnv = {}): Env { + // In unit tests run by `ava`, this environment variable is set for the process, + // but we default to an empty environment here for `testEnv`, so we must set it + // explicitly to ensure that we get test-specific behaviour in functions when + // we need it. + testEnv["NODE_ENV"] = "test"; + return getEnv(testEnv); } @@ -202,10 +208,6 @@ class TestActionsEnv implements ActionsEnv { public getOptionalInput(_name: string): string | undefined { return undefined; } - - public exportVariable(name: string, value: string): void { - this.env.set(name, value); - } } /** diff --git a/src/upload-lib.ts b/src/upload-lib.ts index c5b6c6efd5..17b3422dc9 100644 --- a/src/upload-lib.ts +++ b/src/upload-lib.ts @@ -14,7 +14,7 @@ import { getGitHubVersion, wrapApiConfigurationError } from "./api-client"; import { CodeQL, getCodeQL } from "./codeql"; import { getConfig } from "./config-utils"; import { readDiffRangesJsonFile } from "./diff-informed-analysis-utils"; -import { EnvVar } from "./environment"; +import { EnvVar, exportVariable } from "./environment"; import { FeatureEnablement } from "./feature-flags"; import * as fingerprints from "./fingerprints"; import * as gitUtils from "./git-utils"; @@ -126,7 +126,7 @@ async function combineSarifFilesUsingCLI( logger.warning( `Uploading multiple SARIF runs with the same category is deprecated ${deprecationWarningMessage}. Please update your workflow to upload a single run per category. ${deprecationMoreInformationMessage}`, ); - core.exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true"); + exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true"); } // If not, use the naive method of combining the files. @@ -1032,7 +1032,7 @@ export function validateUniqueCategory( `Category: (${id ? id : "none"}) Tool: (${tool ? tool : "none"})`, ); } - core.exportVariable(sentinelEnvVar, sentinelEnvVar); + exportVariable(sentinelEnvVar, sentinelEnvVar); } } diff --git a/src/util.ts b/src/util.ts index 26b27e5bad..2df488f57f 100644 --- a/src/util.ts +++ b/src/util.ts @@ -14,7 +14,12 @@ import * as apiCompatibility from "./api-compatibility.json"; import type { CodeQL } from "./codeql"; import type { Pack } from "./config/db-config"; import type { Config } from "./config-utils"; -import { EnvVar, getRequiredEnvParam, isInTestMode } from "./environment"; +import { + EnvVar, + getRequiredEnvParam, + isInTestMode, + exportVariable, +} from "./environment"; import * as json from "./json"; import { Language } from "./languages"; import { Logger } from "./logging"; @@ -547,7 +552,7 @@ export function checkGitHubVersionInRange( ); } hasBeenWarnedAboutVersion = true; - core.exportVariable(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true); + exportVariable(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true); } export enum DisallowedAPIVersionReason { @@ -591,11 +596,11 @@ export function assertNever(value: never): never { * knowing what version of CodeQL we're running. */ export function initializeEnvironment(version: string) { - core.exportVariable(EnvVar.FEATURE_MULTI_LANGUAGE, "false"); - core.exportVariable(EnvVar.FEATURE_SANDWICH, "false"); - core.exportVariable(EnvVar.FEATURE_SARIF_COMBINE, "true"); - core.exportVariable(EnvVar.FEATURE_WILL_UPLOAD, "true"); - core.exportVariable(EnvVar.VERSION, version); + exportVariable(EnvVar.FEATURE_MULTI_LANGUAGE, "false"); + exportVariable(EnvVar.FEATURE_SANDWICH, "false"); + exportVariable(EnvVar.FEATURE_SARIF_COMBINE, "true"); + exportVariable(EnvVar.FEATURE_WILL_UPLOAD, "true"); + exportVariable(EnvVar.VERSION, version); } export class HTTPError extends Error { @@ -944,7 +949,7 @@ export async function checkDiskUsage( } else { logger.debug(message); } - core.exportVariable(EnvVar.HAS_WARNED_ABOUT_DISK_SPACE, "true"); + exportVariable(EnvVar.HAS_WARNED_ABOUT_DISK_SPACE, "true"); } return { numAvailableBytes: diskUsage.bavail * blockSizeInBytes, @@ -993,7 +998,7 @@ export function checkActionVersion( "https://github.blog/changelog/2025-10-28-upcoming-deprecation-of-codeql-action-v3/", ); // set LOG_VERSION_DEPRECATION env var to prevent the warning from being logged multiple times - core.exportVariable(EnvVar.LOG_VERSION_DEPRECATION, "true"); + exportVariable(EnvVar.LOG_VERSION_DEPRECATION, "true"); } } } From 59ff83ecef15b13c0ae74b6a22a26ddc1250dbab Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 22 May 2026 14:29:31 +0100 Subject: [PATCH 041/107] Add basic eslint enforcement --- eslint.config.mjs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/eslint.config.mjs b/eslint.config.mjs index 34fe49a9df..ae8f5fc971 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -140,6 +140,18 @@ export default [ "no-async-foreach/no-async-foreach": "error", "no-sequences": "error", "no-shadow": "off", + + // A basic check that we don't use `exportVariable` from `@actions/core`. This rule depends on + // the module being imported as `core`, but that is a good enough check for us. + "no-restricted-syntax": [ + "error", + { + selector: + "MemberExpression[object.name='core'][property.name='exportVariable']", + message: "Use `exportVariable` from `environment.ts` instead.", + }, + ], + // This is overly restrictive with unsetting `EnvVar`s "@typescript-eslint/no-dynamic-delete": "off", "@typescript-eslint/no-shadow": "error", @@ -157,6 +169,15 @@ export default [ ], }, }, + { + files: ["src/environment.ts"], + + // We allow `exportVariable` from `@actions/core` to be used in this file + // since it defines the wrapper around it that other modules use. + rules: { + "no-restricted-syntax": "off", + }, + }, { files: ["**/*.ts", "**/*.js"], From 75ea4cb2e4a573dea67a45cbdb9c63d94414d41b Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 22 May 2026 15:14:24 +0100 Subject: [PATCH 042/107] Add `NODE_ENV` as safe environment variable --- queries/default-setup-environment-variables.ql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/queries/default-setup-environment-variables.ql b/queries/default-setup-environment-variables.ql index 9f677dfb9b..3032cefe07 100644 --- a/queries/default-setup-environment-variables.ql +++ b/queries/default-setup-environment-variables.ql @@ -23,7 +23,8 @@ predicate isSafeForDefaultSetup(string envVar) { "GITHUB_BASE_REF", "GITHUB_EVENT_NAME", "GITHUB_JOB", "GITHUB_RUN_ATTEMPT", "GITHUB_RUN_ID", "GITHUB_SHA", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "GITHUB_TOKEN", "GITHUB_WORKFLOW", "GITHUB_WORKSPACE", "GOFLAGS", "ImageVersion", "JAVA_TOOL_OPTIONS", "RUNNER_ARCH", - "RUNNER_ENVIRONMENT", "RUNNER_NAME", "RUNNER_OS", "RUNNER_TEMP", "RUNNER_TOOL_CACHE" + "RUNNER_ENVIRONMENT", "RUNNER_NAME", "RUNNER_OS", "RUNNER_TEMP", "RUNNER_TOOL_CACHE", + "NODE_ENV" ] } From ebd711ff66bdfe20f4c22a0eeced541bcb5e9fe5 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 7 Oct 2026 20:11:46 +0100 Subject: [PATCH 043/107] Deprecate `isInTestMode` in favour of a more clearly named method --- lib/entry-points.js | 11 ++++++++++- src/environment.ts | 17 ++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 258262f2da..415f8befff 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -166145,6 +166145,15 @@ var ReadOnlyEnv = class { entries() { return Object.entries(this.vars); } + /** + * Gets a value indicating whether we should skip uploads of + * all kinds (SARIF results, status reports, DBs, ...). + * + * This is not guaranteed to be set in all test environments. + */ + isSkippingUploadsInTests() { + return this.getOptional("CODEQL_ACTION_TEST_MODE" /* TEST_MODE */) === "true"; + } /** * Gets a value indicative of whether we are in a testing environment * by testing whether the value of the `NODE_ENV` variable is "test". @@ -166185,7 +166194,7 @@ function getEnv(env = process.env) { return new Env(env); } function isInTestMode() { - return process.env["CODEQL_ACTION_TEST_MODE" /* TEST_MODE */] === "true"; + return getEnv().isSkippingUploadsInTests(); } function exportVariable2(name, val) { const env = getEnv(); diff --git a/src/environment.ts b/src/environment.ts index 4a68e76be1..ed88e96bd1 100644 --- a/src/environment.ts +++ b/src/environment.ts @@ -304,6 +304,16 @@ export class ReadOnlyEnv { return Object.entries(this.vars); } + /** + * Gets a value indicating whether we should skip uploads of + * all kinds (SARIF results, status reports, DBs, ...). + * + * This is not guaranteed to be set in all test environments. + */ + public isSkippingUploadsInTests(): boolean { + return this.getOptional(EnvVar.TEST_MODE) === "true"; + } + /** * Gets a value indicative of whether we are in a testing environment * by testing whether the value of the `NODE_ENV` variable is "test". @@ -366,9 +376,14 @@ export function getEnv(env: NodeJS.ProcessEnv = process.env): Env { * Returns whether we are in test mode. This is used by CodeQL Action PR checks. * * In test mode, we skip several uploads (SARIF results, status reports, DBs, ...). + * + * @deprecated + * The purpose of this function is ambiguous. Use `isSkippingUploadsInTests` on + * a `ReadOnlyEnv` instance instead for equivalent behaviour. Use `isTestingEnv` + * to determine if we are running in a unit test. */ export function isInTestMode(): boolean { - return process.env[EnvVar.TEST_MODE] === "true"; + return getEnv().isSkippingUploadsInTests(); } /** From 38fee79b02b7416b7510f1db2bb7c395df5dd4d5 Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Wed, 7 Oct 2026 15:21:38 -0500 Subject: [PATCH 044/107] Specify allowed characters in change-note filename --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fac24c3d4e..dd0b4886b4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -142,7 +142,7 @@ You may validate your change-note file locally by running `npx tsx pr-checks/cha #### File name -Change-note files must be named according to the following pattern: `YYYY-MM-DD-.md`, where `YYYY-MM-DD` is the date of the change and `` is a short non-spaced description of the change. For example, a change-note file for a JSON-related bug fix that was made on January 1st, 2020 might be named `2020-01-01-fix-json-bug.md`. +Change-note files must be named according to the following pattern: `YYYY-MM-DD-.md`, where `YYYY-MM-DD` is the date of the change and `` is a short description of the change. The `` must contain only lowercase letters (`a-z`), digits (`0-9`), and hyphens (`-`), and must start with a letter or digit. Hyphens may be used to separate words. For example, a change-note file for a JSON-related bug fix that was made on January 1st, 2020 might be named `2020-01-01-fix-json-bug.md`. #### Frontmatter From ce3f825b1db87c5b24305f4d1652b3bd5473600f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 8 Oct 2026 13:01:02 +0000 Subject: [PATCH 045/107] Update changelog and version after v4.38.3 --- CHANGELOG.md | 4 ++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9687f725d8..e25a66e3cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs. +## [UNRELEASED] + +No user facing changes. + ## 4.38.3 - 08 Oct 2026 - _Upcoming breaking change_: CodeQL version 2.21.2 and earlier were discontinued on 24 September 2026 alongside GitHub Enterprise Server 3.17, and will be unsupported by the next minor release of the CodeQL Action. Added a deprecation warning for customers using these versions of CodeQL. [#4188](https://github.com/github/codeql-action/pull/4188) diff --git a/package-lock.json b/package-lock.json index 167f0801b3..50c6c83a79 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codeql", - "version": "4.38.3", + "version": "4.38.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codeql", - "version": "4.38.3", + "version": "4.38.4", "license": "MIT", "workspaces": [ "pr-checks" diff --git a/package.json b/package.json index 5ebf14292b..3b2df60726 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeql", - "version": "4.38.3", + "version": "4.38.4", "private": true, "description": "CodeQL action", "scripts": { From ea60dc6408625ee68582a1a0f1b8c5fcfa5b81e4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 8 Oct 2026 13:01:10 +0000 Subject: [PATCH 046/107] Rebuild --- lib/entry-points.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 93084ea9be..1b31b0648e 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -170143,7 +170143,7 @@ function getDiffRangesJsonFilePath(env = getEnv()) { return path2.join(getTemporaryDirectory(env), PR_DIFF_RANGE_JSON_FILENAME); } function getActionVersion() { - return "4.38.3"; + return "4.38.4"; } function getWorkflowEventName(env = getEnv()) { return env.getRequired("GITHUB_EVENT_NAME" /* GITHUB_EVENT_NAME */); From 2a935ca93d4a319794c6294a9379ecbeb336d32c Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Thu, 8 Oct 2026 12:48:24 -0500 Subject: [PATCH 047/107] Move change-note documentation to `unreleased-change-notes/README.md` --- CONTRIBUTING.md | 53 +------------------------------ unreleased-change-notes/README.md | 48 ++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 52 deletions(-) create mode 100644 unreleased-change-notes/README.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dd0b4886b4..1436c9bb3c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,7 +53,7 @@ Here are a few things you can do that will increase the likelihood of your pull - Write tests. - Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests. - Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). -- For user-facing changes, add a [change-note](#change-notes). +- For user-facing changes, add a change-note file. See [unreleased-change-notes/README.md](unreleased-change-notes/README.md). ## Releasing (write access required) @@ -130,57 +130,6 @@ To deprecate an older version of the Action: 1. Upgrade the Actions warning for customers using the deprecated version to a non-fatal error, and mention that this version of the Action is no longer supported. 1. Make a PR to bump the `OLDEST_SUPPORTED_MAJOR_VERSION` in [config.ts](pr-checks/config.ts). Once this PR is merged, the release process will no longer backport changes to the deprecated release version. -## Change-notes - -Change-notes are Markdown files used to document user-facing changes. When making a change that affects users, create a change-note file in `unreleased-change-notes/` that describes the change. At the next release, the change-note files in `unreleased-change-notes/` will be combined into a new entry in `CHANGELOG.md`. - -### Change-note file format - -Change-note files must follow a certain format so that they can be automatically validated and processed. Failure to follow the format will result in a failed PR check. - -You may validate your change-note file locally by running `npx tsx pr-checks/changenotes.ts validate`. This command will scan all change-note files in `unreleased-change-notes/` and report any errors. - -#### File name - -Change-note files must be named according to the following pattern: `YYYY-MM-DD-.md`, where `YYYY-MM-DD` is the date of the change and `` is a short description of the change. The `` must contain only lowercase letters (`a-z`), digits (`0-9`), and hyphens (`-`), and must start with a letter or digit. Hyphens may be used to separate words. For example, a change-note file for a JSON-related bug fix that was made on January 1st, 2020 might be named `2020-01-01-fix-json-bug.md`. - -#### Frontmatter - -The first line of the file must be a YAML frontmatter block, which is delimited by lines containing three dashes (`---`). The frontmatter block must contain a single `category` field, whose value must be one of the following categories: - -| Category | Description | -| -------- | ----------- | -| `breaking` | A change that introduces backward-incompatible behavior. | -| `feature` | A new capability or behavior added to the Action. | -| `improvement` | An enhancement to existing functionality or performance. | -| `securityFix` | A change that addresses a security vulnerability. | -| `fix` | A bug fix that corrects unexpected behavior. | -| `unship` | Features or options that have been removed. | -| `deprecation` | Deprecation of features that will be removed in future versions. | -| `knownIssue` | A known issue or limitation in the current release. | -| `misc` | Other changes that do not fit into other categories. | - -#### Body - -The body of the change-note file must: - -- Be written in valid [GitHub-Flavored Markdown](https://github.github.com/gfm/). -- Describe the change in a way that is understandable to users of the Action. Limit the description to 1-2 sentences, and avoid technical details that are not relevant to users. -- Be structured as a single unordered Markdown list with hyphen (`-`) bullets. Each list item should describe a single change. If there are multiple changes, use multiple list items. - -### Example change-note file - -``` ---- -category: feature ---- - -- Added support for the SARIF v2.2 specification in the `github/codeql-action/upload` Action. -- Added a new `sarif-version` input to the `github/codeql-action/upload` Action, allowing users to specify the SARIF version to use when uploading results. -``` - - - ## Resources - [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/) diff --git a/unreleased-change-notes/README.md b/unreleased-change-notes/README.md new file mode 100644 index 0000000000..30b3789e43 --- /dev/null +++ b/unreleased-change-notes/README.md @@ -0,0 +1,48 @@ +## unreleased-change-notes + +Change-notes are Markdown files used to document user-facing changes. When making a change that affects users, create a change-note file here that describes the change. At the next release, the change-note files in `unreleased-change-notes/` will be combined into a new entry in `CHANGELOG.md`. + +### Change-note file format + +Change-note files must follow a certain format so that they can be automatically validated and processed. Failure to follow the format will result in a failed PR check. + +You may validate your change-note file locally by running `npx tsx pr-checks/changenotes.ts validate`. This command will scan all change-note files in `unreleased-change-notes/` and report any errors. + +#### File name + +Change-note files must be named according to the following pattern: `YYYY-MM-DD-.md`, where `YYYY-MM-DD` is the date of the change and `` is a short description of the change. The `` must contain only lowercase letters (`a-z`), digits (`0-9`), and hyphens (`-`), and must start with a letter or digit. Hyphens may be used to separate words. For example, a change-note file for a JSON-related bug fix that was made on January 1st, 2020 might be named `2020-01-01-fix-json-bug.md`. + +#### Frontmatter + +The first line of the file must be a YAML frontmatter block, which is delimited by lines containing three dashes (`---`). The frontmatter block must contain a single `category` field, whose value must be one of the following categories: + +| Category | Description | +| -------- | ----------- | +| `breaking` | A change that introduces backward-incompatible behavior. | +| `feature` | A new capability or behavior added to the Action. | +| `improvement` | An enhancement to existing functionality or performance. | +| `securityFix` | A change that addresses a security vulnerability. | +| `fix` | A bug fix that corrects unexpected behavior. | +| `unship` | Features or options that have been removed. | +| `deprecation` | Deprecation of features that will be removed in future versions. | +| `knownIssue` | A known issue or limitation in the current release. | +| `misc` | Other changes that do not fit into other categories. | + +#### Body + +The body of the change-note file must: + +- Be written in valid [GitHub-Flavored Markdown](https://github.github.com/gfm/). +- Describe the change in a way that is understandable to users of the Action. Limit the description to 1-2 sentences, and avoid technical details that are not relevant to users. +- Be structured as a single unordered Markdown list with hyphen (`-`) bullets. Each list item should describe a single change. If there are multiple changes, use multiple list items. + +### Example change-note file + +``` +--- +category: feature +--- + +- Added support for the SARIF v2.2 specification in the `github/codeql-action/upload` Action. +- Added a new `sarif-version` input to the `github/codeql-action/upload` Action, allowing users to specify the SARIF version to use when uploading results. +``` From 3acc10a2cec8c531ed3afd26489b8a377ffacba6 Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Thu, 8 Oct 2026 12:53:37 -0500 Subject: [PATCH 048/107] Exclude `README.md` from change-note validation and assembly --- pr-checks/changenotes.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pr-checks/changenotes.ts b/pr-checks/changenotes.ts index 933d255cd5..26035527b5 100755 --- a/pr-checks/changenotes.ts +++ b/pr-checks/changenotes.ts @@ -28,12 +28,12 @@ interface ChangenoteFile { /** * Returns the absolute file paths of all files in - * {@link CHANGENOTES_DIR} (except ".gitkeep"). + * {@link CHANGENOTES_DIR} (except ".gitkeep" and "README.md"). * */ function listUnreleasedChangenoteDir(): string[] { return fs .readdirSync(CHANGENOTES_DIR) - .filter((name) => name !== ".gitkeep") + .filter((name) => ![".gitkeep", "README.md"].includes(name)) .map((name) => path.join(CHANGENOTES_DIR, name)); } From d6196d87032950013b37a419798b7e74ee12d305 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 8 Oct 2026 20:06:51 +0100 Subject: [PATCH 049/107] Rename `exportVariable` wrapper to `exportEnvVar` --- eslint.config.mjs | 9 +++--- lib/entry-points.js | 64 ++++++++++++++++++++--------------------- src/api-client.ts | 4 +-- src/autobuild.ts | 10 +++---- src/codeql.ts | 4 +-- src/config-utils.ts | 6 ++-- src/debug-artifacts.ts | 4 +-- src/environment.ts | 2 +- src/init-action-post.ts | 6 ++-- src/init.test.ts | 28 +++++++++--------- src/init.ts | 4 +-- src/setup-codeql.ts | 4 +-- src/status-report.ts | 10 +++---- src/upload-lib.ts | 6 ++-- src/util.ts | 18 ++++++------ 15 files changed, 89 insertions(+), 90 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index ae8f5fc971..c3f288c0d0 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -141,14 +141,13 @@ export default [ "no-sequences": "error", "no-shadow": "off", - // A basic check that we don't use `exportVariable` from `@actions/core`. This rule depends on - // the module being imported as `core`, but that is a good enough check for us. + // A basic check that we don't use `exportVariable` from `@actions/core`. "no-restricted-syntax": [ "error", { - selector: - "MemberExpression[object.name='core'][property.name='exportVariable']", - message: "Use `exportVariable` from `environment.ts` instead.", + selector: "MemberExpression[property.name='exportVariable']", + message: + "Use the `export` method of an `Env` instance or `exportEnvVar` from `environment.ts` instead.", }, ], diff --git a/lib/entry-points.js b/lib/entry-points.js index 415f8befff..6bf9275916 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -21641,7 +21641,7 @@ var require_core = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.platform = exports2.toPlatformPath = exports2.toWin32Path = exports2.toPosixPath = exports2.markdownSummary = exports2.summary = exports2.ExitCode = void 0; - exports2.exportVariable = exportVariable3; + exports2.exportVariable = exportVariable2; exports2.setSecret = setSecret2; exports2.addPath = addPath2; exports2.getInput = getInput2; @@ -21673,7 +21673,7 @@ var require_core = __commonJS({ ExitCode2[ExitCode2["Success"] = 0] = "Success"; ExitCode2[ExitCode2["Failure"] = 1] = "Failure"; })(ExitCode || (exports2.ExitCode = ExitCode = {})); - function exportVariable3(name, val) { + function exportVariable2(name, val) { const convertedVal = (0, utils_1.toCommandValue)(val); process.env[name] = convertedVal; const filePath = process.env["GITHUB_ENV"] || ""; @@ -145589,7 +145589,7 @@ var require_core3 = __commonJS({ ExitCode2[ExitCode2["Success"] = 0] = "Success"; ExitCode2[ExitCode2["Failure"] = 1] = "Failure"; })(ExitCode || (exports2.ExitCode = ExitCode = {})); - function exportVariable3(name, val) { + function exportVariable2(name, val) { const convertedVal = (0, utils_1.toCommandValue)(val); process.env[name] = convertedVal; const filePath = process.env["GITHUB_ENV"] || ""; @@ -145598,7 +145598,7 @@ var require_core3 = __commonJS({ } (0, command_1.issueCommand)("set-env", { name }, convertedVal); } - exports2.exportVariable = exportVariable3; + exports2.exportVariable = exportVariable2; function setSecret2(secret) { (0, command_1.issueCommand)("add-mask", {}, secret); } @@ -166196,7 +166196,7 @@ function getEnv(env = process.env) { function isInTestMode() { return getEnv().isSkippingUploadsInTests(); } -function exportVariable2(name, val) { +function exportEnvVar(name, val) { const env = getEnv(); if (typeof val === "string") { env.export(name, val); @@ -169824,7 +169824,7 @@ function checkGitHubVersionInRange(version, logger2) { ); } hasBeenWarnedAboutVersion = true; - exportVariable2(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true); + exportEnvVar(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true); } function apiVersionInRange(version, minimumVersion2, maximumVersion2) { if (!semver.satisfies(version, `>=${minimumVersion2}`)) { @@ -169846,11 +169846,11 @@ function assertNever(value) { throw new ExhaustivityCheckingError(value); } function initializeEnvironment(version) { - exportVariable2("CODEQL_ACTION_FEATURE_MULTI_LANGUAGE" /* FEATURE_MULTI_LANGUAGE */, "false"); - exportVariable2("CODEQL_ACTION_FEATURE_SANDWICH" /* FEATURE_SANDWICH */, "false"); - exportVariable2("CODEQL_ACTION_FEATURE_SARIF_COMBINE" /* FEATURE_SARIF_COMBINE */, "true"); - exportVariable2("CODEQL_ACTION_FEATURE_WILL_UPLOAD" /* FEATURE_WILL_UPLOAD */, "true"); - exportVariable2("CODEQL_ACTION_VERSION" /* VERSION */, version); + exportEnvVar("CODEQL_ACTION_FEATURE_MULTI_LANGUAGE" /* FEATURE_MULTI_LANGUAGE */, "false"); + exportEnvVar("CODEQL_ACTION_FEATURE_SANDWICH" /* FEATURE_SANDWICH */, "false"); + exportEnvVar("CODEQL_ACTION_FEATURE_SARIF_COMBINE" /* FEATURE_SARIF_COMBINE */, "true"); + exportEnvVar("CODEQL_ACTION_FEATURE_WILL_UPLOAD" /* FEATURE_WILL_UPLOAD */, "true"); + exportEnvVar("CODEQL_ACTION_VERSION" /* VERSION */, version); } var HTTPError = class extends Error { status; @@ -170034,7 +170034,7 @@ async function checkDiskUsage(logger2) { } else { logger2.debug(message); } - exportVariable2("CODEQL_ACTION_HAS_WARNED_ABOUT_DISK_SPACE" /* HAS_WARNED_ABOUT_DISK_SPACE */, "true"); + exportEnvVar("CODEQL_ACTION_HAS_WARNED_ABOUT_DISK_SPACE" /* HAS_WARNED_ABOUT_DISK_SPACE */, "true"); } return { numAvailableBytes: diskUsage.bavail * blockSizeInBytes, @@ -170057,7 +170057,7 @@ function checkActionVersion(version, githubVersion) { core3.warning( "CodeQL Action v3 will be deprecated in December 2026. Please update all occurrences of the CodeQL Action in your workflow files to v4. For more information, see https://github.blog/changelog/2025-10-28-upcoming-deprecation-of-codeql-action-v3/" ); - exportVariable2("CODEQL_ACTION_DID_LOG_VERSION_DEPRECATION" /* LOG_VERSION_DEPRECATION */, "true"); + exportEnvVar("CODEQL_ACTION_DID_LOG_VERSION_DEPRECATION" /* LOG_VERSION_DEPRECATION */, "true"); } } } @@ -170813,7 +170813,7 @@ async function getAnalysisKey() { const workflowPath = await getWorkflowRelativePath(); const jobName = getRequiredEnvParam("GITHUB_JOB"); analysisKey = `${workflowPath}:${jobName}`; - exportVariable2("CODEQL_ACTION_ANALYSIS_KEY" /* ANALYSIS_KEY */, analysisKey); + exportEnvVar("CODEQL_ACTION_ANALYSIS_KEY" /* ANALYSIS_KEY */, analysisKey); return analysisKey; } async function getAutomationID() { @@ -171457,12 +171457,12 @@ function getJobStatusDisplayName(status) { } function setJobStatusIfUnsuccessful(actionStatus) { if (actionStatus === "user-error") { - exportVariable2( + exportEnvVar( "CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, process.env["CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */] ?? "JOB_STATUS_CONFIGURATION_ERROR" /* ConfigErrorStatus */ ); } else if (actionStatus === "failure" || actionStatus === "aborted") { - exportVariable2( + exportEnvVar( "CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, process.env["CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */] ?? "JOB_STATUS_FAILURE" /* FailureStatus */ ); @@ -171509,7 +171509,7 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi let workflowStartedAt = process.env["CODEQL_WORKFLOW_STARTED_AT" /* WORKFLOW_STARTED_AT */]; if (workflowStartedAt === void 0) { workflowStartedAt = actionStartedAt.toISOString(); - exportVariable2("CODEQL_WORKFLOW_STARTED_AT" /* WORKFLOW_STARTED_AT */, workflowStartedAt); + exportEnvVar("CODEQL_WORKFLOW_STARTED_AT" /* WORKFLOW_STARTED_AT */, workflowStartedAt); } const runnerOs = getRequiredEnvParam("RUNNER_OS"); const codeQlCliVersion = getCachedCodeQlVersion( @@ -171519,7 +171519,7 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi const actionRef = process.env["GITHUB_ACTION_REF"] || ""; const testingEnvironment = getTestingEnvironment(); if (testingEnvironment) { - exportVariable2("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment); + exportEnvVar("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment); } const isSteadyStateDefaultSetupRun = process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true"; const statusReport = { @@ -174822,10 +174822,10 @@ async function setCppTrapCachingEnvironmentVariables(config, logger2) { ); } else if (config.trapCaches["cpp" /* cpp */]) { logger2.info("Enabling TRAP caching for C/C++."); - exportVariable2(envVar, "true"); + exportEnvVar(envVar, "true"); } else { logger2.debug(`Disabling TRAP caching for C/C++.`); - exportVariable2(envVar, "false"); + exportEnvVar(envVar, "false"); } } } @@ -176716,7 +176716,7 @@ async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defau default: assertNever(source); } - exportVariable2("CODEQL_ACTION_HAS_SET_UP_CODEQL" /* HAS_SET_UP_CODEQL */, "true"); + exportEnvVar("CODEQL_ACTION_HAS_SET_UP_CODEQL" /* HAS_SET_UP_CODEQL */, "true"); return { codeqlFolder, toolsDownloadStatusReport, @@ -177395,7 +177395,7 @@ Output was: ${extractorPath}` Alternatively, if you want to continue using CodeQL CLI version ${result.version}, you can replace 'github/codeql-action/*@v${getActionVersion().split(".")[0]}' by 'github/codeql-action/*@v${getActionVersion()}' in your code scanning workflow to continue using this version of the CodeQL Action.` ); - exportVariable2("CODEQL_ACTION_SUPPRESS_DEPRECATED_SOON_WARNING" /* SUPPRESS_DEPRECATED_SOON_WARNING */, "true"); + exportEnvVar("CODEQL_ACTION_SUPPRESS_DEPRECATED_SOON_WARNING" /* SUPPRESS_DEPRECATED_SOON_WARNING */, "true"); } return codeql; } @@ -177564,16 +177564,16 @@ async function setupCppAutobuild(codeql, logger2) { logger2.info( `Disabling ${featureName} as we are on a self-hosted runner.${getWorkflowEventName() !== "dynamic" ? ` To override this, set the ${envVar} environment variable to 'true' in your workflow. See ${"https://docs.github.com/en/actions/learn-github-actions/variables#defining-environment-variables-for-a-single-workflow" /* DEFINE_ENV_VARIABLES */} for more information.` : ""}` ); - exportVariable2(envVar, "false"); + exportEnvVar(envVar, "false"); } else { logger2.info( `Enabling ${featureName}. This can be disabled by setting the ${envVar} environment variable to 'false'. See ${"https://docs.github.com/en/actions/learn-github-actions/variables#defining-environment-variables-for-a-single-workflow" /* DEFINE_ENV_VARIABLES */} for more information.` ); - exportVariable2(envVar, "true"); + exportEnvVar(envVar, "true"); } } else { logger2.info(`Disabling ${featureName}.`); - exportVariable2(envVar, "false"); + exportEnvVar(envVar, "false"); } } async function runAutobuild(config, language, logger2) { @@ -177588,7 +177588,7 @@ async function runAutobuild(config, language, logger2) { await codeQL.runAutobuild(config, language); } if (language === "go" /* go */) { - exportVariable2("CODEQL_ACTION_DID_AUTOBUILD_GOLANG" /* DID_AUTOBUILD_GOLANG */, "true"); + exportEnvVar("CODEQL_ACTION_DID_AUTOBUILD_GOLANG" /* DID_AUTOBUILD_GOLANG */, "true"); } logger2.endGroup(); } @@ -179786,7 +179786,7 @@ To opt out of this change, switch to an advanced setup workflow and ${envVarOptO To opt out of this change, ${envVarOptOut}`; } logger2.warning(message); - exportVariable2("CODEQL_ACTION_DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION" /* DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION */, "true"); + exportEnvVar("CODEQL_ACTION_DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION" /* DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION */, "true"); } // src/sarif/index.ts @@ -179906,7 +179906,7 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo logger2.warning( `Uploading multiple SARIF runs with the same category is deprecated ${deprecationWarningMessage}. Please update your workflow to upload a single run per category. ${deprecationMoreInformationMessage}` ); - exportVariable2("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true"); + exportEnvVar("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true"); } return combineSarifFiles(sarifFiles, logger2); } @@ -180453,7 +180453,7 @@ function validateUniqueCategory(sarifLog, sentinelPrefix) { `Aborting upload: only one run of the codeql/analyze or codeql/upload-sarif actions is allowed per job per tool/category. The easiest fix is to specify a unique value for the \`category\` input. If .runs[].automationDetails.id is specified in the sarif file, that will take precedence over your configured \`category\`. Category: (${id ? id : "none"}) Tool: (${tool ? tool : "none"})` ); } - exportVariable2(sentinelEnvVar, sentinelEnvVar); + exportEnvVar(sentinelEnvVar, sentinelEnvVar); } } function sanitize(str) { @@ -185720,7 +185720,7 @@ async function uploadArtifacts(logger2, toUpload, rootDir, artifactName, ghVaria } if (isInTestMode()) { await scanArtifactsForTokens(toUpload, logger2); - exportVariable2("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true"); + exportEnvVar("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true"); } const suffix = getArtifactSuffix(getOptionalInput("matrix")); const artifactUploader = await getArtifactUploaderClient(logger2, ghVariant); @@ -187192,14 +187192,14 @@ function getFinalJobStatus(config) { } let jobStatus; if (process.env["CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */] === "true") { - exportVariable2("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, "JOB_STATUS_SUCCESS" /* SuccessStatus */); + exportEnvVar("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, "JOB_STATUS_SUCCESS" /* SuccessStatus */); jobStatus = "JOB_STATUS_SUCCESS" /* SuccessStatus */; } else if (config !== void 0) { jobStatus = "JOB_STATUS_CONFIGURATION_ERROR" /* ConfigErrorStatus */; } else { jobStatus = "JOB_STATUS_UNKNOWN" /* UnknownStatus */; } - exportVariable2("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, jobStatus); + exportEnvVar("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, jobStatus); return jobStatus; } function getJobStatusFromEnvironment() { diff --git a/src/api-client.ts b/src/api-client.ts index 0a6e16b679..6a5e99468c 100644 --- a/src/api-client.ts +++ b/src/api-client.ts @@ -17,7 +17,7 @@ import { ReadOnlyEnv, RegistryProxyVars, getEnv, - exportVariable, + exportEnvVar, } from "./environment"; import { Logger } from "./logging"; import { getRepositoryNwo, RepositoryNwo } from "./repository"; @@ -317,7 +317,7 @@ export async function getAnalysisKey(): Promise { const jobName = getRequiredEnvParam("GITHUB_JOB"); analysisKey = `${workflowPath}:${jobName}`; - exportVariable(EnvVar.ANALYSIS_KEY, analysisKey); + exportEnvVar(EnvVar.ANALYSIS_KEY, analysisKey); return analysisKey; } diff --git a/src/autobuild.ts b/src/autobuild.ts index 6a2c5aa542..46412a0f44 100644 --- a/src/autobuild.ts +++ b/src/autobuild.ts @@ -3,7 +3,7 @@ import { getGitHubVersion } from "./api-client"; import { CodeQL, getCodeQL } from "./codeql"; import * as configUtils from "./config-utils"; import { DocUrl } from "./doc-url"; -import { ActionsEnvVars, EnvVar, exportVariable } from "./environment"; +import { ActionsEnvVars, EnvVar, exportEnvVar } from "./environment"; import { Feature, featureConfig, initFeatures } from "./feature-flags"; import { BuiltInLanguage, Language } from "./languages"; import { Logger } from "./logging"; @@ -134,16 +134,16 @@ export async function setupCppAutobuild(codeql: CodeQL, logger: Logger) { : "" }`, ); - exportVariable(envVar, "false"); + exportEnvVar(envVar, "false"); } else { logger.info( `Enabling ${featureName}. This can be disabled by setting the ${envVar} environment variable to 'false'. See ${DocUrl.DEFINE_ENV_VARIABLES} for more information.`, ); - exportVariable(envVar, "true"); + exportEnvVar(envVar, "true"); } } else { logger.info(`Disabling ${featureName}.`); - exportVariable(envVar, "false"); + exportEnvVar(envVar, "false"); } } @@ -163,7 +163,7 @@ export async function runAutobuild( await codeQL.runAutobuild(config, language); } if (language === BuiltInLanguage.go) { - exportVariable(EnvVar.DID_AUTOBUILD_GOLANG, "true"); + exportEnvVar(EnvVar.DID_AUTOBUILD_GOLANG, "true"); } logger.endGroup(); } diff --git a/src/codeql.ts b/src/codeql.ts index 58d0a9cf69..8f82168722 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -17,7 +17,7 @@ import type { VersionInfo } from "./cli/types"; import { CliError, wrapCliConfigurationError } from "./cli-errors"; import { appendExtraQueryExclusions, type Config } from "./config-utils"; import { DocUrl } from "./doc-url"; -import { EnvVar, getEnv, exportVariable } from "./environment"; +import { EnvVar, getEnv, exportEnvVar } from "./environment"; import { CodeQLDefaultVersionInfo, Feature, @@ -1054,7 +1054,7 @@ async function getCodeQLForCmd( }' by 'github/codeql-action/*@v${getActionVersion()}' in your code scanning workflow to ` + "continue using this version of the CodeQL Action.", ); - exportVariable(EnvVar.SUPPRESS_DEPRECATED_SOON_WARNING, "true"); + exportEnvVar(EnvVar.SUPPRESS_DEPRECATED_SOON_WARNING, "true"); } return codeql; } diff --git a/src/config-utils.ts b/src/config-utils.ts index 54843951ac..f1ec30b2c8 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -45,7 +45,7 @@ import { makeTelemetryDiagnostic, } from "./diagnostics"; import { prepareDiffInformedAnalysis } from "./diff-informed-analysis-utils"; -import { EnvVar, exportVariable } from "./environment"; +import { EnvVar, exportEnvVar } from "./environment"; import * as errorMessages from "./error-messages"; import { Feature, FeatureEnablement, FeatureWithoutCLI } from "./feature-flags"; import { @@ -964,10 +964,10 @@ async function setCppTrapCachingEnvironmentVariables( ); } else if (config.trapCaches[BuiltInLanguage.cpp]) { logger.info("Enabling TRAP caching for C/C++."); - exportVariable(envVar, "true"); + exportEnvVar(envVar, "true"); } else { logger.debug(`Disabling TRAP caching for C/C++.`); - exportVariable(envVar, "false"); + exportEnvVar(envVar, "false"); } } } diff --git a/src/debug-artifacts.ts b/src/debug-artifacts.ts index 4563a90368..afb3d3d1ce 100644 --- a/src/debug-artifacts.ts +++ b/src/debug-artifacts.ts @@ -11,7 +11,7 @@ import { dbIsFinalized } from "./analyze"; import { scanArtifactsForTokens } from "./artifact-scanner"; import { type CodeQL } from "./codeql"; import { Config } from "./config-utils"; -import { EnvVar, exportVariable } from "./environment"; +import { EnvVar, exportEnvVar } from "./environment"; import * as json from "./json"; import { Language } from "./languages"; import { Logger, withGroup } from "./logging"; @@ -330,7 +330,7 @@ export async function uploadArtifacts( // some issues early. if (isInTestMode()) { await scanArtifactsForTokens(toUpload, logger); - exportVariable("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true"); + exportEnvVar("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true"); } const suffix = getArtifactSuffix(getOptionalInput("matrix")); diff --git a/src/environment.ts b/src/environment.ts index ed88e96bd1..c5ef6c5799 100644 --- a/src/environment.ts +++ b/src/environment.ts @@ -393,7 +393,7 @@ export function isInTestMode(): boolean { * * @deprecated Use `export` on an `Env` instance instead. */ -export function exportVariable(name: string, val: any): void { +export function exportEnvVar(name: string, val: any): void { const env = getEnv(); if (typeof val === "string") { diff --git a/src/init-action-post.ts b/src/init-action-post.ts index 90f67ea61b..a81c27810a 100644 --- a/src/init-action-post.ts +++ b/src/init-action-post.ts @@ -21,7 +21,7 @@ import { DependencyCachingUsageReport, getDependencyCacheUsage, } from "./dependency-caching"; -import { EnvVar, getEnv, exportVariable } from "./environment"; +import { EnvVar, getEnv, exportEnvVar } from "./environment"; import { initFeatures } from "./feature-flags"; import * as gitUtils from "./git-utils"; import * as initActionPostHelper from "./init-action-post-helper"; @@ -166,7 +166,7 @@ function getFinalJobStatus(config: Config | undefined): JobStatus { let jobStatus: JobStatus; if (process.env[EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY] === "true") { - exportVariable(EnvVar.JOB_STATUS, JobStatus.SuccessStatus); + exportEnvVar(EnvVar.JOB_STATUS, JobStatus.SuccessStatus); jobStatus = JobStatus.SuccessStatus; } else if (config !== undefined) { // - We have computed a CodeQL config @@ -191,7 +191,7 @@ function getFinalJobStatus(config: Config | undefined): JobStatus { // This shouldn't be necessary, but in the odd case that we run more than one // `init` post step, ensure the job status is consistent between them. - exportVariable(EnvVar.JOB_STATUS, jobStatus); + exportEnvVar(EnvVar.JOB_STATUS, jobStatus); return jobStatus; } diff --git a/src/init.test.ts b/src/init.test.ts index b40f9611d7..9cb169fb27 100644 --- a/src/init.test.ts +++ b/src/init.test.ts @@ -545,7 +545,7 @@ test.serial( test.serial( "file coverage deprecation warning for org-owned repo with default setup recommends repo property", (t) => { - const exportVariableStub = sinon.stub(environment, "exportVariable"); + const exportEnvVarStub = sinon.stub(environment, "exportEnvVar"); sinon.stub(actionsUtil, "isDefaultSetup").returns(true); github.context.payload = { repository: { @@ -565,14 +565,14 @@ test.serial( 'with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then set this property to ' + "`true` in the repository's settings.", ); - t.true(exportVariableStub.calledOnce); + t.true(exportEnvVarStub.calledOnce); }, ); test.serial( "file coverage deprecation warning for org-owned repo with advanced setup recommends env var and repo property", (t) => { - const exportVariableStub = sinon.stub(environment, "exportVariable"); + const exportEnvVarStub = sinon.stub(environment, "exportEnvVar"); sinon.stub(actionsUtil, "isDefaultSetup").returns(false); github.context.payload = { repository: { @@ -593,14 +593,14 @@ test.serial( 'with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then set this property to ' + "`true` in the repository's settings.", ); - t.true(exportVariableStub.calledOnce); + t.true(exportEnvVarStub.calledOnce); }, ); test.serial( "file coverage deprecation warning for user-owned repo with default setup recommends advanced setup", (t) => { - const exportVariableStub = sinon.stub(environment, "exportVariable"); + const exportEnvVarStub = sinon.stub(environment, "exportEnvVar"); sinon.stub(actionsUtil, "isDefaultSetup").returns(true); github.context.payload = { repository: { @@ -619,14 +619,14 @@ test.serial( "To opt out of this change, switch to an advanced setup workflow and " + "set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.", ); - t.true(exportVariableStub.calledOnce); + t.true(exportEnvVarStub.calledOnce); }, ); test.serial( "file coverage deprecation warning for user-owned repo with advanced setup recommends env var", (t) => { - const exportVariableStub = sinon.stub(environment, "exportVariable"); + const exportEnvVarStub = sinon.stub(environment, "exportEnvVar"); sinon.stub(actionsUtil, "isDefaultSetup").returns(false); github.context.payload = { repository: { @@ -644,14 +644,14 @@ test.serial( "to improve analysis performance. File coverage information will still be computed on non-PR analyses.\n\n" + "To opt out of this change, set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.", ); - t.true(exportVariableStub.calledOnce); + t.true(exportEnvVarStub.calledOnce); }, ); test.serial( "file coverage deprecation warning for unknown owner type with default setup recommends advanced setup", (t) => { - const exportVariableStub = sinon.stub(environment, "exportVariable"); + const exportEnvVarStub = sinon.stub(environment, "exportEnvVar"); sinon.stub(actionsUtil, "isDefaultSetup").returns(true); github.context.payload = { repository: undefined }; const messages: LoggedMessage[] = []; @@ -665,14 +665,14 @@ test.serial( "To opt out of this change, switch to an advanced setup workflow and " + "set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.", ); - t.true(exportVariableStub.calledOnce); + t.true(exportEnvVarStub.calledOnce); }, ); test.serial( "file coverage deprecation warning for unknown owner type with advanced setup recommends env var", (t) => { - const exportVariableStub = sinon.stub(environment, "exportVariable"); + const exportEnvVarStub = sinon.stub(environment, "exportEnvVar"); sinon.stub(actionsUtil, "isDefaultSetup").returns(false); github.context.payload = { repository: undefined }; const messages: LoggedMessage[] = []; @@ -685,7 +685,7 @@ test.serial( "to improve analysis performance. File coverage information will still be computed on non-PR analyses.\n\n" + "To opt out of this change, set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.", ); - t.true(exportVariableStub.calledOnce); + t.true(exportEnvVarStub.calledOnce); }, ); @@ -694,10 +694,10 @@ test.serial( (t) => { process.env["CODEQL_ACTION_DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION"] = "true"; - const exportVariableStub = sinon.stub(environment, "exportVariable"); + const exportEnvVarStub = sinon.stub(environment, "exportEnvVar"); const messages: LoggedMessage[] = []; logFileCoverageOnPrsDeprecationWarning(getRecordingLogger(messages)); t.is(messages.length, 0); - t.true(exportVariableStub.notCalled); + t.true(exportEnvVarStub.notCalled); }, ); diff --git a/src/init.ts b/src/init.ts index 06314acf2a..11f1eea2e7 100644 --- a/src/init.ts +++ b/src/init.ts @@ -16,7 +16,7 @@ import { import { GitHubApiDetails } from "./api-client"; import { CodeQL, setupCodeQL } from "./codeql"; import * as configUtils from "./config-utils"; -import { EnvVar, exportVariable } from "./environment"; +import { EnvVar, exportEnvVar } from "./environment"; import { CodeQLDefaultVersionInfo, Feature, @@ -410,5 +410,5 @@ export function logFileCoverageOnPrsDeprecationWarning(logger: Logger): void { } logger.warning(message); - exportVariable(EnvVar.DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION, "true"); + exportEnvVar(EnvVar.DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION, "true"); } diff --git a/src/setup-codeql.ts b/src/setup-codeql.ts index 0c25bbe08d..daaba174c4 100644 --- a/src/setup-codeql.ts +++ b/src/setup-codeql.ts @@ -28,7 +28,7 @@ import { makeDiagnostic, makeTelemetryDiagnostic, } from "./diagnostics"; -import { EnvVar, exportVariable, getEnv } from "./environment"; +import { EnvVar, exportEnvVar, getEnv } from "./environment"; import { CODEQL_VERSION_ZSTD_BUNDLE, CodeQLDefaultVersionInfo, @@ -1070,7 +1070,7 @@ export async function setupCodeQLBundle( // Record that this job now has a copy of the CodeQL tools, so that a later step doesn't delete // the toolcache out from under the path we are about to return. - exportVariable(EnvVar.HAS_SET_UP_CODEQL, "true"); + exportEnvVar(EnvVar.HAS_SET_UP_CODEQL, "true"); return { codeqlFolder, diff --git a/src/status-report.ts b/src/status-report.ts index 43e52f67fb..ae21beb307 100644 --- a/src/status-report.ts +++ b/src/status-report.ts @@ -28,7 +28,7 @@ import { getEnv, ReadOnlyEnv, RegistryProxyVars, - exportVariable, + exportEnvVar, } from "./environment"; import { getRef } from "./git-utils"; import * as json from "./json"; @@ -272,12 +272,12 @@ export function getJobStatusDisplayName(status: JobStatus): string { */ function setJobStatusIfUnsuccessful(actionStatus: ActionStatus) { if (actionStatus === "user-error") { - exportVariable( + exportEnvVar( EnvVar.JOB_STATUS, process.env[EnvVar.JOB_STATUS] ?? JobStatus.ConfigErrorStatus, ); } else if (actionStatus === "failure" || actionStatus === "aborted") { - exportVariable( + exportEnvVar( EnvVar.JOB_STATUS, process.env[EnvVar.JOB_STATUS] ?? JobStatus.FailureStatus, ); @@ -380,7 +380,7 @@ export async function createStatusReportBase( let workflowStartedAt = process.env[EnvVar.WORKFLOW_STARTED_AT]; if (workflowStartedAt === undefined) { workflowStartedAt = actionStartedAt.toISOString(); - exportVariable(EnvVar.WORKFLOW_STARTED_AT, workflowStartedAt); + exportEnvVar(EnvVar.WORKFLOW_STARTED_AT, workflowStartedAt); } const runnerOs = getRequiredEnvParam("RUNNER_OS"); const codeQlCliVersion = getCachedCodeQlVersion( @@ -392,7 +392,7 @@ export async function createStatusReportBase( // re-export the testing environment variable so that it is available to subsequent steps, // even if it was only set for this step if (testingEnvironment) { - exportVariable(EnvVar.TESTING_ENVIRONMENT, testingEnvironment); + exportEnvVar(EnvVar.TESTING_ENVIRONMENT, testingEnvironment); } const isSteadyStateDefaultSetupRun = process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true"; diff --git a/src/upload-lib.ts b/src/upload-lib.ts index 17b3422dc9..9792e0225e 100644 --- a/src/upload-lib.ts +++ b/src/upload-lib.ts @@ -14,7 +14,7 @@ import { getGitHubVersion, wrapApiConfigurationError } from "./api-client"; import { CodeQL, getCodeQL } from "./codeql"; import { getConfig } from "./config-utils"; import { readDiffRangesJsonFile } from "./diff-informed-analysis-utils"; -import { EnvVar, exportVariable } from "./environment"; +import { EnvVar, exportEnvVar } from "./environment"; import { FeatureEnablement } from "./feature-flags"; import * as fingerprints from "./fingerprints"; import * as gitUtils from "./git-utils"; @@ -126,7 +126,7 @@ async function combineSarifFilesUsingCLI( logger.warning( `Uploading multiple SARIF runs with the same category is deprecated ${deprecationWarningMessage}. Please update your workflow to upload a single run per category. ${deprecationMoreInformationMessage}`, ); - exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true"); + exportEnvVar("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true"); } // If not, use the naive method of combining the files. @@ -1032,7 +1032,7 @@ export function validateUniqueCategory( `Category: (${id ? id : "none"}) Tool: (${tool ? tool : "none"})`, ); } - exportVariable(sentinelEnvVar, sentinelEnvVar); + exportEnvVar(sentinelEnvVar, sentinelEnvVar); } } diff --git a/src/util.ts b/src/util.ts index 2df488f57f..674e2a2eef 100644 --- a/src/util.ts +++ b/src/util.ts @@ -18,7 +18,7 @@ import { EnvVar, getRequiredEnvParam, isInTestMode, - exportVariable, + exportEnvVar, } from "./environment"; import * as json from "./json"; import { Language } from "./languages"; @@ -552,7 +552,7 @@ export function checkGitHubVersionInRange( ); } hasBeenWarnedAboutVersion = true; - exportVariable(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true); + exportEnvVar(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true); } export enum DisallowedAPIVersionReason { @@ -596,11 +596,11 @@ export function assertNever(value: never): never { * knowing what version of CodeQL we're running. */ export function initializeEnvironment(version: string) { - exportVariable(EnvVar.FEATURE_MULTI_LANGUAGE, "false"); - exportVariable(EnvVar.FEATURE_SANDWICH, "false"); - exportVariable(EnvVar.FEATURE_SARIF_COMBINE, "true"); - exportVariable(EnvVar.FEATURE_WILL_UPLOAD, "true"); - exportVariable(EnvVar.VERSION, version); + exportEnvVar(EnvVar.FEATURE_MULTI_LANGUAGE, "false"); + exportEnvVar(EnvVar.FEATURE_SANDWICH, "false"); + exportEnvVar(EnvVar.FEATURE_SARIF_COMBINE, "true"); + exportEnvVar(EnvVar.FEATURE_WILL_UPLOAD, "true"); + exportEnvVar(EnvVar.VERSION, version); } export class HTTPError extends Error { @@ -949,7 +949,7 @@ export async function checkDiskUsage( } else { logger.debug(message); } - exportVariable(EnvVar.HAS_WARNED_ABOUT_DISK_SPACE, "true"); + exportEnvVar(EnvVar.HAS_WARNED_ABOUT_DISK_SPACE, "true"); } return { numAvailableBytes: diskUsage.bavail * blockSizeInBytes, @@ -998,7 +998,7 @@ export function checkActionVersion( "https://github.blog/changelog/2025-10-28-upcoming-deprecation-of-codeql-action-v3/", ); // set LOG_VERSION_DEPRECATION env var to prevent the warning from being logged multiple times - exportVariable(EnvVar.LOG_VERSION_DEPRECATION, "true"); + exportEnvVar(EnvVar.LOG_VERSION_DEPRECATION, "true"); } } } From bd97dda6bf153afcaf41c6c5ef65567738a1b4c7 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 8 Oct 2026 20:17:42 +0100 Subject: [PATCH 050/107] Add and use `__CODEQL_ACTION_TEST_ENV__` in tests --- ava.setup.mjs | 1 + build.mjs | 3 ++- lib/entry-points.js | 2 +- src/environment.test.ts | 12 ++++++++++++ src/environment.ts | 7 ++++++- src/testing-utils.ts | 6 ------ 6 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 src/environment.test.ts diff --git a/ava.setup.mjs b/ava.setup.mjs index e6c370e01b..b405991125 100644 --- a/ava.setup.mjs +++ b/ava.setup.mjs @@ -1,3 +1,4 @@ import pkg from "./package.json" with { type: "json" }; globalThis.__CODEQL_ACTION_VERSION__ = pkg.version; +globalThis.__CODEQL_ACTION_TEST_ENV__ = "unit-test"; diff --git a/build.mjs b/build.mjs index a0c3c06189..ecbe5be84d 100644 --- a/build.mjs +++ b/build.mjs @@ -78,7 +78,7 @@ const UPLOAD_LIB_SRC = "./src/upload-lib"; * * The virtual module additionally re-exports `upload-lib` under the `uploadLib` namespace so that * external consumers can access it via the small `lib/upload-lib.js` stub emitted below. - * + * * A tiny stub file is emitted for each Action entrypoint, and one for `upload-lib`. Each stub * imports the shared bundle and calls/re-exports from the respective entry point. * @@ -212,6 +212,7 @@ const context = await esbuild.context({ target: ["node20"], define: { __CODEQL_ACTION_VERSION__: JSON.stringify(pkg.version), + __CODEQL_ACTION_TEST_ENV__: JSON.stringify(""), }, metafile: true, }); diff --git a/lib/entry-points.js b/lib/entry-points.js index 6bf9275916..d537ba3431 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -166161,7 +166161,7 @@ var ReadOnlyEnv = class { * or if this instance was constructed by `getTestEnv`. */ isTestingEnv() { - return this.getOptional("NODE_ENV" /* NODE_ENV */) === "test"; + return false; } }; var Env = class extends ReadOnlyEnv { diff --git a/src/environment.test.ts b/src/environment.test.ts new file mode 100644 index 0000000000..2c8a8a8f1c --- /dev/null +++ b/src/environment.test.ts @@ -0,0 +1,12 @@ +import test from "ava"; + +import { Env, ReadOnlyEnv } from "./environment"; +import { getTestEnv, setupTests } from "./testing-utils"; + +setupTests(test); + +test("isTestingEnv() is true", (t) => { + t.true(new ReadOnlyEnv(process.env).isTestingEnv()); + t.true(new Env(process.env).isTestingEnv()); + t.true(getTestEnv().isTestingEnv()); +}); diff --git a/src/environment.ts b/src/environment.ts index c5ef6c5799..c3aad90863 100644 --- a/src/environment.ts +++ b/src/environment.ts @@ -1,5 +1,10 @@ import * as core from "@actions/core"; +/** + * This constant is set in `ava.setup.mjs` for tests. + */ +declare const __CODEQL_ACTION_TEST_ENV__: string | undefined; + /** * Environment variables used by Default Setup to communicate the private registry proxy configuration. */ @@ -321,7 +326,7 @@ export class ReadOnlyEnv { * or if this instance was constructed by `getTestEnv`. */ public isTestingEnv(): boolean { - return this.getOptional(SystemEnvVar.NODE_ENV) === "test"; + return __CODEQL_ACTION_TEST_ENV__ === "unit-test"; } } diff --git a/src/testing-utils.ts b/src/testing-utils.ts index 2011b56e00..cd60318944 100644 --- a/src/testing-utils.ts +++ b/src/testing-utils.ts @@ -184,12 +184,6 @@ export function makeMacro( } export function getTestEnv(testEnv: NodeJS.ProcessEnv = {}): Env { - // In unit tests run by `ava`, this environment variable is set for the process, - // but we default to an empty environment here for `testEnv`, so we must set it - // explicitly to ensure that we get test-specific behaviour in functions when - // we need it. - testEnv["NODE_ENV"] = "test"; - return getEnv(testEnv); } From 40d76bc72746338d65640ffede693aee5bfb4fb6 Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Thu, 8 Oct 2026 14:55:23 -0500 Subject: [PATCH 051/107] Use actual CHANGELOG.md entries for example change-note --- unreleased-change-notes/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/unreleased-change-notes/README.md b/unreleased-change-notes/README.md index 30b3789e43..cf19da0b46 100644 --- a/unreleased-change-notes/README.md +++ b/unreleased-change-notes/README.md @@ -40,9 +40,9 @@ The body of the change-note file must: ``` --- -category: feature +category: fix --- -- Added support for the SARIF v2.2 specification in the `github/codeql-action/upload` Action. -- Added a new `sarif-version` input to the `github/codeql-action/upload` Action, allowing users to specify the SARIF version to use when uploading results. +- Fixed a bug where a network error while streaming the download of the CodeQL bundle could terminate the `init` Action instead of falling back to downloading the bundle before extracting it. [#4061](https://github.com/github/codeql-action/pull/4061) +- Fix incorrect minimum required Git version for [improved incremental analysis](https://github.com/github/roadmap/issues/1158): it should have been 2.36.0, not 2.11.0. [#3781](https://github.com/github/codeql-action/pull/3781) ``` From cc826bb8e32ca6fbb030841ede3fdaec950ab2bd Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Thu, 8 Oct 2026 14:57:03 -0500 Subject: [PATCH 052/107] Delete unnecessary guidance for change-note body --- unreleased-change-notes/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/unreleased-change-notes/README.md b/unreleased-change-notes/README.md index cf19da0b46..48ce5a3e15 100644 --- a/unreleased-change-notes/README.md +++ b/unreleased-change-notes/README.md @@ -33,7 +33,6 @@ The first line of the file must be a YAML frontmatter block, which is delimited The body of the change-note file must: - Be written in valid [GitHub-Flavored Markdown](https://github.github.com/gfm/). -- Describe the change in a way that is understandable to users of the Action. Limit the description to 1-2 sentences, and avoid technical details that are not relevant to users. - Be structured as a single unordered Markdown list with hyphen (`-`) bullets. Each list item should describe a single change. If there are multiple changes, use multiple list items. ### Example change-note file From 13b13216858f78c10bedda85055369d87f3ef35d Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Thu, 8 Oct 2026 15:01:05 -0500 Subject: [PATCH 053/107] Refine misc. wording of `unreleased-change-notes/README.md` Co-authored-by: Michael B. Gale --- unreleased-change-notes/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unreleased-change-notes/README.md b/unreleased-change-notes/README.md index 48ce5a3e15..d477a0b1b0 100644 --- a/unreleased-change-notes/README.md +++ b/unreleased-change-notes/README.md @@ -1,6 +1,6 @@ -## unreleased-change-notes +## Change notes -Change-notes are Markdown files used to document user-facing changes. When making a change that affects users, create a change-note file here that describes the change. At the next release, the change-note files in `unreleased-change-notes/` will be combined into a new entry in `CHANGELOG.md`. +Change-notes are Markdown files used to document user-facing changes. When making a change that affects users, create a markdown file here that describes the change. During the next release, the change-note files in `unreleased-change-notes/` will automatically be added to `CHANGELOG.md`. ### Change-note file format From 1ced68ed2f8781c0490d1e0142a2d5c15bdf84a2 Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Thu, 8 Oct 2026 15:11:43 -0500 Subject: [PATCH 054/107] Do not validate change-note file names or frontmatter Presently, the strict filename or frontmatter are not being used; so we're validating them unnecessarily. So, for now, remove these checks until we decide to either do something with them, or delete the code entirely. --- pr-checks/changelog/validate.test.ts | 20 -------------------- pr-checks/changelog/validate.ts | 16 +--------------- 2 files changed, 1 insertion(+), 35 deletions(-) diff --git a/pr-checks/changelog/validate.test.ts b/pr-checks/changelog/validate.test.ts index 379b5737a8..77a18e8ba2 100644 --- a/pr-checks/changelog/validate.test.ts +++ b/pr-checks/changelog/validate.test.ts @@ -154,26 +154,6 @@ await describe("isValidChangenoteFile", async () => { assert.equal(isValidChangenoteFile("non-existent-file.md"), false); }); - await it("rejects invalid filename", async () => { - await withTmpFile( - "fix-bug.md", - "---\ncategory: fix\n---\n- Fixed a bug\n", - (filePath) => { - assert.equal(isValidChangenoteFile(filePath), false); - }, - ); - }); - - await it("rejects missing frontmatter", async () => { - await withTmpFile( - "2026-01-01-fix-bug.md", - "- Fixed a bug\n", - (filePath) => { - assert.equal(isValidChangenoteFile(filePath), false); - }, - ); - }); - await it("rejects invalid Markdown", async () => { await withTmpFile( "2026-01-01-fix-bug.md", diff --git a/pr-checks/changelog/validate.ts b/pr-checks/changelog/validate.ts index 3c83276f38..396a8584b4 100644 --- a/pr-checks/changelog/validate.ts +++ b/pr-checks/changelog/validate.ts @@ -95,21 +95,7 @@ export function isValidChangenoteFile(filename: string): boolean { return false; } - const { data: frontmatter, content } = matter(fileData); - - if (!isValidChangenoteFilename(path.basename(filename))) { - isValid = false; - console.error( - `${filename}: invalid filename; must match pattern YYYY-MM-DD-id.md`, - ); - } - if (!hasValidChangenoteCategory(frontmatter)) { - isValid = false; - const categories = Object.keys(VALID_CHANGE_NOTE_CATEGORIES).join(", "); - console.error( - `${filename}: invalid category; must be one of: ${categories}`, - ); - } + const { content } = matter(fileData); if (!isValidChangenoteContent(content)) { isValid = false; console.error( From e57c0e65ddc1f222809299415886044068668890 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 9 Oct 2026 14:14:48 +0100 Subject: [PATCH 055/107] Fix type inference for `ActionState` --- lib/entry-points.js | 14 ++++++-- src/action-common.ts | 71 +++++++++++++++++++++++++++++++++++++- src/init-action.ts | 11 ++++-- src/setup-codeql-action.ts | 11 ++++-- src/start-proxy-action.ts | 10 ++++-- 5 files changed, 107 insertions(+), 10 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 1b31b0648e..9fe963a27a 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -171686,6 +171686,9 @@ async function sendUnhandledErrorStatusReport(actionName, actionStartedAt, error } // src/action-common.ts +function extendActionState(state, extra) { + return { ...state, ...extra }; +} async function runInActions(action) { const startedAt = /* @__PURE__ */ new Date(); const logger2 = getActionsLogger(); @@ -186339,7 +186342,9 @@ async function run3(actionState) { `Failed to parse analysis kinds for 'starting' status report: ${getErrorMessage(err)}` ); } - const actionStateWithFeatures = { ...actionState, features }; + const actionStateWithFeatures = extendActionState(actionState, { + features + }); configFile = await getConfigFileInput( actionStateWithFeatures, repositoryProperties, @@ -187358,7 +187363,9 @@ async function run6(actionState) { logger2 ); const repositoryProperties = repositoryPropertiesResult.orElse({}); - const actionStateWithFeatures = { ...actionState, features }; + const actionStateWithFeatures = extendActionState(actionState, { + features + }); const statusReportBase = await createStatusReportBase( "setup-codeql" /* SetupCodeQL */, "starting", @@ -188153,7 +188160,8 @@ async function run7(action) { all_credentials: credentials, ca }; - const proxyBin = await getProxyBinaryPath({ ...action, features }); + const actionWithFeatures = extendActionState(action, { features }); + const proxyBin = await getProxyBinaryPath(actionWithFeatures); const proxyInfo = await startProxy( proxyBin, proxyConfig, diff --git a/src/action-common.ts b/src/action-common.ts index 17d4344cce..79f1901f22 100644 --- a/src/action-common.ts +++ b/src/action-common.ts @@ -56,6 +56,29 @@ export interface FeatureState { /** Identifies a type of state an Action may have. */ export type StateFeature = keyof FeatureState; +/** + * The `Env` feature implies the availability of the `ReadOnlyEnv` feature. + * + * If `T` is `Env`, this returns `Env | ReadOnlyEnv`. + * Otherwise, it is the identity and returns T. + */ +type ImpliedFeatures = T extends "Env" + ? "Env" | "ReadOnlyEnv" + : T; + +/** + * Given an object type `Obj`, this tries to lookup a corresponding `StateFeature` + * to which the object type belongs in `FeatureState`. Resolves to `never` if there + * is no match. + */ +type FeatureNameFor = { + [K in StateFeature]: [Obj] extends [FeatureState[K]] + ? [FeatureState[K]] extends [Obj] + ? K + : never + : never; +}[StateFeature]; + /** Constructs the intersection of all state types identifies by `Fs`. */ export type FieldsOf = Fs extends [] ? Record @@ -66,8 +89,54 @@ export type FieldsOf = Fs extends [] ? FeatureState[Head] & FieldsOf : never; +/** + * Symbol used for a field in `ActionState` that carries the type array of state features. + * This is a Symbol so that it doesn't clash with any property names we might want to have. + */ +const stateFeatures = Symbol(); + /** Describes the state of an Action that has access to the state corresponding to `Fs`. */ -export type ActionState = FieldsOf; +export type ActionState = FieldsOf & { + /** + * When given a chance, TypeScript will simplify an `ActionState` type as much as possible, + * which results in a concrete object type that doesn't mention `Fs`. + * + * That causes problems for functions which accept `ActionState` values, but need to know the + * feature keys `Fs`. This property here explicitly captures `Fs` in the concrete object type + * that results from simplifying `ActionState`. + * + * This is a function rather than a field, because we want to be able to provide values of type + * `ActionState` to functions expecting `ActionState` where `As` is a subset of `Fs`. + * + * Since function types are contravariant in the types of their parameters, using a function + * type here allows that to happen. + * + * Because the field is optional, we don't have to explicitly provide a value + * for it anywhere while the type is still inferred. + * + * `Fs[number]` returns the union of all features in `Fs`. We wrap it in `ImpliedFeatures` + * so that `Env` is expanded into `Env | ReadOnlyEnv`, allowing functions that expect the + * `ReadOnlyEnv` feature to be provided with an `ActionState` that has the `Env` feature + * without requiring this to be made explicit. + */ + readonly [stateFeatures]?: (ts: ImpliedFeatures) => void; +}; + +/** Extends `state` with an `extra` feature. */ +export function extendActionState< + // In first position, so that it can be explicitly provided if `FeatureNameFor` + // should not work on `extra`. + F extends StateFeature, + Fs extends readonly StateFeature[], + E extends FeatureState[F], +>( + state: ActionState, + extra: E, +): ActionState<[...Fs, FeatureNameFor & F]> { + return { ...state, ...extra } as unknown as ActionState< + [...Fs, FeatureNameFor & F] + >; +} /** The type of an Action's main entry point. This is a function that is provided * with a basic `ActionState` object with features that are always available. diff --git a/src/init-action.ts b/src/init-action.ts index 31414bd80b..ae0cb2114b 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -5,7 +5,12 @@ import * as core from "@actions/core"; import * as io from "@actions/io"; import * as semver from "semver"; -import { Action, ActionState, runInActions } from "./action-common"; +import { + Action, + ActionState, + extendActionState, + runInActions, +} from "./action-common"; import { FileCmdNotFoundError, getActionVersion, @@ -278,7 +283,9 @@ async function run( } // Compute the value of the `config-file` input. - const actionStateWithFeatures = { ...actionState, features }; + const actionStateWithFeatures = extendActionState(actionState, { + features, + }); configFile = await getConfigFileInput( actionStateWithFeatures, repositoryProperties, diff --git a/src/setup-codeql-action.ts b/src/setup-codeql-action.ts index 23a9c65ebd..e80327a81c 100644 --- a/src/setup-codeql-action.ts +++ b/src/setup-codeql-action.ts @@ -1,6 +1,11 @@ import * as core from "@actions/core"; -import { Action, ActionState, runInActions } from "./action-common"; +import { + Action, + ActionState, + extendActionState, + runInActions, +} from "./action-common"; import { getActionVersion, getOptionalInput, @@ -131,7 +136,9 @@ async function run( ); const repositoryProperties = repositoryPropertiesResult.orElse({}); - const actionStateWithFeatures = { ...actionState, features }; + const actionStateWithFeatures = extendActionState(actionState, { + features, + }); const statusReportBase = await createStatusReportBase( ActionName.SetupCodeQL, diff --git a/src/start-proxy-action.ts b/src/start-proxy-action.ts index d965a2dd6b..bc3351da53 100644 --- a/src/start-proxy-action.ts +++ b/src/start-proxy-action.ts @@ -3,7 +3,12 @@ import * as path from "path"; import * as core from "@actions/core"; -import { Action, ActionState, runInActions } from "./action-common"; +import { + Action, + ActionState, + extendActionState, + runInActions, +} from "./action-common"; import * as actionsUtil from "./actions-util"; import { getGitHubVersion } from "./api-client"; import { FeatureEnablement, initFeatures } from "./feature-flags"; @@ -98,7 +103,8 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) { }; // Start the Proxy - const proxyBin = await getProxyBinaryPath({ ...action, features }); + const actionWithFeatures = extendActionState(action, { features }); + const proxyBin = await getProxyBinaryPath(actionWithFeatures); const proxyInfo = await startProxy( proxyBin, proxyConfig, From 45cda5b577ee605521a0a4910167385f413111f6 Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Fri, 9 Oct 2026 08:57:09 -0500 Subject: [PATCH 056/107] Delete unused `path` import --- pr-checks/changelog/validate.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/pr-checks/changelog/validate.ts b/pr-checks/changelog/validate.ts index 396a8584b4..fa0caec3e5 100644 --- a/pr-checks/changelog/validate.ts +++ b/pr-checks/changelog/validate.ts @@ -1,5 +1,4 @@ import * as fs from "node:fs"; -import * as path from "node:path"; import { matter } from "lite-matter"; import type { List, ListItem } from "mdast"; From fa56eef12fd72da6f01e786304612ce03ba93a48 Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Fri, 9 Oct 2026 16:48:00 -0500 Subject: [PATCH 057/107] Delete unnecessary filename/frontmatter validation instructions --- unreleased-change-notes/README.md | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/unreleased-change-notes/README.md b/unreleased-change-notes/README.md index d477a0b1b0..60778c7954 100644 --- a/unreleased-change-notes/README.md +++ b/unreleased-change-notes/README.md @@ -1,6 +1,6 @@ -## Change notes +## Change notes -Change-notes are Markdown files used to document user-facing changes. When making a change that affects users, create a markdown file here that describes the change. During the next release, the change-note files in `unreleased-change-notes/` will automatically be added to `CHANGELOG.md`. +Change-notes are Markdown files used to document user-facing changes. When making a change that affects users, create a Markdown file here that describes the change. During the next release, the change-note files in `unreleased-change-notes/` will automatically be added to `CHANGELOG.md`. ### Change-note file format @@ -8,25 +8,6 @@ Change-note files must follow a certain format so that they can be automatically You may validate your change-note file locally by running `npx tsx pr-checks/changenotes.ts validate`. This command will scan all change-note files in `unreleased-change-notes/` and report any errors. -#### File name - -Change-note files must be named according to the following pattern: `YYYY-MM-DD-.md`, where `YYYY-MM-DD` is the date of the change and `` is a short description of the change. The `` must contain only lowercase letters (`a-z`), digits (`0-9`), and hyphens (`-`), and must start with a letter or digit. Hyphens may be used to separate words. For example, a change-note file for a JSON-related bug fix that was made on January 1st, 2020 might be named `2020-01-01-fix-json-bug.md`. - -#### Frontmatter - -The first line of the file must be a YAML frontmatter block, which is delimited by lines containing three dashes (`---`). The frontmatter block must contain a single `category` field, whose value must be one of the following categories: - -| Category | Description | -| -------- | ----------- | -| `breaking` | A change that introduces backward-incompatible behavior. | -| `feature` | A new capability or behavior added to the Action. | -| `improvement` | An enhancement to existing functionality or performance. | -| `securityFix` | A change that addresses a security vulnerability. | -| `fix` | A bug fix that corrects unexpected behavior. | -| `unship` | Features or options that have been removed. | -| `deprecation` | Deprecation of features that will be removed in future versions. | -| `knownIssue` | A known issue or limitation in the current release. | -| `misc` | Other changes that do not fit into other categories. | #### Body @@ -38,10 +19,6 @@ The body of the change-note file must: ### Example change-note file ``` ---- -category: fix ---- - - Fixed a bug where a network error while streaming the download of the CodeQL bundle could terminate the `init` Action instead of falling back to downloading the bundle before extracting it. [#4061](https://github.com/github/codeql-action/pull/4061) - Fix incorrect minimum required Git version for [improved incremental analysis](https://github.com/github/roadmap/issues/1158): it should have been 2.36.0, not 2.11.0. [#3781](https://github.com/github/codeql-action/pull/3781) ``` From cf8f7b978792800ea9d527b0cfdef71cae962575 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 10:27:31 +0100 Subject: [PATCH 058/107] Add `ActionConfig` type --- src/config/action-config.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/config/action-config.ts b/src/config/action-config.ts index de6882e77e..fcb6a9482a 100644 --- a/src/config/action-config.ts +++ b/src/config/action-config.ts @@ -126,3 +126,19 @@ export interface Config { */ enableFileCoverageInformation: boolean; } + +/** Properties available in `Config`. */ +export type ActionConfigProperties = keyof Config; + +/** + * The CodeQL Action configuration state that is persisted + * between steps of the CodeQL Action in a CodeQL workflow. + * + * By default, this is equivalent to `Config`. By explicitly + * providing required property names for `T` this can be restricted + * to requiring only those. For example, in `ActionConfig<"codeqlCmd">` + * all properties except `codeqlCmd` are optional. + */ +export type ActionConfig< + T extends ActionConfigProperties = ActionConfigProperties, +> = Partial & Pick; From 309f6af89b6ee50bcf8876171b5afb2a329c3a32 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 11:47:59 +0100 Subject: [PATCH 059/107] Change `getGeneratedCodeScanningConfigPath` to not require full `Config` --- src/codeql.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/codeql.ts b/src/codeql.ts index 8913224fab..99ffd69512 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -15,6 +15,7 @@ import * as api from "./api-client"; import * as outputCache from "./cli/output-cache"; import type { VersionInfo } from "./cli/types"; import { CliError, wrapCliConfigurationError } from "./cli-errors"; +import type { ActionConfig } from "./config/action-config"; import { appendExtraQueryExclusions, type Config } from "./config-utils"; import { DocUrl } from "./doc-url"; import { EnvVar, getEnv, exportEnvVar } from "./environment"; @@ -1237,7 +1238,9 @@ export async function getTrapCachingExtractorConfigArgsForLang( * * This will not exist if the configuration is being parsed in the Action. */ -function getGeneratedCodeScanningConfigPath(config: Config): string { +function getGeneratedCodeScanningConfigPath( + config: ActionConfig<"tempDir">, +): string { return path.resolve(config.tempDir, "user-config.yaml"); } From 317f264e1f59264b7f18cfaa42f4642f755257cc Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 11:51:58 +0100 Subject: [PATCH 060/107] Change `diagnosticsExport` to not require full `Config` --- src/codeql.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/codeql.ts b/src/codeql.ts index 99ffd69512..68273d27b5 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -198,7 +198,7 @@ export interface CodeQL { diagnosticsExport( sarifFile: string, automationDetailsId: string | undefined, - config: Config, + config: ActionConfig<"tempDir">, ): Promise; /** Get the location of an extractor for the specified language. */ resolveExtractor(language: Language): Promise; @@ -914,7 +914,7 @@ async function getCodeQLForCmd( async diagnosticsExport( sarifFile: string, automationDetailsId: string | undefined, - config: Config, + config: ActionConfig<"tempDir">, ): Promise { const args = [ "diagnostics", From 19445ddfed42397ecf3ccc1dca379e957cc7631f Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 10:33:15 +0100 Subject: [PATCH 061/107] Reduce `Config` requirements for `tryUploadSarifIfRunFailed` --- src/config-utils.ts | 14 ++++++++++---- src/init-action-post-helper.ts | 16 +++++++++++----- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/config-utils.ts b/src/config-utils.ts index f1ec30b2c8..ebfabad36e 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -21,7 +21,7 @@ import { import * as api from "./api-client"; import { getCachingKind } from "./caching-utils"; import { type CodeQL } from "./codeql"; -import { type Config } from "./config/action-config"; +import { type ActionConfig, type Config } from "./config/action-config"; import { calculateAugmentation, ExcludeQueryFilter, @@ -1618,21 +1618,27 @@ export function appendExtraQueryExclusions( /** * Returns `true` if Code Scanning analysis is enabled, or `false` if not. */ -export function isCodeScanningEnabled(config: Config): boolean { +export function isCodeScanningEnabled( + config: ActionConfig<"analysisKinds">, +): boolean { return config.analysisKinds.includes(AnalysisKind.CodeScanning); } /** * Returns `true` if Code Quality analysis is enabled, or `false` if not. */ -export function isCodeQualityEnabled(config: Config): boolean { +export function isCodeQualityEnabled( + config: ActionConfig<"analysisKinds">, +): boolean { return config.analysisKinds.includes(AnalysisKind.CodeQuality); } /** * Returns `true` if Code Scanning Risk Assessment analysis is enabled, or `false` if not. */ -export function isRiskAssessmentEnabled(config: Config): boolean { +export function isRiskAssessmentEnabled( + config: ActionConfig<"analysisKinds">, +): boolean { return config.analysisKinds.includes(AnalysisKind.RiskAssessment); } diff --git a/src/init-action-post-helper.ts b/src/init-action-post-helper.ts index 93ee391aaa..ce06e17191 100644 --- a/src/init-action-post-helper.ts +++ b/src/init-action-post-helper.ts @@ -7,6 +7,7 @@ import * as actionsUtil from "./actions-util"; import { CodeScanning, RiskAssessment } from "./analyses"; import { getApiClient, getGitHubVersion } from "./api-client"; import { CodeQL, getCodeQL } from "./codeql"; +import type { ActionConfig } from "./config/action-config"; import { Config, isCodeScanningEnabled, @@ -86,6 +87,11 @@ interface FailedSarifInfo { checkoutPath: string; } +/** The minimal Action configuration required to prepare and upload a failed SARIF. */ +export type FailedSarifConfig = ActionConfig< + "codeQLCmd" | "tempDir" | "analysisKinds" | "languages" +>; + /** * Tries to prepare a SARIF file that contains information about a failed analysis. * @@ -94,7 +100,7 @@ interface FailedSarifInfo { async function prepareFailedSarif( logger: Logger, features: FeatureEnablement, - config: Config, + config: FailedSarifConfig, ): Promise> { if (!config.codeQLCmd) { return new Failure({ @@ -160,7 +166,7 @@ async function prepareFailedSarif( async function generateFailedSarif( logger: Logger, features: FeatureEnablement, - config: Config, + config: ActionConfig<"codeQLCmd" | "tempDir">, category: string | undefined, checkoutPath: string, sarifFile?: string, @@ -192,7 +198,7 @@ async function generateFailedSarif( * category for the workflow. */ async function maybeUploadFailedSarif( - config: Config, + config: FailedSarifConfig, repositoryNwo: RepositoryNwo, features: FeatureEnablement, logger: Logger, @@ -227,7 +233,7 @@ async function maybeUploadFailedSarif( /** Uploads a failed SARIF file as workflow artifact, if it can be generated. */ async function maybeUploadFailedSarifArtifact( - config: Config, + config: FailedSarifConfig, features: FeatureEnablement, logger: Logger, ): Promise { @@ -267,7 +273,7 @@ async function maybeUploadFailedSarifArtifact( * @returns The results of uploading the SARIF file for the failure. */ export async function tryUploadSarifIfRunFailed( - config: Config, + config: FailedSarifConfig, repositoryNwo: RepositoryNwo, features: FeatureEnablement, logger: Logger, From 5136039854019b40fed0b0413e52b6dcba4271d5 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 11:01:31 +0100 Subject: [PATCH 062/107] Store partial configuration when `init` is aborted --- lib/entry-points.js | 54 ++++++++++++++--- src/config-utils.ts | 116 +++++++++++++++++++++++++++++++----- src/config/action-config.ts | 11 ++++ src/init-action.ts | 12 ++++ 4 files changed, 171 insertions(+), 22 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 21c0ccd15f..ea86db9891 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -175053,20 +175053,45 @@ function getLocalConfig(logger2, configFile, validateConfig) { function getPathToParsedConfigFile(tempDir) { return path11.join(tempDir, "config"); } -async function saveConfig(config, logger2) { +function getPathToFailedConfigFile(tempDir) { + return path11.join(tempDir, "failed-config"); +} +function saveConfigFile(logger2, configFilePath, config) { const configString = JSON.stringify(config); - const configFile = getPathToParsedConfigFile(config.tempDir); - fs10.mkdirSync(path11.dirname(configFile), { recursive: true }); - fs10.writeFileSync(configFile, configString, "utf8"); + fs10.mkdirSync(path11.dirname(configFilePath), { recursive: true }); + fs10.writeFileSync(configFilePath, configString, "utf8"); logger2.debug("Saved config:"); logger2.debug(configString); } -async function getConfig(tempDir, logger2) { - const configFile = getPathToParsedConfigFile(tempDir); - if (!fs10.existsSync(configFile)) { +async function saveConfig(config, logger2) { + const configFile = getPathToParsedConfigFile(config.tempDir); + saveConfigFile(logger2, configFile, config); +} +function saveAbortedInitConfig(action, config) { + if (action.name !== "init" /* Init */) { + return; + } + const failedConfig = { + version: config.version, + tempDir: config.tempDir, + codeQLCmd: config.codeQLCmd, + debugMode: config.debugMode, + gitHubVersion: config.gitHubVersion, + languages: config.languages, + analysisKinds: config.analysisKinds + }; + action.logger.debug(`Saving config for failed init step.`); + saveConfigFile( + action.logger, + getPathToFailedConfigFile(config.tempDir), + failedConfig + ); +} +function readConfigFile(logger2, configFilePath) { + if (!fs10.existsSync(configFilePath)) { return void 0; } - const configString = fs10.readFileSync(configFile, "utf8"); + const configString = fs10.readFileSync(configFilePath, "utf8"); logger2.debug("Loaded config:"); logger2.debug(configString); const config = JSON.parse(configString); @@ -175087,6 +175112,10 @@ async function getConfig(tempDir, logger2) { } return config; } +async function getConfig(tempDir, logger2) { + const configFile = getPathToParsedConfigFile(tempDir); + return readConfigFile(logger2, configFile); +} async function generateRegistries(registriesInput, tempDir, logger2) { const registries = parseRegistries(registriesInput); let registriesAuthTokens; @@ -186495,6 +186524,15 @@ async function run3(actionState) { } await checkInstallPython311(config.languages, codeql); } catch (unwrappedError) { + if (config !== void 0) { + try { + saveAbortedInitConfig(actionState, config); + } catch (configSaveError) { + logger2.warning( + `Unable to save configuration for '${"init-post" /* InitPost */}' step: ${getErrorMessage(configSaveError)}` + ); + } + } const error3 = wrapError(unwrappedError); core19.setFailed(error3.message); const statusReportBase = await createStatusReportBase( diff --git a/src/config-utils.ts b/src/config-utils.ts index ebfabad36e..107f666661 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -21,7 +21,11 @@ import { import * as api from "./api-client"; import { getCachingKind } from "./caching-utils"; import { type CodeQL } from "./codeql"; -import { type ActionConfig, type Config } from "./config/action-config"; +import { + type AbortedInitConfig, + type ActionConfig, + type Config, +} from "./config/action-config"; import { calculateAugmentation, ExcludeQueryFilter, @@ -71,6 +75,7 @@ import { import { OverlayDatabaseMode } from "./overlay/overlay-database-mode"; import { shouldSkipOverlayAnalysis } from "./overlay/status"; import { RepositoryNwo } from "./repository"; +import { ActionName } from "./status-report"; import { ToolsFeature } from "./tools-features"; import { downloadTrapCaches } from "./trap-caching"; import { @@ -1379,31 +1384,84 @@ export function getPathToParsedConfigFile(tempDir: string): string { return path.join(tempDir, "config"); } +function getPathToFailedConfigFile(tempDir: string): string { + return path.join(tempDir, "failed-config"); +} + /** - * Store the given config to the path returned from getPathToParsedConfigFile. + * Writes {@link config} to {@link configFilePath}. + * + * This function is not intended to be called, other than by + * {@link saveConfig} and {@link saveFailedConfig} below. */ -export async function saveConfig(config: Config, logger: Logger) { +function saveConfigFile( + logger: Logger, + configFilePath: string, + config: Partial, +) { const configString = JSON.stringify(config); - const configFile = getPathToParsedConfigFile(config.tempDir); - fs.mkdirSync(path.dirname(configFile), { recursive: true }); - fs.writeFileSync(configFile, configString, "utf8"); + fs.mkdirSync(path.dirname(configFilePath), { recursive: true }); + fs.writeFileSync(configFilePath, configString, "utf8"); logger.debug("Saved config:"); logger.debug(configString); } /** - * Get the config that has been saved to the given temp dir. - * If the config could not be found then returns undefined. + * Store the given config to the path returned from getPathToParsedConfigFile. */ -export async function getConfig( - tempDir: string, +export async function saveConfig(config: Config, logger: Logger) { + const configFile = getPathToParsedConfigFile(config.tempDir); + saveConfigFile(logger, configFile, config); +} + +/** + * Store parts of {@link config} as a failed configuration file. + * + * The file will only contain parts of {@link config} that are relevant to + * the `init-post` step in the workflow. + */ +export function saveAbortedInitConfig( + action: ActionState<["Base", "Logger"]>, + config: Config, +) { + // Should only be called by init. + if (action.name !== ActionName.Init) { + return; + } + + // Create a copy of the input `Config` that only contains the keys we want. + const failedConfig: AbortedInitConfig = { + version: config.version, + tempDir: config.tempDir, + codeQLCmd: config.codeQLCmd, + debugMode: config.debugMode, + gitHubVersion: config.gitHubVersion, + languages: config.languages, + analysisKinds: config.analysisKinds, + }; + + action.logger.debug(`Saving config for failed init step.`); + saveConfigFile( + action.logger, + getPathToFailedConfigFile(config.tempDir), + failedConfig, + ); +} + +/** + * Attempts to read a {@link Config} from {@link configFilePath}. + * + * This function is not intended to be called, other than by + * {@link getConfig} and {@link getAbortedInitConfig} below. + */ +function readConfigFile( logger: Logger, -): Promise { - const configFile = getPathToParsedConfigFile(tempDir); - if (!fs.existsSync(configFile)) { + configFilePath: string, +): Config | undefined { + if (!fs.existsSync(configFilePath)) { return undefined; } - const configString = fs.readFileSync(configFile, "utf8"); + const configString = fs.readFileSync(configFilePath, "utf8"); logger.debug("Loaded config:"); logger.debug(configString); @@ -1428,6 +1486,36 @@ export async function getConfig( return config as Config; } +/** + * Get the config that has been saved to the given temp dir. + * If the config could not be found then returns undefined. + */ +export async function getConfig( + tempDir: string, + logger: Logger, +): Promise { + const configFile = getPathToParsedConfigFile(tempDir); + return readConfigFile(logger, configFile); +} + +/** + * Loads a {@link AbortedInitConfig} from a failed `init` step if it exists. + * + * The result will only contain parts of a {@link Config} that are relevant to + * the `init-post` step in the workflow. + */ +export function getAbortedInitConfig( + action: ActionState<["Base", "Logger"]>, + tempDir: string, +): AbortedInitConfig | undefined { + // Only intended to be called by the `init-post` action. + if (action.name !== ActionName.InitPost) { + return undefined; + } + + return readConfigFile(action.logger, getPathToFailedConfigFile(tempDir)); +} + /** * Generate a `qlconfig.yml` file from the `registries` input. * This file is used by the CodeQL CLI to list the registries to use for each diff --git a/src/config/action-config.ts b/src/config/action-config.ts index fcb6a9482a..1024c6fecc 100644 --- a/src/config/action-config.ts +++ b/src/config/action-config.ts @@ -142,3 +142,14 @@ export type ActionConfigProperties = keyof Config; export type ActionConfig< T extends ActionConfigProperties = ActionConfigProperties, > = Partial & Pick; + +/** A minimal configuration that we can make available even when `init` aborts. */ +export type AbortedInitConfig = ActionConfig< + | "version" + | "tempDir" + | "gitHubVersion" + | "debugMode" + | "languages" + | "analysisKinds" + | "codeQLCmd" +>; diff --git a/src/init-action.ts b/src/init-action.ts index 8723044da6..5376763b52 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -457,6 +457,18 @@ async function run( await checkInstallPython311(config.languages, codeql); } catch (unwrappedError) { + // If we have initialised the Action state, then try to save a subset of it for use by the `init-post` action + // so that it can try to create and upload additional diagnostic information. + if (config !== undefined) { + try { + configUtils.saveAbortedInitConfig(actionState, config); + } catch (configSaveError) { + logger.warning( + `Unable to save configuration for '${ActionName.InitPost}' step: ${getErrorMessage(configSaveError)}`, + ); + } + } + const error = wrapError(unwrappedError); core.setFailed(error.message); const statusReportBase = await createStatusReportBase( From 4fdbb71b548f7260858d8fe0eebbfcfa9d1f05b5 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Sat, 10 Oct 2026 00:30:06 +0100 Subject: [PATCH 063/107] Use `runInActions` for `init-post` --- lib/entry-points.js | 35 +++++++++++++++-------------------- src/init-action-post.ts | 38 ++++++++++++++++---------------------- src/status-report.ts | 2 ++ 3 files changed, 33 insertions(+), 42 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index ea86db9891..0bb4be3ddb 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -171404,6 +171404,8 @@ function getAddressString(address) { function getDisplayActionName(actionName) { if (actionName === "finish" /* Analyze */) { return "analyze"; + } else if (actionName === "init-post" /* InitPost */) { + return "init post"; } return actionName; } @@ -187108,15 +187110,16 @@ async function removeUploadedSarif(uploadFailedSarifResult, logger2) { } // src/init-action-post.ts -async function run4(startedAt) { - const logger2 = getActionsLogger(); +async function run4(action) { + const logger2 = action.logger; let config; let uploadFailedSarifResult; let dependencyCachingUsage; try { const jobStatus2 = getOptionalInput("job-status"); restoreInputs(logger2); - config = await getConfig(getTemporaryDirectory(), logger2); + const tmpDir = getTemporaryDirectory(); + config = await getConfig(tmpDir, logger2); const gitHubVersion = config?.gitHubVersion ?? await getGitHubVersion(); checkGitHubVersionInRange(gitHubVersion, logger2); const repositoryNwo = getRepositoryNwo(); @@ -187151,9 +187154,9 @@ async function run4(startedAt) { const error3 = wrapApiConfigurationError(wrapError(unwrappedError)); core20.setFailed(error3.message); const statusReportBase2 = await createStatusReportBase( - "init-post" /* InitPost */, + action.name, getActionsStatus(error3), - startedAt, + action.startedAt, config, await checkDiskUsage(logger2), logger2, @@ -187168,9 +187171,9 @@ async function run4(startedAt) { const jobStatus = getFinalJobStatus(config); logger2.info(`CodeQL job status was ${getJobStatusDisplayName(jobStatus)}.`); const statusReportBase = await createStatusReportBase( - "init-post" /* InitPost */, + action.name, "success", - startedAt, + action.startedAt, config, await checkDiskUsage(logger2), logger2 @@ -187214,20 +187217,12 @@ function getJobStatusFromEnvironment() { } return void 0; } +var initPost = { + name: "init-post" /* InitPost */, + run: run4 +}; async function runWrapper5() { - const startedAt = /* @__PURE__ */ new Date(); - const logger2 = getActionsLogger(); - try { - await run4(startedAt); - } catch (error3) { - core20.setFailed(`init post action failed: ${wrapError(error3).message}`); - await sendUnhandledErrorStatusReport( - "init-post" /* InitPost */, - startedAt, - error3, - logger2 - ); - } + return await runInActions(initPost); } // src/resolve-environment-action.ts diff --git a/src/init-action-post.ts b/src/init-action-post.ts index a81c27810a..9e623a5794 100644 --- a/src/init-action-post.ts +++ b/src/init-action-post.ts @@ -6,6 +6,7 @@ import * as core from "@actions/core"; +import { runInActions, type Action, type ActionState } from "./action-common"; import { restoreInputs, getOptionalInput, @@ -25,12 +26,10 @@ import { EnvVar, getEnv, exportEnvVar } from "./environment"; import { initFeatures } from "./feature-flags"; import * as gitUtils from "./git-utils"; import * as initActionPostHelper from "./init-action-post-helper"; -import { getActionsLogger } from "./logging"; import { getRepositoryNwo } from "./repository"; import { StatusReportBase, sendStatusReport, - sendUnhandledErrorStatusReport, createStatusReportBase, getActionsStatus, ActionName, @@ -45,16 +44,17 @@ interface InitPostStatusReport initActionPostHelper.JobStatusReport, initActionPostHelper.DependencyCachingUsageReport {} -async function run(startedAt: Date) { +async function run(action: ActionState<["Base", "Logger"]>) { // To capture errors appropriately, keep as much code within the try-catch as // possible, and only use safe functions outside. + const logger = action.logger; - const logger = getActionsLogger(); let config: Config | undefined; let uploadFailedSarifResult: | initActionPostHelper.UploadFailedSarifResult | undefined; let dependencyCachingUsage: DependencyCachingUsageReport | undefined; + try { // Read the job status before restoring inputs, since it is provided by the Actions runtime // environment for this step and would otherwise be overwritten by the value that the `init` @@ -64,7 +64,8 @@ async function run(startedAt: Date) { // Restore inputs from `init` Action. restoreInputs(logger); - config = await getConfig(getTemporaryDirectory(), logger); + const tmpDir = getTemporaryDirectory(); + config = await getConfig(tmpDir, logger); const gitHubVersion = config?.gitHubVersion ?? (await getGitHubVersion()); checkGitHubVersionInRange(gitHubVersion, logger); @@ -112,9 +113,9 @@ async function run(startedAt: Date) { core.setFailed(error.message); const statusReportBase = await createStatusReportBase( - ActionName.InitPost, + action.name, getActionsStatus(error), - startedAt, + action.startedAt, config, await checkDiskUsage(logger), logger, @@ -130,9 +131,9 @@ async function run(startedAt: Date) { logger.info(`CodeQL job status was ${getJobStatusDisplayName(jobStatus)}.`); const statusReportBase = await createStatusReportBase( - ActionName.InitPost, + action.name, "success", - startedAt, + action.startedAt, config, await checkDiskUsage(logger), logger, @@ -216,18 +217,11 @@ function getJobStatusFromEnvironment(): JobStatus | undefined { return undefined; } +const initPost: Action = { + name: ActionName.InitPost, + run, +}; + export async function runWrapper() { - const startedAt = new Date(); - const logger = getActionsLogger(); - try { - await run(startedAt); - } catch (error) { - core.setFailed(`init post action failed: ${wrapError(error).message}`); - await sendUnhandledErrorStatusReport( - ActionName.InitPost, - startedAt, - error, - logger, - ); - } + return await runInActions(initPost); } diff --git a/src/status-report.ts b/src/status-report.ts index ae21beb307..3f3e1d884c 100644 --- a/src/status-report.ts +++ b/src/status-report.ts @@ -68,6 +68,8 @@ export enum ActionName { export function getDisplayActionName(actionName: ActionName): string { if (actionName === ActionName.Analyze) { return "analyze"; + } else if (actionName === ActionName.InitPost) { + return "init post"; } return actionName; } From f4a15a13fddaf2e467a34d7690be557e678fe505 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 11:25:00 +0100 Subject: [PATCH 064/107] Try to load failed config if normal config is unavailable Adapt relevant functions by narrowing their types or skipping steps that would otherwise have been skipped as well --- lib/entry-points.js | 27 ++++++++++++++++++++++----- src/actions-util.ts | 11 +++++++++-- src/analyze.ts | 3 ++- src/config/action-config.ts | 8 ++++++++ src/debug-artifacts.ts | 17 +++++++++++------ src/init-action-post-helper.ts | 22 ++++++++++++++-------- src/init-action-post.ts | 21 +++++++++++++++++---- src/util.ts | 12 +++++++++--- 8 files changed, 92 insertions(+), 29 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 0bb4be3ddb..7350b20656 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -166098,6 +166098,11 @@ var toolrunner = __toESM(require_toolrunner()); var github = __toESM(require_github()); var io2 = __toESM(require_io()); +// src/config/action-config.ts +function hasConfigKey(config, key) { + return config[key] !== void 0; +} + // src/environment.ts var core = __toESM(require_core()); function getRequiredEnvVar(env, paramName) { @@ -170208,6 +170213,9 @@ function getWorkflowEvent(env = getEnv()) { } } async function printDebugLogs(config) { + if (!hasConfigKey(config, "languages") || !hasConfigKey(config, "dbLocation")) { + return; + } for (const language of config.languages) { const databaseDirectory = getCodeQLDatabasePath(config, language); const logsDirectory = path2.join(databaseDirectory, "log"); @@ -175118,6 +175126,12 @@ async function getConfig(tempDir, logger2) { const configFile = getPathToParsedConfigFile(tempDir); return readConfigFile(logger2, configFile); } +function getAbortedInitConfig(action, tempDir) { + if (action.name !== "init-post" /* InitPost */) { + return void 0; + } + return readConfigFile(action.logger, getPathToFailedConfigFile(tempDir)); +} async function generateRegistries(registriesInput, tempDir, logger2) { const registries = parseRegistries(registriesInput); let registriesAuthTokens; @@ -186963,14 +186977,14 @@ async function uploadFailureInfo(uploadAllAvailableDebugArtifacts, printDebugLog ); } } - if (config.debugMode) { + if (config.debugMode && hasConfigKey(config, "dbLocation")) { logger2.info( "Debug mode is on. Uploading available database bundles and logs as Actions debugging artifacts..." ); await uploadAllAvailableDebugArtifacts(codeql, config, logger2); await printDebugLogs2(config); } - if (isSelfHostedRunner()) { + if (isSelfHostedRunner() && config.dbLocation) { try { fs30.rmSync(config.dbLocation, { recursive: true, @@ -187006,7 +187020,7 @@ function isConclusiveJobStatus(jobStatus) { } } async function recordOverlayStatus(codeql, config, features, jobStatus, env, logger2) { - if (config.overlayDatabaseMode !== "overlay-base" /* OverlayBase */ || env.getOptional("CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */) === "true" || !await features.getValue("overlay_analysis_status_save" /* OverlayAnalysisStatusSave */)) { + if (config.overlayDatabaseMode !== "overlay-base" /* OverlayBase */ || env.getOptional("CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */) === "true" || !await features.getValue("overlay_analysis_status_save" /* OverlayAnalysisStatusSave */) || config.languages === void 0) { return; } if (!isConclusiveJobStatus(jobStatus) && !didCodeQlReportError(env)) { @@ -187120,6 +187134,9 @@ async function run4(action) { restoreInputs(logger2); const tmpDir = getTemporaryDirectory(); config = await getConfig(tmpDir, logger2); + if (config === void 0) { + config = getAbortedInitConfig(action, tmpDir); + } const gitHubVersion = config?.gitHubVersion ?? await getGitHubVersion(); checkGitHubVersionInRange(gitHubVersion, logger2); const repositoryNwo = getRepositoryNwo(); @@ -187129,7 +187146,7 @@ async function run4(action) { getTemporaryDirectory(), logger2 ); - if (config === void 0) { + if (config?.codeQLCmd === void 0) { logger2.warning( "Debugging artifacts are unavailable since the 'init' Action failed before it could produce any." ); @@ -187146,7 +187163,7 @@ async function run4(action) { getEnv(), logger2 ); - if (await isAnalyzingDefaultBranch() && config.dependencyCachingEnabled !== "none" /* None */) { + if (await isAnalyzingDefaultBranch() && hasConfigKey(config, "dependencyCachingEnabled") && config.dependencyCachingEnabled !== "none" /* None */) { dependencyCachingUsage = await getDependencyCacheUsage(logger2); } } diff --git a/src/actions-util.ts b/src/actions-util.ts index ea9a119ed4..e43abbb0b9 100644 --- a/src/actions-util.ts +++ b/src/actions-util.ts @@ -6,7 +6,7 @@ import * as toolrunner from "@actions/exec/lib/toolrunner"; import * as github from "@actions/github"; import * as io from "@actions/io"; -import type { Config } from "./config-utils"; +import { hasConfigKey, type Config } from "./config/action-config"; import { Env, EnvVar, ActionsEnvVars, ReadOnlyEnv } from "./environment"; import { Logger } from "./logging"; import { @@ -131,7 +131,14 @@ export function getWorkflowEvent(env: Env = getEnv()): any { } } -export async function printDebugLogs(config: Config) { +export async function printDebugLogs(config: Partial) { + if ( + !hasConfigKey(config, "languages") || + !hasConfigKey(config, "dbLocation") + ) { + return; + } + for (const language of config.languages) { const databaseDirectory = getCodeQLDatabasePath(config, language); const logsDirectory = path.join(databaseDirectory, "log"); diff --git a/src/analyze.ts b/src/analyze.ts index 4eeb447e18..4d5fd53543 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -9,6 +9,7 @@ import { getTemporaryDirectory } from "./actions-util"; import * as analyses from "./analyses"; import { setupCppAutobuild } from "./autobuild"; import { type CodeQL } from "./codeql"; +import type { ActionConfig } from "./config/action-config"; import { defaultSuites } from "./config/db-config"; import * as configUtils from "./config-utils"; import { @@ -171,7 +172,7 @@ async function shouldExtractLanguage( } export function dbIsFinalized( - config: configUtils.Config, + config: ActionConfig<"dbLocation">, language: Language, logger: Logger, ) { diff --git a/src/config/action-config.ts b/src/config/action-config.ts index 1024c6fecc..110b3665a7 100644 --- a/src/config/action-config.ts +++ b/src/config/action-config.ts @@ -143,6 +143,14 @@ export type ActionConfig< T extends ActionConfigProperties = ActionConfigProperties, > = Partial & Pick; +/** Helper function to check whether `config` has `key` to narrow the type of `config`. */ +export function hasConfigKey( + config: Partial, + key: Key, +): config is ActionConfig { + return config[key] !== undefined; +} + /** A minimal configuration that we can make available even when `init` aborts. */ export type AbortedInitConfig = ActionConfig< | "version" diff --git a/src/debug-artifacts.ts b/src/debug-artifacts.ts index 70c9a0ebd4..56497f14e8 100644 --- a/src/debug-artifacts.ts +++ b/src/debug-artifacts.ts @@ -10,7 +10,7 @@ import { getOptionalInput, getTemporaryDirectory } from "./actions-util"; import { dbIsFinalized } from "./analyze"; import { scanArtifactsForTokens } from "./artifact-scanner"; import { type CodeQL } from "./codeql"; -import { Config } from "./config-utils"; +import type { ActionConfig } from "./config/action-config"; import { EnvVar, exportEnvVar } from "./environment"; import * as json from "./json"; import { Language } from "./languages"; @@ -89,7 +89,7 @@ export async function uploadCombinedSarifArtifacts( * @return The path to that debug artifact, or undefined if an error occurs. */ function tryPrepareSarifDebugArtifact( - config: Config, + config: ActionConfig<"dbLocation">, language: Language, logger: Logger, ): string | undefined { @@ -131,7 +131,7 @@ function tryPrepareSarifDebugArtifact( */ async function tryBundleDatabase( codeql: CodeQL, - config: Config, + config: ActionConfig<"dbLocation">, language: Language, logger: Logger, ): Promise { @@ -157,6 +157,11 @@ async function tryBundleDatabase( } } +/** The minimal configuration needed for `tryUploadAllAvailableDebugArtifacts`. */ +export type UploadDebugArtifactsConfig = ActionConfig< + "languages" | "gitHubVersion" | "dbLocation" | "debugArtifactName" +>; + /** * Attempt to upload all available debug artifacts. * @@ -164,7 +169,7 @@ async function tryBundleDatabase( */ export async function tryUploadAllAvailableDebugArtifacts( codeql: CodeQL, - config: Config, + config: UploadDebugArtifactsConfig, logger: Logger, ) { const filesToUpload: string[] = []; @@ -353,7 +358,7 @@ export async function getArtifactUploaderClient( * all files in the database folder and return the path. */ async function createPartialDatabaseBundle( - config: Config, + config: ActionConfig<"dbLocation">, language: Language, ): Promise { const databasePath = getCodeQLDatabasePath(config, language); @@ -394,7 +399,7 @@ async function createPartialDatabaseBundle( */ async function createDatabaseBundleCli( codeql: CodeQL, - config: Config, + config: ActionConfig<"dbLocation">, language: Language, ): Promise { const databaseBundlePath = await bundleDb( diff --git a/src/init-action-post-helper.ts b/src/init-action-post-helper.ts index ce06e17191..270bc0f079 100644 --- a/src/init-action-post-helper.ts +++ b/src/init-action-post-helper.ts @@ -7,7 +7,11 @@ import * as actionsUtil from "./actions-util"; import { CodeScanning, RiskAssessment } from "./analyses"; import { getApiClient, getGitHubVersion } from "./api-client"; import { CodeQL, getCodeQL } from "./codeql"; -import type { ActionConfig } from "./config/action-config"; +import { + hasConfigKey, + type AbortedInitConfig, + type ActionConfig, +} from "./config/action-config"; import { Config, isCodeScanningEnabled, @@ -17,6 +21,7 @@ import { getArtifactSuffix, getArtifactUploaderClient, sanitizeArtifactName, + type UploadDebugArtifactsConfig, } from "./debug-artifacts"; import * as dependencyCaching from "./dependency-caching"; import { EnvVar, ReadOnlyEnv } from "./environment"; @@ -330,12 +335,12 @@ export async function tryUploadSarifIfRunFailed( export async function uploadFailureInfo( uploadAllAvailableDebugArtifacts: ( codeql: CodeQL, - config: Config, + config: UploadDebugArtifactsConfig, logger: Logger, ) => Promise, - printDebugLogs: (config: Config) => Promise, + printDebugLogs: (config: Partial) => Promise, codeql: CodeQL, - config: Config, + config: Config | AbortedInitConfig, repositoryNwo: RepositoryNwo, features: FeatureEnablement, jobStatus: string | undefined, @@ -382,7 +387,7 @@ export async function uploadFailureInfo( } // Upload appropriate Actions artifacts for debugging - if (config.debugMode) { + if (config.debugMode && hasConfigKey(config, "dbLocation")) { logger.info( "Debug mode is on. Uploading available database bundles and logs as Actions debugging artifacts...", ); @@ -390,7 +395,7 @@ export async function uploadFailureInfo( await printDebugLogs(config); } - if (actionsUtil.isSelfHostedRunner()) { + if (actionsUtil.isSelfHostedRunner() && config.dbLocation) { try { fs.rmSync(config.dbLocation, { recursive: true, @@ -453,7 +458,7 @@ function isConclusiveJobStatus(jobStatus: string | undefined): boolean { */ async function recordOverlayStatus( codeql: CodeQL, - config: Config, + config: Partial, features: FeatureEnablement, jobStatus: string | undefined, env: ReadOnlyEnv, @@ -462,7 +467,8 @@ async function recordOverlayStatus( if ( config.overlayDatabaseMode !== OverlayDatabaseMode.OverlayBase || env.getOptional(EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY) === "true" || - !(await features.getValue(Feature.OverlayAnalysisStatusSave)) + !(await features.getValue(Feature.OverlayAnalysisStatusSave)) || + config.languages === undefined ) { return; } diff --git a/src/init-action-post.ts b/src/init-action-post.ts index 9e623a5794..2325fc5d2d 100644 --- a/src/init-action-post.ts +++ b/src/init-action-post.ts @@ -16,7 +16,12 @@ import { import { getGitHubVersion, wrapApiConfigurationError } from "./api-client"; import { CachingKind } from "./caching-utils"; import { getCodeQL } from "./codeql"; -import { type Config, getConfig } from "./config-utils"; +import { + hasConfigKey, + type AbortedInitConfig, + type Config, +} from "./config/action-config"; +import { getAbortedInitConfig, getConfig } from "./config-utils"; import * as debugArtifacts from "./debug-artifacts"; import { DependencyCachingUsageReport, @@ -49,7 +54,7 @@ async function run(action: ActionState<["Base", "Logger"]>) { // possible, and only use safe functions outside. const logger = action.logger; - let config: Config | undefined; + let config: Config | AbortedInitConfig | undefined; let uploadFailedSarifResult: | initActionPostHelper.UploadFailedSarifResult | undefined; @@ -67,6 +72,13 @@ async function run(action: ActionState<["Base", "Logger"]>) { const tmpDir = getTemporaryDirectory(); config = await getConfig(tmpDir, logger); + // If we weren't able to read the normal configuration file, the `init` step failed before it could write it. + // Try to load the "failed" configuration file instead which may have been written by the `init` step + // with a minimal configuration for this post-action. + if (config === undefined) { + config = getAbortedInitConfig(action, tmpDir); + } + const gitHubVersion = config?.gitHubVersion ?? (await getGitHubVersion()); checkGitHubVersionInRange(gitHubVersion, logger); @@ -78,7 +90,7 @@ async function run(action: ActionState<["Base", "Logger"]>) { logger, ); - if (config === undefined) { + if (config?.codeQLCmd === undefined) { logger.warning( "Debugging artifacts are unavailable since the 'init' Action failed before it could produce any.", ); @@ -103,6 +115,7 @@ async function run(action: ActionState<["Base", "Logger"]>) { // and where caching may not be enabled. if ( (await gitUtils.isAnalyzingDefaultBranch()) && + hasConfigKey(config, "dependencyCachingEnabled") && config.dependencyCachingEnabled !== CachingKind.None ) { dependencyCachingUsage = await getDependencyCacheUsage(logger); @@ -158,7 +171,7 @@ async function run(action: ActionState<["Base", "Logger"]>) { * Otherwise, we determine the job status based on whether the analyze step * completed successfully and whether we have a valid CodeQL config. */ -function getFinalJobStatus(config: Config | undefined): JobStatus { +function getFinalJobStatus(config: Partial | undefined): JobStatus { const existingJobStatus = getJobStatusFromEnvironment(); if (existingJobStatus !== undefined) { return existingJobStatus; diff --git a/src/util.ts b/src/util.ts index 674e2a2eef..566386de62 100644 --- a/src/util.ts +++ b/src/util.ts @@ -12,6 +12,7 @@ import * as semver from "semver"; import * as apiCompatibility from "./api-compatibility.json"; import type { CodeQL } from "./codeql"; +import type { ActionConfig } from "./config/action-config"; import type { Pack } from "./config/db-config"; import type { Config } from "./config-utils"; import { @@ -445,7 +446,10 @@ export function getThreadsFlag( /** * Get the path where the CodeQL database for the given language lives. */ -export function getCodeQLDatabasePath(config: Config, language: Language) { +export function getCodeQLDatabasePath( + config: ActionConfig<"dbLocation">, + language: Language, +) { return path.resolve(config.dbLocation, language); } @@ -639,7 +643,9 @@ export async function codeQlVersionAtLeast( return semver.gte((await codeql.getVersion()).version, requiredVersion); } -export function getBaseDatabaseOidsFilePath(config: Config): string { +export function getBaseDatabaseOidsFilePath( + config: ActionConfig<"dbLocation">, +): string { return path.join(config.dbLocation, BASE_DATABASE_OIDS_FILE_NAME); } @@ -651,7 +657,7 @@ export function getBaseDatabaseOidsFilePath(config: Config): string { * given `includeDiagnostics` value. */ export async function bundleDb( - config: Config, + config: ActionConfig<"dbLocation">, language: Language, codeql: CodeQL, dbName: string, From 409be011364777ecfccd19c9c837565ee94628f5 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 11:29:29 +0100 Subject: [PATCH 065/107] Replace deprecated functions in `init-action.post.ts` --- lib/entry-points.js | 18 +++++++++--------- src/init-action-post.ts | 27 ++++++++++++++++----------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 7350b20656..1cee05cfb4 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -187160,7 +187160,7 @@ async function run4(action) { repositoryNwo, features, jobStatus2, - getEnv(), + action.env, logger2 ); if (await isAnalyzingDefaultBranch() && hasConfigKey(config, "dependencyCachingEnabled") && config.dependencyCachingEnabled !== "none" /* None */) { @@ -187185,7 +187185,7 @@ async function run4(action) { } return; } - const jobStatus = getFinalJobStatus(config); + const jobStatus = getFinalJobStatus(action, config); logger2.info(`CodeQL job status was ${getJobStatusDisplayName(jobStatus)}.`); const statusReportBase = await createStatusReportBase( action.name, @@ -187207,25 +187207,25 @@ async function run4(action) { logger2.info("Status report sent for init-post step."); } } -function getFinalJobStatus(config) { - const existingJobStatus = getJobStatusFromEnvironment(); +function getFinalJobStatus(action, config) { + const existingJobStatus = getJobStatusFromEnvironment(action.env); if (existingJobStatus !== void 0) { return existingJobStatus; } let jobStatus; - if (process.env["CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */] === "true") { - exportEnvVar("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, "JOB_STATUS_SUCCESS" /* SuccessStatus */); + if (action.env.getOptional("CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */) === "true") { + action.env.export("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, "JOB_STATUS_SUCCESS" /* SuccessStatus */); jobStatus = "JOB_STATUS_SUCCESS" /* SuccessStatus */; } else if (config !== void 0) { jobStatus = "JOB_STATUS_CONFIGURATION_ERROR" /* ConfigErrorStatus */; } else { jobStatus = "JOB_STATUS_UNKNOWN" /* UnknownStatus */; } - exportEnvVar("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, jobStatus); + action.env.export("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, jobStatus); return jobStatus; } -function getJobStatusFromEnvironment() { - const jobStatusFromEnvironment = process.env["CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */]; +function getJobStatusFromEnvironment(env) { + const jobStatusFromEnvironment = env.getOptional("CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */); if (jobStatusFromEnvironment !== void 0) { if (Object.values(JobStatus).includes(jobStatusFromEnvironment)) { return jobStatusFromEnvironment; diff --git a/src/init-action-post.ts b/src/init-action-post.ts index 2325fc5d2d..dd981c200a 100644 --- a/src/init-action-post.ts +++ b/src/init-action-post.ts @@ -27,7 +27,7 @@ import { DependencyCachingUsageReport, getDependencyCacheUsage, } from "./dependency-caching"; -import { EnvVar, getEnv, exportEnvVar } from "./environment"; +import { EnvVar, type ReadOnlyEnv } from "./environment"; import { initFeatures } from "./feature-flags"; import * as gitUtils from "./git-utils"; import * as initActionPostHelper from "./init-action-post-helper"; @@ -49,7 +49,7 @@ interface InitPostStatusReport initActionPostHelper.JobStatusReport, initActionPostHelper.DependencyCachingUsageReport {} -async function run(action: ActionState<["Base", "Logger"]>) { +async function run(action: ActionState<["Base", "Logger", "Env"]>) { // To capture errors appropriately, keep as much code within the try-catch as // possible, and only use safe functions outside. const logger = action.logger; @@ -105,7 +105,7 @@ async function run(action: ActionState<["Base", "Logger"]>) { repositoryNwo, features, jobStatus, - getEnv(), + action.env, logger, ); @@ -140,7 +140,7 @@ async function run(action: ActionState<["Base", "Logger"]>) { } return; } - const jobStatus = getFinalJobStatus(config); + const jobStatus = getFinalJobStatus(action, config); logger.info(`CodeQL job status was ${getJobStatusDisplayName(jobStatus)}.`); const statusReportBase = await createStatusReportBase( @@ -171,16 +171,21 @@ async function run(action: ActionState<["Base", "Logger"]>) { * Otherwise, we determine the job status based on whether the analyze step * completed successfully and whether we have a valid CodeQL config. */ -function getFinalJobStatus(config: Partial | undefined): JobStatus { - const existingJobStatus = getJobStatusFromEnvironment(); +function getFinalJobStatus( + action: ActionState<["Env"]>, + config: Partial | undefined, +): JobStatus { + const existingJobStatus = getJobStatusFromEnvironment(action.env); if (existingJobStatus !== undefined) { return existingJobStatus; } let jobStatus: JobStatus; - if (process.env[EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY] === "true") { - exportEnvVar(EnvVar.JOB_STATUS, JobStatus.SuccessStatus); + if ( + action.env.getOptional(EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY) === "true" + ) { + action.env.export(EnvVar.JOB_STATUS, JobStatus.SuccessStatus); jobStatus = JobStatus.SuccessStatus; } else if (config !== undefined) { // - We have computed a CodeQL config @@ -205,7 +210,7 @@ function getFinalJobStatus(config: Partial | undefined): JobStatus { // This shouldn't be necessary, but in the odd case that we run more than one // `init` post step, ensure the job status is consistent between them. - exportEnvVar(EnvVar.JOB_STATUS, jobStatus); + action.env.export(EnvVar.JOB_STATUS, jobStatus); return jobStatus; } @@ -214,8 +219,8 @@ function getFinalJobStatus(config: Partial | undefined): JobStatus { * * If the job status is invalid, return `UnknownStatus`. */ -function getJobStatusFromEnvironment(): JobStatus | undefined { - const jobStatusFromEnvironment = process.env[EnvVar.JOB_STATUS]; +function getJobStatusFromEnvironment(env: ReadOnlyEnv): JobStatus | undefined { + const jobStatusFromEnvironment = env.getOptional(EnvVar.JOB_STATUS); if (jobStatusFromEnvironment !== undefined) { // Validate the job status from the environment. If it is invalid, return unknown. From ecfc96e0a902c35a8a5d7c6c4e2c79f257469589 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 12:49:48 +0100 Subject: [PATCH 066/107] Add `getDisplayActionName` tests --- lib/entry-points.js | 11 +++++++---- src/action-common.test.ts | 18 ++++++++++++++++++ src/status-report.ts | 18 ++++++++++++------ 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 1cee05cfb4..44d94d1e08 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -171409,11 +171409,14 @@ function getAddressString(address) { } // src/status-report.ts +var ACTION_DISPLAY_NAMES = { + ["finish" /* Analyze */]: "analyze", + ["init-post" /* InitPost */]: "init post" +}; function getDisplayActionName(actionName) { - if (actionName === "finish" /* Analyze */) { - return "analyze"; - } else if (actionName === "init-post" /* InitPost */) { - return "init post"; + const displayName = ACTION_DISPLAY_NAMES[actionName]; + if (displayName !== void 0) { + return displayName; } return actionName; } diff --git a/src/action-common.test.ts b/src/action-common.test.ts index fc2e0a9aaa..449300a8d2 100644 --- a/src/action-common.test.ts +++ b/src/action-common.test.ts @@ -19,6 +19,24 @@ import { getErrorMessage } from "./util"; setupTests(test); +for (const [key, displayName] of Object.entries( + statusReport.ACTION_DISPLAY_NAMES, +)) { + test(`getDisplayActionName - '${displayName}' instead of '${key}'`, (t) => { + t.is(statusReport.getDisplayActionName(key as ActionName), displayName); + }); +} + +test("getDisplayActionName - returns action name", (t) => { + for (const actionName of Object.values(ActionName)) { + if (statusReport.ACTION_DISPLAY_NAMES[actionName]) { + continue; + } + + t.is(statusReport.getDisplayActionName(actionName), actionName); + } +}); + interface RunInActionsTestOpts { runFn?: () => Promise; expectedErrorMessage?: string; diff --git a/src/status-report.ts b/src/status-report.ts index 3f3e1d884c..fc45e82d67 100644 --- a/src/status-report.ts +++ b/src/status-report.ts @@ -61,15 +61,21 @@ export enum ActionName { UploadSarif = "upload-sarif", } +/** A partial mapping from `ActionName` to names for actions whose display name is not the `ActionName` value. */ +export const ACTION_DISPLAY_NAMES: Partial> = { + [ActionName.Analyze]: "analyze", + [ActionName.InitPost]: "init post", +}; + /** - * Maps an `ActionName` to its display name. Usually that is the same, except - * for `ActionName.Analyze` where it is `"analyze"` instead of `"finish"`. + * Maps an {@link ActionName} to its display name. Usually that is the same, except + * for actions which have a different display name in {@link ACTION_DISPLAY_NAMES}. */ export function getDisplayActionName(actionName: ActionName): string { - if (actionName === ActionName.Analyze) { - return "analyze"; - } else if (actionName === ActionName.InitPost) { - return "init post"; + const displayName = ACTION_DISPLAY_NAMES[actionName]; + + if (displayName !== undefined) { + return displayName; } return actionName; } From ac8654a8f263da108af61eb039965094ceaffdbb Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 12:50:01 +0100 Subject: [PATCH 067/107] Add `printDebugLogs` tests --- src/actions-util.test.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/actions-util.test.ts b/src/actions-util.test.ts index 3940cf7551..1217e831a0 100644 --- a/src/actions-util.test.ts +++ b/src/actions-util.test.ts @@ -7,12 +7,13 @@ import { isAnalyzingPullRequest, isDefaultSetup, isDynamicWorkflow, + printDebugLogs, } from "./actions-util"; import { computeAutomationID } from "./api-client"; import { EnvVar } from "./environment"; import { getRunnerLogger } from "./logging"; import { setupTests } from "./testing-utils"; -import { initializeEnvironment } from "./util"; +import { initializeEnvironment, withTmpDir } from "./util"; setupTests(test); @@ -100,6 +101,19 @@ test("computeAutomationID()", async (t) => { ); }); +test("printDebugLogs - doesn't throw when config doesn't have needed properties", async (t) => { + await t.notThrowsAsync(printDebugLogs({})); + await t.notThrowsAsync(printDebugLogs({ languages: [] })); + await t.notThrowsAsync(printDebugLogs({ dbLocation: "nowhere" })); +}); + +test("printDebugLogs - doesn't throw when language db doesn't exist", async (t) => + withTmpDir(async (tmpDir) => { + await t.notThrowsAsync( + printDebugLogs({ dbLocation: tmpDir, languages: ["javascript"] }), + ); + })); + test.serial("getPullRequestBranches() with pull request context", (t) => { withMockedContext( { From c1b620cc0e7973d9e01f4777f33bdafdbb570868 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 14:56:00 +0100 Subject: [PATCH 068/107] Allow `initializeEnvironment` to accept `Env` --- lib/entry-points.js | 12 ++++++------ src/setup/repository.test.ts | 11 ++++++----- src/util.ts | 14 ++++++++------ 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 846ab37e40..9f49031d9e 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -169810,12 +169810,12 @@ var ExhaustivityCheckingError = class extends Error { function assertNever(value) { throw new ExhaustivityCheckingError(value); } -function initializeEnvironment(version) { - exportEnvVar("CODEQL_ACTION_FEATURE_MULTI_LANGUAGE" /* FEATURE_MULTI_LANGUAGE */, "false"); - exportEnvVar("CODEQL_ACTION_FEATURE_SANDWICH" /* FEATURE_SANDWICH */, "false"); - exportEnvVar("CODEQL_ACTION_FEATURE_SARIF_COMBINE" /* FEATURE_SARIF_COMBINE */, "true"); - exportEnvVar("CODEQL_ACTION_FEATURE_WILL_UPLOAD" /* FEATURE_WILL_UPLOAD */, "true"); - exportEnvVar("CODEQL_ACTION_VERSION" /* VERSION */, version); +function initializeEnvironment(version, env = getEnv()) { + env.export("CODEQL_ACTION_FEATURE_MULTI_LANGUAGE" /* FEATURE_MULTI_LANGUAGE */, "false"); + env.export("CODEQL_ACTION_FEATURE_SANDWICH" /* FEATURE_SANDWICH */, "false"); + env.export("CODEQL_ACTION_FEATURE_SARIF_COMBINE" /* FEATURE_SARIF_COMBINE */, "true"); + env.export("CODEQL_ACTION_FEATURE_WILL_UPLOAD" /* FEATURE_WILL_UPLOAD */, "true"); + env.export("CODEQL_ACTION_VERSION" /* VERSION */, version); } var HTTPError = class extends Error { status; diff --git a/src/setup/repository.test.ts b/src/setup/repository.test.ts index 56eb74786f..d1c6d034c0 100644 --- a/src/setup/repository.test.ts +++ b/src/setup/repository.test.ts @@ -5,7 +5,7 @@ import * as sinon from "sinon"; import * as actionsUtil from "../actions-util"; import { ActionsEnvVars } from "../environment"; -import { callee, setupTests } from "../testing-utils"; +import { callee, getTestEnv, setupTests } from "../testing-utils"; import { initializeEnvironment } from "../util"; import { getCodeQLActionRepository } from "./repository"; @@ -13,13 +13,14 @@ import { getCodeQLActionRepository } from "./repository"; setupTests(test); test.serial("getCodeQLActionRepository", async (t) => { - initializeEnvironment("1.2.3"); + const initialEnv = getTestEnv({ + [ActionsEnvVars.RUNNER_TEMP]: path.dirname(__dirname), + }); + initializeEnvironment("1.2.3", initialEnv); const target = callee(getCodeQLActionRepository) .withArgs() - .withEnv((env) => { - env.set(ActionsEnvVars.RUNNER_TEMP, path.dirname(__dirname)); - }); + .withEnv(initialEnv); // isRunningLocalAction() === true await target.passes(t.deepEqual, "github/codeql-action"); diff --git a/src/util.ts b/src/util.ts index 674e2a2eef..3a42d8b945 100644 --- a/src/util.ts +++ b/src/util.ts @@ -19,6 +19,8 @@ import { getRequiredEnvParam, isInTestMode, exportEnvVar, + getEnv, + type Env, } from "./environment"; import * as json from "./json"; import { Language } from "./languages"; @@ -595,12 +597,12 @@ export function assertNever(value: never): never { * Set some initial environment variables that we can set even without * knowing what version of CodeQL we're running. */ -export function initializeEnvironment(version: string) { - exportEnvVar(EnvVar.FEATURE_MULTI_LANGUAGE, "false"); - exportEnvVar(EnvVar.FEATURE_SANDWICH, "false"); - exportEnvVar(EnvVar.FEATURE_SARIF_COMBINE, "true"); - exportEnvVar(EnvVar.FEATURE_WILL_UPLOAD, "true"); - exportEnvVar(EnvVar.VERSION, version); +export function initializeEnvironment(version: string, env: Env = getEnv()) { + env.export(EnvVar.FEATURE_MULTI_LANGUAGE, "false"); + env.export(EnvVar.FEATURE_SANDWICH, "false"); + env.export(EnvVar.FEATURE_SARIF_COMBINE, "true"); + env.export(EnvVar.FEATURE_WILL_UPLOAD, "true"); + env.export(EnvVar.VERSION, version); } export class HTTPError extends Error { From ad8ebce2932d8d44604dd6430e4fae7c3ff55873 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 15:27:32 +0100 Subject: [PATCH 069/107] Add and use `RepositoryNwoStr` type --- lib/entry-points.js | 13 ++++++++++++- src/repository.ts | 8 ++++++++ src/setup/repository.ts | 19 +++++++++++++++---- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 9f49031d9e..99b2b4fc2c 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -170631,6 +170631,9 @@ retry.VERSION = VERSION7; var import_undici = __toESM(require_undici()); // src/repository.ts +function isRepositoryNwoStr(val) { + return val.includes("/"); +} function getRepositoryNwo() { return getRepositoryNwoFromEnv("GITHUB_REPOSITORY"); } @@ -175669,7 +175672,15 @@ function getCodeQLActionRepository(action) { ); return CODEQL_DEFAULT_ACTION_REPOSITORY; } - return action.env.getRequired("GITHUB_ACTION_REPOSITORY" /* GITHUB_ACTION_REPOSITORY */); + const actionRepository = action.env.getRequired( + "GITHUB_ACTION_REPOSITORY" /* GITHUB_ACTION_REPOSITORY */ + ); + if (isRepositoryNwoStr(actionRepository)) { + return actionRepository; + } + throw new Error( + `The value of '${"GITHUB_ACTION_REPOSITORY" /* GITHUB_ACTION_REPOSITORY */}' is '${actionRepository}', which does not match the expected 'owner/repo' format.` + ); } var DEFAULT_DOWNLOAD_SOURCE = [ GITHUB_DOTCOM_URL, diff --git a/src/repository.ts b/src/repository.ts index f1e7f369bc..652521fe33 100644 --- a/src/repository.ts +++ b/src/repository.ts @@ -6,6 +6,14 @@ export interface RepositoryNwo { repo: string; } +/** An approximation of what a repository NWO string looks like. */ +export type RepositoryNwoStr = `${string}/${string}`; + +/** A basic check that `val` looks like a `RepositoryNwoStr`. */ +export function isRepositoryNwoStr(val: string): val is RepositoryNwoStr { + return val.includes("/"); +} + /** * Get the repository name with owner from the environment variable * `GITHUB_REPOSITORY`. diff --git a/src/setup/repository.ts b/src/setup/repository.ts index 3d760858e7..98165ea306 100644 --- a/src/setup/repository.ts +++ b/src/setup/repository.ts @@ -2,6 +2,7 @@ import { ActionState } from "../action-common"; import { isRunningLocalAction } from "../actions-util"; import * as api from "../api-client"; import { ActionsEnvVars } from "../environment"; +import { isRepositoryNwoStr, type RepositoryNwoStr } from "../repository"; import { GITHUB_DOTCOM_URL } from "../util"; /** The NWO of the standard CodeQL Action repository. */ @@ -17,7 +18,7 @@ export const CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action"; */ export function getCodeQLActionRepository( action: ActionState<["ReadOnlyEnv", "Logger"]>, -): string { +): RepositoryNwoStr { if (isRunningLocalAction(action.env)) { // This handles the case where the Action does not come from an Action repository, // e.g. our integration tests which use the Action code from the current checkout. @@ -28,11 +29,21 @@ export function getCodeQLActionRepository( return CODEQL_DEFAULT_ACTION_REPOSITORY; } - return action.env.getRequired(ActionsEnvVars.GITHUB_ACTION_REPOSITORY); + const actionRepository = action.env.getRequired( + ActionsEnvVars.GITHUB_ACTION_REPOSITORY, + ); + + if (isRepositoryNwoStr(actionRepository)) { + return actionRepository; + } + + throw new Error( + `The value of '${ActionsEnvVars.GITHUB_ACTION_REPOSITORY}' is '${actionRepository}', which does not match the expected 'owner/repo' format.`, + ); } /**A download source is a pair of strings. */ -export type DownloadSource = [string, string]; +export type DownloadSource = [string, RepositoryNwoStr]; /** GitHub.com, and the canonical Action. */ export const DEFAULT_DOWNLOAD_SOURCE: DownloadSource = [ @@ -88,7 +99,7 @@ export async function getCodeQLAssetDownloadURL( ): Promise { const codeQLActionRepository = getCodeQLActionRepository(action); - const potentialDownloadSources: Array<[string, string]> = [ + const potentialDownloadSources: Array<[string, RepositoryNwoStr]> = [ // This GitHub instance, and this Action. [apiDetails.url, codeQLActionRepository], // This GitHub instance, and the canonical Action. From 1a92e13c5e077a3c134060c2c5042760c9d9ae42 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 15:28:08 +0100 Subject: [PATCH 070/107] Use `GITHUB_DOTCOM_URL` in `getDefaultDotComDownloadURL` --- lib/entry-points.js | 2 +- src/setup/repository.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 99b2b4fc2c..507d2ddf54 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -175690,7 +175690,7 @@ var isSameDownloadSource = ([srcUrl, srcRepo], [otherUrl, otherRepo]) => { return srcUrl === otherUrl && srcRepo === otherRepo; }; function getDefaultDotComDownloadURL(tagName, assetName) { - return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${assetName}`; + return `${GITHUB_DOTCOM_URL}/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${assetName}`; } async function getCodeQLAssetDownloadURL(action, apiDetails, tagName, assetName, assetKind = "CodeQL bundle") { const codeQLActionRepository = getCodeQLActionRepository(action); diff --git a/src/setup/repository.ts b/src/setup/repository.ts index 98165ea306..0cdfaa1738 100644 --- a/src/setup/repository.ts +++ b/src/setup/repository.ts @@ -67,7 +67,7 @@ export function getDefaultDotComDownloadURL( tagName: string, assetName: string, ): DownloadURL { - return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${assetName}`; + return `${GITHUB_DOTCOM_URL}/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${assetName}`; } /** Enumerates log-friendly descriptions of different kinds of assets we might look for in releases. */ From e93db40ccef689468ceaf388bd289a07b47c052d Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 15:28:55 +0100 Subject: [PATCH 071/107] Use "asset" in comment --- src/setup/repository.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/setup/repository.ts b/src/setup/repository.ts index 0cdfaa1738..004beb1dc1 100644 --- a/src/setup/repository.ts +++ b/src/setup/repository.ts @@ -119,7 +119,7 @@ export async function getCodeQLAssetDownloadURL( ); for (const [apiURL, repository] of uniqueDownloadSources) { - // If we've reached the final case, short-circuit the API check since we know the bundle exists and is public. + // If we've reached the final case, short-circuit the API check since we know the asset exists and is public. if (isSameDownloadSource(DEFAULT_DOWNLOAD_SOURCE, [apiURL, repository])) { break; } From fdc069b4ec7f588ddf76a7e600213d2112842d04 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 15:29:50 +0100 Subject: [PATCH 072/107] Use `DownloadSource` for `potentialDownloadSources` --- src/setup/repository.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/setup/repository.ts b/src/setup/repository.ts index 004beb1dc1..f4e69797ec 100644 --- a/src/setup/repository.ts +++ b/src/setup/repository.ts @@ -99,7 +99,7 @@ export async function getCodeQLAssetDownloadURL( ): Promise { const codeQLActionRepository = getCodeQLActionRepository(action); - const potentialDownloadSources: Array<[string, RepositoryNwoStr]> = [ + const potentialDownloadSources: DownloadSource[] = [ // This GitHub instance, and this Action. [apiDetails.url, codeQLActionRepository], // This GitHub instance, and the canonical Action. From 06bd6e2f9d18767c683a39083f38deaa106e46ce Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 15:31:11 +0100 Subject: [PATCH 073/107] `DotCom` => `Dotcom` --- lib/entry-points.js | 4 ++-- src/setup/repository.ts | 4 ++-- src/start-proxy.test.ts | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 507d2ddf54..a6e80b84ea 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -175689,7 +175689,7 @@ var DEFAULT_DOWNLOAD_SOURCE = [ var isSameDownloadSource = ([srcUrl, srcRepo], [otherUrl, otherRepo]) => { return srcUrl === otherUrl && srcRepo === otherRepo; }; -function getDefaultDotComDownloadURL(tagName, assetName) { +function getDefaultDotcomDownloadURL(tagName, assetName) { return `${GITHUB_DOTCOM_URL}/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${tagName}/${assetName}`; } async function getCodeQLAssetDownloadURL(action, apiDetails, tagName, assetName, assetKind = "CodeQL bundle") { @@ -175732,7 +175732,7 @@ async function getCodeQLAssetDownloadURL(action, apiDetails, tagName, assetName, ); } } - return getDefaultDotComDownloadURL(tagName, assetName); + return getDefaultDotcomDownloadURL(tagName, assetName); } // src/tar.ts diff --git a/src/setup/repository.ts b/src/setup/repository.ts index f4e69797ec..636787024d 100644 --- a/src/setup/repository.ts +++ b/src/setup/repository.ts @@ -63,7 +63,7 @@ const isSameDownloadSource = ( export type DownloadURL = string; /** Gets the default GitHub.com download URL for `assetName` in a release tagged `tagName`. */ -export function getDefaultDotComDownloadURL( +export function getDefaultDotcomDownloadURL( tagName: string, assetName: string, ): DownloadURL { @@ -147,5 +147,5 @@ export async function getCodeQLAssetDownloadURL( } } - return getDefaultDotComDownloadURL(tagName, assetName); + return getDefaultDotcomDownloadURL(tagName, assetName); } diff --git a/src/start-proxy.test.ts b/src/start-proxy.test.ts index b0bdd7bd33..ed2007fe61 100644 --- a/src/start-proxy.test.ts +++ b/src/start-proxy.test.ts @@ -780,7 +780,7 @@ test.serial( t.is(info.version, defaults.cliVersion); t.is( info.url, - repository.getDefaultDotComDownloadURL( + repository.getDefaultDotcomDownloadURL( defaults.bundleVersion, startProxyExports.getProxyPackage(BundlePlatform.Linux64), ), @@ -810,7 +810,7 @@ test.serial( t.is(info.version, defaults.cliVersion); t.is( info.url, - repository.getDefaultDotComDownloadURL( + repository.getDefaultDotcomDownloadURL( defaults.bundleVersion, startProxyExports.getProxyPackage(getTestPlatform(state)), ), @@ -842,7 +842,7 @@ test.serial( t.is(info.version, defaults.cliVersion); t.is( info.url, - repository.getDefaultDotComDownloadURL( + repository.getDefaultDotcomDownloadURL( defaults.bundleVersion, startProxyExports.getProxyPackage(getTestPlatform(state)), ), From 3d7016f5140155c81cbea404bdd435836d97ae56 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 15:39:38 +0100 Subject: [PATCH 074/107] Log more in `getProxyBinaryPath` --- lib/entry-points.js | 47 +++++++++++++++++++++++++-------------- src/start-proxy.ts | 54 +++++++++++++++++++++++++++++++-------------- 2 files changed, 67 insertions(+), 34 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index a6e80b84ea..a2951f159c 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -187759,25 +187759,38 @@ function getProxyFilename() { } async function getProxyBinaryPath(action, apiDetails) { const logger2 = action.logger; - const proxyFileName = getProxyFilename(); - const proxyInfo = await getDownloadUrl(action, apiDetails); - let proxyBin = toolcache4.find(proxyFileName, proxyInfo.version); - if (!proxyBin) { - const authorization = getAuthorizationHeaderFor( - logger2, - apiDetails, - proxyInfo.url - ); - const temp = await downloadProxy(logger2, proxyInfo.url, authorization); - const extracted = await extractProxy(logger2, temp); - proxyBin = await cacheProxy( - logger2, - extracted, - proxyFileName, - proxyInfo.version + logger2.startGroup("Setting up authentication proxy"); + try { + const proxyFileName = getProxyFilename(); + const proxyInfo = await getDownloadUrl(action, apiDetails); + logger2.info( + `Using authentication proxy from CodeQL release ${proxyInfo.version}.` ); + let proxyBin = toolcache4.find(proxyFileName, proxyInfo.version); + if (!proxyBin) { + logger2.info( + `Authentication proxy is not in the toolcache. Will try to download it from '${proxyInfo.url}'.` + ); + const authorization = getAuthorizationHeaderFor( + logger2, + apiDetails, + proxyInfo.url + ); + const temp = await downloadProxy(logger2, proxyInfo.url, authorization); + logger2.info(`Downloaded the authentication proxy assset to '${temp}'.`); + const extracted = await extractProxy(logger2, temp); + proxyBin = await cacheProxy( + logger2, + extracted, + proxyFileName, + proxyInfo.version + ); + logger2.info(`Extracted the authentication proxy to '${proxyBin}'.`); + } + return path27.join(proxyBin, proxyFileName); + } finally { + logger2.endGroup(); } - return path27.join(proxyBin, proxyFileName); } // src/start-proxy/ca.ts diff --git a/src/start-proxy.ts b/src/start-proxy.ts index 9558b119ee..ca2f5c2b5b 100644 --- a/src/start-proxy.ts +++ b/src/start-proxy.ts @@ -537,24 +537,44 @@ export async function getProxyBinaryPath( apiDetails: GitHubApiDetails, ): Promise { const logger = action.logger; - const proxyFileName = getProxyFilename(); - const proxyInfo = await getDownloadUrl(action, apiDetails); + logger.startGroup("Setting up authentication proxy"); - let proxyBin = toolcache.find(proxyFileName, proxyInfo.version); - if (!proxyBin) { - const authorization = getAuthorizationHeaderFor( - logger, - apiDetails, - proxyInfo.url, - ); - const temp = await downloadProxy(logger, proxyInfo.url, authorization); - const extracted = await extractProxy(logger, temp); - proxyBin = await cacheProxy( - logger, - extracted, - proxyFileName, - proxyInfo.version, + try { + const proxyFileName = getProxyFilename(); + const proxyInfo = await getDownloadUrl(action, apiDetails); + + logger.info( + `Using authentication proxy from CodeQL release ${proxyInfo.version}.`, ); + + let proxyBin = toolcache.find(proxyFileName, proxyInfo.version); + + if (!proxyBin) { + logger.info( + `Authentication proxy is not in the toolcache. Will try to download it from '${proxyInfo.url}'.`, + ); + + const authorization = getAuthorizationHeaderFor( + logger, + apiDetails, + proxyInfo.url, + ); + const temp = await downloadProxy(logger, proxyInfo.url, authorization); + + logger.info(`Downloaded the authentication proxy assset to '${temp}'.`); + + const extracted = await extractProxy(logger, temp); + proxyBin = await cacheProxy( + logger, + extracted, + proxyFileName, + proxyInfo.version, + ); + + logger.info(`Extracted the authentication proxy to '${proxyBin}'.`); + } + return path.join(proxyBin, proxyFileName); + } finally { + logger.endGroup(); } - return path.join(proxyBin, proxyFileName); } From dd3898ae5842543c91979b8a9b9b3f47bfdee874 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 15:40:20 +0100 Subject: [PATCH 075/107] Await `toolcache.downloadTool` --- lib/entry-points.js | 2 +- src/start-proxy.ts | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index a2951f159c..f22ad311fc 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -187718,7 +187718,7 @@ async function getDownloadUrl(action, apiDetails) { } async function downloadProxy(logger2, url2, authorization) { try { - return toolcache4.downloadTool( + return await toolcache4.downloadTool( url2, /* dest: */ void 0, diff --git a/src/start-proxy.ts b/src/start-proxy.ts index ca2f5c2b5b..21a5012f12 100644 --- a/src/start-proxy.ts +++ b/src/start-proxy.ts @@ -461,9 +461,14 @@ export async function downloadProxy( try { // Download the proxy archive from `url`. We let `downloadTool` choose where // to store it. The path to the downloaded file will be returned if successful. - return toolcache.downloadTool(url, /* dest: */ undefined, authorization, { - accept: "application/octet-stream", - }); + return await toolcache.downloadTool( + url, + /* dest: */ undefined, + authorization, + { + accept: "application/octet-stream", + }, + ); } catch (error) { logger.error( `Failed to download proxy archive from ${url}: ${getErrorMessage(error)}`, From ac44fd090137600c00845d6ea3297cda7fefdad7 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 15:41:25 +0100 Subject: [PATCH 076/107] Remove duplicated assertions --- src/start-proxy.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/start-proxy.test.ts b/src/start-proxy.test.ts index ed2007fe61..b8de01c07e 100644 --- a/src/start-proxy.test.ts +++ b/src/start-proxy.test.ts @@ -1079,8 +1079,6 @@ test.serial( st.onceWith(extractTar, archivePath); st.onceWith(cacheDir, extractedPath); - t.assert(extractTar.calledOnceWith(archivePath)); - t.assert(cacheDir.calledOnceWith(extractedPath)); t.assert(path); t.is( path, From a1794a03ffd7b772215b9612f0024299630d2c6c Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 15:45:21 +0100 Subject: [PATCH 077/107] Fix `mockGetReleaseByTag` usage --- src/start-proxy.test.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/start-proxy.test.ts b/src/start-proxy.test.ts index b8de01c07e..d01543e709 100644 --- a/src/start-proxy.test.ts +++ b/src/start-proxy.test.ts @@ -729,7 +729,10 @@ function mockGetReleaseByTag(expectedTag?: string, assets?: ReleaseAssets) { } }); - return mockGetApiClient({ repos: { getReleaseByTag } }); + return { + getReleaseByTag, + getApiClient: mockGetApiClient({ repos: { getReleaseByTag } }), + }; } function mockOfflineFeatures(tempDir: string, logger: Logger) { @@ -833,7 +836,7 @@ test.serial( sinon.stub(actionsUtil, "isRunningLocalAction").returns(true); for (const assets of testAssets) { - const stub = mockGetReleaseByTag(defaults.bundleVersion, assets); + const stubs = mockGetReleaseByTag(defaults.bundleVersion, assets); const info = await startProxyExports.getDownloadUrl( state, SAMPLE_DOTCOM_API_DETAILS, @@ -848,7 +851,9 @@ test.serial( ), ); - stub.restore(); + // mockGetReleaseByTag stubs the global getApiClient; since we are calling + // that in a loop, we need to manually restore it here + stubs.getApiClient.restore(); } }); }, @@ -864,7 +869,7 @@ test.serial("getDownloadUrl returns matching release asset", async (t) => { url: "url-we-want", }, ]; - const getReleaseByTag = mockGetReleaseByTag(defaults.bundleVersion, assets); + const stubs = mockGetReleaseByTag(defaults.bundleVersion, assets); await withTmpDir(async (tempDir) => { state.env.set(ActionsEnvVars.RUNNER_TEMP, tempDir); @@ -879,7 +884,7 @@ test.serial("getDownloadUrl returns matching release asset", async (t) => { SAMPLE_DOTCOM_API_DETAILS, ); - t.is(getReleaseByTag.callCount, 1); + t.is(stubs.getReleaseByTag.callCount, 1); t.is(info.version, defaults.cliVersion); t.is(info.url, "url-we-want"); @@ -1036,7 +1041,7 @@ test.serial( const logger = new RecordingLogger(); const state = initAllState({ logger }); const downloadUrl = "url-we-want"; - const getApiClient = mockGetReleaseByTag(defaults.bundleVersion, [ + const stubs = mockGetReleaseByTag(defaults.bundleVersion, [ { name: startProxyExports.getProxyPackage(getTestPlatform(state)), url: downloadUrl, @@ -1070,7 +1075,7 @@ test.serial( SAMPLE_DOTCOM_API_DETAILS, ); - t.is(getApiClient.callCount, 1); + t.is(stubs.getReleaseByTag.callCount, 1); t.assert(find.calledOnce); t.assert(getAuthorizationHeaderFor.calledOnce); From 8fed29eed7c56f2ad5ff4886a0b5bac4a7d60868 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 15:47:52 +0100 Subject: [PATCH 078/107] Rename `apiURL` to `instanceURL` --- lib/entry-points.js | 8 ++++---- src/setup/repository.ts | 10 ++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index f22ad311fc..6e080eaa5d 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -175707,8 +175707,8 @@ async function getCodeQLAssetDownloadURL(action, apiDetails, tagName, assetName, return !self2.slice(0, index2).some((other) => isSameDownloadSource(source, other)); } ); - for (const [apiURL, repository] of uniqueDownloadSources) { - if (isSameDownloadSource(DEFAULT_DOWNLOAD_SOURCE, [apiURL, repository])) { + for (const [instanceURL, repository] of uniqueDownloadSources) { + if (isSameDownloadSource(DEFAULT_DOWNLOAD_SOURCE, [instanceURL, repository])) { break; } const [repositoryOwner, repositoryName] = repository.split("/"); @@ -175721,14 +175721,14 @@ async function getCodeQLAssetDownloadURL(action, apiDetails, tagName, assetName, for (const asset of release2.data.assets) { if (asset.name === assetName) { action.logger.info( - `Found ${assetKind} ${assetName} in ${repository} on ${apiURL} with URL ${asset.url}.` + `Found ${assetKind} ${assetName} in ${repository} on ${instanceURL} with URL ${asset.url}.` ); return asset.url; } } } catch (e) { action.logger.info( - `Looked for ${assetKind} ${assetName} in ${repository} on ${apiURL} but got error ${e}.` + `Looked for ${assetKind} ${assetName} in ${repository} on ${instanceURL} but got error ${e}.` ); } } diff --git a/src/setup/repository.ts b/src/setup/repository.ts index 636787024d..2e53872974 100644 --- a/src/setup/repository.ts +++ b/src/setup/repository.ts @@ -118,9 +118,11 @@ export async function getCodeQLAssetDownloadURL( }, ); - for (const [apiURL, repository] of uniqueDownloadSources) { + for (const [instanceURL, repository] of uniqueDownloadSources) { // If we've reached the final case, short-circuit the API check since we know the asset exists and is public. - if (isSameDownloadSource(DEFAULT_DOWNLOAD_SOURCE, [apiURL, repository])) { + if ( + isSameDownloadSource(DEFAULT_DOWNLOAD_SOURCE, [instanceURL, repository]) + ) { break; } @@ -135,14 +137,14 @@ export async function getCodeQLAssetDownloadURL( for (const asset of release.data.assets) { if (asset.name === assetName) { action.logger.info( - `Found ${assetKind} ${assetName} in ${repository} on ${apiURL} with URL ${asset.url}.`, + `Found ${assetKind} ${assetName} in ${repository} on ${instanceURL} with URL ${asset.url}.`, ); return asset.url; } } } catch (e) { action.logger.info( - `Looked for ${assetKind} ${assetName} in ${repository} on ${apiURL} but got error ${e}.`, + `Looked for ${assetKind} ${assetName} in ${repository} on ${instanceURL} but got error ${e}.`, ); } } From 5aa103d050a3985a691d3cb0c4d2f1055d523cd1 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 15:52:22 +0100 Subject: [PATCH 079/107] Add `InstanceURL` and use in `DownloadSource` --- src/setup/repository.ts | 4 ++-- src/util.ts | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/setup/repository.ts b/src/setup/repository.ts index 2e53872974..959ca4b8d7 100644 --- a/src/setup/repository.ts +++ b/src/setup/repository.ts @@ -3,7 +3,7 @@ import { isRunningLocalAction } from "../actions-util"; import * as api from "../api-client"; import { ActionsEnvVars } from "../environment"; import { isRepositoryNwoStr, type RepositoryNwoStr } from "../repository"; -import { GITHUB_DOTCOM_URL } from "../util"; +import { GITHUB_DOTCOM_URL, type InstanceURL } from "../util"; /** The NWO of the standard CodeQL Action repository. */ export const CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action"; @@ -43,7 +43,7 @@ export function getCodeQLActionRepository( } /**A download source is a pair of strings. */ -export type DownloadSource = [string, RepositoryNwoStr]; +export type DownloadSource = [InstanceURL, RepositoryNwoStr]; /** GitHub.com, and the canonical Action. */ export const DEFAULT_DOWNLOAD_SOURCE: DownloadSource = [ diff --git a/src/util.ts b/src/util.ts index 3a42d8b945..0b10e0f043 100644 --- a/src/util.ts +++ b/src/util.ts @@ -46,10 +46,13 @@ const BASE_DATABASE_OIDS_FILE_NAME = "base-database-oids.json"; */ const BROKEN_VERSIONS = ["0.0.0-20211207"]; +/** A string representing a GitHub instance. */ +export type InstanceURL = string; + /** * The URL for github.com. */ -export const GITHUB_DOTCOM_URL = "https://github.com"; +export const GITHUB_DOTCOM_URL: InstanceURL = "https://github.com"; /** * Default name of the debugging artifact. From bed4cc0475d6e30e9748893fe473bf1f7a50ecad Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 22:39:08 +0100 Subject: [PATCH 080/107] Add log message for `!config.dbLocation` case --- lib/entry-points.js | 4 ++++ src/init-action-post-helper.ts | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/lib/entry-points.js b/lib/entry-points.js index 44d94d1e08..ece461a1ff 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -187002,6 +187002,10 @@ async function uploadFailureInfo(uploadAllAvailableDebugArtifacts, printDebugLog `Failed to clean up database cluster directory ${config.dbLocation}. Details: ${e}` ); } + } else if (config.dbLocation === void 0) { + logger2.debug( + "Skipping cleanup of database cluster directory since the configuration does not include a database path." + ); } else { logger2.debug( "Skipping cleanup of database cluster directory since we are running on a GitHub-hosted runner which will be automatically cleaned up." diff --git a/src/init-action-post-helper.ts b/src/init-action-post-helper.ts index 270bc0f079..3d3ffc5703 100644 --- a/src/init-action-post-helper.ts +++ b/src/init-action-post-helper.ts @@ -410,6 +410,10 @@ export async function uploadFailureInfo( `Failed to clean up database cluster directory ${config.dbLocation}. Details: ${e}`, ); } + } else if (config.dbLocation === undefined) { + logger.debug( + "Skipping cleanup of database cluster directory since the configuration does not include a database path.", + ); } else { logger.debug( "Skipping cleanup of database cluster directory since we are running on a GitHub-hosted " + From be78e02f2d2944ae3e88a618a0ef431e6a2125ce Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 22:39:34 +0100 Subject: [PATCH 081/107] Fix comment --- src/config-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config-utils.ts b/src/config-utils.ts index 107f666661..fea7bec018 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -1392,7 +1392,7 @@ function getPathToFailedConfigFile(tempDir: string): string { * Writes {@link config} to {@link configFilePath}. * * This function is not intended to be called, other than by - * {@link saveConfig} and {@link saveFailedConfig} below. + * {@link saveConfig} and {@link saveAbortedInitConfig} below. */ function saveConfigFile( logger: Logger, From e3aeabd8f1a1a8f097f23b77f7b92b3355f35b38 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 22:40:25 +0100 Subject: [PATCH 082/107] Fix example in comment --- src/config/action-config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/action-config.ts b/src/config/action-config.ts index 110b3665a7..10f315028f 100644 --- a/src/config/action-config.ts +++ b/src/config/action-config.ts @@ -136,7 +136,7 @@ export type ActionConfigProperties = keyof Config; * * By default, this is equivalent to `Config`. By explicitly * providing required property names for `T` this can be restricted - * to requiring only those. For example, in `ActionConfig<"codeqlCmd">` + * to requiring only those. For example, in `ActionConfig<"codeQLCmd">` * all properties except `codeqlCmd` are optional. */ export type ActionConfig< From 26c6f91e6be5ab02622aad5c9776f7d5924d4147 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 22:42:38 +0100 Subject: [PATCH 083/107] Throw if aborted config functions are called incorrectly --- lib/entry-points.js | 8 ++++++-- src/config-utils.ts | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index ece461a1ff..3c5ee3bd27 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -175082,7 +175082,9 @@ async function saveConfig(config, logger2) { } function saveAbortedInitConfig(action, config) { if (action.name !== "init" /* Init */) { - return; + throw new Error( + `Internal error: 'saveAbortedInitConfig' should only be called by '${"init" /* Init */}', but was called by '${action.name}'.` + ); } const failedConfig = { version: config.version, @@ -175131,7 +175133,9 @@ async function getConfig(tempDir, logger2) { } function getAbortedInitConfig(action, tempDir) { if (action.name !== "init-post" /* InitPost */) { - return void 0; + throw new Error( + `Internal error: 'getAbortedInitConfig' should only be called by '${"init-post" /* InitPost */}', but was called by '${action.name}'.` + ); } return readConfigFile(action.logger, getPathToFailedConfigFile(tempDir)); } diff --git a/src/config-utils.ts b/src/config-utils.ts index fea7bec018..e0b005db78 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -1426,7 +1426,9 @@ export function saveAbortedInitConfig( ) { // Should only be called by init. if (action.name !== ActionName.Init) { - return; + throw new Error( + `Internal error: 'saveAbortedInitConfig' should only be called by '${ActionName.Init}', but was called by '${action.name}'.`, + ); } // Create a copy of the input `Config` that only contains the keys we want. @@ -1510,7 +1512,9 @@ export function getAbortedInitConfig( ): AbortedInitConfig | undefined { // Only intended to be called by the `init-post` action. if (action.name !== ActionName.InitPost) { - return undefined; + throw new Error( + `Internal error: 'getAbortedInitConfig' should only be called by '${ActionName.InitPost}', but was called by '${action.name}'.`, + ); } return readConfigFile(action.logger, getPathToFailedConfigFile(tempDir)); From 67f44bc916315c958f56c99b58ba434c49ec215d Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 22:48:21 +0100 Subject: [PATCH 084/107] Use `Logger` for `printDebugLogs` and log when returning early --- lib/entry-points.js | 41 ++++++++++++++++++---------------- src/actions-util.test.ts | 12 +++++----- src/actions-util.ts | 15 ++++++++----- src/init-action-post-helper.ts | 4 ++-- 4 files changed, 40 insertions(+), 32 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 3c5ee3bd27..6003234204 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -21656,8 +21656,8 @@ var require_core = __commonJS({ exports2.warning = warning14; exports2.notice = notice; exports2.info = info8; - exports2.startGroup = startGroup4; - exports2.endGroup = endGroup4; + exports2.startGroup = startGroup3; + exports2.endGroup = endGroup3; exports2.group = group; exports2.saveState = saveState3; exports2.getState = getState3; @@ -21755,20 +21755,20 @@ Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); function info8(message) { process.stdout.write(message + os7.EOL); } - function startGroup4(name) { + function startGroup3(name) { (0, command_1.issue)("group", name); } - function endGroup4() { + function endGroup3() { (0, command_1.issue)("endgroup"); } function group(name, fn) { return __awaiter2(this, void 0, void 0, function* () { - startGroup4(name); + startGroup3(name); let result; try { result = yield fn(); } finally { - endGroup4(); + endGroup3(); } return result; }); @@ -145686,22 +145686,22 @@ Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); process.stdout.write(message + os7.EOL); } exports2.info = info8; - function startGroup4(name) { + function startGroup3(name) { (0, command_1.issue)("group", name); } - exports2.startGroup = startGroup4; - function endGroup4() { + exports2.startGroup = startGroup3; + function endGroup3() { (0, command_1.issue)("endgroup"); } - exports2.endGroup = endGroup4; + exports2.endGroup = endGroup3; function group(name, fn) { return __awaiter2(this, void 0, void 0, function* () { - startGroup4(name); + startGroup3(name); let result; try { result = yield fn(); } finally { - endGroup4(); + endGroup3(); } return result; }); @@ -170212,30 +170212,33 @@ function getWorkflowEvent(env = getEnv()) { ); } } -async function printDebugLogs(config) { +async function printDebugLogs(logger2, config) { if (!hasConfigKey(config, "languages") || !hasConfigKey(config, "dbLocation")) { + logger2.debug( + `Not printing debug logs, because the configuration does not include the 'languages' or 'dbLocation' fields.` + ); return; } for (const language of config.languages) { const databaseDirectory = getCodeQLDatabasePath(config, language); const logsDirectory = path2.join(databaseDirectory, "log"); if (!doesDirectoryExist(logsDirectory)) { - core4.info(`Directory ${logsDirectory} does not exist.`); + logger2.info(`Directory ${logsDirectory} does not exist.`); continue; } const walkLogFiles = (dir) => { const entries = fs2.readdirSync(dir, { withFileTypes: true }); if (entries.length === 0) { - core4.info(`No debug logs found at directory ${logsDirectory}.`); + logger2.info(`No debug logs found at directory ${logsDirectory}.`); } for (const entry of entries) { if (entry.isFile()) { const absolutePath = path2.resolve(dir, entry.name); - core4.startGroup( + logger2.startGroup( `CodeQL Debug Logs - ${language} - ${entry.name} from file at path ${absolutePath}` ); - process.stdout.write(fs2.readFileSync(absolutePath)); - core4.endGroup(); + logger2.info(fs2.readFileSync(absolutePath, "utf-8")); + logger2.endGroup(); } else if (entry.isDirectory()) { walkLogFiles(path2.resolve(dir, entry.name)); } @@ -186989,7 +186992,7 @@ async function uploadFailureInfo(uploadAllAvailableDebugArtifacts, printDebugLog "Debug mode is on. Uploading available database bundles and logs as Actions debugging artifacts..." ); await uploadAllAvailableDebugArtifacts(codeql, config, logger2); - await printDebugLogs2(config); + await printDebugLogs2(logger2, config); } if (isSelfHostedRunner() && config.dbLocation) { try { diff --git a/src/actions-util.test.ts b/src/actions-util.test.ts index 1217e831a0..17cf96a4a5 100644 --- a/src/actions-util.test.ts +++ b/src/actions-util.test.ts @@ -12,7 +12,7 @@ import { import { computeAutomationID } from "./api-client"; import { EnvVar } from "./environment"; import { getRunnerLogger } from "./logging"; -import { setupTests } from "./testing-utils"; +import { RecordingLogger, setupTests } from "./testing-utils"; import { initializeEnvironment, withTmpDir } from "./util"; setupTests(test); @@ -102,15 +102,17 @@ test("computeAutomationID()", async (t) => { }); test("printDebugLogs - doesn't throw when config doesn't have needed properties", async (t) => { - await t.notThrowsAsync(printDebugLogs({})); - await t.notThrowsAsync(printDebugLogs({ languages: [] })); - await t.notThrowsAsync(printDebugLogs({ dbLocation: "nowhere" })); + const logger = new RecordingLogger(); + await t.notThrowsAsync(printDebugLogs(logger, {})); + await t.notThrowsAsync(printDebugLogs(logger, { languages: [] })); + await t.notThrowsAsync(printDebugLogs(logger, { dbLocation: "nowhere" })); }); test("printDebugLogs - doesn't throw when language db doesn't exist", async (t) => withTmpDir(async (tmpDir) => { + const logger = new RecordingLogger(); await t.notThrowsAsync( - printDebugLogs({ dbLocation: tmpDir, languages: ["javascript"] }), + printDebugLogs(logger, { dbLocation: tmpDir, languages: ["javascript"] }), ); })); diff --git a/src/actions-util.ts b/src/actions-util.ts index e43abbb0b9..62ab42440c 100644 --- a/src/actions-util.ts +++ b/src/actions-util.ts @@ -131,11 +131,14 @@ export function getWorkflowEvent(env: Env = getEnv()): any { } } -export async function printDebugLogs(config: Partial) { +export async function printDebugLogs(logger: Logger, config: Partial) { if ( !hasConfigKey(config, "languages") || !hasConfigKey(config, "dbLocation") ) { + logger.debug( + `Not printing debug logs, because the configuration does not include the 'languages' or 'dbLocation' fields.`, + ); return; } @@ -143,23 +146,23 @@ export async function printDebugLogs(config: Partial) { const databaseDirectory = getCodeQLDatabasePath(config, language); const logsDirectory = path.join(databaseDirectory, "log"); if (!doesDirectoryExist(logsDirectory)) { - core.info(`Directory ${logsDirectory} does not exist.`); + logger.info(`Directory ${logsDirectory} does not exist.`); continue; // Skip this language database. } const walkLogFiles = (dir: string) => { const entries = fs.readdirSync(dir, { withFileTypes: true }); if (entries.length === 0) { - core.info(`No debug logs found at directory ${logsDirectory}.`); + logger.info(`No debug logs found at directory ${logsDirectory}.`); } for (const entry of entries) { if (entry.isFile()) { const absolutePath = path.resolve(dir, entry.name); - core.startGroup( + logger.startGroup( `CodeQL Debug Logs - ${language} - ${entry.name} from file at path ${absolutePath}`, ); - process.stdout.write(fs.readFileSync(absolutePath)); - core.endGroup(); + logger.info(fs.readFileSync(absolutePath, "utf-8")); + logger.endGroup(); } else if (entry.isDirectory()) { walkLogFiles(path.resolve(dir, entry.name)); } diff --git a/src/init-action-post-helper.ts b/src/init-action-post-helper.ts index 3d3ffc5703..e9ebf93a3a 100644 --- a/src/init-action-post-helper.ts +++ b/src/init-action-post-helper.ts @@ -338,7 +338,7 @@ export async function uploadFailureInfo( config: UploadDebugArtifactsConfig, logger: Logger, ) => Promise, - printDebugLogs: (config: Partial) => Promise, + printDebugLogs: (logger: Logger, config: Partial) => Promise, codeql: CodeQL, config: Config | AbortedInitConfig, repositoryNwo: RepositoryNwo, @@ -392,7 +392,7 @@ export async function uploadFailureInfo( "Debug mode is on. Uploading available database bundles and logs as Actions debugging artifacts...", ); await uploadAllAvailableDebugArtifacts(codeql, config, logger); - await printDebugLogs(config); + await printDebugLogs(logger, config); } if (actionsUtil.isSelfHostedRunner() && config.dbLocation) { From 6a9f7e7fc3ed89bafa53a68079075ba34a2043f8 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 22:50:11 +0100 Subject: [PATCH 085/107] Log if returning early from `recordOverlayStatus` due to no languages --- lib/entry-points.js | 7 ++++++- src/init-action-post-helper.ts | 8 ++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 6003234204..8424aef54c 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -187034,7 +187034,12 @@ function isConclusiveJobStatus(jobStatus) { } } async function recordOverlayStatus(codeql, config, features, jobStatus, env, logger2) { - if (config.overlayDatabaseMode !== "overlay-base" /* OverlayBase */ || env.getOptional("CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */) === "true" || !await features.getValue("overlay_analysis_status_save" /* OverlayAnalysisStatusSave */) || config.languages === void 0) { + if (config.overlayDatabaseMode !== "overlay-base" /* OverlayBase */ || env.getOptional("CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY" /* ANALYZE_DID_COMPLETE_SUCCESSFULLY */) === "true" || !await features.getValue("overlay_analysis_status_save" /* OverlayAnalysisStatusSave */)) { + return; + } else if (config.languages === void 0) { + logger2.debug( + "Not recording overlay status, because the configuration contains no 'languages'." + ); return; } if (!isConclusiveJobStatus(jobStatus) && !didCodeQlReportError(env)) { diff --git a/src/init-action-post-helper.ts b/src/init-action-post-helper.ts index e9ebf93a3a..b6aeb5bd34 100644 --- a/src/init-action-post-helper.ts +++ b/src/init-action-post-helper.ts @@ -471,10 +471,14 @@ async function recordOverlayStatus( if ( config.overlayDatabaseMode !== OverlayDatabaseMode.OverlayBase || env.getOptional(EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY) === "true" || - !(await features.getValue(Feature.OverlayAnalysisStatusSave)) || - config.languages === undefined + !(await features.getValue(Feature.OverlayAnalysisStatusSave)) ) { return; + } else if (config.languages === undefined) { + logger.debug( + "Not recording overlay status, because the configuration contains no 'languages'.", + ); + return; } // Only record a failure when the job outcome tells us something about the analysis. A cancelled From 9645acc2ffa222c2ee9640ed957226723f16e74f Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 12 Oct 2026 22:54:47 +0100 Subject: [PATCH 086/107] Revert `config === undefined` condition --- lib/entry-points.js | 2 +- src/init-action-post.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 8424aef54c..373cdedc01 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -187165,7 +187165,7 @@ async function run4(action) { getTemporaryDirectory(), logger2 ); - if (config?.codeQLCmd === void 0) { + if (config === void 0) { logger2.warning( "Debugging artifacts are unavailable since the 'init' Action failed before it could produce any." ); diff --git a/src/init-action-post.ts b/src/init-action-post.ts index dd981c200a..689cfd4659 100644 --- a/src/init-action-post.ts +++ b/src/init-action-post.ts @@ -90,7 +90,7 @@ async function run(action: ActionState<["Base", "Logger", "Env"]>) { logger, ); - if (config?.codeQLCmd === undefined) { + if (config === undefined) { logger.warning( "Debugging artifacts are unavailable since the 'init' Action failed before it could produce any.", ); From b67b5abe29b2f646e6cb9afe110070e2f422b873 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 13 Oct 2026 12:13:59 +0100 Subject: [PATCH 087/107] Use `parseRepositoryNwo` in `getCodeQLAssetDownloadURL` --- lib/entry-points.js | 2 +- src/setup/repository.ts | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 6e080eaa5d..30df46a5b9 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -175711,7 +175711,7 @@ async function getCodeQLAssetDownloadURL(action, apiDetails, tagName, assetName, if (isSameDownloadSource(DEFAULT_DOWNLOAD_SOURCE, [instanceURL, repository])) { break; } - const [repositoryOwner, repositoryName] = repository.split("/"); + const { owner: repositoryOwner, repo: repositoryName } = parseRepositoryNwo(repository); try { const release2 = await getApiClient().rest.repos.getReleaseByTag({ owner: repositoryOwner, diff --git a/src/setup/repository.ts b/src/setup/repository.ts index 959ca4b8d7..6da0ea3e9a 100644 --- a/src/setup/repository.ts +++ b/src/setup/repository.ts @@ -2,7 +2,11 @@ import { ActionState } from "../action-common"; import { isRunningLocalAction } from "../actions-util"; import * as api from "../api-client"; import { ActionsEnvVars } from "../environment"; -import { isRepositoryNwoStr, type RepositoryNwoStr } from "../repository"; +import { + isRepositoryNwoStr, + parseRepositoryNwo, + type RepositoryNwoStr, +} from "../repository"; import { GITHUB_DOTCOM_URL, type InstanceURL } from "../util"; /** The NWO of the standard CodeQL Action repository. */ @@ -126,7 +130,8 @@ export async function getCodeQLAssetDownloadURL( break; } - const [repositoryOwner, repositoryName] = repository.split("/"); + const { owner: repositoryOwner, repo: repositoryName } = + parseRepositoryNwo(repository); try { const release = await api.getApiClient().rest.repos.getReleaseByTag({ owner: repositoryOwner, From aa80ca0686300d00833eb4f65641ac310b892784 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 13 Oct 2026 18:59:11 +0100 Subject: [PATCH 088/107] Move `start-proxy` status report handling into its own file --- lib/entry-points.js | 114 +++++++++++---------- src/start-proxy.test.ts | 88 +--------------- src/start-proxy.ts | 142 +------------------------- src/start-proxy/status-report.test.ts | 94 +++++++++++++++++ src/start-proxy/status-report.ts | 140 +++++++++++++++++++++++++ 5 files changed, 298 insertions(+), 280 deletions(-) create mode 100644 src/start-proxy/status-report.test.ts create mode 100644 src/start-proxy/status-report.ts diff --git a/lib/entry-points.js b/lib/entry-points.js index 373cdedc01..f3d3022b0d 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -187524,50 +187524,27 @@ var core25 = __toESM(require_core()); // src/start-proxy.ts var path27 = __toESM(require("path")); -var core24 = __toESM(require_core()); var toolcache4 = __toESM(require_tool_cache()); -// src/start-proxy/validation.ts +// src/start-proxy/status-report.ts var core23 = __toESM(require_core()); -function cloneCredential(schema, obj) { - const result = {}; - for (const key of Object.keys(schema)) { - if (!isDefined2(obj[key])) { - continue; - } - result[key] = obj[key]; - } - return result; -} -function getAuthConfig(config) { - for (const oidcSchema of oidcSchemas) { - if (validateSchema(oidcSchema.schema, config)) { - return cloneCredential(oidcSchema.schema, config); - } - } - if (isToken(config)) { - if (isDefined2(config.token)) { - core23.setSecret(config.token); - } - return cloneCredential(tokenSchema, config); - } else { - let username = void 0; - let password = void 0; - if ("password" in config && isString(config.password)) { - core23.setSecret(config.password); - password = config.password; - } - if ("username" in config && isString(config.username)) { - username = config.username; - } - return { - username, - password +async function sendSuccessStatusReport(startedAt, config, registry_types, logger2) { + const statusReportBase = await createStatusReportBase( + "start-proxy" /* StartProxy */, + "success", + startedAt, + config, + await checkDiskUsage(logger2), + logger2 + ); + if (statusReportBase !== void 0) { + const statusReport = { + ...statusReportBase, + registry_types: registry_types.join(",") }; + await sendStatusReport(statusReport); } } - -// src/start-proxy.ts function getStartProxyErrorMessage(errorType) { switch (errorType) { case 0 /* DownloadFailed */: @@ -187585,23 +187562,6 @@ var StartProxyError = class extends Error { this.errorType = errorType; } }; -async function sendSuccessStatusReport(startedAt, config, registry_types, logger2) { - const statusReportBase = await createStatusReportBase( - "start-proxy" /* StartProxy */, - "success", - startedAt, - config, - await checkDiskUsage(logger2), - logger2 - ); - if (statusReportBase !== void 0) { - const statusReport = { - ...statusReportBase, - registry_types: registry_types.join(",") - }; - await sendStatusReport(statusReport); - } -} function getSafeErrorMessage(error3) { if (error3 instanceof StartProxyError) { return getStartProxyErrorMessage(error3.errorType); @@ -187610,7 +187570,7 @@ function getSafeErrorMessage(error3) { } async function sendFailedStatusReport(logger2, startedAt, language, unwrappedError) { const error3 = wrapError(unwrappedError); - core24.setFailed(`start-proxy action failed: ${error3.message}`); + core23.setFailed(`start-proxy action failed: ${error3.message}`); const statusReportMessage = getSafeErrorMessage(error3); const errorStatusReportBase = await createStatusReportBase( "start-proxy" /* StartProxy */, @@ -187627,6 +187587,48 @@ async function sendFailedStatusReport(logger2, startedAt, language, unwrappedErr await sendStatusReport(errorStatusReportBase); } } + +// src/start-proxy/validation.ts +var core24 = __toESM(require_core()); +function cloneCredential(schema, obj) { + const result = {}; + for (const key of Object.keys(schema)) { + if (!isDefined2(obj[key])) { + continue; + } + result[key] = obj[key]; + } + return result; +} +function getAuthConfig(config) { + for (const oidcSchema of oidcSchemas) { + if (validateSchema(oidcSchema.schema, config)) { + return cloneCredential(oidcSchema.schema, config); + } + } + if (isToken(config)) { + if (isDefined2(config.token)) { + core24.setSecret(config.token); + } + return cloneCredential(tokenSchema, config); + } else { + let username = void 0; + let password = void 0; + if ("password" in config && isString(config.password)) { + core24.setSecret(config.password); + password = config.password; + } + if ("username" in config && isString(config.username)) { + username = config.username; + } + return { + username, + password + }; + } +} + +// src/start-proxy.ts var UPDATEJOB_PROXY = "update-job-proxy"; var UPDATEJOB_PROXY_VERSION = "v2.0.20250624110901"; var UPDATEJOB_PROXY_URL_PREFIX = "https://github.com/github/codeql-action/releases/download/codeql-bundle-v2.22.0/"; diff --git a/src/start-proxy.test.ts b/src/start-proxy.test.ts index bd24897136..86bb993481 100644 --- a/src/start-proxy.test.ts +++ b/src/start-proxy.test.ts @@ -1,6 +1,5 @@ import * as filepath from "path"; -import * as core from "@actions/core"; import * as toolcache from "@actions/tool-cache"; import test, { ExecutionContext } from "ava"; import sinon from "sinon"; @@ -15,7 +14,6 @@ import { BuiltInLanguage } from "./languages"; import { getRunnerLogger, Logger } from "./logging"; import { BundlePlatform, getBundlePlatform } from "./platform"; import * as startProxyExports from "./start-proxy"; -import * as statusReport from "./status-report"; import { assertNotLogged, checkExpectedLogMessages, @@ -27,94 +25,10 @@ import { setupTests, withRecordingLoggerAsync, } from "./testing-utils"; -import { - ConfigurationError, - GitHubVariant, - GitHubVersion, - withTmpDir, -} from "./util"; +import { GitHubVariant, GitHubVersion, withTmpDir } from "./util"; setupTests(test); -const sendFailedStatusReportTest = makeMacro({ - exec: async ( - t: ExecutionContext, - err: Error, - expectedMessage: string, - expectedStatus: statusReport.ActionStatus = "failure", - ) => { - const now = new Date(); - - // Override core.setFailed to avoid it setting the program's exit code - sinon.stub(core, "setFailed").returns(); - - const createStatusReportBase = sinon.stub( - statusReport, - "createStatusReportBase", - ); - createStatusReportBase.resolves(undefined); - - await withRecordingLoggerAsync(async (logger) => { - await startProxyExports.sendFailedStatusReport( - logger, - now, - undefined, - err, - ); - - // Check that the stub has been called exactly once, with the expected arguments, - // but not with the message from the error. - sinon.assert.calledOnceWithExactly( - createStatusReportBase, - statusReport.ActionName.StartProxy, - expectedStatus, - now, - sinon.match.any, - sinon.match.any, - sinon.match.any, - expectedMessage, - ); - t.false( - createStatusReportBase.calledWith( - statusReport.ActionName.StartProxy, - expectedStatus, - now, - sinon.match.any, - sinon.match.any, - sinon.match.any, - sinon.match((msg: string) => msg.includes(err.message)), - ), - "createStatusReportBase was called with the error message", - ); - }); - }, - - title: (providedTitle = "") => `sendFailedStatusReport - ${providedTitle}`, -}); - -sendFailedStatusReportTest.serial( - "reports generic error message for non-StartProxyError error", - new Error("Something went wrong today"), - "Error from start-proxy Action omitted (Error).", -); - -sendFailedStatusReportTest.serial( - "reports generic error message for non-StartProxyError error with safe error message", - new Error( - startProxyExports.getStartProxyErrorMessage( - startProxyExports.StartProxyErrorType.DownloadFailed, - ), - ), - "Error from start-proxy Action omitted (Error).", -); - -sendFailedStatusReportTest.serial( - "reports generic error message for ConfigurationError error", - new ConfigurationError("Something went wrong today"), - "Error from start-proxy Action omitted (ConfigurationError).", - "user-error", -); - const toEncodedJSON = (data: any) => Buffer.from(JSON.stringify(data)).toString("base64"); diff --git a/src/start-proxy.ts b/src/start-proxy.ts index 6221c9940f..84ed5fb174 100644 --- a/src/start-proxy.ts +++ b/src/start-proxy.ts @@ -1,6 +1,5 @@ import * as path from "path"; -import * as core from "@actions/core"; import * as toolcache from "@actions/tool-cache"; import { ActionState } from "./action-common"; @@ -11,7 +10,6 @@ import { getGitHubVersion, } from "./api-client"; import * as artifactScanner from "./artifact-scanner"; -import { Config } from "./config-utils"; import * as defaults from "./defaults.json"; import { CodeQLDefaultVersionInfo, @@ -22,6 +20,10 @@ import * as json from "./json"; import { BuiltInLanguage } from "./languages"; import { Logger } from "./logging"; import { BundlePlatform, getBundlePlatform } from "./platform"; +import { + StartProxyError, + StartProxyErrorType, +} from "./start-proxy/status-report"; import { Address, Registry, @@ -32,144 +34,10 @@ import { RawCredential, } from "./start-proxy/types"; import { getAuthConfig } from "./start-proxy/validation"; -import { - ActionName, - createStatusReportBase, - getActionsStatus, - sendStatusReport, - StatusReportBase, -} from "./status-report"; -import * as util from "./util"; import { ConfigurationError, getErrorMessage, isDefined } from "./util"; export * from "./start-proxy/types"; - -/** - * Enumerates specific error types for which we have corresponding error messages that - * are safe to include in status reports. - */ -export enum StartProxyErrorType { - DownloadFailed, - ExtractionFailed, - CacheFailed, -} - -/** - * @returns The error message corresponding to the error type. - */ -export function getStartProxyErrorMessage( - errorType: StartProxyErrorType, -): string { - switch (errorType) { - case StartProxyErrorType.DownloadFailed: - return "Failed to download proxy archive."; - case StartProxyErrorType.ExtractionFailed: - return "Failed to extract proxy archive."; - case StartProxyErrorType.CacheFailed: - return "Failed to add proxy to toolcache"; - } -} - -/** - * We want to avoid accidentally leaking secrets that may be contained in exception - * messages in the `start-proxy` action. Consequently, we don't report the messages - * of arbitrary exceptions. This type of error ensures that the message is one from - * `StartProxyErrorType` and therefore safe to include in a status report. - */ -export class StartProxyError extends Error { - public readonly errorType: StartProxyErrorType; - - constructor(errorType: StartProxyErrorType) { - super(); - this.errorType = errorType; - } -} - -/** - * Sends a status report for the `start-proxy` action indicating a successful outcome. - * - * @param startedAt When the action was started. - * @param config The configuration used. - * @param registry_types The types of registries that are configured. - * @param logger The logger to use. - */ -export async function sendSuccessStatusReport( - startedAt: Date, - config: Partial, - registry_types: string[], - logger: Logger, -) { - const statusReportBase = await createStatusReportBase( - ActionName.StartProxy, - "success", - startedAt, - config, - await util.checkDiskUsage(logger), - logger, - ); - if (statusReportBase !== undefined) { - const statusReport: StatusReportBase = { - ...statusReportBase, - registry_types: registry_types.join(","), - }; - await sendStatusReport(statusReport); - } -} - -/** - * Returns an error message for `error` that can safely be reported in a status report, - * i.e. that does not contain sensitive information. - * - * @param error The error for which to get an error message. - */ -export function getSafeErrorMessage(error: Error): string { - // If the error is a `StartProxyError`, resolve the error type to the corresponding - // error message. - if (error instanceof StartProxyError) { - return getStartProxyErrorMessage(error.errorType); - } - - // Otherwise, omit the actual error message. - return `Error from start-proxy Action omitted (${error.constructor.name}).`; -} - -/** - * Sends a status report for the `start-proxy` action indicating a failure. - * - * @param logger The logger to use. - * @param startedAt When the action was started. - * @param language The language provided as input, if any. - * @param unwrappedError The exception that was thrown. - */ -export async function sendFailedStatusReport( - logger: Logger, - startedAt: Date, - language: BuiltInLanguage | undefined, - unwrappedError: unknown, -) { - const error = util.wrapError(unwrappedError); - core.setFailed(`start-proxy action failed: ${error.message}`); - - // To avoid the possibility of leaking sensitive information into the telemetry, - // we don't include arbitrary error messages. Instead, `getSafeErrorMessage` will - // return a generic message that includes the type of the error, unless it can decide - // that the message is safe to include. - const statusReportMessage = getSafeErrorMessage(error); - const errorStatusReportBase = await createStatusReportBase( - ActionName.StartProxy, - getActionsStatus(error), - startedAt, - { - languages: language === undefined ? undefined : [language], - }, - await util.checkDiskUsage(logger), - logger, - statusReportMessage, - ); - if (errorStatusReportBase !== undefined) { - await sendStatusReport(errorStatusReportBase); - } -} +export * from "./start-proxy/status-report"; export const UPDATEJOB_PROXY = "update-job-proxy"; export const UPDATEJOB_PROXY_VERSION = "v2.0.20250624110901"; diff --git a/src/start-proxy/status-report.test.ts b/src/start-proxy/status-report.test.ts new file mode 100644 index 0000000000..15772872bc --- /dev/null +++ b/src/start-proxy/status-report.test.ts @@ -0,0 +1,94 @@ +import * as core from "@actions/core"; +import test, { ExecutionContext } from "ava"; +import sinon from "sinon"; + +import * as statusReport from "../status-report"; +import { + makeMacro, + setupTests, + withRecordingLoggerAsync, +} from "../testing-utils"; +import { ConfigurationError } from "../util"; + +import * as startProxyExports from "./status-report"; + +setupTests(test); + +const sendFailedStatusReportTest = makeMacro({ + exec: async ( + t: ExecutionContext, + err: Error, + expectedMessage: string, + expectedStatus: statusReport.ActionStatus = "failure", + ) => { + const now = new Date(); + + // Override core.setFailed to avoid it setting the program's exit code + sinon.stub(core, "setFailed").returns(); + + const createStatusReportBase = sinon.stub( + statusReport, + "createStatusReportBase", + ); + createStatusReportBase.resolves(undefined); + + await withRecordingLoggerAsync(async (logger) => { + await startProxyExports.sendFailedStatusReport( + logger, + now, + undefined, + err, + ); + + // Check that the stub has been called exactly once, with the expected arguments, + // but not with the message from the error. + sinon.assert.calledOnceWithExactly( + createStatusReportBase, + statusReport.ActionName.StartProxy, + expectedStatus, + now, + sinon.match.any, + sinon.match.any, + sinon.match.any, + expectedMessage, + ); + t.false( + createStatusReportBase.calledWith( + statusReport.ActionName.StartProxy, + expectedStatus, + now, + sinon.match.any, + sinon.match.any, + sinon.match.any, + sinon.match((msg: string) => msg.includes(err.message)), + ), + "createStatusReportBase was called with the error message", + ); + }); + }, + + title: (providedTitle = "") => `sendFailedStatusReport - ${providedTitle}`, +}); + +sendFailedStatusReportTest.serial( + "reports generic error message for non-StartProxyError error", + new Error("Something went wrong today"), + "Error from start-proxy Action omitted (Error).", +); + +sendFailedStatusReportTest.serial( + "reports generic error message for non-StartProxyError error with safe error message", + new Error( + startProxyExports.getStartProxyErrorMessage( + startProxyExports.StartProxyErrorType.DownloadFailed, + ), + ), + "Error from start-proxy Action omitted (Error).", +); + +sendFailedStatusReportTest.serial( + "reports generic error message for ConfigurationError error", + new ConfigurationError("Something went wrong today"), + "Error from start-proxy Action omitted (ConfigurationError).", + "user-error", +); diff --git a/src/start-proxy/status-report.ts b/src/start-proxy/status-report.ts new file mode 100644 index 0000000000..0810780343 --- /dev/null +++ b/src/start-proxy/status-report.ts @@ -0,0 +1,140 @@ +import * as core from "@actions/core"; + +import type { Config } from "../config-utils"; +import type { BuiltInLanguage } from "../languages"; +import type { Logger } from "../logging"; +import { + ActionName, + createStatusReportBase, + getActionsStatus, + sendStatusReport, + type StatusReportBase, +} from "../status-report"; +import * as util from "../util"; + +/** + * Sends a status report for the `start-proxy` action indicating a successful outcome. + * + * @param startedAt When the action was started. + * @param config The configuration used. + * @param registry_types The types of registries that are configured. + * @param logger The logger to use. + */ +export async function sendSuccessStatusReport( + startedAt: Date, + config: Partial, + registry_types: string[], + logger: Logger, +) { + const statusReportBase = await createStatusReportBase( + ActionName.StartProxy, + "success", + startedAt, + config, + await util.checkDiskUsage(logger), + logger, + ); + if (statusReportBase !== undefined) { + const statusReport: StatusReportBase = { + ...statusReportBase, + registry_types: registry_types.join(","), + }; + await sendStatusReport(statusReport); + } +} + +/** + * Enumerates specific error types for which we have corresponding error messages that + * are safe to include in status reports. + */ +export enum StartProxyErrorType { + DownloadFailed, + ExtractionFailed, + CacheFailed, +} + +/** + * @returns The error message corresponding to the error type. + */ +export function getStartProxyErrorMessage( + errorType: StartProxyErrorType, +): string { + switch (errorType) { + case StartProxyErrorType.DownloadFailed: + return "Failed to download proxy archive."; + case StartProxyErrorType.ExtractionFailed: + return "Failed to extract proxy archive."; + case StartProxyErrorType.CacheFailed: + return "Failed to add proxy to toolcache"; + } +} + +/** + * We want to avoid accidentally leaking secrets that may be contained in exception + * messages in the `start-proxy` action. Consequently, we don't report the messages + * of arbitrary exceptions. This type of error ensures that the message is one from + * `StartProxyErrorType` and therefore safe to include in a status report. + */ +export class StartProxyError extends Error { + public readonly errorType: StartProxyErrorType; + + constructor(errorType: StartProxyErrorType) { + super(); + this.errorType = errorType; + } +} + +/** + * Returns an error message for `error` that can safely be reported in a status report, + * i.e. that does not contain sensitive information. + * + * @param error The error for which to get an error message. + */ +export function getSafeErrorMessage(error: Error): string { + // If the error is a `StartProxyError`, resolve the error type to the corresponding + // error message. + if (error instanceof StartProxyError) { + return getStartProxyErrorMessage(error.errorType); + } + + // Otherwise, omit the actual error message. + return `Error from start-proxy Action omitted (${error.constructor.name}).`; +} + +/** + * Sends a status report for the `start-proxy` action indicating a failure. + * + * @param logger The logger to use. + * @param startedAt When the action was started. + * @param language The language provided as input, if any. + * @param unwrappedError The exception that was thrown. + */ +export async function sendFailedStatusReport( + logger: Logger, + startedAt: Date, + language: BuiltInLanguage | undefined, + unwrappedError: unknown, +) { + const error = util.wrapError(unwrappedError); + core.setFailed(`start-proxy action failed: ${error.message}`); + + // To avoid the possibility of leaking sensitive information into the telemetry, + // we don't include arbitrary error messages. Instead, `getSafeErrorMessage` will + // return a generic message that includes the type of the error, unless it can decide + // that the message is safe to include. + const statusReportMessage = getSafeErrorMessage(error); + const errorStatusReportBase = await createStatusReportBase( + ActionName.StartProxy, + getActionsStatus(error), + startedAt, + { + languages: language === undefined ? undefined : [language], + }, + await util.checkDiskUsage(logger), + logger, + statusReportMessage, + ); + if (errorStatusReportBase !== undefined) { + await sendStatusReport(errorStatusReportBase); + } +} From 6308e366c9d998b0750856f929c0c17ed1014b89 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 13 Oct 2026 19:06:14 +0100 Subject: [PATCH 089/107] Return release version from `getProxyBinaryPath` --- lib/entry-points.js | 7 +++++-- src/start-proxy-action.ts | 2 +- src/start-proxy.test.ts | 16 +++++++++++----- src/start-proxy.ts | 20 +++++++++++++++++--- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index f3d3022b0d..00309ef50d 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -187870,7 +187870,10 @@ async function getProxyBinaryPath(action) { proxyInfo.version ); } - return path27.join(proxyBin, proxyFileName); + return { + path: path27.join(proxyBin, proxyFileName), + version: proxyInfo.version + }; } // src/start-proxy/ca.ts @@ -188235,7 +188238,7 @@ async function run7(action) { const actionWithFeatures = extendActionState(action, { features }); const proxyBin = await getProxyBinaryPath(actionWithFeatures); const proxyInfo = await startProxy( - proxyBin, + proxyBin.path, proxyConfig, proxyLogFilePath, logger2 diff --git a/src/start-proxy-action.ts b/src/start-proxy-action.ts index bc3351da53..9f96e1503c 100644 --- a/src/start-proxy-action.ts +++ b/src/start-proxy-action.ts @@ -106,7 +106,7 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) { const actionWithFeatures = extendActionState(action, { features }); const proxyBin = await getProxyBinaryPath(actionWithFeatures); const proxyInfo = await startProxy( - proxyBin, + proxyBin.path, proxyConfig, proxyLogFilePath, logger, diff --git a/src/start-proxy.test.ts b/src/start-proxy.test.ts index 86bb993481..66edd0c62f 100644 --- a/src/start-proxy.test.ts +++ b/src/start-proxy.test.ts @@ -886,9 +886,10 @@ test.serial( t.assert(path); t.is( - path, + path.path, filepath.join(toolcachePath, startProxyExports.getProxyFilename()), ); + t.is(path.version, startProxyExports.UPDATEJOB_PROXY_VERSION); }); }, ); @@ -939,9 +940,10 @@ test.serial( t.assert(cacheDir.calledOnceWith(extractedPath)); t.assert(path); t.is( - path, + path.path, filepath.join(toolcachePath, startProxyExports.getProxyFilename()), ); + t.is(path.version, defaults.cliVersion); checkExpectedLogMessages(t, logger.messages, [ `Found '${startProxyExports.getProxyPackage(getTestPlatform(state))}' in release '${defaults.bundleVersion}' at '${downloadUrl}'`, @@ -954,7 +956,8 @@ test.serial( async (t) => { const logger = new RecordingLogger(); const state = initAllState({ logger }); - const expectedTag = "codeql-bundle-v2.20.1"; + const expectedVersion = "2.20.1"; + const expectedTag = `codeql-bundle-v${expectedVersion}`; const expectedParams = { owner: "github", repo: "codeql-action", @@ -1012,7 +1015,9 @@ test.serial( const getDefaultCliVersion = sinon .stub(features, "getEnabledDefaultCliVersions") .resolves({ - enabledVersions: [{ cliVersion: "2.20.1", tagName: expectedTag }], + enabledVersions: [ + { cliVersion: expectedVersion, tagName: expectedTag }, + ], }); const path = await startProxyExports.getProxyBinaryPath({ ...state, @@ -1033,9 +1038,10 @@ test.serial( t.assert(path); t.is( - path, + path.path, filepath.join(toolcachePath, startProxyExports.getProxyFilename()), ); + t.is(path.version, expectedVersion); }); checkExpectedLogMessages(t, logger.messages, [ diff --git a/src/start-proxy.ts b/src/start-proxy.ts index 84ed5fb174..e22346d3ac 100644 --- a/src/start-proxy.ts +++ b/src/start-proxy.ts @@ -428,17 +428,27 @@ export function getProxyFilename() { : UPDATEJOB_PROXY; } +export type ProxyBinary = { + /** The path to the proxy binary to run. */ + path: string; + /** + * The version associated with the proxy binary. + * This usually corresponds to the CodeQL CLI release that the binary was obtained from. + */ + version: string; +}; + /** * Gets a path to the proxy binary. If possible, this function will find the proxy in the * runner's tool cache. Otherwise, it downloads and extracts the proxy binary, * and stores it in the tool cache. * * @param action The action state. - * @returns The path to the proxy binary. + * @returns The path to the proxy binary and its version. */ export async function getProxyBinaryPath( action: ActionState<["Base", "Logger", "FeatureFlags"]>, -): Promise { +): Promise { const logger = action.logger; const proxyFileName = getProxyFilename(); const proxyInfo = await getDownloadUrl(action); @@ -460,5 +470,9 @@ export async function getProxyBinaryPath( proxyInfo.version, ); } - return path.join(proxyBin, proxyFileName); + + return { + path: path.join(proxyBin, proxyFileName), + version: proxyInfo.version, + }; } From 43db2c064ca6c19f843f4791c5cfa3fc73138669 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 13 Oct 2026 19:12:13 +0100 Subject: [PATCH 090/107] Include proxy version in telemetry --- lib/entry-points.js | 6 ++++-- src/start-proxy-action.ts | 1 + src/start-proxy/status-report.ts | 15 ++++++++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 00309ef50d..d4c353c9f3 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -187528,7 +187528,7 @@ var toolcache4 = __toESM(require_tool_cache()); // src/start-proxy/status-report.ts var core23 = __toESM(require_core()); -async function sendSuccessStatusReport(startedAt, config, registry_types, logger2) { +async function sendSuccessStatusReport(startedAt, config, registry_types, status, logger2) { const statusReportBase = await createStatusReportBase( "start-proxy" /* StartProxy */, "success", @@ -187540,7 +187540,8 @@ async function sendSuccessStatusReport(startedAt, config, registry_types, logger if (statusReportBase !== void 0) { const statusReport = { ...statusReportBase, - registry_types: registry_types.join(",") + registry_types: registry_types.join(","), + start_proxy: status }; await sendStatusReport(statusReport); } @@ -188250,6 +188251,7 @@ async function run7(action) { languages: language === void 0 ? void 0 : [language] }, proxyConfig.all_credentials.map((c) => c.type), + { proxy_version: proxyBin.version }, logger2 ); } catch (unwrappedError) { diff --git a/src/start-proxy-action.ts b/src/start-proxy-action.ts index 9f96e1503c..8a5f5af146 100644 --- a/src/start-proxy-action.ts +++ b/src/start-proxy-action.ts @@ -122,6 +122,7 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) { languages: language === undefined ? undefined : [language], }, proxyConfig.all_credentials.map((c) => c.type), + { proxy_version: proxyBin.version }, logger, ); } catch (unwrappedError) { diff --git a/src/start-proxy/status-report.ts b/src/start-proxy/status-report.ts index 0810780343..685be3dbee 100644 --- a/src/start-proxy/status-report.ts +++ b/src/start-proxy/status-report.ts @@ -12,18 +12,30 @@ import { } from "../status-report"; import * as util from "../util"; +/** Additional status report data from `start-proxy`. */ +export interface StartProxyStatus { + proxy_version: string; +} + +/** The type of successful status reports from `start-proxy`. */ +type StartProxySuccessReport = StatusReportBase & { + start_proxy: StartProxyStatus; +}; + /** * Sends a status report for the `start-proxy` action indicating a successful outcome. * * @param startedAt When the action was started. * @param config The configuration used. * @param registry_types The types of registries that are configured. + * @param status Status information. * @param logger The logger to use. */ export async function sendSuccessStatusReport( startedAt: Date, config: Partial, registry_types: string[], + status: StartProxyStatus, logger: Logger, ) { const statusReportBase = await createStatusReportBase( @@ -35,9 +47,10 @@ export async function sendSuccessStatusReport( logger, ); if (statusReportBase !== undefined) { - const statusReport: StatusReportBase = { + const statusReport: StartProxySuccessReport = { ...statusReportBase, registry_types: registry_types.join(","), + start_proxy: status, }; await sendStatusReport(statusReport); } From 6aee1f8ef9c4cb021dafe1c97ea41122dd03b98b Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 14 Oct 2026 10:30:14 +0100 Subject: [PATCH 091/107] Sort `registry_types` in status report --- lib/entry-points.js | 2 +- src/start-proxy/status-report.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index d4c353c9f3..1b67d38e13 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -187540,7 +187540,7 @@ async function sendSuccessStatusReport(startedAt, config, registry_types, status if (statusReportBase !== void 0) { const statusReport = { ...statusReportBase, - registry_types: registry_types.join(","), + registry_types: registry_types.sort().join(","), start_proxy: status }; await sendStatusReport(statusReport); diff --git a/src/start-proxy/status-report.ts b/src/start-proxy/status-report.ts index 685be3dbee..76ad3c8da3 100644 --- a/src/start-proxy/status-report.ts +++ b/src/start-proxy/status-report.ts @@ -49,7 +49,7 @@ export async function sendSuccessStatusReport( if (statusReportBase !== undefined) { const statusReport: StartProxySuccessReport = { ...statusReportBase, - registry_types: registry_types.join(","), + registry_types: registry_types.sort().join(","), start_proxy: status, }; await sendStatusReport(statusReport); From 15800587e38e5a271757432b15bc7ab06517df43 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 14 Oct 2026 10:31:29 +0100 Subject: [PATCH 092/107] Add unit test for `sendSuccessStatusReport` --- src/start-proxy/status-report.test.ts | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/start-proxy/status-report.test.ts b/src/start-proxy/status-report.test.ts index 15772872bc..c734783964 100644 --- a/src/start-proxy/status-report.test.ts +++ b/src/start-proxy/status-report.test.ts @@ -4,7 +4,9 @@ import sinon from "sinon"; import * as statusReport from "../status-report"; import { + createTestConfig, makeMacro, + RecordingLogger, setupTests, withRecordingLoggerAsync, } from "../testing-utils"; @@ -14,6 +16,46 @@ import * as startProxyExports from "./status-report"; setupTests(test); +test.serial("sendSuccessStatusReport", async (t) => { + const logger = new RecordingLogger(); + const now = new Date(); + const config = createTestConfig({}); + const proxy_version = "1.2.3"; + const registry_types = ["git_source", "docker_registry"]; + + const createStatusReportBase = sinon.stub( + statusReport, + "createStatusReportBase", + ); + createStatusReportBase.resolves({ + action_name: statusReport.ActionName.StartProxy, + } as statusReport.StatusReportBase); + + const sendStatusReport = sinon + .stub(statusReport, "sendStatusReport") + .resolves(); + + await startProxyExports.sendSuccessStatusReport( + now, + config, + registry_types, + { proxy_version }, + logger, + ); + + t.is(createStatusReportBase.callCount, 1); + + t.is(sendStatusReport.callCount, 1); + t.is(sendStatusReport.args[0].length, 1); + + const arg = sendStatusReport.args[0][0]; + t.like(arg, { + action_name: statusReport.ActionName.StartProxy, + registry_types: "docker_registry,git_source", + start_proxy: { proxy_version }, + }); +}); + const sendFailedStatusReportTest = makeMacro({ exec: async ( t: ExecutionContext, From efdb69c1d759ed1f924e3f7b296fac7c53339b9a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Oct 2026 09:49:53 +0000 Subject: [PATCH 093/107] Bump the npm-minor group across 1 directory with 7 updates Bumps the npm-minor group with 7 updates in the / directory: | Package | From | To | | --- | --- | --- | | [@actions/cache](https://github.com/actions/toolkit/tree/HEAD/packages/cache) | `5.2.0` | `5.3.0` | | [follow-redirects](https://github.com/follow-redirects/follow-redirects) | `1.16.0` | `1.16.1` | | [js-yaml](https://github.com/nodeca/js-yaml) | `5.4.2` | `5.4.3` | | [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) | `65.0.1` | `65.2.0` | | [globals](https://github.com/sindresorhus/globals) | `17.12.0` | `17.13.0` | | [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.70.1` | `8.71.1` | | [mdast-util-from-markdown](https://github.com/syntax-tree/mdast-util-from-markdown) | `2.0.3` | `2.1.0` | Updates `@actions/cache` from 5.2.0 to 5.3.0 - [Changelog](https://github.com/actions/toolkit/blob/main/packages/cache/RELEASES.md) - [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/cache) Updates `follow-redirects` from 1.16.0 to 1.16.1 - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.16.0...v1.16.1) Updates `js-yaml` from 5.4.2 to 5.4.3 - [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodeca/js-yaml/compare/5.4.2...5.4.3) Updates `eslint-plugin-jsdoc` from 65.0.1 to 65.2.0 - [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases) - [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v65.0.1...v65.2.0) Updates `globals` from 17.12.0 to 17.13.0 - [Release notes](https://github.com/sindresorhus/globals/releases) - [Commits](https://github.com/sindresorhus/globals/compare/v17.12.0...v17.13.0) Updates `typescript-eslint` from 8.70.1 to 8.71.1 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.71.1/packages/typescript-eslint) Updates `mdast-util-from-markdown` from 2.0.3 to 2.1.0 - [Release notes](https://github.com/syntax-tree/mdast-util-from-markdown/releases) - [Commits](https://github.com/syntax-tree/mdast-util-from-markdown/compare/2.0.3...2.1.0) --- updated-dependencies: - dependency-name: "@actions/cache" dependency-version: 5.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-minor - dependency-name: follow-redirects dependency-version: 1.16.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: npm-minor - dependency-name: js-yaml dependency-version: 5.4.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: npm-minor - dependency-name: eslint-plugin-jsdoc dependency-version: 65.2.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: npm-minor - dependency-name: globals dependency-version: 17.13.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: npm-minor - dependency-name: typescript-eslint dependency-version: 8.71.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: npm-minor - dependency-name: mdast-util-from-markdown dependency-version: 2.1.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 178 ++++++++++++++++++++--------------------- package.json | 12 +-- pr-checks/package.json | 2 +- 3 files changed, 96 insertions(+), 96 deletions(-) diff --git a/package-lock.json b/package-lock.json index 050ff1e484..391d707ef3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "dependencies": { "@actions/artifact": "^5.0.3", "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2", - "@actions/cache": "^5.2.0", + "@actions/cache": "^5.3.0", "@actions/core": "^2.0.3", "@actions/exec": "^2.0.0", "@actions/github": "^8.0.1", @@ -28,10 +28,10 @@ "@octokit/plugin-retry": "^8.1.1", "archiver": "^8.0.0", "fast-deep-equal": "^3.1.3", - "follow-redirects": "^1.16.0", + "follow-redirects": "^1.16.1", "get-folder-size": "^5.0.0", "https-proxy-agent": "^7.0.6", - "js-yaml": "^5.4.2", + "js-yaml": "^5.4.3", "jsonschema": "1.5.0", "long": "^5.3.2", "node-forge": "^1.4.0", @@ -58,14 +58,14 @@ "eslint-import-resolver-typescript": "^4.4.5", "eslint-plugin-github": "^6.1.2", "eslint-plugin-import-x": "^4.17.1", - "eslint-plugin-jsdoc": "^65.0.1", + "eslint-plugin-jsdoc": "^65.2.0", "eslint-plugin-no-async-foreach": "^0.1.1", "glob": "^13.0.6", - "globals": "^17.12.0", + "globals": "^17.13.0", "nock": "^14.0.17", "sinon": "^22.1.0", "typescript": "^6.0.3", - "typescript-eslint": "^8.70.1" + "typescript-eslint": "^8.71.1" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -459,19 +459,19 @@ } }, "node_modules/@actions/cache": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@actions/cache/-/cache-5.2.0.tgz", - "integrity": "sha512-1R1Oc8cuDNCygsIP7gLiKLGCymOw/k5FkGQkXZFcLz6/RWyMImkfP0dZX6kjA9SRAmANcKNocI2XrsIaZ1it8w==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@actions/cache/-/cache-5.3.0.tgz", + "integrity": "sha512-VqJBlQFt1lpp7op7o/Z0syWywX9cN8TxjFCPjHyGHmXCiczU5NII5ZdEpGpTelUnOGFG2bO7viUx9q3q7WR/Gg==", "license": "MIT", "dependencies": { - "@actions/core": "^2.0.0", + "@actions/core": "^2.0.3", "@actions/exec": "^2.0.0", "@actions/glob": "^0.5.1", "@actions/http-client": "^3.0.2", "@actions/io": "^2.0.0", "@azure/abort-controller": "^1.1.0", - "@azure/core-rest-pipeline": "^1.22.0", - "@azure/storage-blob": "^12.29.1", + "@azure/core-rest-pipeline": "^1.25.0", + "@azure/storage-blob": "^12.34.0", "@protobuf-ts/runtime-rpc": "^2.11.1", "semver": "^6.3.1" } @@ -2718,17 +2718,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.70.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.70.1.tgz", - "integrity": "sha512-nDNrUQ/4ruSNYbu749TRY7cfrzPtoLHEXSNBI8aaNY32LlZCajixqRf3FqcKC4p5Cam4VOHYx/t+i5+nKXvrqA==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.71.1.tgz", + "integrity": "sha512-nNlBf6HuotqMgZvSkWD5hNdemiBIxQ2NmrlgfcUIeZRs+BbakjscCQRq/Hb74EFVnFiSWWdL12JruqwBy3ERDw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.70.1", - "@typescript-eslint/type-utils": "8.70.1", - "@typescript-eslint/utils": "8.70.1", - "@typescript-eslint/visitor-keys": "8.70.1", + "@typescript-eslint/scope-manager": "8.71.1", + "@typescript-eslint/type-utils": "8.71.1", + "@typescript-eslint/utils": "8.71.1", + "@typescript-eslint/visitor-keys": "8.71.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -2741,7 +2741,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.70.1", + "@typescript-eslint/parser": "^8.71.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } @@ -2757,16 +2757,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.70.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.70.1.tgz", - "integrity": "sha512-nO974WLllwhSFWQXnMLj6nDGa8f0khKEz1JzpPJ1u7Vm/4X1X6ZHajpoknU4bb41vJyMB0HHVyS2GqdhWfIXZw==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.71.1.tgz", + "integrity": "sha512-oM/5sAqz/l1v/zYK1qTOPrn2+JIrBGC1V6uNYucRO5gh6eT9vWJ/RhPbGE59byvZEUQ4VP6XkLBaS5Jti5jpvw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.70.1", - "@typescript-eslint/types": "8.70.1", - "@typescript-eslint/typescript-estree": "8.70.1", - "@typescript-eslint/visitor-keys": "8.70.1", + "@typescript-eslint/scope-manager": "8.71.1", + "@typescript-eslint/types": "8.71.1", + "@typescript-eslint/typescript-estree": "8.71.1", + "@typescript-eslint/visitor-keys": "8.71.1", "debug": "^4.4.3" }, "engines": { @@ -2800,14 +2800,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.70.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.70.1.tgz", - "integrity": "sha512-62xOgboPfwc3/IgPSX/W6oQR3ZbF04194FPGUGH8HL8iLFHbt/456/8Ph1wLNUgVF+s94FlHoipBsz+v7+LMnA==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.71.1.tgz", + "integrity": "sha512-Oijc9RUsohHjncg6iGi7gCtjnEjYt9FWv9u6ygK8uKcHK5eLjLAkqERQ9BaytbpceOFdk6kifPCS/zAZE+A99g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.70.1", - "@typescript-eslint/types": "^8.70.1", + "@typescript-eslint/tsconfig-utils": "^8.71.1", + "@typescript-eslint/types": "^8.71.1", "debug": "^4.4.3" }, "engines": { @@ -2840,14 +2840,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.70.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.70.1.tgz", - "integrity": "sha512-Pa0EeSeAusQc1WbjQMac+YfenewYTBu0KjgYvkUKwhXaHUKbFog23Dm/rp0DX/6tyYOQ3Xl1a+3EcFNZynGHCw==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.71.1.tgz", + "integrity": "sha512-1YUDZXdTnXLlob03SFHBipdyMBsDVm7zoSz0ytTJ39dk5J1TgsTK03VlR/dLXG/RLLUrPcYbD4rp23BmHxHP0w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.70.1", - "@typescript-eslint/visitor-keys": "8.70.1" + "@typescript-eslint/types": "8.71.1", + "@typescript-eslint/visitor-keys": "8.71.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2858,9 +2858,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.70.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.70.1.tgz", - "integrity": "sha512-jumze1fPI+sDOaM2TWGQdn39PDxTr7TZGeuyLkAbNyx2vtMT3uRnVKChN0hfht5V2TugphJzF6bYXvBcE09qqg==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.71.1.tgz", + "integrity": "sha512-oTvkml5SxXhgg+WWKhod5qWQICDXtOB+/Hi9VdPKFAANJ2b7YOgMffgvzXuqog7R6A/JtrzRf128dsxummyWhg==", "dev": true, "license": "MIT", "engines": { @@ -2875,15 +2875,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.70.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.70.1.tgz", - "integrity": "sha512-7zKTnyvaVWqzLZHPFQtX1hVHqgkMC+WebPWakNCSyrQVbIP1AM0L0TlBZtACldIRb6PptI8Odk+jyZ5kP3B1VA==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.71.1.tgz", + "integrity": "sha512-kH3t3jZCYv2PZSBEWPKTariLrCaoF1CLoPitYFBJOhAGEwWnSRAtGEifrfrpBa4K9JlwWNZotgA5w3/wLSk/FQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.70.1", - "@typescript-eslint/typescript-estree": "8.70.1", - "@typescript-eslint/utils": "8.70.1", + "@typescript-eslint/types": "8.71.1", + "@typescript-eslint/typescript-estree": "8.71.1", + "@typescript-eslint/utils": "8.71.1", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -2918,9 +2918,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.70.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.70.1.tgz", - "integrity": "sha512-Dm1ypdhhrGCTyyehxElhgJ6kgk8MVCv5qXdoOVqPr1uqk42jX8KjrZqhROvdShczA8qrDoYiOWn1ykWlx2k81Q==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.71.1.tgz", + "integrity": "sha512-ybYnPTUwg3VQQOFEiBPLs8Jxl1ry2vXdn1kVKguomBbvxpetdu3MKTNDqFNUrlG8ylP9MpZosmXMFYlGQHk1oQ==", "dev": true, "license": "MIT", "engines": { @@ -2932,16 +2932,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.70.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.70.1.tgz", - "integrity": "sha512-TU8PwyGN0PQJUcE96mw8eCQ44SmxGdQlJmlWakHaHQ15eIuuvye5yNtmh/i6oS88jzXVQB71xdNkbkB/fMwL0g==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.71.1.tgz", + "integrity": "sha512-pSKSEK1JJpHs6KiKVtABCE4iJK5d7FLFzDXQNBQ2oRY7LEd3UwOt3TZemTgu9syTIf56dJWlTn/pdmrO9oKUXQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.70.1", - "@typescript-eslint/tsconfig-utils": "8.70.1", - "@typescript-eslint/types": "8.70.1", - "@typescript-eslint/visitor-keys": "8.70.1", + "@typescript-eslint/project-service": "8.71.1", + "@typescript-eslint/tsconfig-utils": "8.71.1", + "@typescript-eslint/types": "8.71.1", + "@typescript-eslint/visitor-keys": "8.71.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -3017,16 +3017,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.70.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.70.1.tgz", - "integrity": "sha512-Esgul8MsnKnRLdYU2Eb2cRV9bS5HJYtKj1ByJnOzzG2M58DGdSUQ1jUuILxipqcpB2h9WLrbD5GijIWUjX/Tqw==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.71.1.tgz", + "integrity": "sha512-CBjT6gfAz3DW2j9Q4moFnqt208Aq+506sVGXfpRcyAeqn0EpayL0mjdWoCO2t3RC7GewNrFxdeehuEaPg6DMzQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.70.1", - "@typescript-eslint/types": "8.70.1", - "@typescript-eslint/typescript-estree": "8.70.1" + "@typescript-eslint/scope-manager": "8.71.1", + "@typescript-eslint/types": "8.71.1", + "@typescript-eslint/typescript-estree": "8.71.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3041,13 +3041,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.70.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.70.1.tgz", - "integrity": "sha512-Vwj9lUIW5Xq3wQ9w6gv3R86g1hMK8f2zNOdGTAgeXUMMXFK78G9ruCjjqutHMNJc0+CH7LYRnHeUB9IT8wFmcw==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.71.1.tgz", + "integrity": "sha512-0GxiUGqMU0qXJt58cBsiG3DP8lUmBaFo2vChtUX+CT7PnR3v/VGLLrzVP4K9r1lNiZXjHYefMBbPunplr09v6w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.70.1", + "@typescript-eslint/types": "8.71.1", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -5381,9 +5381,9 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "65.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-65.0.1.tgz", - "integrity": "sha512-7IvB+ZS71WCw5tGKh6f6D5k55qtXKdrGTnIpQTBKWdpyZ5IfhGHfh0i6ArWlCJ4JEtz22YRk5Bqu1MvbOlpMKQ==", + "version": "65.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-65.2.0.tgz", + "integrity": "sha512-IMZaNwdDa5otUQYGWN1pzywZLsGKswitvFFNhcO8IOsBfaWpWIDXYuZh2sYhe9MNyKN9hz0YryOFaKdpbTP5Bw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -6007,9 +6007,9 @@ "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", - "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.1.tgz", + "integrity": "sha512-FNvFGzoMLWmE6Yj9spb/zjd7yiNCHiAW9/Tg9CXrQ8wuu32HtlJOwWO11OJafl5FfY3DxTdQ0vj42zU1kvv5jg==", "funding": [ { "type": "individual", @@ -6293,9 +6293,9 @@ } }, "node_modules/globals": { - "version": "17.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.12.0.tgz", - "integrity": "sha512-cezEd/DTyyht9cvSSURyygXPfy04GtWO/5e6ZPvH7fCtjKz9PYOmuawphw1Ctd1f6C+5JypXfGD7ahNMXvevBA==", + "version": "17.13.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.13.0.tgz", + "integrity": "sha512-RwMTC61u7hrG3ZJMkZQOK4JLJrKS8QtoTii63EmWvFXHqycY9FObBJQCbsLxSO8kjKhWE5kV1GC+Vb1g3RI0Zg==", "dev": true, "license": "MIT", "engines": { @@ -7136,9 +7136,9 @@ } }, "node_modules/js-yaml": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.4.2.tgz", - "integrity": "sha512-m+aqu+LwO1O6sIopafj8HUVl5aawITwZQe/yHpMCKjaWBaA/d07B/QdMb3529REftiU+RMMHL3Vlsw3hON7vWg==", + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.4.3.tgz", + "integrity": "sha512-yzzNtgczwgoVHNigCyKTXcQJU4Y8t/ikU4UxXW0BvrLfHTGWZhsNcOT2s/a7vn81/4KqVnNmHjaUEPlvWnNwVw==", "funding": [ { "type": "github", @@ -7494,9 +7494,9 @@ } }, "node_modules/mdast-util-from-markdown": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", - "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.1.0.tgz", + "integrity": "sha512-KRLgmPaP2H1ul2bpoJkOS+9pAcDAAj9Nu1mqLnh8NLeJG5tlvj42TH80PIGBpROWlRXLk0lDrWNuZCFy/tsB4A==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -9996,16 +9996,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.70.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.70.1.tgz", - "integrity": "sha512-AcWG7KDjZ2THNXsgwttMaGmzVi0VFRlFYfqFHYQRbDpF3owuYbuiL8c7UUrd2k8s3PoSfIQrWfrGXfcElrWLYA==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.71.1.tgz", + "integrity": "sha512-oiNVPC3/NbV1FpaHU07l8O6ynqG9v4PAiW2WvTrAmZdR0f2HI/gE668ElMLCK7Xbsu5k2fK5C4fXNiq05j7/nQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.70.1", - "@typescript-eslint/parser": "8.70.1", - "@typescript-eslint/typescript-estree": "8.70.1", - "@typescript-eslint/utils": "8.70.1" + "@typescript-eslint/eslint-plugin": "8.71.1", + "@typescript-eslint/parser": "8.71.1", + "@typescript-eslint/typescript-estree": "8.71.1", + "@typescript-eslint/utils": "8.71.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10503,7 +10503,7 @@ "@octokit/plugin-paginate-rest": ">=15.0.0", "@octokit/plugin-rest-endpoint-methods": "^18.0.0", "lite-matter": "^0.1.2", - "mdast-util-from-markdown": "^2.0.3", + "mdast-util-from-markdown": "^2.1.0", "semver": "^7.8.5", "yaml": "^2.9.1" }, diff --git a/package.json b/package.json index 51fd4a4505..c627b93583 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "dependencies": { "@actions/artifact": "^5.0.3", "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2", - "@actions/cache": "^5.2.0", + "@actions/cache": "^5.3.0", "@actions/core": "^2.0.3", "@actions/exec": "^2.0.0", "@actions/github": "^8.0.1", @@ -36,10 +36,10 @@ "@octokit/plugin-retry": "^8.1.1", "archiver": "^8.0.0", "fast-deep-equal": "^3.1.3", - "follow-redirects": "^1.16.0", + "follow-redirects": "^1.16.1", "get-folder-size": "^5.0.0", "https-proxy-agent": "^7.0.6", - "js-yaml": "^5.4.2", + "js-yaml": "^5.4.3", "jsonschema": "1.5.0", "long": "^5.3.2", "node-forge": "^1.4.0", @@ -66,14 +66,14 @@ "eslint-import-resolver-typescript": "^4.4.5", "eslint-plugin-github": "^6.1.2", "eslint-plugin-import-x": "^4.17.1", - "eslint-plugin-jsdoc": "^65.0.1", + "eslint-plugin-jsdoc": "^65.2.0", "eslint-plugin-no-async-foreach": "^0.1.1", "glob": "^13.0.6", - "globals": "^17.12.0", + "globals": "^17.13.0", "nock": "^14.0.17", "sinon": "^22.1.0", "typescript": "^6.0.3", - "typescript-eslint": "^8.70.1" + "typescript-eslint": "^8.71.1" }, "overrides": { "@actions/tool-cache": { diff --git a/pr-checks/package.json b/pr-checks/package.json index 3d6b3d07e6..a6e67e5277 100644 --- a/pr-checks/package.json +++ b/pr-checks/package.json @@ -9,7 +9,7 @@ "@octokit/plugin-paginate-rest": ">=15.0.0", "@octokit/plugin-rest-endpoint-methods": "^18.0.0", "lite-matter": "^0.1.2", - "mdast-util-from-markdown": "^2.0.3", + "mdast-util-from-markdown": "^2.1.0", "semver": "^7.8.5", "yaml": "^2.9.1" }, From 25fe42ad78275cee8b1b655ade6fd15224aba711 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 14 Oct 2026 09:51:41 +0000 Subject: [PATCH 094/107] Rebuild --- lib/entry-points.js | 92 ++++++++++++++++++++++++++++----------------- 1 file changed, 58 insertions(+), 34 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 373cdedc01..4bda956850 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -100013,7 +100013,7 @@ var require_package = __commonJS({ "node_modules/@actions/cache/package.json"(exports2, module2) { module2.exports = { name: "@actions/cache", - version: "5.2.0", + version: "5.3.0", preview: true, description: "Actions cache lib", keywords: [ @@ -100050,22 +100050,22 @@ var require_package = __commonJS({ url: "https://github.com/actions/toolkit/issues" }, dependencies: { - "@actions/core": "^2.0.0", + "@actions/core": "^2.0.3", "@actions/exec": "^2.0.0", "@actions/glob": "^0.5.1", - "@protobuf-ts/runtime-rpc": "^2.11.1", "@actions/http-client": "^3.0.2", "@actions/io": "^2.0.0", "@azure/abort-controller": "^1.1.0", - "@azure/core-rest-pipeline": "^1.22.0", - "@azure/storage-blob": "^12.29.1", + "@azure/core-rest-pipeline": "^1.25.0", + "@azure/storage-blob": "^12.34.0", + "@protobuf-ts/runtime-rpc": "^2.11.1", semver: "^6.3.1" }, devDependencies: { - "@types/node": "^24.1.0", - "@types/semver": "^6.0.0", - "@protobuf-ts/plugin": "^2.9.4", - typescript: "^5.2.2" + "@protobuf-ts/plugin": "^2.11.1", + "@types/node": "^24.13.6", + "@types/semver": "^6.2.7", + typescript: "^5.9.3" }, overrides: { "uri-js": "npm:uri-js-replace@^1.0.1", @@ -105592,6 +105592,7 @@ var require_tar = __commonJS({ exports2.listTar = listTar; exports2.extractTar = extractTar3; exports2.createTar = createTar; + var core29 = __importStar2(require_core()); var exec_1 = require_exec(); var io9 = __importStar2(require_io()); var fs_1 = require("fs"); @@ -105644,7 +105645,7 @@ var require_tar = __commonJS({ args.push("--posix", "-cf", BSD_TAR_ZSTD ? tarFile : cacheFileName.replace(new RegExp(`\\${path30.sep}`, "g"), "/"), "--exclude", BSD_TAR_ZSTD ? tarFile : cacheFileName.replace(new RegExp(`\\${path30.sep}`, "g"), "/"), "-P", "-C", workingDirectory.replace(new RegExp(`\\${path30.sep}`, "g"), "/"), "--files-from", constants_1.ManifestFilename); break; case "extract": - args.push("-xf", BSD_TAR_ZSTD ? tarFile : archivePath.replace(new RegExp(`\\${path30.sep}`, "g"), "/"), "-P", "-C", workingDirectory.replace(new RegExp(`\\${path30.sep}`, "g"), "/")); + args.push("-xf", BSD_TAR_ZSTD ? tarFile : archivePath.replace(new RegExp(`\\${path30.sep}`, "g"), "/"), "-P", "-C", BSD_TAR_ZSTD ? quoteAbsolutePath(workingDirectory) : workingDirectory.replace(new RegExp(`\\${path30.sep}`, "g"), "/")); break; case "list": args.push("-tf", BSD_TAR_ZSTD ? tarFile : archivePath.replace(new RegExp(`\\${path30.sep}`, "g"), "/"), "-P"); @@ -105675,16 +105676,19 @@ var require_tar = __commonJS({ } else { args = [[...tarArgs].join(" "), [...compressionArgs].join(" ")]; } - if (BSD_TAR_ZSTD) { - return args; - } - return [args.join(" ")]; + return { + commands: BSD_TAR_ZSTD ? args : [args.join(" ")], + requiresTempDirectory: BSD_TAR_ZSTD && type !== "create" + }; }); } function getWorkingDirectory() { var _a6; return (_a6 = process.env["GITHUB_WORKSPACE"]) !== null && _a6 !== void 0 ? _a6 : process.cwd(); } + function quoteAbsolutePath(filePath) { + return `"${path30.resolve(filePath).replace(new RegExp(`\\${path30.sep}`, "g"), "/")}"`; + } function getDecompressionProgram(tarPath, compressionMethod, archivePath) { return __awaiter2(this, void 0, void 0, function* () { const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD && compressionMethod !== constants_1.CompressionMethod.Gzip && IS_WINDOWS; @@ -105693,17 +105697,13 @@ var require_tar = __commonJS({ return BSD_TAR_ZSTD ? [ "zstd -d --long=30 --force -o", constants_1.TarFilename, - archivePath.replace(new RegExp(`\\${path30.sep}`, "g"), "/") + quoteAbsolutePath(archivePath) ] : [ "--use-compress-program", IS_WINDOWS ? '"zstd -d --long=30"' : "unzstd --long=30" ]; case constants_1.CompressionMethod.ZstdWithoutLong: - return BSD_TAR_ZSTD ? [ - "zstd -d --force -o", - constants_1.TarFilename, - archivePath.replace(new RegExp(`\\${path30.sep}`, "g"), "/") - ] : ["--use-compress-program", IS_WINDOWS ? '"zstd -d"' : "unzstd"]; + return BSD_TAR_ZSTD ? ["zstd -d --force -o", constants_1.TarFilename, quoteAbsolutePath(archivePath)] : ["--use-compress-program", IS_WINDOWS ? '"zstd -d"' : "unzstd"]; default: return ["-z"]; } @@ -105748,24 +105748,39 @@ var require_tar = __commonJS({ } }); } + function execReadCommands(archivePath, compressionMethod, type) { + return __awaiter2(this, void 0, void 0, function* () { + const { commands, requiresTempDirectory } = yield getCommands(compressionMethod, type, archivePath); + const tempDirectory = requiresTempDirectory ? yield utils.createTempDirectory() : void 0; + try { + yield execCommands(commands, tempDirectory); + } finally { + if (tempDirectory) { + try { + yield io9.rmRF(tempDirectory); + } catch (error3) { + core29.debug(`Failed to delete temporary tar directory: ${error3}`); + } + } + } + }); + } function listTar(archivePath, compressionMethod) { return __awaiter2(this, void 0, void 0, function* () { - const commands = yield getCommands(compressionMethod, "list", archivePath); - yield execCommands(commands); + yield execReadCommands(archivePath, compressionMethod, "list"); }); } function extractTar3(archivePath, compressionMethod) { return __awaiter2(this, void 0, void 0, function* () { const workingDirectory = getWorkingDirectory(); yield io9.mkdirP(workingDirectory); - const commands = yield getCommands(compressionMethod, "extract", archivePath); - yield execCommands(commands); + yield execReadCommands(archivePath, compressionMethod, "extract"); }); } function createTar(archiveFolder, sourceDirectories, compressionMethod) { return __awaiter2(this, void 0, void 0, function* () { (0, fs_1.writeFileSync)(path30.join(archiveFolder, constants_1.ManifestFilename), sourceDirectories.join("\n")); - const commands = yield getCommands(compressionMethod, "create"); + const { commands } = yield getCommands(compressionMethod, "create"); yield execCommands(commands, archiveFolder); }); } @@ -107381,6 +107396,12 @@ var require_follow_redirects = __commonJS({ RedirectableRequest.prototype._sanitizeOptions = function(options) { if (!options.headers) { options.headers = {}; + } else if (Array.isArray(options.headers)) { + var headerList = options.headers; + options.headers = {}; + for (var i = 0; i < headerList.length; i += 2) { + options.headers[headerList[i]] = headerList[i + 1]; + } } if (!isArray2(options.sensitiveHeaders)) { options.sensitiveHeaders = []; @@ -107655,7 +107676,7 @@ var require_follow_redirects = __commonJS({ return URL2 && value instanceof URL2; } function escapeRegex(regex) { - return regex.replace(/[\]\\/()*+?.$]/g, "\\$&"); + return regex.replace(/[[\]\\/()*+?.^$|]/g, "\\$&"); } module2.exports = wrap({ http, https: https3 }); module2.exports.wrap = wrap; @@ -168147,7 +168168,7 @@ function readBlockScalar(state, parentIndent, props) { state.position = linePosition + column; throwError(state, "tab characters must not be used in indentation"); } - if (column < maxLeadingIndent) { + if (column >= parentIndent && column < maxLeadingIndent) { state.position = linePosition + column; throwError(state, "bad indentation of a mapping entry"); } @@ -168357,13 +168378,16 @@ function readBlockMapping(state, nodeIndent, flowIndent, props) { ch = state.input.charCodeAt(++state.position); if (!isWsOrEolOrEnd(ch)) throwError(state, "a whitespace character is expected after the key-value separator within a block mapping"); if (!mappingOpened) { - restoreState(state, beforeKey); - addMappingEvent(state, beforeKey.position, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, COLLECTION_STYLE.BLOCK); + state.events.splice(beforeKey.eventsLength, 0, { + type: EVENT_ID.MAPPING, + start: beforeKey.position, + anchorStart: props.anchorStart, + anchorEnd: props.anchorEnd, + tagStart: props.tagStart, + tagEnd: props.tagEnd, + style: COLLECTION_STYLE.BLOCK + }); mappingOpened = true; - parseNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true); - ch = state.input.charCodeAt(state.position); - while (isWhiteSpace(ch)) ch = state.input.charCodeAt(++state.position); - state.position++; } detected = true; atExplicitKey = false; @@ -188637,7 +188661,7 @@ tmp/lib/tmp.js: *) js-yaml/dist/js-yaml.mjs: - (*! js-yaml 5.4.2 https://github.com/nodeca/js-yaml @license MIT *) + (*! js-yaml 5.4.3 https://github.com/nodeca/js-yaml @license MIT *) long/index.js: (** From 71ad3a794a9edd2ecb4843da2d0d24bab3908a2e Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 14 Oct 2026 13:57:43 +0100 Subject: [PATCH 095/107] Fix typo in log message --- lib/entry-points.js | 2 +- src/start-proxy.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index e6beeaf6d9..9f141a0780 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -187870,7 +187870,7 @@ async function getProxyBinaryPath(action, apiDetails) { proxyInfo.url ); const temp = await downloadProxy(logger2, proxyInfo.url, authorization); - logger2.info(`Downloaded the authentication proxy assset to '${temp}'.`); + logger2.info(`Downloaded the authentication proxy asset to '${temp}'.`); const extracted = await extractProxy(logger2, temp); proxyBin = await cacheProxy( logger2, diff --git a/src/start-proxy.ts b/src/start-proxy.ts index 21a5012f12..b0cfd6270e 100644 --- a/src/start-proxy.ts +++ b/src/start-proxy.ts @@ -566,7 +566,7 @@ export async function getProxyBinaryPath( ); const temp = await downloadProxy(logger, proxyInfo.url, authorization); - logger.info(`Downloaded the authentication proxy assset to '${temp}'.`); + logger.info(`Downloaded the authentication proxy asset to '${temp}'.`); const extracted = await extractProxy(logger, temp); proxyBin = await cacheProxy( From 962aaad9386547e14df8ca7552245b0a9b3e8218 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 14 Oct 2026 13:58:37 +0100 Subject: [PATCH 096/107] Rename `proxyBin` to `proxyDir` --- lib/entry-points.js | 10 +++++----- src/start-proxy.ts | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 9f141a0780..8d6df2f785 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -187859,8 +187859,8 @@ async function getProxyBinaryPath(action, apiDetails) { logger2.info( `Using authentication proxy from CodeQL release ${proxyInfo.version}.` ); - let proxyBin = toolcache4.find(proxyFileName, proxyInfo.version); - if (!proxyBin) { + let proxyDir = toolcache4.find(proxyFileName, proxyInfo.version); + if (!proxyDir) { logger2.info( `Authentication proxy is not in the toolcache. Will try to download it from '${proxyInfo.url}'.` ); @@ -187872,15 +187872,15 @@ async function getProxyBinaryPath(action, apiDetails) { const temp = await downloadProxy(logger2, proxyInfo.url, authorization); logger2.info(`Downloaded the authentication proxy asset to '${temp}'.`); const extracted = await extractProxy(logger2, temp); - proxyBin = await cacheProxy( + proxyDir = await cacheProxy( logger2, extracted, proxyFileName, proxyInfo.version ); - logger2.info(`Extracted the authentication proxy to '${proxyBin}'.`); + logger2.info(`Extracted the authentication proxy to '${proxyDir}'.`); } - return path27.join(proxyBin, proxyFileName); + return path27.join(proxyDir, proxyFileName); } finally { logger2.endGroup(); } diff --git a/src/start-proxy.ts b/src/start-proxy.ts index b0cfd6270e..c3826ed6e3 100644 --- a/src/start-proxy.ts +++ b/src/start-proxy.ts @@ -552,9 +552,9 @@ export async function getProxyBinaryPath( `Using authentication proxy from CodeQL release ${proxyInfo.version}.`, ); - let proxyBin = toolcache.find(proxyFileName, proxyInfo.version); + let proxyDir = toolcache.find(proxyFileName, proxyInfo.version); - if (!proxyBin) { + if (!proxyDir) { logger.info( `Authentication proxy is not in the toolcache. Will try to download it from '${proxyInfo.url}'.`, ); @@ -569,16 +569,16 @@ export async function getProxyBinaryPath( logger.info(`Downloaded the authentication proxy asset to '${temp}'.`); const extracted = await extractProxy(logger, temp); - proxyBin = await cacheProxy( + proxyDir = await cacheProxy( logger, extracted, proxyFileName, proxyInfo.version, ); - logger.info(`Extracted the authentication proxy to '${proxyBin}'.`); + logger.info(`Extracted the authentication proxy to '${proxyDir}'.`); } - return path.join(proxyBin, proxyFileName); + return path.join(proxyDir, proxyFileName); } finally { logger.endGroup(); } From 28d5dd981873bfedbe4f650248813f333fe96451 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 14 Oct 2026 15:07:40 +0100 Subject: [PATCH 097/107] Revert "Allow logging functions to accept `string[]` directly" This reverts commit 909fda1468f8ef25624848914b92c3faeba7cfe7. --- lib/entry-points.js | 20 ++++---------------- src/logging.test.ts | 17 ----------------- src/logging.ts | 43 ++++++++----------------------------------- src/testing-utils.ts | 14 +++++++------- 4 files changed, 19 insertions(+), 75 deletions(-) delete mode 100644 src/logging.test.ts diff --git a/lib/entry-points.js b/lib/entry-points.js index 8d6df2f785..e56668bbe2 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -170475,24 +170475,12 @@ function fixCodeQualityCategory(logger2, category, env = getEnv()) { // src/logging.ts var core5 = __toESM(require_core()); -var joinMessageStrings = (message) => { - if (Array.isArray(message)) { - return message.join(" "); - } else { - return message; - } -}; -var autoJoinMessageStrings = (fn) => { - return (message) => { - return fn(joinMessageStrings(message)); - }; -}; function getActionsLogger() { return { - debug: autoJoinMessageStrings(core5.debug), - info: autoJoinMessageStrings(core5.info), - warning: autoJoinMessageStrings(core5.warning), - error: autoJoinMessageStrings(core5.error), + debug: core5.debug, + info: core5.info, + warning: core5.warning, + error: core5.error, isDebug: core5.isDebug, startGroup: core5.startGroup, endGroup: core5.endGroup diff --git a/src/logging.test.ts b/src/logging.test.ts deleted file mode 100644 index 33f6f8c162..0000000000 --- a/src/logging.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import test from "ava"; - -import { joinMessageStrings } from "./logging"; -import { setupTests } from "./testing-utils"; - -setupTests(test); - -test("joinMessageStrings", async (t) => { - // For strings and errors, it is the identity function. - t.deepEqual(joinMessageStrings("Hello"), "Hello"); - - const error = new Error("Some error"); - t.deepEqual(joinMessageStrings(error), error); - - // For arrays of strings, we get a join-ed string. - t.deepEqual(joinMessageStrings(["foo", "bar"]), "foo bar"); -}); diff --git a/src/logging.ts b/src/logging.ts index 177aca6c7b..2c34cb54d4 100644 --- a/src/logging.ts +++ b/src/logging.ts @@ -1,16 +1,10 @@ import * as core from "@actions/core"; -/** Types that all of our logging functions accept. */ -export type Loggable = string | string[]; - -/** Some logging functions also accept errors directly. */ -export type LoggableError = Loggable | Error; - export interface Logger { - debug: (message: Loggable) => void; - info: (message: Loggable) => void; - warning: (message: LoggableError) => void; - error: (message: LoggableError) => void; + debug: (message: string) => void; + info: (message: string) => void; + warning: (message: string | Error) => void; + error: (message: string | Error) => void; isDebug: () => boolean; @@ -18,33 +12,12 @@ export interface Logger { endGroup: () => void; } -/** If `message` is an array of strings, the array is `join`-ed into one string separated by spaces. */ -export const joinMessageStrings = ( - message: string[] | string | T, -): string | T => { - if (Array.isArray(message)) { - return message.join(" "); - } else { - return message; - } -}; - -/** - * Wraps a logging function so that `joinMessageStrings` is applied to the input before - * calling the wrapped logging function. - */ -const autoJoinMessageStrings = (fn: (msg: string | T) => void) => { - return (message: string[] | string | T) => { - return fn(joinMessageStrings(message)); - }; -}; - export function getActionsLogger(): Logger { return { - debug: autoJoinMessageStrings(core.debug), - info: autoJoinMessageStrings(core.info), - warning: autoJoinMessageStrings(core.warning), - error: autoJoinMessageStrings(core.error), + debug: core.debug, + info: core.info, + warning: core.warning, + error: core.error, isDebug: core.isDebug, startGroup: core.startGroup, endGroup: core.endGroup, diff --git a/src/testing-utils.ts b/src/testing-utils.ts index 4ff4d49343..d48f9e90f8 100644 --- a/src/testing-utils.ts +++ b/src/testing-utils.ts @@ -30,7 +30,7 @@ import { featureConfig, FeatureEnablement, } from "./feature-flags"; -import { joinMessageStrings, Loggable, LoggableError, Logger } from "./logging"; +import { Logger } from "./logging"; import { OverlayDatabaseMode } from "./overlay/overlay-database-mode"; import { getBundlePlatform } from "./platform"; import { ActionName } from "./status-report"; @@ -658,8 +658,8 @@ export class RecordingLogger implements Logger { constructor(private readonly logToConsole: boolean = true) {} - private addMessage(level: LogLevel, message: LoggableError): void { - this.messages.push({ type: level, message: joinMessageStrings(message) }); + private addMessage(level: LogLevel, message: string | Error): void { + this.messages.push({ type: level, message }); if (this.logToConsole) { // eslint-disable-next-line no-console @@ -684,19 +684,19 @@ export class RecordingLogger implements Logger { return true; } - debug(message: Loggable) { + debug(message: string) { this.addMessage("debug", message); } - info(message: Loggable) { + info(message: string) { this.addMessage("info", message); } - warning(message: LoggableError) { + warning(message: string | Error) { this.addMessage("warning", message); } - error(message: LoggableError) { + error(message: string | Error) { this.addMessage("error", message); } From c98271eca28faaceae6b197b4e5d2a3a7991cc5a Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 14 Oct 2026 15:57:53 +0100 Subject: [PATCH 098/107] Add change note for #4148 --- unreleased-change-notes/analyze-checkout-path-validation.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 unreleased-change-notes/analyze-checkout-path-validation.md diff --git a/unreleased-change-notes/analyze-checkout-path-validation.md b/unreleased-change-notes/analyze-checkout-path-validation.md new file mode 100644 index 0000000000..4704376a47 --- /dev/null +++ b/unreleased-change-notes/analyze-checkout-path-validation.md @@ -0,0 +1 @@ +- The `codeql-action/analyze` step now validates that a correct argument for the `checkout_path` input has been provided. The `checkout_path` input must be set to the path where the repository that is being analyzed is checked out at on the runner, if that path is something other than the workspace root. If the path does not point to a repository checkout or is different from the path that was used by `codeql-action/init`, then the CodeQL Action now produces a warning. [#4148](https://github.com/github/codeql-action/pull/4148) From c8bd0195fb2ec9584b1bd6faf9ff5e2983c63d82 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 14 Oct 2026 16:03:37 +0100 Subject: [PATCH 099/107] Add change note for #4198 --- unreleased-change-notes/start-proxy-setup-logic.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 unreleased-change-notes/start-proxy-setup-logic.md diff --git a/unreleased-change-notes/start-proxy-setup-logic.md b/unreleased-change-notes/start-proxy-setup-logic.md new file mode 100644 index 0000000000..fc3582843e --- /dev/null +++ b/unreleased-change-notes/start-proxy-setup-logic.md @@ -0,0 +1 @@ +- The `codeql-action/start-proxy` step that is used in Code Scanning Default Setup now finds CodeQL releases using the same logic as `codeql-action/init`. This primarily benefits customers who are using GitHub instances other than `github.com` where the `codeql-action/start-proxy` step may previously have been unable to locate recent releases and ended up using outdated versions of the private registry authentication proxy as a result. [#4198](https://github.com/github/codeql-action/pull/4198) From a897ed5c2eeeb4862bf224c65f62a8b2478eb581 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Wed, 14 Oct 2026 16:05:40 +0100 Subject: [PATCH 100/107] Add change note for #4206 --- unreleased-change-notes/restore-keys.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 unreleased-change-notes/restore-keys.md diff --git a/unreleased-change-notes/restore-keys.md b/unreleased-change-notes/restore-keys.md new file mode 100644 index 0000000000..3612c1b607 --- /dev/null +++ b/unreleased-change-notes/restore-keys.md @@ -0,0 +1 @@ +- Resolved an issue with third-party caching implementations that prevented caches from being restored correctly. [#4206](https://github.com/github/codeql-action/pull/4206) From 8dec0b9f88b61a76f5fc97056ee8e7dc8a1a8022 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 15 Oct 2026 11:03:10 +0100 Subject: [PATCH 101/107] Rename `path` to `result` in tests --- src/start-proxy.test.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/start-proxy.test.ts b/src/start-proxy.test.ts index 22a9537cd4..78704a38a6 100644 --- a/src/start-proxy.test.ts +++ b/src/start-proxy.test.ts @@ -935,17 +935,17 @@ test.serial( sinon.stub(actionsUtil, "isRunningLocalAction").returns(true); const features = mockOfflineFeatures(tempDir, logger); - const path = await startProxyExports.getProxyBinaryPath( + const result = await startProxyExports.getProxyBinaryPath( initAllState({ logger, features }), SAMPLE_DOTCOM_API_DETAILS, ); - t.assert(path); + t.assert(result); t.is( - path.path, + result.path, filepath.join(toolcachePath, startProxyExports.getProxyFilename()), ); - t.is(path.version, defaults.cliVersion); + t.is(result.version, defaults.cliVersion); }); }, ); @@ -982,7 +982,7 @@ test.serial( sinon.stub(actionsUtil, "isRunningLocalAction").returns(false); state.env.set(ActionsEnvVars.GITHUB_ACTION_REPOSITORY, "test/repo"); - const path = await startProxyExports.getProxyBinaryPath( + const result = await startProxyExports.getProxyBinaryPath( { ...state, features: createFeatures([]), @@ -999,12 +999,12 @@ test.serial( st.onceWith(extractTar, archivePath); st.onceWith(cacheDir, extractedPath); - t.assert(path); + t.assert(result); t.is( - path.path, + result.path, filepath.join(toolcachePath, startProxyExports.getProxyFilename()), ); - t.is(path.version, defaults.cliVersion); + t.is(result.version, defaults.cliVersion); checkExpectedLogMessages(t, logger.messages, [ `Found private registry proxy ${startProxyExports.getProxyPackage(getTestPlatform(state))} in test/repo on https://github.com with URL ${downloadUrl}`, @@ -1080,7 +1080,7 @@ test.serial( sinon.stub(actionsUtil, "isRunningLocalAction").returns(false); state.env.set(ActionsEnvVars.GITHUB_ACTION_REPOSITORY, "test/repo"); - const path = await startProxyExports.getProxyBinaryPath( + const result = await startProxyExports.getProxyBinaryPath( { ...state, features, @@ -1098,12 +1098,12 @@ test.serial( st.onceWith(extractTar, archivePath); st.onceWith(cacheDir, extractedPath); - t.assert(path); + t.assert(result); t.is( - path.path, + result.path, filepath.join(toolcachePath, startProxyExports.getProxyFilename()), ); - t.is(path.version, expectedVersion); + t.is(result.version, expectedVersion); }); checkExpectedLogMessages(t, logger.messages, [ From 444333376e064d207fe1dc74e881528bf11649c1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 15 Oct 2026 10:34:02 +0000 Subject: [PATCH 102/107] Update changelog for v4.39.0 --- CHANGELOG.md | 5 ++++- unreleased-change-notes/analyze-checkout-path-validation.md | 1 - unreleased-change-notes/restore-keys.md | 1 - unreleased-change-notes/start-proxy-setup-logic.md | 1 - 4 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 unreleased-change-notes/analyze-checkout-path-validation.md delete mode 100644 unreleased-change-notes/restore-keys.md delete mode 100644 unreleased-change-notes/start-proxy-setup-logic.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ce2edd612..1a55f7e091 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,12 @@ See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs. -## [UNRELEASED] +## 4.39.0 - 15 Oct 2026 - _Breaking change_: Bump the minimum required CodeQL bundle version to 2.20.7. [#4205](https://github.com/github/codeql-action/pull/4205) +- The `codeql-action/analyze` step now validates that a correct argument for the `checkout_path` input has been provided. The `checkout_path` input must be set to the path where the repository that is being analyzed is checked out at on the runner, if that path is something other than the workspace root. If the path does not point to a repository checkout or is different from the path that was used by `codeql-action/init`, then the CodeQL Action now produces a warning. [#4148](https://github.com/github/codeql-action/pull/4148) +- Resolved an issue with third-party caching implementations that prevented caches from being restored correctly. [#4206](https://github.com/github/codeql-action/pull/4206) +- The `codeql-action/start-proxy` step that is used in Code Scanning Default Setup now finds CodeQL releases using the same logic as `codeql-action/init`. This primarily benefits customers who are using GitHub instances other than `github.com` where the `codeql-action/start-proxy` step may previously have been unable to locate recent releases and ended up using outdated versions of the private registry authentication proxy as a result. [#4198](https://github.com/github/codeql-action/pull/4198) ## 4.38.3 - 08 Oct 2026 diff --git a/unreleased-change-notes/analyze-checkout-path-validation.md b/unreleased-change-notes/analyze-checkout-path-validation.md deleted file mode 100644 index 4704376a47..0000000000 --- a/unreleased-change-notes/analyze-checkout-path-validation.md +++ /dev/null @@ -1 +0,0 @@ -- The `codeql-action/analyze` step now validates that a correct argument for the `checkout_path` input has been provided. The `checkout_path` input must be set to the path where the repository that is being analyzed is checked out at on the runner, if that path is something other than the workspace root. If the path does not point to a repository checkout or is different from the path that was used by `codeql-action/init`, then the CodeQL Action now produces a warning. [#4148](https://github.com/github/codeql-action/pull/4148) diff --git a/unreleased-change-notes/restore-keys.md b/unreleased-change-notes/restore-keys.md deleted file mode 100644 index 3612c1b607..0000000000 --- a/unreleased-change-notes/restore-keys.md +++ /dev/null @@ -1 +0,0 @@ -- Resolved an issue with third-party caching implementations that prevented caches from being restored correctly. [#4206](https://github.com/github/codeql-action/pull/4206) diff --git a/unreleased-change-notes/start-proxy-setup-logic.md b/unreleased-change-notes/start-proxy-setup-logic.md deleted file mode 100644 index fc3582843e..0000000000 --- a/unreleased-change-notes/start-proxy-setup-logic.md +++ /dev/null @@ -1 +0,0 @@ -- The `codeql-action/start-proxy` step that is used in Code Scanning Default Setup now finds CodeQL releases using the same logic as `codeql-action/init`. This primarily benefits customers who are using GitHub instances other than `github.com` where the `codeql-action/start-proxy` step may previously have been unable to locate recent releases and ended up using outdated versions of the private registry authentication proxy as a result. [#4198](https://github.com/github/codeql-action/pull/4198) From eb1c428e6e3725d2b527aec0ee5db4303c8f669d Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 15 Oct 2026 11:39:58 +0100 Subject: [PATCH 103/107] Trigger workflows From c823e5d85028c044d6792aaafd8008a564540ba4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 15 Oct 2026 10:58:49 +0000 Subject: [PATCH 104/107] Revert "Update version and changelog for v3.38.3" This reverts commit 9c17bbcb81030063aac86535ce09e63416c7c589. --- CHANGELOG.md | 100 +++++++++++++++++++++++++-------------------------- package.json | 2 +- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d42005e30..9687f725d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,102 +2,102 @@ See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs. -## 3.38.3 - 08 Oct 2026 +## 4.38.3 - 08 Oct 2026 - _Upcoming breaking change_: CodeQL version 2.21.2 and earlier were discontinued on 24 September 2026 alongside GitHub Enterprise Server 3.17, and will be unsupported by the next minor release of the CodeQL Action. Added a deprecation warning for customers using these versions of CodeQL. [#4188](https://github.com/github/codeql-action/pull/4188) - Update default CodeQL bundle version to [2.27.2](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.27.2). [#4203](https://github.com/github/codeql-action/pull/4203) - Fixed a bug where the decision of whether to use a per-language bundle did not account for custom configurations that reference queries outside of compiled CodeQL packs. This issue was caught during internal testing and did not affect any customer repositories. We will resume the roll out of per-language bundles in the coming weeks. [#4184](https://github.com/github/codeql-action/pull/4184) -## 3.38.2 - 24 Sept 2026 +## 4.38.2 - 24 Sept 2026 - Update default CodeQL bundle version to [2.27.1](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.27.1). [#4160](https://github.com/github/codeql-action/pull/4160) -## 3.38.1 - 18 Sept 2026 +## 4.38.1 - 18 Sept 2026 - The CodeQL Action now has experimental support for CodeQL releases for which per-language bundles are available. Per-language bundles support analysis for a single language and are therefore smaller than the combined bundles that allow analysis for all supported languages. As a result, per-language bundles take up less space on disk and are faster to download. We expect to roll this change out to everyone in the coming weeks. [#4146](https://github.com/github/codeql-action/pull/4146) -## 3.38.0 - 09 Sept 2026 +## 4.38.0 - 09 Sept 2026 - On GitHub-hosted runners, the CodeQL Action now deletes unused CodeQL bundles from the toolcache before downloading a different bundle, which frees up disk space for the analysis. We expect to roll this change out to everyone in September. [#4124](https://github.com/github/codeql-action/pull/4124) - The CodeQL Action now supports CodeQL releases that are compatible with Linux Arm64 and downloads the native `linux-arm64` CodeQL bundle when available. [#4072](https://github.com/github/codeql-action/pull/4072) - Update default CodeQL bundle version to [2.27.0](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.27.0). [#4129](https://github.com/github/codeql-action/pull/4129) -## 3.37.9 - 26 Aug 2026 +## 4.37.9 - 26 Aug 2026 - Update default CodeQL bundle version to [2.26.4](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.4). [#4106](https://github.com/github/codeql-action/pull/4106) -## 3.37.8 - 21 Aug 2026 +## 4.37.8 - 21 Aug 2026 No user facing changes. -## 3.37.7 - 13 Aug 2026 +## 4.37.7 - 13 Aug 2026 - Update default CodeQL bundle version to [2.26.3](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.3). [#4085](https://github.com/github/codeql-action/pull/4085) -## 3.37.6 - 04 Aug 2026 +## 4.37.6 - 04 Aug 2026 - Changed the default filepath for the new remote file address format that was introduced in CodeQL Action 4.37.0 / 3.37.0 to `.github/codeql-config.yml` to align it with the suggested path that is used elsewhere. [#4070](https://github.com/github/codeql-action/pull/4070) -## 3.37.5 - 03 Aug 2026 +## 4.37.5 - 03 Aug 2026 - Fixed a bug where a network error while streaming the download of the CodeQL bundle could terminate the `init` Action instead of falling back to downloading the bundle before extracting it. [#4061](https://github.com/github/codeql-action/pull/4061) -## 3.37.4 - 29 Jul 2026 +## 4.37.4 - 29 Jul 2026 - This version of the CodeQL Action adds support for the `tools` input for the `codeql-action/init` step to be specified using a `github-codeql-tools` [repository property](https://docs.github.com/en/organizations/managing-organization-settings/managing-custom-properties-for-repositories-in-your-organization). This feature will gradually be rolled out following the release of this version. Once rolled out, this allows for the CodeQL CLI version that is used in GitHub-managed workflows, such as Default Setup, to be set to a custom value. For example, customers who run into issues with rate limits when a new CodeQL CLI version is released can set the value to `toolcache` to always use the CodeQL CLI version that is available in the runner toolcache. For Advanced Setup workflows, the value provided for `tools` in the workflow definition always takes precedence unless the value of the repository property starts with `!`. [#4037](https://github.com/github/codeql-action/pull/4037) - Update default CodeQL bundle version to [2.26.2](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.2). [#4051](https://github.com/github/codeql-action/pull/4051) -## 3.37.3 - 22 Jul 2026 +## 4.37.3 - 22 Jul 2026 No user facing changes. -## 3.37.2 - 21 Jul 2026 +## 4.37.2 - 21 Jul 2026 - The new address format for the `config-file` input that was introduced in CodeQL Action 4.37.0 is now enabled by default. In addition to the format described there, the `remote=` prefix can now be used to explicitly indicate that the input refers to a remote file. All previous input formats continue to be accepted as well. [#4023](https://github.com/github/codeql-action/pull/4023) - The CodeQL Action can now make use of [configured private registries](https://docs.github.com/en/code-security/how-tos/secure-at-scale/configure-organization-security/manage-usage-and-access/giving-org-access-private-registries) in Default Setup to retrieve CodeQL configuration files from remote repositories that require authentication. This will allow customers to store their CodeQL configuration in a single repository that can then be referenced by Default Setup workflows in other repositories. We expect to roll this and other, related changes out to everyone in July. [#4007](https://github.com/github/codeql-action/pull/4007) -## 3.37.1 - 16 Jul 2026 +## 4.37.1 - 16 Jul 2026 - _Upcoming breaking change_: Add a deprecation warning for customers using CodeQL version 2.20.6 and earlier. These versions of CodeQL were discontinued on 1 July 2026 alongside GitHub Enterprise Server 3.16, and will be unsupported by the next minor release of the CodeQL Action. [#3956](https://github.com/github/codeql-action/pull/3956) - Update default CodeQL bundle version to [2.26.1](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.1). [#4019](https://github.com/github/codeql-action/pull/4019) -## 3.37.0 - 08 Jul 2026 +## 4.37.0 - 08 Jul 2026 - Update default CodeQL bundle version to [2.26.0](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.0). [#3995](https://github.com/github/codeql-action/pull/3995) - In addition to the existing input format, the `config-file` input for the `codeql-action/init` step will soon support a new `[owner/]repo[@ref][:path]` format. All components except the repository name are optional. If omitted, `owner` defaults to the same owner as the repository the analysis is running for, `ref` to `main`, and `path` to `.github/codeql-action.yaml`. Support for this format ships in this version of the CodeQL Action, but will only be enabled over the coming weeks. [#3973](https://github.com/github/codeql-action/pull/3973) -## 3.36.3 - 01 Jul 2026 +## 4.36.3 - 01 Jul 2026 No user facing changes. -## 3.36.2 - 04 Jun 2026 +## 4.36.2 - 04 Jun 2026 - Cache CodeQL CLI version information across Actions steps. [#3943](https://github.com/github/codeql-action/pull/3943) - Reduce requests while waiting for analysis processing by using exponential backoff when polling SARIF processing status. [#3937](https://github.com/github/codeql-action/pull/3937) - Update default CodeQL bundle version to [2.25.6](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.6). [#3948](https://github.com/github/codeql-action/pull/3948) -## 3.36.1 - 02 Jun 2026 +## 4.36.1 - 02 Jun 2026 No user facing changes. -## 3.36.0 - 22 May 2026 +## 4.36.0 - 22 May 2026 - _Breaking change_: Bump the minimum required CodeQL bundle version to 2.19.4. [#3894](https://github.com/github/codeql-action/pull/3894) - Add support for SHA-256 Git object IDs. [#3893](https://github.com/github/codeql-action/pull/3893) - Update default CodeQL bundle version to [2.25.5](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.5). [#3926](https://github.com/github/codeql-action/pull/3926) -## 3.35.5 - 15 May 2026 +## 4.35.5 - 15 May 2026 - We have improved how the JavaScript bundles for the CodeQL Action are generated to avoid duplication across bundles and reduce the size of the repository by around 70%. This should have no effect on the runtime behaviour of the CodeQL Action. [#3899](https://github.com/github/codeql-action/pull/3899) - For performance and accuracy reasons, [improved incremental analysis](https://github.com/github/roadmap/issues/1158) will now only be enabled on a pull request when diff-informed analysis is also enabled for that run. If diff-informed analysis is unavailable (for example, because the PR diff ranges could not be computed), the action will fall back to a full analysis. [#3791](https://github.com/github/codeql-action/pull/3791) - If multiple inputs are provided for the GitHub-internal `analysis-kinds` input, only `code-scanning` will be enabled. The `analysis-kinds` input is experimental, for GitHub-internal use only, and may change without notice at any time. [#3892](https://github.com/github/codeql-action/pull/3892) - Added an experimental change which, when running a Code Scanning analysis for a PR with [improved incremental analysis](https://github.com/github/roadmap/issues/1158) enabled, prefers CodeQL CLI versions that have a cached overlay-base database for the configured languages. This speeds up analysis for a repository when there is not yet a cached overlay-base database for the latest CLI version. We expect to roll this change out to everyone in May. [#3880](https://github.com/github/codeql-action/pull/3880) -## 3.35.4 - 07 May 2026 +## 4.35.4 - 07 May 2026 - Update default CodeQL bundle version to [2.25.4](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.4). [#3881](https://github.com/github/codeql-action/pull/3881) -## 3.35.3 - 01 May 2026 +## 4.35.3 - 01 May 2026 - _Upcoming breaking change_: Add a deprecation warning for customers using CodeQL version 2.19.3 and earlier. These versions of CodeQL were discontinued on 9 April 2026 alongside GitHub Enterprise Server 3.15, and will be unsupported by the next minor release of the CodeQL Action. [#3837](https://github.com/github/codeql-action/pull/3837) - Configurations for private registries that use Cloudsmith or GCP OIDC are now accepted. [#3850](https://github.com/github/codeql-action/pull/3850) @@ -105,7 +105,7 @@ No user facing changes. - Fixed a bug where two diagnostics produced within the same millisecond could overwrite each other on disk, causing one of them to be lost. [#3852](https://github.com/github/codeql-action/pull/3852) - Update default CodeQL bundle version to [2.25.3](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.3). [#3865](https://github.com/github/codeql-action/pull/3865) -## 3.35.2 - 15 Apr 2026 +## 4.35.2 - 15 Apr 2026 - The undocumented TRAP cache cleanup feature that could be enabled using the `CODEQL_ACTION_CLEANUP_TRAP_CACHES` environment variable is deprecated and will be removed in May 2026. If you are affected by this, we recommend disabling TRAP caching by passing the `trap-caching: false` input to the `init` Action. [#3795](https://github.com/github/codeql-action/pull/3795) - The Git version 2.36.0 requirement for improved incremental analysis now only applies to repositories that contain submodules. [#3789](https://github.com/github/codeql-action/pull/3789) @@ -113,26 +113,26 @@ No user facing changes. - Fixed a bug in the validation of OIDC configurations for private registries that was added in CodeQL Action 4.33.0 / 3.33.0. [#3807](https://github.com/github/codeql-action/pull/3807) - Update default CodeQL bundle version to [2.25.2](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.2). [#3823](https://github.com/github/codeql-action/pull/3823) -## 3.35.1 - 27 Mar 2026 +## 4.35.1 - 27 Mar 2026 - Fix incorrect minimum required Git version for [improved incremental analysis](https://github.com/github/roadmap/issues/1158): it should have been 2.36.0, not 2.11.0. [#3781](https://github.com/github/codeql-action/pull/3781) -## 3.35.0 - 27 Mar 2026 +## 4.35.0 - 27 Mar 2026 - Reduced the minimum Git version required for [improved incremental analysis](https://github.com/github/roadmap/issues/1158) from 2.38.0 to 2.11.0. [#3767](https://github.com/github/codeql-action/pull/3767) - Update default CodeQL bundle version to [2.25.1](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.1). [#3773](https://github.com/github/codeql-action/pull/3773) -## 3.34.1 - 20 Mar 2026 +## 4.34.1 - 20 Mar 2026 - Downgrade default CodeQL bundle version to [2.24.3](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.3) due to issues with a small percentage of Actions and JavaScript analyses. [#3762](https://github.com/github/codeql-action/pull/3762) -## 3.34.0 - 20 Mar 2026 +## 4.34.0 - 20 Mar 2026 - Added an experimental change which disables TRAP caching when [improved incremental analysis](https://github.com/github/roadmap/issues/1158) is enabled, since improved incremental analysis supersedes TRAP caching. This will improve performance and reduce Actions cache usage. We expect to roll this change out to everyone in March. [#3569](https://github.com/github/codeql-action/pull/3569) - We are rolling out improved incremental analysis to C/C++ analyses that use build mode `none`. We expect this rollout to be complete by the end of April 2026. [#3584](https://github.com/github/codeql-action/pull/3584) - Update default CodeQL bundle version to [2.25.0](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.0). [#3585](https://github.com/github/codeql-action/pull/3585) -## 3.33.0 - 16 Mar 2026 +## 4.33.0 - 16 Mar 2026 - Upcoming change: Starting April 2026, the CodeQL Action will skip collecting file coverage information on pull requests to improve analysis performance. File coverage information will still be computed on non-PR analyses. Pull request analyses will log a warning about this upcoming change. [#3562](https://github.com/github/codeql-action/pull/3562) @@ -146,11 +146,11 @@ No user facing changes. - Fixed the retry mechanism for database uploads. Previously this would fail with the error "Response body object should not be disturbed or locked". [#3564](https://github.com/github/codeql-action/pull/3564) - A warning is now emitted if the CodeQL Action detects a repository property whose name suggests that it relates to the CodeQL Action, but which is not one of the properties recognised by the current version of the CodeQL Action. [#3570](https://github.com/github/codeql-action/pull/3570) -## 3.32.6 - 05 Mar 2026 +## 4.32.6 - 05 Mar 2026 - Update default CodeQL bundle version to [2.24.3](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.3). [#3548](https://github.com/github/codeql-action/pull/3548) -## 3.32.5 - 02 Mar 2026 +## 4.32.5 - 02 Mar 2026 - Repositories owned by an organization can now set up the `github-codeql-disable-overlay` custom repository property to disable [improved incremental analysis for CodeQL](https://github.com/github/roadmap/issues/1158). First, create a custom repository property with the name `github-codeql-disable-overlay` and the type "True/false" in the organization's settings. Then in the repository's settings, set this property to `true` to disable improved incremental analysis. For more information, 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). This feature is not yet available on GitHub Enterprise Server. [#3507](https://github.com/github/codeql-action/pull/3507) - Added an experimental change so that when [improved incremental analysis](https://github.com/github/roadmap/issues/1158) fails on a runner — potentially due to insufficient disk space — the failure is recorded in the Actions cache so that subsequent runs will automatically skip improved incremental analysis until something changes (e.g. a larger runner is provisioned or a new CodeQL version is released). We expect to roll this change out to everyone in March. [#3487](https://github.com/github/codeql-action/pull/3487) @@ -160,7 +160,7 @@ No user facing changes. - Added an experimental change which allows the `start-proxy` action to resolve the CodeQL CLI version from feature flags instead of using the linked CLI bundle version. We expect to roll this change out to everyone in March. [#3512](https://github.com/github/codeql-action/pull/3512) - The previously experimental changes from versions 4.32.3, 4.32.4, 3.32.3 and 3.32.4 are now enabled by default. [#3503](https://github.com/github/codeql-action/pull/3503), [#3504](https://github.com/github/codeql-action/pull/3504) -## 3.32.4 - 20 Feb 2026 +## 4.32.4 - 20 Feb 2026 - Update default CodeQL bundle version to [2.24.2](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.2). [#3493](https://github.com/github/codeql-action/pull/3493) - Added an experimental change which improves how certificates are generated for the authentication proxy that is used by the CodeQL Action in Default Setup when [private package registries are configured](https://docs.github.com/en/code-security/how-tos/secure-at-scale/configure-organization-security/manage-usage-and-access/giving-org-access-private-registries). This is expected to generate more widely compatible certificates and should have no impact on analyses which are working correctly already. We expect to roll this change out to everyone in February. [#3473](https://github.com/github/codeql-action/pull/3473) @@ -168,89 +168,89 @@ No user facing changes. - Added a setting which allows the CodeQL Action to enable network debugging for Java programs. This will help GitHub staff support customers with troubleshooting issues in GitHub-managed CodeQL workflows, such as Default Setup. This setting can only be enabled by GitHub staff. [#3485](https://github.com/github/codeql-action/pull/3485) - Added a setting which enables GitHub-managed workflows, such as Default Setup, to use a [nightly CodeQL CLI release](https://github.com/dsp-testing/codeql-cli-nightlies) instead of the latest, stable release that is used by default. This will help GitHub staff support customers whose analyses for a given repository or organization require early access to a change in an upcoming CodeQL CLI release. This setting can only be enabled by GitHub staff. [#3484](https://github.com/github/codeql-action/pull/3484) -## 3.32.3 - 13 Feb 2026 +## 4.32.3 - 13 Feb 2026 - Added experimental support for testing connections to [private package registries](https://docs.github.com/en/code-security/how-tos/secure-at-scale/configure-organization-security/manage-usage-and-access/giving-org-access-private-registries). This feature is not currently enabled for any analysis. In the future, it may be enabled by default for Default Setup. [#3466](https://github.com/github/codeql-action/pull/3466) -## 3.32.2 - 05 Feb 2026 +## 4.32.2 - 05 Feb 2026 - Update default CodeQL bundle version to [2.24.1](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.1). [#3460](https://github.com/github/codeql-action/pull/3460) -## 3.32.1 - 02 Feb 2026 +## 4.32.1 - 02 Feb 2026 - A warning is now shown in Default Setup workflow logs if a [private package registry is configured](https://docs.github.com/en/code-security/how-tos/secure-at-scale/configure-organization-security/manage-usage-and-access/giving-org-access-private-registries) using a GitHub Personal Access Token (PAT), but no username is configured. [#3422](https://github.com/github/codeql-action/pull/3422) - Fixed a bug which caused the CodeQL Action to fail when repository properties cannot successfully be retrieved. [#3421](https://github.com/github/codeql-action/pull/3421) -## 3.32.0 - 26 Jan 2026 +## 4.32.0 - 26 Jan 2026 - Update default CodeQL bundle version to [2.24.0](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.0). [#3425](https://github.com/github/codeql-action/pull/3425) -## 3.31.11 - 23 Jan 2026 +## 4.31.11 - 23 Jan 2026 - When running a Default Setup workflow with [Actions debugging enabled](https://docs.github.com/en/actions/how-tos/monitor-workflows/enable-debug-logging), the CodeQL Action will now use more unique names when uploading logs from the Dependabot authentication proxy as workflow artifacts. This ensures that the artifact names do not clash between multiple jobs in a build matrix. [#3409](https://github.com/github/codeql-action/pull/3409) - Improved error handling throughout the CodeQL Action. [#3415](https://github.com/github/codeql-action/pull/3415) - Added experimental support for automatically excluding [generated files](https://docs.github.com/en/repositories/working-with-files/managing-files/customizing-how-changed-files-appear-on-github) from the analysis. This feature is not currently enabled for any analysis. In the future, it may be enabled by default for some GitHub-managed analyses. [#3318](https://github.com/github/codeql-action/pull/3318) - The changelog extracts that are included with releases of the CodeQL Action are now shorter to avoid duplicated information from appearing in Dependabot PRs. [#3403](https://github.com/github/codeql-action/pull/3403) -## 3.31.10 - 12 Jan 2026 +## 4.31.10 - 12 Jan 2026 - Update default CodeQL bundle version to 2.23.9. [#3393](https://github.com/github/codeql-action/pull/3393) -## 3.31.9 - 16 Dec 2025 +## 4.31.9 - 16 Dec 2025 No user facing changes. -## 3.31.8 - 11 Dec 2025 +## 4.31.8 - 11 Dec 2025 - Update default CodeQL bundle version to 2.23.8. [#3354](https://github.com/github/codeql-action/pull/3354) -## 3.31.7 - 05 Dec 2025 +## 4.31.7 - 05 Dec 2025 - Update default CodeQL bundle version to 2.23.7. [#3343](https://github.com/github/codeql-action/pull/3343) -## 3.31.6 - 01 Dec 2025 +## 4.31.6 - 01 Dec 2025 No user facing changes. -## 3.31.5 - 24 Nov 2025 +## 4.31.5 - 24 Nov 2025 - Update default CodeQL bundle version to 2.23.6. [#3321](https://github.com/github/codeql-action/pull/3321) -## 3.31.4 - 18 Nov 2025 +## 4.31.4 - 18 Nov 2025 No user facing changes. -## 3.31.3 - 13 Nov 2025 +## 4.31.3 - 13 Nov 2025 - CodeQL Action v3 will be deprecated in December 2026. The Action now logs a warning for customers who are running v3 but could be running v4. For more information, see [Upcoming deprecation of CodeQL Action v3](https://github.blog/changelog/2025-10-28-upcoming-deprecation-of-codeql-action-v3/). - Update default CodeQL bundle version to 2.23.5. [#3288](https://github.com/github/codeql-action/pull/3288) -## 3.31.2 - 30 Oct 2025 +## 4.31.2 - 30 Oct 2025 No user facing changes. -## 3.31.1 - 30 Oct 2025 +## 4.31.1 - 30 Oct 2025 - The `add-snippets` input has been removed from the `analyze` action. This input has been deprecated since CodeQL Action 3.26.4 in August 2024 when this removal was announced. -## 3.31.0 - 24 Oct 2025 +## 4.31.0 - 24 Oct 2025 - Bump minimum CodeQL bundle version to 2.17.6. [#3223](https://github.com/github/codeql-action/pull/3223) - When SARIF files are uploaded by the `analyze` or `upload-sarif` actions, the CodeQL Action automatically performs post-processing steps to prepare the data for the upload. Previously, these post-processing steps were only performed before an upload took place. We are now changing this so that the post-processing steps will always be performed, even when the SARIF files are not uploaded. This does not change anything for the `upload-sarif` action. For `analyze`, this may affect Advanced Setup for CodeQL users who specify a value other than `always` for the `upload` input. [#3222](https://github.com/github/codeql-action/pull/3222) -## 3.30.9 - 17 Oct 2025 +## 4.30.9 - 17 Oct 2025 - Update default CodeQL bundle version to 2.23.3. [#3205](https://github.com/github/codeql-action/pull/3205) - Experimental: A new `setup-codeql` action has been added which is similar to `init`, except it only installs the CodeQL CLI and does not initialize a database. Do not use this in production as it is part of an internal experiment and subject to change at any time. [#3204](https://github.com/github/codeql-action/pull/3204) -## 3.30.8 - 10 Oct 2025 +## 4.30.8 - 10 Oct 2025 No user facing changes. -## 3.30.7 - 06 Oct 2025 +## 4.30.7 - 06 Oct 2025 +- [v4+ only] The CodeQL Action now runs on Node.js v24. [#3169](https://github.com/github/codeql-action/pull/3169) -No user facing changes. ## 3.30.6 - 02 Oct 2025 - Update default CodeQL bundle version to 2.23.2. [#3168](https://github.com/github/codeql-action/pull/3168) diff --git a/package.json b/package.json index 49d78c4929..5ebf14292b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeql", - "version": "3.38.3", + "version": "4.38.3", "private": true, "description": "CodeQL action", "scripts": { From e8f64d6fac61855678421499ed6f6d80398e7525 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 15 Oct 2026 10:58:49 +0000 Subject: [PATCH 105/107] Revert "Rebuild" This reverts commit 472ce8f9d01be74275b11b5f47a932a21f441bb3. --- lib/entry-points.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 9aecd7e991..93084ea9be 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -170143,7 +170143,7 @@ function getDiffRangesJsonFilePath(env = getEnv()) { return path2.join(getTemporaryDirectory(env), PR_DIFF_RANGE_JSON_FILENAME); } function getActionVersion() { - return "3.38.3"; + return "4.38.3"; } function getWorkflowEventName(env = getEnv()) { return env.getRequired("GITHUB_EVENT_NAME" /* GITHUB_EVENT_NAME */); From c157d4497c2f98deabe50560625b632a5fe5f735 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 15 Oct 2026 10:58:49 +0000 Subject: [PATCH 106/107] Update version and changelog for v3.39.0 --- CHANGELOG.md | 102 +++++++++++++++++++++++++-------------------------- package.json | 2 +- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a55f7e091..f58bf64810 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,109 +2,109 @@ See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs. -## 4.39.0 - 15 Oct 2026 +## 3.39.0 - 15 Oct 2026 - _Breaking change_: Bump the minimum required CodeQL bundle version to 2.20.7. [#4205](https://github.com/github/codeql-action/pull/4205) - The `codeql-action/analyze` step now validates that a correct argument for the `checkout_path` input has been provided. The `checkout_path` input must be set to the path where the repository that is being analyzed is checked out at on the runner, if that path is something other than the workspace root. If the path does not point to a repository checkout or is different from the path that was used by `codeql-action/init`, then the CodeQL Action now produces a warning. [#4148](https://github.com/github/codeql-action/pull/4148) - Resolved an issue with third-party caching implementations that prevented caches from being restored correctly. [#4206](https://github.com/github/codeql-action/pull/4206) - The `codeql-action/start-proxy` step that is used in Code Scanning Default Setup now finds CodeQL releases using the same logic as `codeql-action/init`. This primarily benefits customers who are using GitHub instances other than `github.com` where the `codeql-action/start-proxy` step may previously have been unable to locate recent releases and ended up using outdated versions of the private registry authentication proxy as a result. [#4198](https://github.com/github/codeql-action/pull/4198) -## 4.38.3 - 08 Oct 2026 +## 3.38.3 - 08 Oct 2026 - _Upcoming breaking change_: CodeQL version 2.21.2 and earlier were discontinued on 24 September 2026 alongside GitHub Enterprise Server 3.17, and will be unsupported by the next minor release of the CodeQL Action. Added a deprecation warning for customers using these versions of CodeQL. [#4188](https://github.com/github/codeql-action/pull/4188) - Update default CodeQL bundle version to [2.27.2](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.27.2). [#4203](https://github.com/github/codeql-action/pull/4203) - Fixed a bug where the decision of whether to use a per-language bundle did not account for custom configurations that reference queries outside of compiled CodeQL packs. This issue was caught during internal testing and did not affect any customer repositories. We will resume the roll out of per-language bundles in the coming weeks. [#4184](https://github.com/github/codeql-action/pull/4184) -## 4.38.2 - 24 Sept 2026 +## 3.38.2 - 24 Sept 2026 - Update default CodeQL bundle version to [2.27.1](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.27.1). [#4160](https://github.com/github/codeql-action/pull/4160) -## 4.38.1 - 18 Sept 2026 +## 3.38.1 - 18 Sept 2026 - The CodeQL Action now has experimental support for CodeQL releases for which per-language bundles are available. Per-language bundles support analysis for a single language and are therefore smaller than the combined bundles that allow analysis for all supported languages. As a result, per-language bundles take up less space on disk and are faster to download. We expect to roll this change out to everyone in the coming weeks. [#4146](https://github.com/github/codeql-action/pull/4146) -## 4.38.0 - 09 Sept 2026 +## 3.38.0 - 09 Sept 2026 - On GitHub-hosted runners, the CodeQL Action now deletes unused CodeQL bundles from the toolcache before downloading a different bundle, which frees up disk space for the analysis. We expect to roll this change out to everyone in September. [#4124](https://github.com/github/codeql-action/pull/4124) - The CodeQL Action now supports CodeQL releases that are compatible with Linux Arm64 and downloads the native `linux-arm64` CodeQL bundle when available. [#4072](https://github.com/github/codeql-action/pull/4072) - Update default CodeQL bundle version to [2.27.0](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.27.0). [#4129](https://github.com/github/codeql-action/pull/4129) -## 4.37.9 - 26 Aug 2026 +## 3.37.9 - 26 Aug 2026 - Update default CodeQL bundle version to [2.26.4](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.4). [#4106](https://github.com/github/codeql-action/pull/4106) -## 4.37.8 - 21 Aug 2026 +## 3.37.8 - 21 Aug 2026 No user facing changes. -## 4.37.7 - 13 Aug 2026 +## 3.37.7 - 13 Aug 2026 - Update default CodeQL bundle version to [2.26.3](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.3). [#4085](https://github.com/github/codeql-action/pull/4085) -## 4.37.6 - 04 Aug 2026 +## 3.37.6 - 04 Aug 2026 - Changed the default filepath for the new remote file address format that was introduced in CodeQL Action 4.37.0 / 3.37.0 to `.github/codeql-config.yml` to align it with the suggested path that is used elsewhere. [#4070](https://github.com/github/codeql-action/pull/4070) -## 4.37.5 - 03 Aug 2026 +## 3.37.5 - 03 Aug 2026 - Fixed a bug where a network error while streaming the download of the CodeQL bundle could terminate the `init` Action instead of falling back to downloading the bundle before extracting it. [#4061](https://github.com/github/codeql-action/pull/4061) -## 4.37.4 - 29 Jul 2026 +## 3.37.4 - 29 Jul 2026 - This version of the CodeQL Action adds support for the `tools` input for the `codeql-action/init` step to be specified using a `github-codeql-tools` [repository property](https://docs.github.com/en/organizations/managing-organization-settings/managing-custom-properties-for-repositories-in-your-organization). This feature will gradually be rolled out following the release of this version. Once rolled out, this allows for the CodeQL CLI version that is used in GitHub-managed workflows, such as Default Setup, to be set to a custom value. For example, customers who run into issues with rate limits when a new CodeQL CLI version is released can set the value to `toolcache` to always use the CodeQL CLI version that is available in the runner toolcache. For Advanced Setup workflows, the value provided for `tools` in the workflow definition always takes precedence unless the value of the repository property starts with `!`. [#4037](https://github.com/github/codeql-action/pull/4037) - Update default CodeQL bundle version to [2.26.2](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.2). [#4051](https://github.com/github/codeql-action/pull/4051) -## 4.37.3 - 22 Jul 2026 +## 3.37.3 - 22 Jul 2026 No user facing changes. -## 4.37.2 - 21 Jul 2026 +## 3.37.2 - 21 Jul 2026 - The new address format for the `config-file` input that was introduced in CodeQL Action 4.37.0 is now enabled by default. In addition to the format described there, the `remote=` prefix can now be used to explicitly indicate that the input refers to a remote file. All previous input formats continue to be accepted as well. [#4023](https://github.com/github/codeql-action/pull/4023) - The CodeQL Action can now make use of [configured private registries](https://docs.github.com/en/code-security/how-tos/secure-at-scale/configure-organization-security/manage-usage-and-access/giving-org-access-private-registries) in Default Setup to retrieve CodeQL configuration files from remote repositories that require authentication. This will allow customers to store their CodeQL configuration in a single repository that can then be referenced by Default Setup workflows in other repositories. We expect to roll this and other, related changes out to everyone in July. [#4007](https://github.com/github/codeql-action/pull/4007) -## 4.37.1 - 16 Jul 2026 +## 3.37.1 - 16 Jul 2026 - _Upcoming breaking change_: Add a deprecation warning for customers using CodeQL version 2.20.6 and earlier. These versions of CodeQL were discontinued on 1 July 2026 alongside GitHub Enterprise Server 3.16, and will be unsupported by the next minor release of the CodeQL Action. [#3956](https://github.com/github/codeql-action/pull/3956) - Update default CodeQL bundle version to [2.26.1](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.1). [#4019](https://github.com/github/codeql-action/pull/4019) -## 4.37.0 - 08 Jul 2026 +## 3.37.0 - 08 Jul 2026 - Update default CodeQL bundle version to [2.26.0](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.0). [#3995](https://github.com/github/codeql-action/pull/3995) - In addition to the existing input format, the `config-file` input for the `codeql-action/init` step will soon support a new `[owner/]repo[@ref][:path]` format. All components except the repository name are optional. If omitted, `owner` defaults to the same owner as the repository the analysis is running for, `ref` to `main`, and `path` to `.github/codeql-action.yaml`. Support for this format ships in this version of the CodeQL Action, but will only be enabled over the coming weeks. [#3973](https://github.com/github/codeql-action/pull/3973) -## 4.36.3 - 01 Jul 2026 +## 3.36.3 - 01 Jul 2026 No user facing changes. -## 4.36.2 - 04 Jun 2026 +## 3.36.2 - 04 Jun 2026 - Cache CodeQL CLI version information across Actions steps. [#3943](https://github.com/github/codeql-action/pull/3943) - Reduce requests while waiting for analysis processing by using exponential backoff when polling SARIF processing status. [#3937](https://github.com/github/codeql-action/pull/3937) - Update default CodeQL bundle version to [2.25.6](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.6). [#3948](https://github.com/github/codeql-action/pull/3948) -## 4.36.1 - 02 Jun 2026 +## 3.36.1 - 02 Jun 2026 No user facing changes. -## 4.36.0 - 22 May 2026 +## 3.36.0 - 22 May 2026 - _Breaking change_: Bump the minimum required CodeQL bundle version to 2.19.4. [#3894](https://github.com/github/codeql-action/pull/3894) - Add support for SHA-256 Git object IDs. [#3893](https://github.com/github/codeql-action/pull/3893) - Update default CodeQL bundle version to [2.25.5](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.5). [#3926](https://github.com/github/codeql-action/pull/3926) -## 4.35.5 - 15 May 2026 +## 3.35.5 - 15 May 2026 - We have improved how the JavaScript bundles for the CodeQL Action are generated to avoid duplication across bundles and reduce the size of the repository by around 70%. This should have no effect on the runtime behaviour of the CodeQL Action. [#3899](https://github.com/github/codeql-action/pull/3899) - For performance and accuracy reasons, [improved incremental analysis](https://github.com/github/roadmap/issues/1158) will now only be enabled on a pull request when diff-informed analysis is also enabled for that run. If diff-informed analysis is unavailable (for example, because the PR diff ranges could not be computed), the action will fall back to a full analysis. [#3791](https://github.com/github/codeql-action/pull/3791) - If multiple inputs are provided for the GitHub-internal `analysis-kinds` input, only `code-scanning` will be enabled. The `analysis-kinds` input is experimental, for GitHub-internal use only, and may change without notice at any time. [#3892](https://github.com/github/codeql-action/pull/3892) - Added an experimental change which, when running a Code Scanning analysis for a PR with [improved incremental analysis](https://github.com/github/roadmap/issues/1158) enabled, prefers CodeQL CLI versions that have a cached overlay-base database for the configured languages. This speeds up analysis for a repository when there is not yet a cached overlay-base database for the latest CLI version. We expect to roll this change out to everyone in May. [#3880](https://github.com/github/codeql-action/pull/3880) -## 4.35.4 - 07 May 2026 +## 3.35.4 - 07 May 2026 - Update default CodeQL bundle version to [2.25.4](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.4). [#3881](https://github.com/github/codeql-action/pull/3881) -## 4.35.3 - 01 May 2026 +## 3.35.3 - 01 May 2026 - _Upcoming breaking change_: Add a deprecation warning for customers using CodeQL version 2.19.3 and earlier. These versions of CodeQL were discontinued on 9 April 2026 alongside GitHub Enterprise Server 3.15, and will be unsupported by the next minor release of the CodeQL Action. [#3837](https://github.com/github/codeql-action/pull/3837) - Configurations for private registries that use Cloudsmith or GCP OIDC are now accepted. [#3850](https://github.com/github/codeql-action/pull/3850) @@ -112,7 +112,7 @@ No user facing changes. - Fixed a bug where two diagnostics produced within the same millisecond could overwrite each other on disk, causing one of them to be lost. [#3852](https://github.com/github/codeql-action/pull/3852) - Update default CodeQL bundle version to [2.25.3](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.3). [#3865](https://github.com/github/codeql-action/pull/3865) -## 4.35.2 - 15 Apr 2026 +## 3.35.2 - 15 Apr 2026 - The undocumented TRAP cache cleanup feature that could be enabled using the `CODEQL_ACTION_CLEANUP_TRAP_CACHES` environment variable is deprecated and will be removed in May 2026. If you are affected by this, we recommend disabling TRAP caching by passing the `trap-caching: false` input to the `init` Action. [#3795](https://github.com/github/codeql-action/pull/3795) - The Git version 2.36.0 requirement for improved incremental analysis now only applies to repositories that contain submodules. [#3789](https://github.com/github/codeql-action/pull/3789) @@ -120,26 +120,26 @@ No user facing changes. - Fixed a bug in the validation of OIDC configurations for private registries that was added in CodeQL Action 4.33.0 / 3.33.0. [#3807](https://github.com/github/codeql-action/pull/3807) - Update default CodeQL bundle version to [2.25.2](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.2). [#3823](https://github.com/github/codeql-action/pull/3823) -## 4.35.1 - 27 Mar 2026 +## 3.35.1 - 27 Mar 2026 - Fix incorrect minimum required Git version for [improved incremental analysis](https://github.com/github/roadmap/issues/1158): it should have been 2.36.0, not 2.11.0. [#3781](https://github.com/github/codeql-action/pull/3781) -## 4.35.0 - 27 Mar 2026 +## 3.35.0 - 27 Mar 2026 - Reduced the minimum Git version required for [improved incremental analysis](https://github.com/github/roadmap/issues/1158) from 2.38.0 to 2.11.0. [#3767](https://github.com/github/codeql-action/pull/3767) - Update default CodeQL bundle version to [2.25.1](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.1). [#3773](https://github.com/github/codeql-action/pull/3773) -## 4.34.1 - 20 Mar 2026 +## 3.34.1 - 20 Mar 2026 - Downgrade default CodeQL bundle version to [2.24.3](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.3) due to issues with a small percentage of Actions and JavaScript analyses. [#3762](https://github.com/github/codeql-action/pull/3762) -## 4.34.0 - 20 Mar 2026 +## 3.34.0 - 20 Mar 2026 - Added an experimental change which disables TRAP caching when [improved incremental analysis](https://github.com/github/roadmap/issues/1158) is enabled, since improved incremental analysis supersedes TRAP caching. This will improve performance and reduce Actions cache usage. We expect to roll this change out to everyone in March. [#3569](https://github.com/github/codeql-action/pull/3569) - We are rolling out improved incremental analysis to C/C++ analyses that use build mode `none`. We expect this rollout to be complete by the end of April 2026. [#3584](https://github.com/github/codeql-action/pull/3584) - Update default CodeQL bundle version to [2.25.0](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.0). [#3585](https://github.com/github/codeql-action/pull/3585) -## 4.33.0 - 16 Mar 2026 +## 3.33.0 - 16 Mar 2026 - Upcoming change: Starting April 2026, the CodeQL Action will skip collecting file coverage information on pull requests to improve analysis performance. File coverage information will still be computed on non-PR analyses. Pull request analyses will log a warning about this upcoming change. [#3562](https://github.com/github/codeql-action/pull/3562) @@ -153,11 +153,11 @@ No user facing changes. - Fixed the retry mechanism for database uploads. Previously this would fail with the error "Response body object should not be disturbed or locked". [#3564](https://github.com/github/codeql-action/pull/3564) - A warning is now emitted if the CodeQL Action detects a repository property whose name suggests that it relates to the CodeQL Action, but which is not one of the properties recognised by the current version of the CodeQL Action. [#3570](https://github.com/github/codeql-action/pull/3570) -## 4.32.6 - 05 Mar 2026 +## 3.32.6 - 05 Mar 2026 - Update default CodeQL bundle version to [2.24.3](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.3). [#3548](https://github.com/github/codeql-action/pull/3548) -## 4.32.5 - 02 Mar 2026 +## 3.32.5 - 02 Mar 2026 - Repositories owned by an organization can now set up the `github-codeql-disable-overlay` custom repository property to disable [improved incremental analysis for CodeQL](https://github.com/github/roadmap/issues/1158). First, create a custom repository property with the name `github-codeql-disable-overlay` and the type "True/false" in the organization's settings. Then in the repository's settings, set this property to `true` to disable improved incremental analysis. For more information, 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). This feature is not yet available on GitHub Enterprise Server. [#3507](https://github.com/github/codeql-action/pull/3507) - Added an experimental change so that when [improved incremental analysis](https://github.com/github/roadmap/issues/1158) fails on a runner — potentially due to insufficient disk space — the failure is recorded in the Actions cache so that subsequent runs will automatically skip improved incremental analysis until something changes (e.g. a larger runner is provisioned or a new CodeQL version is released). We expect to roll this change out to everyone in March. [#3487](https://github.com/github/codeql-action/pull/3487) @@ -167,7 +167,7 @@ No user facing changes. - Added an experimental change which allows the `start-proxy` action to resolve the CodeQL CLI version from feature flags instead of using the linked CLI bundle version. We expect to roll this change out to everyone in March. [#3512](https://github.com/github/codeql-action/pull/3512) - The previously experimental changes from versions 4.32.3, 4.32.4, 3.32.3 and 3.32.4 are now enabled by default. [#3503](https://github.com/github/codeql-action/pull/3503), [#3504](https://github.com/github/codeql-action/pull/3504) -## 4.32.4 - 20 Feb 2026 +## 3.32.4 - 20 Feb 2026 - Update default CodeQL bundle version to [2.24.2](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.2). [#3493](https://github.com/github/codeql-action/pull/3493) - Added an experimental change which improves how certificates are generated for the authentication proxy that is used by the CodeQL Action in Default Setup when [private package registries are configured](https://docs.github.com/en/code-security/how-tos/secure-at-scale/configure-organization-security/manage-usage-and-access/giving-org-access-private-registries). This is expected to generate more widely compatible certificates and should have no impact on analyses which are working correctly already. We expect to roll this change out to everyone in February. [#3473](https://github.com/github/codeql-action/pull/3473) @@ -175,89 +175,89 @@ No user facing changes. - Added a setting which allows the CodeQL Action to enable network debugging for Java programs. This will help GitHub staff support customers with troubleshooting issues in GitHub-managed CodeQL workflows, such as Default Setup. This setting can only be enabled by GitHub staff. [#3485](https://github.com/github/codeql-action/pull/3485) - Added a setting which enables GitHub-managed workflows, such as Default Setup, to use a [nightly CodeQL CLI release](https://github.com/dsp-testing/codeql-cli-nightlies) instead of the latest, stable release that is used by default. This will help GitHub staff support customers whose analyses for a given repository or organization require early access to a change in an upcoming CodeQL CLI release. This setting can only be enabled by GitHub staff. [#3484](https://github.com/github/codeql-action/pull/3484) -## 4.32.3 - 13 Feb 2026 +## 3.32.3 - 13 Feb 2026 - Added experimental support for testing connections to [private package registries](https://docs.github.com/en/code-security/how-tos/secure-at-scale/configure-organization-security/manage-usage-and-access/giving-org-access-private-registries). This feature is not currently enabled for any analysis. In the future, it may be enabled by default for Default Setup. [#3466](https://github.com/github/codeql-action/pull/3466) -## 4.32.2 - 05 Feb 2026 +## 3.32.2 - 05 Feb 2026 - Update default CodeQL bundle version to [2.24.1](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.1). [#3460](https://github.com/github/codeql-action/pull/3460) -## 4.32.1 - 02 Feb 2026 +## 3.32.1 - 02 Feb 2026 - A warning is now shown in Default Setup workflow logs if a [private package registry is configured](https://docs.github.com/en/code-security/how-tos/secure-at-scale/configure-organization-security/manage-usage-and-access/giving-org-access-private-registries) using a GitHub Personal Access Token (PAT), but no username is configured. [#3422](https://github.com/github/codeql-action/pull/3422) - Fixed a bug which caused the CodeQL Action to fail when repository properties cannot successfully be retrieved. [#3421](https://github.com/github/codeql-action/pull/3421) -## 4.32.0 - 26 Jan 2026 +## 3.32.0 - 26 Jan 2026 - Update default CodeQL bundle version to [2.24.0](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.0). [#3425](https://github.com/github/codeql-action/pull/3425) -## 4.31.11 - 23 Jan 2026 +## 3.31.11 - 23 Jan 2026 - When running a Default Setup workflow with [Actions debugging enabled](https://docs.github.com/en/actions/how-tos/monitor-workflows/enable-debug-logging), the CodeQL Action will now use more unique names when uploading logs from the Dependabot authentication proxy as workflow artifacts. This ensures that the artifact names do not clash between multiple jobs in a build matrix. [#3409](https://github.com/github/codeql-action/pull/3409) - Improved error handling throughout the CodeQL Action. [#3415](https://github.com/github/codeql-action/pull/3415) - Added experimental support for automatically excluding [generated files](https://docs.github.com/en/repositories/working-with-files/managing-files/customizing-how-changed-files-appear-on-github) from the analysis. This feature is not currently enabled for any analysis. In the future, it may be enabled by default for some GitHub-managed analyses. [#3318](https://github.com/github/codeql-action/pull/3318) - The changelog extracts that are included with releases of the CodeQL Action are now shorter to avoid duplicated information from appearing in Dependabot PRs. [#3403](https://github.com/github/codeql-action/pull/3403) -## 4.31.10 - 12 Jan 2026 +## 3.31.10 - 12 Jan 2026 - Update default CodeQL bundle version to 2.23.9. [#3393](https://github.com/github/codeql-action/pull/3393) -## 4.31.9 - 16 Dec 2025 +## 3.31.9 - 16 Dec 2025 No user facing changes. -## 4.31.8 - 11 Dec 2025 +## 3.31.8 - 11 Dec 2025 - Update default CodeQL bundle version to 2.23.8. [#3354](https://github.com/github/codeql-action/pull/3354) -## 4.31.7 - 05 Dec 2025 +## 3.31.7 - 05 Dec 2025 - Update default CodeQL bundle version to 2.23.7. [#3343](https://github.com/github/codeql-action/pull/3343) -## 4.31.6 - 01 Dec 2025 +## 3.31.6 - 01 Dec 2025 No user facing changes. -## 4.31.5 - 24 Nov 2025 +## 3.31.5 - 24 Nov 2025 - Update default CodeQL bundle version to 2.23.6. [#3321](https://github.com/github/codeql-action/pull/3321) -## 4.31.4 - 18 Nov 2025 +## 3.31.4 - 18 Nov 2025 No user facing changes. -## 4.31.3 - 13 Nov 2025 +## 3.31.3 - 13 Nov 2025 - CodeQL Action v3 will be deprecated in December 2026. The Action now logs a warning for customers who are running v3 but could be running v4. For more information, see [Upcoming deprecation of CodeQL Action v3](https://github.blog/changelog/2025-10-28-upcoming-deprecation-of-codeql-action-v3/). - Update default CodeQL bundle version to 2.23.5. [#3288](https://github.com/github/codeql-action/pull/3288) -## 4.31.2 - 30 Oct 2025 +## 3.31.2 - 30 Oct 2025 No user facing changes. -## 4.31.1 - 30 Oct 2025 +## 3.31.1 - 30 Oct 2025 - The `add-snippets` input has been removed from the `analyze` action. This input has been deprecated since CodeQL Action 3.26.4 in August 2024 when this removal was announced. -## 4.31.0 - 24 Oct 2025 +## 3.31.0 - 24 Oct 2025 - Bump minimum CodeQL bundle version to 2.17.6. [#3223](https://github.com/github/codeql-action/pull/3223) - When SARIF files are uploaded by the `analyze` or `upload-sarif` actions, the CodeQL Action automatically performs post-processing steps to prepare the data for the upload. Previously, these post-processing steps were only performed before an upload took place. We are now changing this so that the post-processing steps will always be performed, even when the SARIF files are not uploaded. This does not change anything for the `upload-sarif` action. For `analyze`, this may affect Advanced Setup for CodeQL users who specify a value other than `always` for the `upload` input. [#3222](https://github.com/github/codeql-action/pull/3222) -## 4.30.9 - 17 Oct 2025 +## 3.30.9 - 17 Oct 2025 - Update default CodeQL bundle version to 2.23.3. [#3205](https://github.com/github/codeql-action/pull/3205) - Experimental: A new `setup-codeql` action has been added which is similar to `init`, except it only installs the CodeQL CLI and does not initialize a database. Do not use this in production as it is part of an internal experiment and subject to change at any time. [#3204](https://github.com/github/codeql-action/pull/3204) -## 4.30.8 - 10 Oct 2025 +## 3.30.8 - 10 Oct 2025 No user facing changes. -## 4.30.7 - 06 Oct 2025 +## 3.30.7 - 06 Oct 2025 -- [v4+ only] The CodeQL Action now runs on Node.js v24. [#3169](https://github.com/github/codeql-action/pull/3169) +No user facing changes. ## 3.30.6 - 02 Oct 2025 - Update default CodeQL bundle version to 2.23.2. [#3168](https://github.com/github/codeql-action/pull/3168) diff --git a/package.json b/package.json index 755d561f10..ff8358dc1d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeql", - "version": "4.39.0", + "version": "3.39.0", "private": true, "description": "CodeQL action", "scripts": { From 67cc5f0aacd29aa878a58298ac1604a2098e07d7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 15 Oct 2026 10:58:58 +0000 Subject: [PATCH 107/107] Rebuild --- lib/entry-points.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 650857e9c3..7d745b86ba 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -170183,7 +170183,7 @@ function getDiffRangesJsonFilePath(env = getEnv()) { return path2.join(getTemporaryDirectory(env), PR_DIFF_RANGE_JSON_FILENAME); } function getActionVersion() { - return "4.39.0"; + return "3.39.0"; } function getWorkflowEventName(env = getEnv()) { return env.getRequired("GITHUB_EVENT_NAME" /* GITHUB_EVENT_NAME */);