From 2c5fdfb30ef7694da916ea8d9fc2eb016c8fa4ca Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Fri, 13 Feb 2026 15:24:41 -0800 Subject: [PATCH] [release/v7.5] Fix merge conflict checker for empty file lists and filter *.cs files (#26813) --- .../merge-conflict-checker/README.md | 2 + .../merge-conflict-checker/action.yml | 3 +- test/infrastructure/ciModule.Tests.ps1 | 14 ++-- tools/ci.psm1 | 72 ++++++++++++++++--- 4 files changed, 77 insertions(+), 14 deletions(-) diff --git a/.github/actions/infrastructure/merge-conflict-checker/README.md b/.github/actions/infrastructure/merge-conflict-checker/README.md index aeae4a29b9..b53d6f9996 100644 --- a/.github/actions/infrastructure/merge-conflict-checker/README.md +++ b/.github/actions/infrastructure/merge-conflict-checker/README.md @@ -56,8 +56,10 @@ jobs: - **File Handling**: - Checks only files that were added, modified, or renamed - Skips deleted files + - **Filters out `*.cs` files** (C# files are excluded from merge conflict checking) - Skips binary/unreadable files - Skips directories +- **Empty File List**: Gracefully handles cases where no files need checking (e.g., PRs that only delete files) ## Example Output diff --git a/.github/actions/infrastructure/merge-conflict-checker/action.yml b/.github/actions/infrastructure/merge-conflict-checker/action.yml index a86cfa5470..41c7d2ad94 100644 --- a/.github/actions/infrastructure/merge-conflict-checker/action.yml +++ b/.github/actions/infrastructure/merge-conflict-checker/action.yml @@ -25,7 +25,8 @@ runs: run: | # Get changed files from environment variable (secure against injection) $changedFilesJson = $env:CHANGED_FILES_JSON - $changedFiles = $changedFilesJson | ConvertFrom-Json + # Ensure we always have an array (ConvertFrom-Json returns null for empty JSON arrays) + $changedFiles = @($changedFilesJson | ConvertFrom-Json) # Import ci.psm1 and run the check Import-Module "$env:GITHUB_WORKSPACE/tools/ci.psm1" -Force diff --git a/test/infrastructure/ciModule.Tests.ps1 b/test/infrastructure/ciModule.Tests.ps1 index f88d5787fc..b7320ff49b 100644 --- a/test/infrastructure/ciModule.Tests.ps1 +++ b/test/infrastructure/ciModule.Tests.ps1 @@ -30,11 +30,17 @@ Describe "Test-MergeConflictMarker" { } Context "When no files are provided" { - It "Should handle empty file array" { - # The function parameter has Mandatory validation which rejects empty arrays by design - # This test verifies that behavior + It "Should handle empty file array gracefully" { + # The function now accepts empty arrays to handle cases like delete-only PRs $emptyArray = @() - { Test-MergeConflictMarker -File $emptyArray -WorkspacePath $script:testWorkspace -OutputPath $script:testOutputPath -SummaryPath $script:testSummaryPath } | Should -Throw -ExpectedMessage "*empty array*" + Test-MergeConflictMarker -File $emptyArray -WorkspacePath $script:testWorkspace -OutputPath $script:testOutputPath -SummaryPath $script:testSummaryPath + + $outputs = Get-Content $script:testOutputPath + $outputs | Should -Contain "files-checked=0" + $outputs | Should -Contain "conflicts-found=0" + + $summary = Get-Content $script:testSummaryPath -Raw + $summary | Should -Match "No Files to Check" } } diff --git a/tools/ci.psm1 b/tools/ci.psm1 index bcc816cc91..07839996d2 100644 --- a/tools/ci.psm1 +++ b/tools/ci.psm1 @@ -932,12 +932,12 @@ function New-LinuxPackage } else { "${env:BUILD_ARTIFACTSTAGINGDIRECTORY}" } - + # Ensure artifacts directory exists if (-not (Test-Path $artifactsDir)) { New-Item -ItemType Directory -Path $artifactsDir -Force | Out-Null } - + Write-Log -message "Artifacts directory: $artifactsDir" Copy-Item $packageObj.FullName -Destination $artifactsDir -Force } @@ -950,7 +950,7 @@ function New-LinuxPackage } else { "${env:BUILD_ARTIFACTSTAGINGDIRECTORY}" } - + # Create and package Raspbian .tgz # Build must be clean for Raspbian Start-PSBuild -PSModuleRestore -Clean -Runtime linux-arm -Configuration 'Release' @@ -1039,8 +1039,9 @@ Function Test-MergeConflictMarker #> [CmdletBinding()] param( - [Parameter(Mandatory)] - [string[]] $File, + [Parameter()] + [AllowEmptyCollection()] + [string[]] $File = @(), [Parameter()] [string] $WorkspacePath = $PWD, @@ -1054,10 +1055,63 @@ Function Test-MergeConflictMarker Write-Host "Starting merge conflict marker check..." -ForegroundColor Cyan - Write-Host "Checking $($File.Count) changed files for merge conflict markers" -ForegroundColor Cyan + # Helper function to write outputs when no files to check + function Write-NoFilesOutput { + param( + [string]$Message, + [string]$OutputPath, + [string]$SummaryPath + ) + + # Output results to GitHub Actions + if ($OutputPath) { + "files-checked=0" | Out-File -FilePath $OutputPath -Append -Encoding utf8 + "conflicts-found=0" | Out-File -FilePath $OutputPath -Append -Encoding utf8 + } + + # Create GitHub Actions job summary + if ($SummaryPath) { + $summaryContent = @" +# Merge Conflict Marker Check Results + +## Summary +- **Files Checked:** 0 +- **Files with Conflicts:** 0 + +## ℹ️ No Files to Check + +$Message + +"@ + $summaryContent | Out-File -FilePath $SummaryPath -Encoding utf8 + } + } + + # Handle empty file list (e.g., when PR only deletes files) + if ($File.Count -eq 0) { + Write-Host "No files to check (empty file list)" -ForegroundColor Yellow + Write-NoFilesOutput -Message "No files were provided for checking (this can happen when a PR only deletes files)." -OutputPath $OutputPath -SummaryPath $SummaryPath + return + } + + # Filter out *.cs files from merge conflict checking + $filesToCheck = @($File | Where-Object { $_ -notlike "*.cs" }) + $filteredCount = $File.Count - $filesToCheck.Count + + if ($filteredCount -gt 0) { + Write-Host "Filtered out $filteredCount *.cs file(s) from merge conflict checking" -ForegroundColor Yellow + } + + if ($filesToCheck.Count -eq 0) { + Write-Host "No files to check after filtering (all files were *.cs)" -ForegroundColor Yellow + Write-NoFilesOutput -Message "All $filteredCount file(s) were filtered out (*.cs files are excluded from merge conflict checking)." -OutputPath $OutputPath -SummaryPath $SummaryPath + return + } + + Write-Host "Checking $($filesToCheck.Count) changed files for merge conflict markers" -ForegroundColor Cyan # Convert relative paths to absolute paths for processing - $absolutePaths = $File | ForEach-Object { + $absolutePaths = $filesToCheck | ForEach-Object { if ([System.IO.Path]::IsPathRooted($_)) { $_ } else { @@ -1081,14 +1135,14 @@ Function Test-MergeConflictMarker } $filesChecked++ - + # Get relative path for display $relativePath = if ($WorkspacePath -and $filePath.StartsWith($WorkspacePath)) { $filePath.Substring($WorkspacePath.Length).TrimStart([System.IO.Path]::DirectorySeparatorChar, [System.IO.Path]::AltDirectorySeparatorChar) } else { $filePath } - + Write-Host " Checking: $relativePath" -ForegroundColor Gray # Search for conflict markers using Select-String