Merge pull request #3852 from github/henrymercer/avoid-diagnostic-collisions

Add random suffix when writing diagnostics to avoid filename collisions
This commit is contained in:
Henry Mercer
2026-04-28 12:04:59 +00:00
committed by GitHub
8 changed files with 60 additions and 15 deletions
+1 -1
View File
@@ -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
+7 -2
View File
@@ -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,10 +107893,14 @@ function writeDiagnostic(config, language, diagnostic) {
);
try {
(0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true });
const uniqueSuffix = (diagnosticCounter++).toString();
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(":", "")}.json`
`codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json`
);
(0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic));
} catch (err) {
+7 -2
View File
@@ -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,10 +165812,14 @@ function writeDiagnostic(config, language, diagnostic) {
);
try {
(0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true });
const uniqueSuffix = (diagnosticCounter++).toString();
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(":", "")}.json`
`codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json`
);
(0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic));
} catch (err) {
+7 -2
View File
@@ -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,10 +105398,14 @@ function writeDiagnostic(config, language, diagnostic) {
);
try {
(0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true });
const uniqueSuffix = (diagnosticCounter++).toString();
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(":", "")}.json`
`codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json`
);
(0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic));
} catch (err) {
+7 -2
View File
@@ -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,10 +105468,14 @@ function writeDiagnostic(config, language, diagnostic) {
);
try {
(0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true });
const uniqueSuffix = (diagnosticCounter++).toString();
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(":", "")}.json`
`codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json`
);
(0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic));
} catch (err) {
+7 -2
View File
@@ -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,10 +107503,14 @@ function writeDiagnostic(config, language, diagnostic) {
);
try {
(0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true });
const uniqueSuffix = (diagnosticCounter++).toString();
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(":", "")}.json`
`codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json`
);
(0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic));
} catch (err) {
+7 -2
View File
@@ -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,10 +108259,14 @@ function writeDiagnostic(config, language, diagnostic) {
);
try {
(0, import_fs.mkdirSync)(diagnosticsPath, { recursive: true });
const uniqueSuffix = (diagnosticCounter++).toString();
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(":", "")}.json`
`codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json`
);
(0, import_fs.writeFileSync)(jsonPath, JSON.stringify(diagnostic));
} catch (err) {
+17 -2
View File
@@ -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,10 +174,18 @@ function writeDiagnostic(
// Create the directory if it doesn't exist yet.
mkdirSync(diagnosticsPath, { recursive: true });
// 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(
/[^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(":", "")}.json`,
`codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json`,
);
writeFileSync(jsonPath, JSON.stringify(diagnostic));