diff --git a/.github/workflows/artifacts-summary.lock.yml b/.github/workflows/artifacts-summary.lock.yml index e39b1baf647..67c9493b83b 100644 --- a/.github/workflows/artifacts-summary.lock.yml +++ b/.github/workflows/artifacts-summary.lock.yml @@ -3120,9 +3120,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -3136,6 +3144,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3168,11 +3183,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/audit-workflows.lock.yml b/.github/workflows/audit-workflows.lock.yml index 96f00346740..9d4b111f2ba 100644 --- a/.github/workflows/audit-workflows.lock.yml +++ b/.github/workflows/audit-workflows.lock.yml @@ -2982,9 +2982,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -2998,6 +3006,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3030,11 +3045,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml index b0a062680c6..4e80cc3741e 100644 --- a/.github/workflows/brave.lock.yml +++ b/.github/workflows/brave.lock.yml @@ -3879,9 +3879,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -3895,6 +3903,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3927,11 +3942,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/changeset-generator.lock.yml b/.github/workflows/changeset-generator.lock.yml index 3c78ff261a9..24b99e643e8 100644 --- a/.github/workflows/changeset-generator.lock.yml +++ b/.github/workflows/changeset-generator.lock.yml @@ -3289,9 +3289,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -3305,6 +3313,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3337,11 +3352,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml index a3e66a053be..66ea1cf6090 100644 --- a/.github/workflows/ci-doctor.lock.yml +++ b/.github/workflows/ci-doctor.lock.yml @@ -3205,9 +3205,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -3221,6 +3229,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3253,11 +3268,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/cli-version-checker.lock.yml b/.github/workflows/cli-version-checker.lock.yml index 8b4f58a74fb..54ac5ca05a5 100644 --- a/.github/workflows/cli-version-checker.lock.yml +++ b/.github/workflows/cli-version-checker.lock.yml @@ -2775,9 +2775,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -2791,6 +2799,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -2823,11 +2838,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/daily-doc-updater.lock.yml b/.github/workflows/daily-doc-updater.lock.yml index 684bf9ed403..b96033cec72 100644 --- a/.github/workflows/daily-doc-updater.lock.yml +++ b/.github/workflows/daily-doc-updater.lock.yml @@ -2917,9 +2917,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -2933,6 +2941,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -2965,11 +2980,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/daily-news.lock.yml b/.github/workflows/daily-news.lock.yml index d0149d9ea0b..eca26d361ba 100644 --- a/.github/workflows/daily-news.lock.yml +++ b/.github/workflows/daily-news.lock.yml @@ -3135,9 +3135,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -3151,6 +3159,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3183,11 +3198,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml index 2c1b6304573..3786da81d71 100644 --- a/.github/workflows/dev.lock.yml +++ b/.github/workflows/dev.lock.yml @@ -3520,9 +3520,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -3536,6 +3544,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3568,11 +3583,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/duplicate-code-detector.lock.yml b/.github/workflows/duplicate-code-detector.lock.yml index 7f0dfe6d766..5fa7ab88efd 100644 --- a/.github/workflows/duplicate-code-detector.lock.yml +++ b/.github/workflows/duplicate-code-detector.lock.yml @@ -2733,9 +2733,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -2749,6 +2757,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -2781,11 +2796,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/example-workflow-analyzer.lock.yml b/.github/workflows/example-workflow-analyzer.lock.yml index 10b81dad3d4..7b4848cdc2d 100644 --- a/.github/workflows/example-workflow-analyzer.lock.yml +++ b/.github/workflows/example-workflow-analyzer.lock.yml @@ -2693,9 +2693,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -2709,6 +2717,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -2741,11 +2756,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/github-mcp-tools-report.lock.yml b/.github/workflows/github-mcp-tools-report.lock.yml index 288b6cad6c7..e2b55a3f4dd 100644 --- a/.github/workflows/github-mcp-tools-report.lock.yml +++ b/.github/workflows/github-mcp-tools-report.lock.yml @@ -3110,9 +3110,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -3126,6 +3134,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3158,11 +3173,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/go-pattern-detector.lock.yml b/.github/workflows/go-pattern-detector.lock.yml index d6c0b251640..adb94faa1f4 100644 --- a/.github/workflows/go-pattern-detector.lock.yml +++ b/.github/workflows/go-pattern-detector.lock.yml @@ -2810,9 +2810,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -2826,6 +2834,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -2858,11 +2873,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/lockfile-stats.lock.yml b/.github/workflows/lockfile-stats.lock.yml index d82ccfd62ee..105764b27ca 100644 --- a/.github/workflows/lockfile-stats.lock.yml +++ b/.github/workflows/lockfile-stats.lock.yml @@ -3045,9 +3045,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -3061,6 +3069,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3093,11 +3108,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/mcp-inspector.lock.yml b/.github/workflows/mcp-inspector.lock.yml index 19a6f53b3c7..e9362919d9a 100644 --- a/.github/workflows/mcp-inspector.lock.yml +++ b/.github/workflows/mcp-inspector.lock.yml @@ -4082,9 +4082,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -4098,6 +4106,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -4130,11 +4145,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/notion-issue-summary.lock.yml b/.github/workflows/notion-issue-summary.lock.yml index 013bf634859..da0f1851d16 100644 --- a/.github/workflows/notion-issue-summary.lock.yml +++ b/.github/workflows/notion-issue-summary.lock.yml @@ -3098,9 +3098,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -3114,6 +3122,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3146,11 +3161,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/pdf-summary.lock.yml b/.github/workflows/pdf-summary.lock.yml index b19824869ed..b19e33233f0 100644 --- a/.github/workflows/pdf-summary.lock.yml +++ b/.github/workflows/pdf-summary.lock.yml @@ -3832,9 +3832,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -3848,6 +3856,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3880,11 +3895,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/plan.lock.yml b/.github/workflows/plan.lock.yml index 64ae8533ac9..4aec6b9b97f 100644 --- a/.github/workflows/plan.lock.yml +++ b/.github/workflows/plan.lock.yml @@ -3709,9 +3709,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -3725,6 +3733,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3757,11 +3772,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/poem-bot.lock.yml b/.github/workflows/poem-bot.lock.yml index 9c00bc03076..6870f413767 100644 --- a/.github/workflows/poem-bot.lock.yml +++ b/.github/workflows/poem-bot.lock.yml @@ -3826,9 +3826,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -3842,6 +3850,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3874,11 +3889,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/q.lock.yml b/.github/workflows/q.lock.yml index 1a101fcde18..cbdcf674c3e 100644 --- a/.github/workflows/q.lock.yml +++ b/.github/workflows/q.lock.yml @@ -4137,9 +4137,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -4153,6 +4161,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -4185,11 +4200,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/repo-tree-map.lock.yml b/.github/workflows/repo-tree-map.lock.yml index 6c814a4536f..179c3da5641 100644 --- a/.github/workflows/repo-tree-map.lock.yml +++ b/.github/workflows/repo-tree-map.lock.yml @@ -3140,9 +3140,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -3156,6 +3164,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3188,11 +3203,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/research.lock.yml b/.github/workflows/research.lock.yml index 05f92b3d23a..5bd1fe11b46 100644 --- a/.github/workflows/research.lock.yml +++ b/.github/workflows/research.lock.yml @@ -3116,9 +3116,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -3132,6 +3140,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3164,11 +3179,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/scout.lock.yml b/.github/workflows/scout.lock.yml index ece4e34ef1c..cc2b33f4f86 100644 --- a/.github/workflows/scout.lock.yml +++ b/.github/workflows/scout.lock.yml @@ -4255,9 +4255,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -4271,6 +4279,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -4303,11 +4318,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/security-fix-pr.lock.yml b/.github/workflows/security-fix-pr.lock.yml index 75b19948087..55c31d711e0 100644 --- a/.github/workflows/security-fix-pr.lock.yml +++ b/.github/workflows/security-fix-pr.lock.yml @@ -2862,9 +2862,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -2878,6 +2886,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -2910,11 +2925,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 1c55198e341..dbdc8da8fb8 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -2652,9 +2652,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -2668,6 +2676,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -2700,11 +2715,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index 272d4af88e3..84164cf6b31 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -2480,9 +2480,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -2496,6 +2504,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -2528,11 +2543,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index 20a06df56a1..60f087f3298 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -3066,9 +3066,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -3082,6 +3090,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3114,11 +3129,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/technical-doc-writer.lock.yml b/.github/workflows/technical-doc-writer.lock.yml index ec79a533df2..eb7bc7fa697 100644 --- a/.github/workflows/technical-doc-writer.lock.yml +++ b/.github/workflows/technical-doc-writer.lock.yml @@ -2966,9 +2966,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -2982,6 +2990,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3014,11 +3029,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/test-post-steps.lock.yml b/.github/workflows/test-post-steps.lock.yml index 5ab6af89378..4311731c8aa 100644 --- a/.github/workflows/test-post-steps.lock.yml +++ b/.github/workflows/test-post-steps.lock.yml @@ -1574,9 +1574,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -1590,6 +1598,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -1622,11 +1637,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/tidy.lock.yml b/.github/workflows/tidy.lock.yml index f298414ac72..08a4cc977a8 100644 --- a/.github/workflows/tidy.lock.yml +++ b/.github/workflows/tidy.lock.yml @@ -3583,9 +3583,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -3599,6 +3607,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3631,11 +3646,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml index 6548fc51e77..dfea3717da1 100644 --- a/.github/workflows/unbloat-docs.lock.yml +++ b/.github/workflows/unbloat-docs.lock.yml @@ -3442,9 +3442,17 @@ jobs: let hasErrors = false; const MAX_ITERATIONS_PER_LINE = 10000; const ITERATION_WARNING_THRESHOLD = 1000; + const MAX_TOTAL_ERRORS = 100; + const MAX_LINE_LENGTH = 10000; + const TOP_SLOW_PATTERNS_COUNT = 5; core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -3458,6 +3466,13 @@ jobs: if (shouldSkipLine(line)) { continue; } + if (line.length > MAX_LINE_LENGTH) { + continue; + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } let match; let iterationCount = 0; let lastIndex = -1; @@ -3490,11 +3505,37 @@ jobs: } else { core.warning(errorMessage); } + patternMatches++; + totalMatches++; } if (iterationCount > 100) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); return hasErrors; diff --git a/pkg/workflow/js/validate_errors.cjs b/pkg/workflow/js/validate_errors.cjs index 7b8c5251f93..929228a9979 100644 --- a/pkg/workflow/js/validate_errors.cjs +++ b/pkg/workflow/js/validate_errors.cjs @@ -140,14 +140,24 @@ function validateErrors(logContent, patterns) { const lines = logContent.split("\n"); let hasErrors = false; - // Configuration for infinite loop detection + // Configuration for infinite loop detection and performance const MAX_ITERATIONS_PER_LINE = 10000; // Maximum regex matches per line const ITERATION_WARNING_THRESHOLD = 1000; // Warn if iterations exceed this + const MAX_TOTAL_ERRORS = 100; // Stop after finding this many errors (prevents excessive processing) + const MAX_LINE_LENGTH = 10000; // Skip lines longer than this (likely JSON payloads) + const TOP_SLOW_PATTERNS_COUNT = 5; // Number of slowest patterns to report core.info(`Starting error validation with ${patterns.length} patterns and ${lines.length} lines`); + const validationStartTime = Date.now(); + let totalMatches = 0; + let patternStats = []; + for (let patternIndex = 0; patternIndex < patterns.length; patternIndex++) { const pattern = patterns[patternIndex]; + const patternStartTime = Date.now(); + let patternMatches = 0; + let regex; try { regex = new RegExp(pattern.pattern, "g"); @@ -166,6 +176,18 @@ function validateErrors(logContent, patterns) { continue; } + // Skip very long lines that are likely JSON payloads or dumps + // These rarely contain actionable error messages and are expensive to process + if (line.length > MAX_LINE_LENGTH) { + continue; + } + + // Early termination if we've found too many errors + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping error validation after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + let match; let iterationCount = 0; let lastIndex = -1; @@ -208,6 +230,9 @@ function validateErrors(logContent, patterns) { } else { core.warning(errorMessage); } + + patternMatches++; + totalMatches++; } // Log if we had a significant number of matches on a line @@ -215,6 +240,40 @@ function validateErrors(logContent, patterns) { core.info(`Line ${lineIndex + 1} had ${iterationCount} matches for pattern: ${pattern.description || pattern.pattern}`); } } + + // Track pattern performance + const patternElapsed = Date.now() - patternStartTime; + patternStats.push({ + description: pattern.description || "Unknown", + pattern: pattern.pattern.substring(0, 50) + (pattern.pattern.length > 50 ? "..." : ""), + matches: patternMatches, + timeMs: patternElapsed, + }); + + // Log slow patterns (> 5 seconds) + if (patternElapsed > 5000) { + core.warning(`Pattern "${pattern.description}" took ${patternElapsed}ms to process (${patternMatches} matches)`); + } + + // Early termination if we've found enough errors + if (totalMatches >= MAX_TOTAL_ERRORS) { + core.warning(`Stopping pattern processing after finding ${totalMatches} matches (max: ${MAX_TOTAL_ERRORS})`); + break; + } + } + + // Log performance summary + const validationElapsed = Date.now() - validationStartTime; + core.info(`Validation summary: ${totalMatches} total matches found in ${validationElapsed}ms`); + + // Log top slowest patterns + patternStats.sort((a, b) => b.timeMs - a.timeMs); + const topSlow = patternStats.slice(0, TOP_SLOW_PATTERNS_COUNT); + if (topSlow.length > 0 && topSlow[0].timeMs > 1000) { + core.info(`Top ${TOP_SLOW_PATTERNS_COUNT} slowest patterns:`); + topSlow.forEach((stat, idx) => { + core.info(` ${idx + 1}. "${stat.description}" - ${stat.timeMs}ms (${stat.matches} matches)`); + }); } core.info(`Error validation completed. Errors found: ${hasErrors}`); diff --git a/pkg/workflow/js/validate_errors.test.cjs b/pkg/workflow/js/validate_errors.test.cjs index 6c416b4b564..b7cdc9346e8 100644 --- a/pkg/workflow/js/validate_errors.test.cjs +++ b/pkg/workflow/js/validate_errors.test.cjs @@ -389,9 +389,10 @@ describe("infinite loop detection", () => { expect(hasIterationWarning).toBe(true); }); - test("should enforce maximum iteration limit", () => { - // Create a line with an extreme number of potential matches - const massivePattern = "X".repeat(15000); // More than MAX_ITERATIONS_PER_LINE + test("should enforce maximum iteration limit or max error limit", () => { + // Create a line with an extreme number of potential matches but within MAX_LINE_LENGTH + // Use 9000 chars to stay under the 10KB limit but still exceed MAX_ITERATIONS_PER_LINE + const massivePattern = "X".repeat(9000); const logContent = massivePattern; const patterns = [ @@ -405,11 +406,15 @@ describe("infinite loop detection", () => { validateErrors(logContent, patterns); - // Should have logged an error about maximum iteration limit + // Should have logged either an error about maximum iteration limit OR stopping due to max errors const errorCalls = global.core.error.mock.calls.map(call => call[0]); + const warningCalls = global.core.warning.mock.calls.map(call => call[0]); + const hasMaxIterationError = errorCalls.some(msg => msg.includes("Maximum iteration limit") || msg.includes("10000")); + const hasMaxErrorsWarning = warningCalls.some(msg => msg.includes("Stopping") && (msg.includes("100") || msg.includes("max"))); - expect(hasMaxIterationError).toBe(true); + // Either condition should be true (we hit one of the limits) + expect(hasMaxIterationError || hasMaxErrorsWarning).toBe(true); }); test("should not have patterns that match empty string (zero-width)", () => {