From a48ca72395ed26ccd09443c2613f24ff11707af8 Mon Sep 17 00:00:00 2001 From: Sam Chau Date: Wed, 27 Aug 2025 04:41:43 +0930 Subject: [PATCH] ci(validation): add regex pattern validation --- .github/workflows/regex.yml | 55 ++++++++++++++++++++++++++++ scripts/unitTest.ps1 | 1 + scripts/validatePattern.ps1 | 73 +++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 .github/workflows/regex.yml create mode 100644 scripts/unitTest.ps1 create mode 100644 scripts/validatePattern.ps1 diff --git a/.github/workflows/regex.yml b/.github/workflows/regex.yml new file mode 100644 index 0000000..59e0158 --- /dev/null +++ b/.github/workflows/regex.yml @@ -0,0 +1,55 @@ +name: Validate Regex Patterns + +on: + push: + paths: + - 'regex_patterns/**/*.yml' + - 'regex_patterns/**/*.yaml' + - '.github/workflows/regex.yml' + - 'scripts/validatePattern.ps1' + pull_request: + paths: + - 'regex_patterns/**/*.yml' + - 'regex_patterns/**/*.yaml' + - '.github/workflows/regex.yml' + - 'scripts/validatePattern.ps1' + workflow_dispatch: + +jobs: + discover-patterns: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + + - id: set-matrix + run: | + patterns=$(find regex_patterns -name "*.yml" -o -name "*.yaml" | jq -R -s -c 'split("\n")[:-1] | map({file: ., name: (. | split("/")[-1] | split(".")[0])})') + echo "matrix=$patterns" >> $GITHUB_OUTPUT + echo "Found patterns: $patterns" + + validate-pattern: + needs: discover-patterns + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + pattern: ${{ fromJson(needs.discover-patterns.outputs.matrix) }} + name: Validate ${{ matrix.pattern.name }} + steps: + - uses: actions/checkout@v4 + + - name: Setup PowerShell + run: | + sudo apt-get update + sudo apt-get install -y powershell + + - name: Validate Pattern + run: | + pwsh scripts/validatePattern.ps1 -YamlFilePath "${{ matrix.pattern.file }}" + + - name: Run Unit Tests + run: | + echo "TODO: Implement unit tests for ${{ matrix.pattern.file }}" + # TODO: Add test runner command here \ No newline at end of file diff --git a/scripts/unitTest.ps1 b/scripts/unitTest.ps1 new file mode 100644 index 0000000..11c112d --- /dev/null +++ b/scripts/unitTest.ps1 @@ -0,0 +1 @@ +# TODO: Run a single unit test given a regular expression and unit test. A unit test includes the input string and whether it should match or not. \ No newline at end of file diff --git a/scripts/validatePattern.ps1 b/scripts/validatePattern.ps1 new file mode 100644 index 0000000..f4d1d5a --- /dev/null +++ b/scripts/validatePattern.ps1 @@ -0,0 +1,73 @@ +param( + [Parameter(Mandatory=$true)] + [string]$YamlFilePath +) + +$moduleName = "regex" + +function Write-Log { + param( + [Parameter(Mandatory=$true)] + [string]$Level, + [Parameter(Mandatory=$true)] + [string]$Message + ) + + $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" + $levelPadded = $Level.ToUpper().PadRight(7) + $modulePadded = $moduleName.PadRight(0) + + # Write colored level + Write-Host -NoNewline "[" + if ($Level -eq "ERROR") { + Write-Host -NoNewline $levelPadded -ForegroundColor Red + } + elseif ($Level -eq "SUCCESS") { + Write-Host -NoNewline $levelPadded -ForegroundColor Green + } + elseif ($Level -eq "INFO") { + Write-Host -NoNewline $levelPadded -ForegroundColor Cyan + } + else { + Write-Host -NoNewline $levelPadded + } + Write-Host -NoNewline "] " + + # Write grey timestamp + Write-Host -NoNewline "[$timestamp] " -ForegroundColor DarkGray + + # Write module and message in normal color + Write-Host "[$modulePadded] $Message" +} + +try { + # Check if file exists + if (-not (Test-Path $YamlFilePath)) { + Write-Log -Level "ERROR" -Message "YAML file not found: $YamlFilePath" + exit 1 + } + + # Read YAML content + $yamlContent = Get-Content -Path $YamlFilePath -Raw + + # Extract pattern field from YAML + $patternMatch = [regex]::Match($yamlContent, 'pattern:\s*(.+)') + $pattern = $patternMatch.Groups[1].Value.Trim() + + Write-Log -Level "INFO" -Message "Found pattern: $pattern" + + # Validate the pattern against .NET regex engine + try { + $regex = New-Object System.Text.RegularExpressions.Regex($pattern) + Write-Log -Level "SUCCESS" -Message "Valid regex pattern" + exit 0 + } + catch { + Write-Log -Level "ERROR" -Message "Pattern validation failed: $_" + exit 1 + } +} +catch { + Write-Log -Level "ERROR" -Message "Script execution failed: $_" + exit 1 +} \ No newline at end of file