From 772ffcd99900db4f9e34cf418500c4b823d48464 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 6 Oct 2026 10:58:36 +0100 Subject: [PATCH 01/20] 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 f8bc73a5f..e0a72fae3 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 93084ea9b..2702988bc 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 4d4e4a091..f8231e44b 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 02/20] 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 2702988bc..00a0da96b 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 167f0801b..e3b9d3025 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 5ebf14292..c49797fcb 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 03/20] 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 ccbb1b5a6..ac3340261 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 2acc617cb..edaccddd0 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 a43705b70..5f976dd4e 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 0a0f201ea..38133994c 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 b3638ca6d..f26b4eb2e 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 f67cef5c7..936fe6e95 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 c27f19511..8792aea32 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 b9d80d107..22f0d7991 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 8589ba80e..c7dbd97f5 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 9b40c2e41..28d8fe9a2 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 04/20] 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 ac3340261..fb471c5ea 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 edaccddd0..b3b043def 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 5f976dd4e..20bdea695 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 38133994c..8bc4514f0 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 28d8fe9a2..8dc1dd1d1 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 05/20] 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 00a0da96b..675b28f94 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 7963fa52b..a954ed40f 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 06/20] 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 675b28f94..83ca4b421 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 31414bd80..b226a0cb5 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 07/20] 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 83ca4b421..2f95ef18f 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 3f9b2fafb..a8d6dc433 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 370816aef..16ecb6d5d 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 9f5f1775d..e0bdb5c5e 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 0e6dae13a..93ee391aa 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 4931be65b..35e626c88 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 bc0e1361c..82961842e 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 08/20] 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 2f95ef18f..5857b85cb 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 b226a0cb5..7a9ba1681 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 09/20] 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 5857b85cb..7baf461da 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 d585fd6d8..4eeb447e1 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 49b790102..28f89b115 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 59b50e2df..f74d0bd25 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 10/20] 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 c7dbd97f5..e0b91ae9c 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 11/20] 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 e0a72fae3..3d6eaebec 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 39f1b3fa8d8dee53e188d34abe2f6aaad7216cfb Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Wed, 7 Oct 2026 13:11:34 -0500 Subject: [PATCH 12/20] Document change-notes process --- CONTRIBUTING.md | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 216097f89..fac24c3d4 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 38fee79b02b7416b7510f1db2bb7c395df5dd4d5 Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Wed, 7 Oct 2026 15:21:38 -0500 Subject: [PATCH 13/20] 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 fac24c3d4..dd0b4886b 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 2a935ca93d4a319794c6294a9379ecbeb336d32c Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Thu, 8 Oct 2026 12:48:24 -0500 Subject: [PATCH 14/20] 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 dd0b4886b..1436c9bb3 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 000000000..30b3789e4 --- /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 15/20] 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 933d255cd..26035527b 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 40d76bc72746338d65640ffede693aee5bfb4fb6 Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Thu, 8 Oct 2026 14:55:23 -0500 Subject: [PATCH 16/20] 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 30b3789e4..cf19da0b4 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 17/20] 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 cf19da0b4..48ce5a3e1 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 18/20] 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 48ce5a3e1..d477a0b1b 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 e57c0e65ddc1f222809299415886044068668890 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 9 Oct 2026 14:14:48 +0100 Subject: [PATCH 19/20] 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 1b31b0648..9fe963a27 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 17d4344cc..79f1901f2 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 31414bd80..ae0cb2114 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 23a9c65eb..e80327a81 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 d965a2dd6..bc3351da5 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 fa56eef12fd72da6f01e786304612ce03ba93a48 Mon Sep 17 00:00:00 2001 From: Mario Campos Date: Fri, 9 Oct 2026 16:48:00 -0500 Subject: [PATCH 20/20] 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 d477a0b1b..60778c795 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) ```