From cdb655d6d4cbc2686e6e01bc971017d495693931 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 28 Apr 2026 11:29:32 +0100 Subject: [PATCH 01/10] Add random suffix when writing diagnostics to avoid filename collisions --- lib/analyze-action.js | 3 ++- lib/init-action-post.js | 3 ++- lib/init-action.js | 3 ++- lib/setup-codeql-action.js | 3 ++- lib/upload-lib.js | 3 ++- lib/upload-sarif-action.js | 3 ++- src/diagnostics.ts | 8 +++++++- 7 files changed, 19 insertions(+), 7 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 712b2b62b..020c41d20 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -107892,10 +107892,11 @@ function writeDiagnostic(config, language, diagnostic) { ); try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); + const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); const jsonPath = import_path.default.resolve( diagnosticsPath, // Remove colons from the timestamp as these are not allowed in Windows filenames. - `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}.json` + `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}-${uniqueSuffix}.json` ); (0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic)); } catch (err) { diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 59a13f628..e401797e9 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -165811,10 +165811,11 @@ function writeDiagnostic(config, language, diagnostic) { ); try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); + const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); const jsonPath = import_path.default.resolve( diagnosticsPath, // Remove colons from the timestamp as these are not allowed in Windows filenames. - `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}.json` + `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}-${uniqueSuffix}.json` ); (0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic)); } catch (err) { diff --git a/lib/init-action.js b/lib/init-action.js index 51f1eef91..977240f21 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -105397,10 +105397,11 @@ function writeDiagnostic(config, language, diagnostic) { ); try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); + const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); const jsonPath = import_path.default.resolve( diagnosticsPath, // Remove colons from the timestamp as these are not allowed in Windows filenames. - `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}.json` + `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}-${uniqueSuffix}.json` ); (0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic)); } catch (err) { diff --git a/lib/setup-codeql-action.js b/lib/setup-codeql-action.js index 58431548c..48a206e8a 100644 --- a/lib/setup-codeql-action.js +++ b/lib/setup-codeql-action.js @@ -105467,10 +105467,11 @@ function writeDiagnostic(config, language, diagnostic) { ); try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); + const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); const jsonPath = import_path.default.resolve( diagnosticsPath, // Remove colons from the timestamp as these are not allowed in Windows filenames. - `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}.json` + `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}-${uniqueSuffix}.json` ); (0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic)); } catch (err) { diff --git a/lib/upload-lib.js b/lib/upload-lib.js index 60cd5fe57..faca0370a 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -107502,10 +107502,11 @@ function writeDiagnostic(config, language, diagnostic) { ); try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); + const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); const jsonPath = import_path.default.resolve( diagnosticsPath, // Remove colons from the timestamp as these are not allowed in Windows filenames. - `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}.json` + `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}-${uniqueSuffix}.json` ); (0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic)); } catch (err) { diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index aeaf1e7c6..d412f3547 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -108258,10 +108258,11 @@ function writeDiagnostic(config, language, diagnostic) { ); try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); + const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); const jsonPath = import_path.default.resolve( diagnosticsPath, // Remove colons from the timestamp as these are not allowed in Windows filenames. - `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}.json` + `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}-${uniqueSuffix}.json` ); (0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic)); } catch (err) { diff --git a/src/diagnostics.ts b/src/diagnostics.ts index 4d8fc87b5..6b1911d05 100644 --- a/src/diagnostics.ts +++ b/src/diagnostics.ts @@ -167,10 +167,16 @@ function writeDiagnostic( // Create the directory if it doesn't exist yet. mkdirSync(diagnosticsPath, { recursive: true }); + // Include a random suffix to avoid filename collisions between diagnostics + // produced within the same millisecond. This doesn't need to be + // cryptographically secure, so `Math.random` is fine. + const uniqueSuffix = Math.floor(Math.random() * 0x100000000) + .toString(16) + .padStart(8, "0"); const jsonPath = path.resolve( diagnosticsPath, // Remove colons from the timestamp as these are not allowed in Windows filenames. - `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}.json`, + `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}-${uniqueSuffix}.json`, ); writeFileSync(jsonPath, JSON.stringify(diagnostic)); From e73c940c9bfd79008a4b792d6fb46a19273cb59a Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 28 Apr 2026 11:33:48 +0100 Subject: [PATCH 02/10] Defensively sanitize timestamp --- lib/analyze-action.js | 7 +++++-- lib/init-action-post.js | 7 +++++-- lib/init-action.js | 7 +++++-- lib/setup-codeql-action.js | 7 +++++-- lib/upload-lib.js | 7 +++++-- lib/upload-sarif-action.js | 7 +++++-- src/diagnostics.ts | 9 +++++++-- 7 files changed, 37 insertions(+), 14 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 020c41d20..72da44c72 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -107893,10 +107893,13 @@ function writeDiagnostic(config, language, diagnostic) { try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); + const sanitizedTimestamp = diagnostic.timestamp.replace( + /[^a-zA-Z0-9.-]/g, + "" + ); const jsonPath = import_path.default.resolve( diagnosticsPath, - // Remove colons from the timestamp as these are not allowed in Windows filenames. - `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}-${uniqueSuffix}.json` + `codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json` ); (0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic)); } catch (err) { diff --git a/lib/init-action-post.js b/lib/init-action-post.js index e401797e9..9a8363372 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -165812,10 +165812,13 @@ function writeDiagnostic(config, language, diagnostic) { try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); + const sanitizedTimestamp = diagnostic.timestamp.replace( + /[^a-zA-Z0-9.-]/g, + "" + ); const jsonPath = import_path.default.resolve( diagnosticsPath, - // Remove colons from the timestamp as these are not allowed in Windows filenames. - `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}-${uniqueSuffix}.json` + `codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json` ); (0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic)); } catch (err) { diff --git a/lib/init-action.js b/lib/init-action.js index 977240f21..3e779fe79 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -105398,10 +105398,13 @@ function writeDiagnostic(config, language, diagnostic) { try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); + const sanitizedTimestamp = diagnostic.timestamp.replace( + /[^a-zA-Z0-9.-]/g, + "" + ); const jsonPath = import_path.default.resolve( diagnosticsPath, - // Remove colons from the timestamp as these are not allowed in Windows filenames. - `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}-${uniqueSuffix}.json` + `codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json` ); (0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic)); } catch (err) { diff --git a/lib/setup-codeql-action.js b/lib/setup-codeql-action.js index 48a206e8a..0c492ed45 100644 --- a/lib/setup-codeql-action.js +++ b/lib/setup-codeql-action.js @@ -105468,10 +105468,13 @@ function writeDiagnostic(config, language, diagnostic) { try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); + const sanitizedTimestamp = diagnostic.timestamp.replace( + /[^a-zA-Z0-9.-]/g, + "" + ); const jsonPath = import_path.default.resolve( diagnosticsPath, - // Remove colons from the timestamp as these are not allowed in Windows filenames. - `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}-${uniqueSuffix}.json` + `codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json` ); (0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic)); } catch (err) { diff --git a/lib/upload-lib.js b/lib/upload-lib.js index faca0370a..c34c46ec7 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -107503,10 +107503,13 @@ function writeDiagnostic(config, language, diagnostic) { try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); + const sanitizedTimestamp = diagnostic.timestamp.replace( + /[^a-zA-Z0-9.-]/g, + "" + ); const jsonPath = import_path.default.resolve( diagnosticsPath, - // Remove colons from the timestamp as these are not allowed in Windows filenames. - `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}-${uniqueSuffix}.json` + `codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json` ); (0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic)); } catch (err) { diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index d412f3547..e4b8dbde7 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -108259,10 +108259,13 @@ function writeDiagnostic(config, language, diagnostic) { try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); + const sanitizedTimestamp = diagnostic.timestamp.replace( + /[^a-zA-Z0-9.-]/g, + "" + ); const jsonPath = import_path.default.resolve( diagnosticsPath, - // Remove colons from the timestamp as these are not allowed in Windows filenames. - `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}-${uniqueSuffix}.json` + `codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json` ); (0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic)); } catch (err) { diff --git a/src/diagnostics.ts b/src/diagnostics.ts index 6b1911d05..ab9ca4a7a 100644 --- a/src/diagnostics.ts +++ b/src/diagnostics.ts @@ -173,10 +173,15 @@ function writeDiagnostic( const uniqueSuffix = Math.floor(Math.random() * 0x100000000) .toString(16) .padStart(8, "0"); + // We should only need to remove colons, but to be defensive, only allow a restricted set of + // characters. + const sanitizedTimestamp = diagnostic.timestamp.replace( + /[^a-zA-Z0-9.-]/g, + "", + ); const jsonPath = path.resolve( diagnosticsPath, - // Remove colons from the timestamp as these are not allowed in Windows filenames. - `codeql-action-${diagnostic.timestamp.replaceAll(":", "")}-${uniqueSuffix}.json`, + `codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json`, ); writeFileSync(jsonPath, JSON.stringify(diagnostic)); From c109008fac92e5836f4c5914b9e93744216d279d Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 28 Apr 2026 11:35:30 +0100 Subject: [PATCH 03/10] Add changelog note --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d831f31be..ff4e2d3bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th ## [UNRELEASED] -No user facing changes. +- 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) ## 4.35.2 - 15 Apr 2026 From 245f6828c4b868031d4f50d96c64c536f031e265 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 28 Apr 2026 12:42:42 +0100 Subject: [PATCH 04/10] Use a counter instead of Math.random for diagnostic filename suffix --- lib/analyze-action.js | 3 ++- lib/init-action-post.js | 3 ++- lib/init-action.js | 3 ++- lib/setup-codeql-action.js | 3 ++- lib/upload-lib.js | 3 ++- lib/upload-sarif-action.js | 3 ++- src/diagnostics.ts | 16 ++++++++++------ 7 files changed, 22 insertions(+), 12 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 72da44c72..750a0e52d 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -107850,6 +107850,7 @@ function formatDuration(durationMs) { // src/diagnostics.ts var unwrittenDiagnostics = []; var unwrittenDefaultLanguageDiagnostics = []; +var diagnosticCounter = 0; function makeDiagnostic(id, name, data = void 0) { return { ...data, @@ -107892,7 +107893,7 @@ function writeDiagnostic(config, language, diagnostic) { ); try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); - const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); + const uniqueSuffix = (diagnosticCounter++).toString(); const sanitizedTimestamp = diagnostic.timestamp.replace( /[^a-zA-Z0-9.-]/g, "" diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 9a8363372..3f44bd4d3 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -165769,6 +165769,7 @@ function formatDuration(durationMs) { // src/diagnostics.ts var unwrittenDiagnostics = []; var unwrittenDefaultLanguageDiagnostics = []; +var diagnosticCounter = 0; function makeDiagnostic(id, name, data = void 0) { return { ...data, @@ -165811,7 +165812,7 @@ function writeDiagnostic(config, language, diagnostic) { ); try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); - const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); + const uniqueSuffix = (diagnosticCounter++).toString(); const sanitizedTimestamp = diagnostic.timestamp.replace( /[^a-zA-Z0-9.-]/g, "" diff --git a/lib/init-action.js b/lib/init-action.js index 3e779fe79..a3c7ab96b 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -105355,6 +105355,7 @@ function formatDuration(durationMs) { // src/diagnostics.ts var unwrittenDiagnostics = []; var unwrittenDefaultLanguageDiagnostics = []; +var diagnosticCounter = 0; function makeDiagnostic(id, name, data = void 0) { return { ...data, @@ -105397,7 +105398,7 @@ function writeDiagnostic(config, language, diagnostic) { ); try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); - const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); + const uniqueSuffix = (diagnosticCounter++).toString(); const sanitizedTimestamp = diagnostic.timestamp.replace( /[^a-zA-Z0-9.-]/g, "" diff --git a/lib/setup-codeql-action.js b/lib/setup-codeql-action.js index 0c492ed45..64e6a317c 100644 --- a/lib/setup-codeql-action.js +++ b/lib/setup-codeql-action.js @@ -105425,6 +105425,7 @@ function formatDuration(durationMs) { // src/diagnostics.ts var unwrittenDiagnostics = []; var unwrittenDefaultLanguageDiagnostics = []; +var diagnosticCounter = 0; function makeDiagnostic(id, name, data = void 0) { return { ...data, @@ -105467,7 +105468,7 @@ function writeDiagnostic(config, language, diagnostic) { ); try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); - const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); + const uniqueSuffix = (diagnosticCounter++).toString(); const sanitizedTimestamp = diagnostic.timestamp.replace( /[^a-zA-Z0-9.-]/g, "" diff --git a/lib/upload-lib.js b/lib/upload-lib.js index c34c46ec7..4bd41931b 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -107460,6 +107460,7 @@ function formatDuration(durationMs) { // src/diagnostics.ts var unwrittenDiagnostics = []; var unwrittenDefaultLanguageDiagnostics = []; +var diagnosticCounter = 0; function makeDiagnostic(id, name, data = void 0) { return { ...data, @@ -107502,7 +107503,7 @@ function writeDiagnostic(config, language, diagnostic) { ); try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); - const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); + const uniqueSuffix = (diagnosticCounter++).toString(); const sanitizedTimestamp = diagnostic.timestamp.replace( /[^a-zA-Z0-9.-]/g, "" diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index e4b8dbde7..e6ca76b23 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -108216,6 +108216,7 @@ var import_fs = require("fs"); var import_path = __toESM(require("path")); var unwrittenDiagnostics = []; var unwrittenDefaultLanguageDiagnostics = []; +var diagnosticCounter = 0; function makeDiagnostic(id, name, data = void 0) { return { ...data, @@ -108258,7 +108259,7 @@ function writeDiagnostic(config, language, diagnostic) { ); try { (0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true }); - const uniqueSuffix = Math.floor(Math.random() * 4294967296).toString(16).padStart(8, "0"); + const uniqueSuffix = (diagnosticCounter++).toString(); const sanitizedTimestamp = diagnostic.timestamp.replace( /[^a-zA-Z0-9.-]/g, "" diff --git a/src/diagnostics.ts b/src/diagnostics.ts index ab9ca4a7a..65e82ce1a 100644 --- a/src/diagnostics.ts +++ b/src/diagnostics.ts @@ -72,6 +72,13 @@ let unwrittenDiagnostics: UnwrittenDiagnostic[] = []; */ let unwrittenDefaultLanguageDiagnostics: DiagnosticMessage[] = []; +/** + * Counter used to generate a unique suffix for each diagnostic filename, so that + * two diagnostics produced within the same millisecond do not overwrite each + * other on disk. + */ +let diagnosticCounter = 0; + /** * Constructs a new diagnostic message with the specified id and name, as well as optional additional data. * @@ -167,12 +174,9 @@ function writeDiagnostic( // Create the directory if it doesn't exist yet. mkdirSync(diagnosticsPath, { recursive: true }); - // Include a random suffix to avoid filename collisions between diagnostics - // produced within the same millisecond. This doesn't need to be - // cryptographically secure, so `Math.random` is fine. - const uniqueSuffix = Math.floor(Math.random() * 0x100000000) - .toString(16) - .padStart(8, "0"); + // Include a monotonically increasing suffix to avoid filename collisions + // between diagnostics produced within the same millisecond. + const uniqueSuffix = (diagnosticCounter++).toString(); // We should only need to remove colons, but to be defensive, only allow a restricted set of // characters. const sanitizedTimestamp = diagnostic.timestamp.replace( From de303a9db5f6c95afba6ef555829f5e6f14599d6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 00:32:32 +0000 Subject: [PATCH 05/10] Update supported GitHub Enterprise Server versions --- lib/analyze-action-post.js | 2 +- lib/autobuild-action.js | 2 +- lib/init-action-post.js | 2 +- lib/init-action.js | 2 +- lib/resolve-environment-action.js | 2 +- lib/setup-codeql-action.js | 2 +- lib/start-proxy-action-post.js | 2 +- lib/upload-sarif-action-post.js | 2 +- src/api-compatibility.json | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/analyze-action-post.js b/lib/analyze-action-post.js index aa0463414..78954afbe 100644 --- a/lib/analyze-action-post.js +++ b/lib/analyze-action-post.js @@ -161660,7 +161660,7 @@ var semver = __toESM(require_semver2()); // src/api-compatibility.json var maximumVersion = "3.21"; -var minimumVersion = "3.14"; +var minimumVersion = "3.16"; // src/json/index.ts function isObject2(value) { diff --git a/lib/autobuild-action.js b/lib/autobuild-action.js index a1b0a3255..379911bd5 100644 --- a/lib/autobuild-action.js +++ b/lib/autobuild-action.js @@ -103552,7 +103552,7 @@ var semver = __toESM(require_semver2()); // src/api-compatibility.json var maximumVersion = "3.21"; -var minimumVersion = "3.14"; +var minimumVersion = "3.16"; // src/json/index.ts function isObject2(value) { diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 3f44bd4d3..2e065ac6b 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -164557,7 +164557,7 @@ var semver = __toESM(require_semver2()); // src/api-compatibility.json var maximumVersion = "3.21"; -var minimumVersion = "3.14"; +var minimumVersion = "3.16"; // src/json/index.ts function isObject2(value) { diff --git a/lib/init-action.js b/lib/init-action.js index a3c7ab96b..1970c1279 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -103760,7 +103760,7 @@ var semver = __toESM(require_semver2()); // src/api-compatibility.json var maximumVersion = "3.21"; -var minimumVersion = "3.14"; +var minimumVersion = "3.16"; // src/json/index.ts function isObject2(value) { diff --git a/lib/resolve-environment-action.js b/lib/resolve-environment-action.js index 02342c09b..5fa8073dd 100644 --- a/lib/resolve-environment-action.js +++ b/lib/resolve-environment-action.js @@ -103552,7 +103552,7 @@ var semver = __toESM(require_semver2()); // src/api-compatibility.json var maximumVersion = "3.21"; -var minimumVersion = "3.14"; +var minimumVersion = "3.16"; // src/json/index.ts function isObject2(value) { diff --git a/lib/setup-codeql-action.js b/lib/setup-codeql-action.js index 64e6a317c..636a142b8 100644 --- a/lib/setup-codeql-action.js +++ b/lib/setup-codeql-action.js @@ -103597,7 +103597,7 @@ var semver = __toESM(require_semver2()); // src/api-compatibility.json var maximumVersion = "3.21"; -var minimumVersion = "3.14"; +var minimumVersion = "3.16"; // src/json/index.ts function isObject2(value) { diff --git a/lib/start-proxy-action-post.js b/lib/start-proxy-action-post.js index 00a390c1f..11e1e8a97 100644 --- a/lib/start-proxy-action-post.js +++ b/lib/start-proxy-action-post.js @@ -161656,7 +161656,7 @@ var semver = __toESM(require_semver2()); // src/api-compatibility.json var maximumVersion = "3.21"; -var minimumVersion = "3.14"; +var minimumVersion = "3.16"; // src/json/index.ts function isObject2(value) { diff --git a/lib/upload-sarif-action-post.js b/lib/upload-sarif-action-post.js index 00baeb360..9f2fd24eb 100644 --- a/lib/upload-sarif-action-post.js +++ b/lib/upload-sarif-action-post.js @@ -161656,7 +161656,7 @@ var semver = __toESM(require_semver2()); // src/api-compatibility.json var maximumVersion = "3.21"; -var minimumVersion = "3.14"; +var minimumVersion = "3.16"; // src/json/index.ts function isObject2(value) { diff --git a/src/api-compatibility.json b/src/api-compatibility.json index 2e55b9ad7..2cded5e4c 100644 --- a/src/api-compatibility.json +++ b/src/api-compatibility.json @@ -1 +1 @@ -{"maximumVersion": "3.21", "minimumVersion": "3.14"} +{"maximumVersion": "3.21", "minimumVersion": "3.16"} From 97be3af35ac37441d1b6361481ce99f353df02c2 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 28 Apr 2026 15:32:55 +0100 Subject: [PATCH 06/10] Deprecate CodeQL versions 2.19.3 and earlier --- CHANGELOG.md | 1 + lib/analyze-action-post.js | 6 +++--- lib/analyze-action.js | 6 +++--- lib/autobuild-action.js | 6 +++--- lib/init-action-post.js | 6 +++--- lib/init-action.js | 6 +++--- lib/resolve-environment-action.js | 6 +++--- lib/setup-codeql-action.js | 6 +++--- lib/upload-lib.js | 6 +++--- lib/upload-sarif-action.js | 6 +++--- src/codeql.ts | 6 +++--- 11 files changed, 31 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff4e2d3bf..7bca7fa9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th ## [UNRELEASED] - 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) +- _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) ## 4.35.2 - 15 Apr 2026 diff --git a/lib/analyze-action-post.js b/lib/analyze-action-post.js index 78954afbe..e09612b2c 100644 --- a/lib/analyze-action-post.js +++ b/lib/analyze-action-post.js @@ -163010,9 +163010,9 @@ async function shouldEnableIndirectTracing(codeql, config) { // src/codeql.ts var cachedCodeQL = void 0; var CODEQL_MINIMUM_VERSION = "2.17.6"; -var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; -var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; -var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; +var CODEQL_NEXT_MINIMUM_VERSION = "2.19.4"; +var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.15"; +var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-04-09"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; async function getCodeQL(cmd) { if (cachedCodeQL === void 0) { diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 750a0e52d..372021fc2 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -110045,9 +110045,9 @@ async function endTracingForCluster(codeql, config, logger) { // src/codeql.ts var cachedCodeQL = void 0; var CODEQL_MINIMUM_VERSION = "2.17.6"; -var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; -var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; -var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; +var CODEQL_NEXT_MINIMUM_VERSION = "2.19.4"; +var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.15"; +var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-04-09"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { try { diff --git a/lib/autobuild-action.js b/lib/autobuild-action.js index 379911bd5..6825745a3 100644 --- a/lib/autobuild-action.js +++ b/lib/autobuild-action.js @@ -105422,9 +105422,9 @@ async function endTracingForCluster(codeql, config, logger) { // src/codeql.ts var cachedCodeQL = void 0; var CODEQL_MINIMUM_VERSION = "2.17.6"; -var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; -var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; -var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; +var CODEQL_NEXT_MINIMUM_VERSION = "2.19.4"; +var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.15"; +var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-04-09"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; async function getCodeQL(cmd) { if (cachedCodeQL === void 0) { diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 2e065ac6b..e8dc72e0b 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -167857,9 +167857,9 @@ async function shouldEnableIndirectTracing(codeql, config) { // src/codeql.ts var cachedCodeQL = void 0; var CODEQL_MINIMUM_VERSION = "2.17.6"; -var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; -var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; -var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; +var CODEQL_NEXT_MINIMUM_VERSION = "2.19.4"; +var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.15"; +var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-04-09"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { try { diff --git a/lib/init-action.js b/lib/init-action.js index 1970c1279..d0b0a8b61 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -108975,9 +108975,9 @@ async function getCombinedTracerConfig(codeql, config) { // src/codeql.ts var cachedCodeQL = void 0; var CODEQL_MINIMUM_VERSION = "2.17.6"; -var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; -var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; -var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; +var CODEQL_NEXT_MINIMUM_VERSION = "2.19.4"; +var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.15"; +var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-04-09"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { try { diff --git a/lib/resolve-environment-action.js b/lib/resolve-environment-action.js index 5fa8073dd..87def4ccd 100644 --- a/lib/resolve-environment-action.js +++ b/lib/resolve-environment-action.js @@ -105059,9 +105059,9 @@ async function shouldEnableIndirectTracing(codeql, config) { // src/codeql.ts var cachedCodeQL = void 0; var CODEQL_MINIMUM_VERSION = "2.17.6"; -var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; -var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; -var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; +var CODEQL_NEXT_MINIMUM_VERSION = "2.19.4"; +var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.15"; +var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-04-09"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; async function getCodeQL(cmd) { if (cachedCodeQL === void 0) { diff --git a/lib/setup-codeql-action.js b/lib/setup-codeql-action.js index 636a142b8..a2699cb27 100644 --- a/lib/setup-codeql-action.js +++ b/lib/setup-codeql-action.js @@ -106468,9 +106468,9 @@ async function shouldEnableIndirectTracing(codeql, config) { // src/codeql.ts var cachedCodeQL = void 0; var CODEQL_MINIMUM_VERSION = "2.17.6"; -var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; -var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; -var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; +var CODEQL_NEXT_MINIMUM_VERSION = "2.19.4"; +var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.15"; +var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-04-09"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { try { diff --git a/lib/upload-lib.js b/lib/upload-lib.js index 4bd41931b..0d9ffc35e 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -109154,9 +109154,9 @@ async function shouldEnableIndirectTracing(codeql, config) { // src/codeql.ts var cachedCodeQL = void 0; var CODEQL_MINIMUM_VERSION = "2.17.6"; -var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; -var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; -var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; +var CODEQL_NEXT_MINIMUM_VERSION = "2.19.4"; +var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.15"; +var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-04-09"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { try { diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index e6ca76b23..02f6c1fb3 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -109820,9 +109820,9 @@ async function shouldEnableIndirectTracing(codeql, config) { // src/codeql.ts var cachedCodeQL = void 0; var CODEQL_MINIMUM_VERSION = "2.17.6"; -var CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; -var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; -var GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; +var CODEQL_NEXT_MINIMUM_VERSION = "2.19.4"; +var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.15"; +var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-04-09"; var EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, checkVersion) { try { diff --git a/src/codeql.ts b/src/codeql.ts index fda355033..ecad2ea19 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -282,17 +282,17 @@ const CODEQL_MINIMUM_VERSION = "2.17.6"; /** * This version will shortly become the oldest version of CodeQL that the Action will run with. */ -const CODEQL_NEXT_MINIMUM_VERSION = "2.17.6"; +const CODEQL_NEXT_MINIMUM_VERSION = "2.19.4"; /** * This is the version of GHES that was most recently deprecated. */ -const GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13"; +const GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.15"; /** * This is the deprecation date for the version of GHES that was most recently deprecated. */ -const GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19"; +const GHES_MOST_RECENT_DEPRECATION_DATE = "2026-04-09"; /** The CLI verbosity level to use for extraction in debug mode. */ const EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++"; From 0a636086c932e088ee3a3cbfc20fc728a58d5bd6 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 28 Apr 2026 15:08:54 +0100 Subject: [PATCH 07/10] Add GHES 3.21 to supported versions table --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 35b50c6a3..bee9072a0 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,7 @@ We typically release new minor versions of the CodeQL Action and Bundle when a n | Minimum CodeQL Action | Minimum CodeQL Bundle Version | GitHub Environment | Notes | |-----------------------|-------------------------------|--------------------|-------| +| `v4.33.0` | `2.24.3` | Enterprise Server 3.21 | | | `v4.31.10` | `2.23.9` | Enterprise Server 3.20 | | | `v3.29.11` | `2.22.4` | Enterprise Server 3.19 | | | `v3.28.21` | `2.21.3` | Enterprise Server 3.18 | | From 56733fb5ae9b8f71546e1785beafb3fedc08f933 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 28 Apr 2026 19:00:28 +0100 Subject: [PATCH 08/10] Add log group for downloading overlay-base DB --- lib/init-action.js | 25 +++++++++++++++---------- src/init-action.ts | 27 ++++++++++++++++----------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/lib/init-action.js b/lib/init-action.js index a3c7ab96b..3c50d8fd4 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -110659,17 +110659,22 @@ async function run(startedAt) { let dependencyCachingStatus; try { if (config.overlayDatabaseMode === "overlay" /* Overlay */ && config.useOverlayDatabaseCaching) { - overlayBaseDatabaseStats = await downloadOverlayBaseDatabaseFromCache( - codeql, - config, - logger + await withGroupAsync( + "Checking cache for overlay-base database", + async () => { + overlayBaseDatabaseStats = await downloadOverlayBaseDatabaseFromCache( + codeql, + config, + logger + ); + if (!overlayBaseDatabaseStats) { + config.overlayDatabaseMode = "none" /* None */; + logger.info( + `No overlay-base database found in cache, reverting overlay database mode to ${"none" /* None */}.` + ); + } + } ); - if (!overlayBaseDatabaseStats) { - config.overlayDatabaseMode = "none" /* None */; - logger.info( - `No overlay-base database found in cache, reverting overlay database mode to ${"none" /* None */}.` - ); - } } if (config.overlayDatabaseMode !== "overlay" /* Overlay */) { cleanupDatabaseClusterDirectory(config, logger); diff --git a/src/init-action.ts b/src/init-action.ts index 37a9df9c8..859dcefa2 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -465,18 +465,23 @@ async function run(startedAt: Date) { // necessary preparations. So, in that mode, we would assume that // everything is in order and let the analysis fail if that turns out not // to be the case. - overlayBaseDatabaseStats = await downloadOverlayBaseDatabaseFromCache( - codeql, - config, - logger, + await withGroupAsync( + "Checking cache for overlay-base database", + async () => { + overlayBaseDatabaseStats = await downloadOverlayBaseDatabaseFromCache( + codeql, + config, + logger, + ); + if (!overlayBaseDatabaseStats) { + config.overlayDatabaseMode = OverlayDatabaseMode.None; + logger.info( + "No overlay-base database found in cache, " + + `reverting overlay database mode to ${OverlayDatabaseMode.None}.`, + ); + } + }, ); - if (!overlayBaseDatabaseStats) { - config.overlayDatabaseMode = OverlayDatabaseMode.None; - logger.info( - "No overlay-base database found in cache, " + - `reverting overlay database mode to ${OverlayDatabaseMode.None}.`, - ); - } } if (config.overlayDatabaseMode !== OverlayDatabaseMode.Overlay) { From 5145c112e77f2225fe26c100ee77650666dffbfc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 18:00:14 +0000 Subject: [PATCH 09/10] Bump ruby/setup-ruby Bumps the actions-minor group with 1 update in the /.github/workflows directory: [ruby/setup-ruby](https://github.com/ruby/setup-ruby). Updates `ruby/setup-ruby` from 1.301.0 to 1.305.0 - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/4c56a21280b36d862b5fc31348f463d60bdc55d5...0cb964fd540e0a24c900370abf38a33466142735) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.305.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/__rubocop-multi-language.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/__rubocop-multi-language.yml b/.github/workflows/__rubocop-multi-language.yml index 442fd0b93..33e78dd70 100644 --- a/.github/workflows/__rubocop-multi-language.yml +++ b/.github/workflows/__rubocop-multi-language.yml @@ -59,7 +59,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Set up Ruby - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + uses: ruby/setup-ruby@0cb964fd540e0a24c900370abf38a33466142735 # v1.305.0 with: ruby-version: 2.6 - name: Install Code Scanning integration From f07336045603d079c731c23865d67bcb5df643a9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 18:02:23 +0000 Subject: [PATCH 10/10] Rebuild --- pr-checks/checks/rubocop-multi-language.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pr-checks/checks/rubocop-multi-language.yml b/pr-checks/checks/rubocop-multi-language.yml index ecfdcde46..504dce1cd 100644 --- a/pr-checks/checks/rubocop-multi-language.yml +++ b/pr-checks/checks/rubocop-multi-language.yml @@ -5,7 +5,7 @@ versions: - default steps: - name: Set up Ruby - uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0 + uses: ruby/setup-ruby@0cb964fd540e0a24c900370abf38a33466142735 # v1.305.0 with: ruby-version: 2.6 - name: Install Code Scanning integration