diff --git a/pkg/workflow/compiler_jobs.go b/pkg/workflow/compiler_jobs.go index 90d5ba12d3..256069c5b4 100644 --- a/pkg/workflow/compiler_jobs.go +++ b/pkg/workflow/compiler_jobs.go @@ -17,6 +17,12 @@ import ( var compilerJobsLog = logger.New("workflow:compiler_jobs") +// Pre-compiled regexes for performance (avoid recompilation in hot paths) +var ( + // runtimeImportMacroRe matches runtime-import macros: {{#runtime-import filepath}} or {{#runtime-import? filepath}} + runtimeImportMacroRe = regexp.MustCompile(`\{\{#runtime-import\??[ \t]+([^\}]+)\}\}`) +) + // This file contains job building functions extracted from compiler.go // These functions are responsible for constructing the various jobs that make up // a compiled agentic workflow, including activation, main, safe outputs, and custom jobs. @@ -449,11 +455,8 @@ func containsRuntimeImports(markdownContent string) bool { return false } - // Pattern: {{#runtime-import filepath}} or {{#runtime-import? filepath}} - // Match any runtime-import macro - macroPattern := `\{\{#runtime-import\??[ \t]+([^\}]+)\}\}` - macroRe := regexp.MustCompile(macroPattern) - matches := macroRe.FindAllStringSubmatch(markdownContent, -1) + // Use pre-compiled regex from package level for performance + matches := runtimeImportMacroRe.FindAllStringSubmatch(markdownContent, -1) for _, match := range matches { if len(match) > 1 { filepath := strings.TrimSpace(match[1]) diff --git a/pkg/workflow/expression_extraction.go b/pkg/workflow/expression_extraction.go index 8db19c0416..bb2ef7458c 100644 --- a/pkg/workflow/expression_extraction.go +++ b/pkg/workflow/expression_extraction.go @@ -13,6 +13,13 @@ import ( var expressionExtractionLog = logger.New("workflow:expression_extraction") +// Pre-compiled regexes for performance (avoid recompilation in hot paths) +var ( + // expressionExtractionRegex matches GitHub Actions expressions: ${{ ... }} + // Uses (?s) flag for dotall mode, non-greedy matching + expressionExtractionRegex = regexp.MustCompile(`\$\{\{(.*?)\}\}`) +) + // ExpressionMapping represents a mapping between a GitHub expression and its environment variable type ExpressionMapping struct { Original string // The original ${{ ... }} expression @@ -40,11 +47,8 @@ func NewExpressionExtractor() *ExpressionExtractor { func (e *ExpressionExtractor) ExtractExpressions(markdown string) ([]*ExpressionMapping, error) { expressionExtractionLog.Printf("Extracting expressions from markdown: content_length=%d", len(markdown)) - // Regular expression to match GitHub Actions expressions: ${{ ... }} - // Use (?s) flag for dotall mode, non-greedy matching - expressionRegex := regexp.MustCompile(`\$\{\{(.*?)\}\}`) - - matches := expressionRegex.FindAllStringSubmatch(markdown, -1) + // Use pre-compiled regex from package level for performance + matches := expressionExtractionRegex.FindAllStringSubmatch(markdown, -1) expressionExtractionLog.Printf("Found %d expression matches", len(matches)) for _, match := range matches { diff --git a/pkg/workflow/repo_memory.go b/pkg/workflow/repo_memory.go index 2c3fb8b686..100dd7fedb 100644 --- a/pkg/workflow/repo_memory.go +++ b/pkg/workflow/repo_memory.go @@ -26,6 +26,12 @@ import ( var repoMemoryLog = logger.New("workflow:repo_memory") +// Pre-compiled regexes for performance (avoid recompilation in hot paths) +var ( + // branchPrefixValidPattern matches valid branch prefix characters (alphanumeric, hyphens, underscores) + branchPrefixValidPattern = regexp.MustCompile(`^[a-zA-Z0-9_-]+$`) +) + // RepoMemoryConfig holds configuration for repo-memory functionality type RepoMemoryConfig struct { BranchPrefix string `yaml:"branch-prefix,omitempty"` // branch prefix (default: "memory") @@ -74,8 +80,8 @@ func validateBranchPrefix(prefix string) error { } // Check for alphanumeric and branch-friendly characters (alphanumeric, hyphens, underscores) - validPattern := regexp.MustCompile(`^[a-zA-Z0-9_-]+$`) - if !validPattern.MatchString(prefix) { + // Use pre-compiled regex from package level for performance + if !branchPrefixValidPattern.MatchString(prefix) { return fmt.Errorf("branch-prefix must contain only alphanumeric characters, hyphens, and underscores, got '%s'", prefix) } diff --git a/pkg/workflow/template_validation.go b/pkg/workflow/template_validation.go index 550a734777..9f5bae4c61 100644 --- a/pkg/workflow/template_validation.go +++ b/pkg/workflow/template_validation.go @@ -39,16 +39,19 @@ import ( var templateValidationLog = logger.New("workflow:template_validation") +// Pre-compiled regexes for performance (avoid recompilation in hot paths) +var ( + // templateRegionPattern matches template conditional blocks with their content + // Uses (?s) for dotall mode, .*? (non-greedy) with \s* to handle expressions with or without trailing spaces + templateRegionPattern = regexp.MustCompile(`(?s)\{\{#if\s+.*?\s*\}\}(.*?)\{\{/if\}\}`) +) + // validateNoIncludesInTemplateRegions checks that import directives // are not used inside template conditional blocks ({{#if...}}{{/if}}) func validateNoIncludesInTemplateRegions(markdown string) error { templateValidationLog.Print("Validating that imports are not inside template regions") - // Find all template regions by matching {{#if...}}...{{/if}} blocks - // This regex matches template conditional blocks with their content - // Uses .*? (non-greedy) with \s* to handle expressions with or without trailing spaces - templateRegionPattern := regexp.MustCompile(`(?s)\{\{#if\s+.*?\s*\}\}(.*?)\{\{/if\}\}`) - + // Use pre-compiled regex from package level for performance matches := templateRegionPattern.FindAllStringSubmatch(markdown, -1) templateValidationLog.Printf("Found %d template regions to validate", len(matches))