From a5bbb767d25b0c6acdf39450447c01c4d567a92a Mon Sep 17 00:00:00 2001 From: John Lambert Date: Wed, 25 Mar 2026 10:31:13 -0400 Subject: [PATCH 1/5] Fix whitespace tooling edge cases --- Build/Agent/check-and-fix-whitespace.ps1 | 11 ++++++++++- Build/Agent/check-whitespace.ps1 | 7 +++++-- Build/Agent/fix-whitespace.ps1 | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Build/Agent/check-and-fix-whitespace.ps1 b/Build/Agent/check-and-fix-whitespace.ps1 index 95edb1d09c..6d75df4c4a 100644 --- a/Build/Agent/check-and-fix-whitespace.ps1 +++ b/Build/Agent/check-and-fix-whitespace.ps1 @@ -1,9 +1,18 @@ #!/usr/bin/env pwsh $ErrorActionPreference = 'Continue' +if (Test-Path -LiteralPath 'check-results.log') { + Remove-Item -LiteralPath 'check-results.log' -Force +} + & "$PSScriptRoot/check-whitespace.ps1" $ec = $LASTEXITCODE -& "$PSScriptRoot/fix-whitespace.ps1" +if ($ec -eq 0 -or (Test-Path -LiteralPath 'check-results.log')) { + & "$PSScriptRoot/fix-whitespace.ps1" +} +else { + Write-Error 'Whitespace checker failed before producing results; skipping fixer.' +} exit $ec diff --git a/Build/Agent/check-whitespace.ps1 b/Build/Agent/check-whitespace.ps1 index dcfd38ea5d..b31f46b1f7 100644 --- a/Build/Agent/check-whitespace.ps1 +++ b/Build/Agent/check-whitespace.ps1 @@ -38,6 +38,9 @@ Write-Host "Base ref: $baseRef ($baseSha)" $log = git log --check --pretty=format:'---% h% s' "$baseSha.." 2>&1 $null = $log | Tee-Object -FilePath check-results.log $log | Out-Host + if (-not (Test-Path -LiteralPath 'check-results.log')) { + New-Item -ItemType File -Path 'check-results.log' -Force | Out-Null + } $problems = New-Object System.Collections.Generic.List[string] $commit = '' @@ -46,7 +49,7 @@ $commitTextmd = '' $repoPath = Get-RepoPath $headRef = (git rev-parse --abbrev-ref HEAD 2>$null) -Get-Content check-results.log | ForEach-Object { + $log | ForEach-Object { $line = $_ switch -regex ($line) { '^---\s' { @@ -83,7 +86,7 @@ Get-Content check-results.log | ForEach-Object { } if ($problems.Count -gt 0) { - Write-Host "`u26A0`uFE0F Please review the output for further information." + Write-Host '[WARN] Please review the output for further information.' Write-Host '### A whitespace issue was found in one or more of the commits.' Write-Host 'This check validates commit history from origin/main..HEAD, not just the current working tree.' Write-Host 'If the report names an older commit, fix the file and then amend, squash, or rebase so that commit no longer appears in the branch history.' diff --git a/Build/Agent/fix-whitespace.ps1 b/Build/Agent/fix-whitespace.ps1 index 324a254a2f..821b62f6fc 100644 --- a/Build/Agent/fix-whitespace.ps1 +++ b/Build/Agent/fix-whitespace.ps1 @@ -78,7 +78,7 @@ if (Test-Path -LiteralPath 'check-results.log') { if (-not $fixFiles -or $fixFiles.Count -eq 0) { $base = Get-BaseRef Write-Host "Fixing whitespace for files changed since $base..HEAD" - $fixFiles = git diff --name-only "$base"..HEAD + $fixFiles = git diff --name-only $base HEAD } $files = $fixFiles | Where-Object { $_ -and (Test-Path $_) } From d57ec0ed42fdc12e533002965c410d16bbb14014 Mon Sep 17 00:00:00 2001 From: John Lambert Date: Wed, 25 Mar 2026 14:42:03 -0400 Subject: [PATCH 2/5] Converge CI linting on PowerShell --- .github/workflows/CommitMessage.yml | 50 +++++++++------- .github/workflows/check-whitespace.yml | 4 +- Build/Agent/check-and-fix-whitespace.ps1 | 12 ++-- Build/Agent/check-and-fix-whitespace.sh | 6 -- Build/Agent/check-whitespace.ps1 | 20 ++++--- Build/Agent/check-whitespace.sh | 72 ------------------------ Build/Agent/commit-messages.ps1 | 32 ++++++++--- Build/Agent/commit-messages.sh | 32 ----------- Build/Agent/fix-whitespace.ps1 | 5 +- Build/Agent/fix-whitespace.sh | 36 ------------ 10 files changed, 78 insertions(+), 191 deletions(-) delete mode 100644 Build/Agent/check-and-fix-whitespace.sh delete mode 100644 Build/Agent/check-whitespace.sh delete mode 100644 Build/Agent/commit-messages.sh delete mode 100644 Build/Agent/fix-whitespace.sh diff --git a/.github/workflows/CommitMessage.yml b/.github/workflows/CommitMessage.yml index 28dced92fa..185c8a9349 100644 --- a/.github/workflows/CommitMessage.yml +++ b/.github/workflows/CommitMessage.yml @@ -12,27 +12,36 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Install dependencies - run: | - pip install --upgrade gitlint - name: Lint git commit messages - shell: bash - # run the linter and tee the output to a file, this will make the check fail but allow us to use the results in summary - run: gitlint --ignore body-is-missing --commits origin/$GITHUB_BASE_REF.. 2>&1 | tee check_results.log - - name: Propegate Error Summary + shell: pwsh + run: ./Build/Agent/commit-messages.ps1 + - name: Propagate Error Summary + id: commit_message_summary if: always() - shell: bash - # put the output of the commit message linting into the summary for the job and in an environment variable + shell: pwsh run: | - # Change the commit part of the log into a markdown link to the commit - commitsUrl="https:\/\/github.com\/${{ github.repository_owner }}\/${{ github.event.repository.name }}\/commit\/" - sed -i "s/Commit \([0-9a-f]\{7,40\}\)/[commit \1]($commitsUrl\1)/g" check_results.log - # Put the results into the job summary - cat check_results.log >> "$GITHUB_STEP_SUMMARY" - # Put the results into a multi-line environment variable to use in the next step - echo "check_results<<###LINT_DELIMITER###" >> "$GITHUB_ENV" - echo "$(cat check_results.log)" >> "$GITHUB_ENV" - echo "###LINT_DELIMITER###" >> "$GITHUB_ENV" + $resultsLogPath = 'check_results.log' + if (Test-Path -LiteralPath $resultsLogPath) { + $content = Get-Content -LiteralPath $resultsLogPath -Raw + $commitUrl = 'https://github.com/${{ github.repository_owner }}/${{ github.event.repository.name }}/commit/' + $content = [regex]::Replace($content, 'Commit ([0-9a-f]{7,40})', { + param($match) + $sha = $match.Groups[1].Value + return "[commit $sha]($commitUrl$sha)" + }) + Set-Content -LiteralPath $resultsLogPath -Value $content -NoNewline + } + else { + $content = 'Commit message checker failed before producing details.' + } + if ($env:GITHUB_STEP_SUMMARY) { + Add-Content -LiteralPath $env:GITHUB_STEP_SUMMARY -Value $content + } + if ($env:GITHUB_OUTPUT) { + Add-Content -LiteralPath $env:GITHUB_OUTPUT -Value 'check_results<<###LINT_DELIMITER###' + Add-Content -LiteralPath $env:GITHUB_OUTPUT -Value $content + Add-Content -LiteralPath $env:GITHUB_OUTPUT -Value '###LINT_DELIMITER###' + } # add a comment on the PR if the commit message linting failed - name: Comment on PR if: failure() @@ -40,8 +49,8 @@ jobs: with: header: Commit Comment message: | - ⚠️ Commit Message Format Issues ⚠️ - ${{ env.check_results }} + [WARN] Commit message format issues + ${{ steps.commit_message_summary.outputs.check_results }} - name: Clear PR Comment if: success() uses: marocchino/sticky-pull-request-comment@v2 @@ -49,4 +58,3 @@ jobs: header: Commit Comment hide: true hide_classify: "RESOLVED" - \ No newline at end of file diff --git a/.github/workflows/check-whitespace.yml b/.github/workflows/check-whitespace.yml index 53700f9f15..54b0f65450 100644 --- a/.github/workflows/check-whitespace.yml +++ b/.github/workflows/check-whitespace.yml @@ -18,5 +18,5 @@ jobs: fetch-depth: 0 - name: Run whitespace check script - shell: bash - run: bash ./Build/Agent/check-whitespace.sh + shell: pwsh + run: ./Build/Agent/check-whitespace.ps1 diff --git a/Build/Agent/check-and-fix-whitespace.ps1 b/Build/Agent/check-and-fix-whitespace.ps1 index 6d75df4c4a..18e6e961a1 100644 --- a/Build/Agent/check-and-fix-whitespace.ps1 +++ b/Build/Agent/check-and-fix-whitespace.ps1 @@ -1,18 +1,22 @@ #!/usr/bin/env pwsh $ErrorActionPreference = 'Continue' -if (Test-Path -LiteralPath 'check-results.log') { - Remove-Item -LiteralPath 'check-results.log' -Force +$resultsLogPath = 'check-results.log' +$checkSucceededCode = 0 +$checkFoundIssuesCode = 2 + +if (Test-Path -LiteralPath $resultsLogPath) { + Remove-Item -LiteralPath $resultsLogPath -Force } & "$PSScriptRoot/check-whitespace.ps1" $ec = $LASTEXITCODE -if ($ec -eq 0 -or (Test-Path -LiteralPath 'check-results.log')) { +if ($ec -eq $checkSucceededCode -or $ec -eq $checkFoundIssuesCode) { & "$PSScriptRoot/fix-whitespace.ps1" } else { - Write-Error 'Whitespace checker failed before producing results; skipping fixer.' + Write-Error 'Whitespace checker failed unexpectedly; skipping fixer.' } exit $ec diff --git a/Build/Agent/check-and-fix-whitespace.sh b/Build/Agent/check-and-fix-whitespace.sh deleted file mode 100644 index 1aa31c88d2..0000000000 --- a/Build/Agent/check-and-fix-whitespace.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -set +e -bash "$(dirname "$0")/check-whitespace.sh" -ec=$? -bash "$(dirname "$0")/fix-whitespace.sh" -exit $ec diff --git a/Build/Agent/check-whitespace.ps1 b/Build/Agent/check-whitespace.ps1 index b31f46b1f7..858e56b63f 100644 --- a/Build/Agent/check-whitespace.ps1 +++ b/Build/Agent/check-whitespace.ps1 @@ -1,8 +1,13 @@ -# Mirrored from .github/workflows/check-whitespace.yml, ported to PowerShell for local use -# Exits non-zero if any whitespace problems are found +# Runs the whitespace check used by CI and local validation. +# Exit codes: +# 0 = checker completed and found no whitespace issues +# 2 = checker completed and found whitespace issues +# 1 = checker could not complete successfully $ErrorActionPreference = 'Stop' +$resultsLogPath = 'check-results.log' + # Import shared git helpers $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path . (Join-Path $ScriptDir 'GitHelpers.ps1') @@ -34,13 +39,10 @@ if (-not $baseSha) { Write-Host "Base ref: $baseRef ($baseSha)" -# Run git log --check and tee output to a file (like CI) +# Run git log --check and tee output to a file for later inspection. $log = git log --check --pretty=format:'---% h% s' "$baseSha.." 2>&1 -$null = $log | Tee-Object -FilePath check-results.log +$null = $log | Tee-Object -FilePath $resultsLogPath $log | Out-Host - if (-not (Test-Path -LiteralPath 'check-results.log')) { - New-Item -ItemType File -Path 'check-results.log' -Force | Out-Null - } $problems = New-Object System.Collections.Generic.List[string] $commit = '' @@ -49,7 +51,7 @@ $commitTextmd = '' $repoPath = Get-RepoPath $headRef = (git rev-parse --abbrev-ref HEAD 2>$null) - $log | ForEach-Object { +$log | ForEach-Object { $line = $_ switch -regex ($line) { '^---\s' { @@ -93,7 +95,7 @@ if ($problems.Count -gt 0) { Write-Host '' Write-Host 'Errors:' $problems | ForEach-Object { Write-Host $_ } - exit 1 + exit 2 } Write-Host 'No problems found' diff --git a/Build/Agent/check-whitespace.sh b/Build/Agent/check-whitespace.sh deleted file mode 100644 index 0c7be3034e..0000000000 --- a/Build/Agent/check-whitespace.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -# shellcheck source=lib_git.sh -source "${SCRIPT_DIR}/lib_git.sh" - -# Determine base commit/ref -BASE_SHA="${1:-}" -if [[ -z "$BASE_SHA" ]]; then - if [[ -n "${GITHUB_EVENT_PULL_REQUEST_BASE_SHA:-}" ]]; then - BASE_SHA="$GITHUB_EVENT_PULL_REQUEST_BASE_SHA" - elif [[ -n "${GITHUB_BASE_REF:-}" ]]; then - BASE_SHA="origin/${GITHUB_BASE_REF}" - else - BASE_SHA="$(git_default_branch_ref)" - fi -fi - -echo "Checking whitespace with git log --check from ${BASE_SHA}..HEAD" -git log --check --pretty=format:"---% h% s" "${BASE_SHA}.." | tee check-results.log - -# Parse results to prepare a summary if running in GitHub Actions -problems=() -commit="" -commitText="" -commitTextmd="" -while IFS='' read -r line || [[ -n "$line" ]]; do - case "$line" in - "--- "*) - # format: --- - read -r _ commit commitText <<<"$line" - if [[ -n "${GITHUB_REPOSITORY:-}" ]]; then - commitTextmd="[${commit}](https://github.com/${GITHUB_REPOSITORY}/commit/${commit}) ${commitText}" - else - commitTextmd="${commit} ${commitText}" - fi - ;; - "") ;; - *:[1-9]*:*) - file="${line%%:*}" - afterFile="${line#*:}" - lineNumber="${afterFile%%:*}" - problems+=("[${commitTextmd}]") - if [[ -n "${GITHUB_REPOSITORY:-}" ]] && [[ -n "${GITHUB_REF_NAME:-}" ]]; then - problems+=("[${line}](https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_REF_NAME}/${file}#L${lineNumber})") - else - problems+=("${line}") - fi - problems+=("") - ;; - esac -done < check-results.log - -if [[ ${#problems[@]} -gt 0 ]]; then - echo "Whitespace issues were found." >&2 - if [[ -n "${GITHUB_STEP_SUMMARY:-}" ]]; then - { - echo "⚠️ Please review the Summary output for further information." - echo "### A whitespace issue was found in one or more of the commits." - echo - echo "Errors:" - for i in "${problems[@]}"; do - echo "$i" - done - } >> "$GITHUB_STEP_SUMMARY" - fi - exit 1 -fi - -echo "No problems found" -exit 0 diff --git a/Build/Agent/commit-messages.ps1 b/Build/Agent/commit-messages.ps1 index d6cf36e74e..1de94f55e6 100644 --- a/Build/Agent/commit-messages.ps1 +++ b/Build/Agent/commit-messages.ps1 @@ -1,14 +1,33 @@ -# Mirrored from .github/workflows/CommitMessage.yml, ported to PowerShell -# Installs gitlint and lints commit messages since PR base (or origin default branch) +# Runs the commit-message lint used by CI and local validation. +# Exits with gitlint's exit code. $ErrorActionPreference = 'Stop' +$resultsLogPath = 'check_results.log' + # Import shared git helpers $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path . (Join-Path $ScriptDir 'GitHelpers.ps1') -# Ensure Python/pip can install gitlint -python -m pip install --upgrade gitlint +function Install-GitLint { + $pythonCommand = $null + foreach ($candidate in @('python', 'python3')) { + if (Get-Command $candidate -ErrorAction SilentlyContinue) { + $pythonCommand = $candidate + break + } + } + + if (-not $pythonCommand) { + throw 'Unable to locate python or python3 to install gitlint.' + } + + & $pythonCommand -m pip install --upgrade gitlint +} + +if (-not (Get-Command gitlint -ErrorAction SilentlyContinue)) { + Install-GitLint +} # Ensure we have up-to-date refs git fetch origin 2>$null | Out-Null @@ -25,11 +44,10 @@ else { $range = 'HEAD~20..HEAD' } -# Run gitlint and tee to check_results.log like CI -# Note: PowerShell uses Tee-Object instead of POSIX tee +# Run gitlint and tee output to a file for CI summaries and local inspection. $cmd = @('gitlint', '--ignore', 'body-is-missing', '--commits', $range) Write-Host "Running: $($cmd -join ' ')" -$proc = & gitlint --ignore body-is-missing --commits $range 2>&1 | Tee-Object -FilePath check_results.log +$proc = & gitlint --ignore body-is-missing --commits $range 2>&1 | Tee-Object -FilePath $resultsLogPath $exit = $LASTEXITCODE $proc | Out-Host exit $exit diff --git a/Build/Agent/commit-messages.sh b/Build/Agent/commit-messages.sh deleted file mode 100644 index 1d1ba309c1..0000000000 --- a/Build/Agent/commit-messages.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -# shellcheck source=lib_git.sh -source "${SCRIPT_DIR}/lib_git.sh" - -# Determine base ref for commit range -BASE_REF="" -if [[ -n "${GITHUB_BASE_REF:-}" ]]; then - BASE_REF="origin/${GITHUB_BASE_REF}" -else - BASE_REF="$(git_default_branch_ref)" -fi - -# Ensure gitlint is available -if ! command -v gitlint >/dev/null 2>&1; then - if command -v python3 >/dev/null 2>&1; then - python3 -m pip install --upgrade gitlint - else - pip install --upgrade gitlint - fi -fi - -echo "Running gitlint against range: ${BASE_REF}..HEAD" -# Run gitlint and tee output to check_results.log (used by CI summary/comment) -set +e -gitlint --ignore body-is-missing --commits "${BASE_REF}.." 2>&1 | tee check_results.log -exit_code=${PIPESTATUS[0]} -set -e - -exit ${exit_code} diff --git a/Build/Agent/fix-whitespace.ps1 b/Build/Agent/fix-whitespace.ps1 index 821b62f6fc..13605f882c 100644 --- a/Build/Agent/fix-whitespace.ps1 +++ b/Build/Agent/fix-whitespace.ps1 @@ -77,8 +77,9 @@ if (Test-Path -LiteralPath 'check-results.log') { } if (-not $fixFiles -or $fixFiles.Count -eq 0) { $base = Get-BaseRef - Write-Host "Fixing whitespace for files changed since $base..HEAD" - $fixFiles = git diff --name-only $base HEAD + Write-Host "Fixing whitespace for files changed on the current branch since it diverged from $base" + Write-Host "This compares merge-base($base, HEAD) to HEAD, so only branch-introduced file changes are considered." + $fixFiles = git diff --name-only "$base...HEAD" } $files = $fixFiles | Where-Object { $_ -and (Test-Path $_) } diff --git a/Build/Agent/fix-whitespace.sh b/Build/Agent/fix-whitespace.sh deleted file mode 100644 index 2b5c2c5259..0000000000 --- a/Build/Agent/fix-whitespace.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -# shellcheck source=lib_git.sh -source "${SCRIPT_DIR}/lib_git.sh" - -# Determine base ref -if [[ -n "${GITHUB_BASE_REF:-}" ]]; then - base="origin/${GITHUB_BASE_REF}" -else - base="$(git_default_branch_ref)" -fi - -files=() -if [[ -f "check-results.log" ]]; then - # Extract unique file paths from check results - mapfile -t files < <(awk -F':' '/^[^:]+:[1-9][0-9]*:/ {print $1}' check-results.log | awk '!seen[$0]++') - [[ ${#files[@]} -gt 0 ]] && echo "Fixing whitespace for files listed in check-results.log" -fi - -if [[ ${#files[@]} -eq 0 ]]; then - echo "Fixing whitespace for files changed since ${base}..HEAD" - mapfile -t files < <(git diff --name-only "$base"..HEAD) -fi - -for f in "${files[@]}"; do - [[ -f "$f" ]] || continue - # Strip trailing spaces/tabs on each line and ensure exactly one trailing newline - # Using perl for robust in-place editing across platforms - perl -0777 -pe 's/[ \t]+$//mg; s/\s*\z/\n/s' -i "$f" || true - echo "Fixed whitespace: $f" -done - -echo "Whitespace fix completed. Review changes, commit, and rebase as needed." -exit 0 From dd8906ee94e5f67f16ad0e1183e73613a044dad5 Mon Sep 17 00:00:00 2001 From: John Lambert Date: Thu, 26 Mar 2026 13:49:55 -0400 Subject: [PATCH 3/5] Align CI check result contracts --- .github/workflows/CommitMessage.yml | 12 ++++++++++-- Build/Agent/check-whitespace.ps1 | 8 +++++++- Build/Agent/commit-messages.ps1 | 8 +++++++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CommitMessage.yml b/.github/workflows/CommitMessage.yml index 185c8a9349..a26c530e4b 100644 --- a/.github/workflows/CommitMessage.yml +++ b/.github/workflows/CommitMessage.yml @@ -13,6 +13,7 @@ jobs: with: fetch-depth: 0 - name: Lint git commit messages + id: lint_commit_messages shell: pwsh run: ./Build/Agent/commit-messages.ps1 - name: Propagate Error Summary @@ -31,9 +32,15 @@ jobs: }) Set-Content -LiteralPath $resultsLogPath -Value $content -NoNewline } + elseif ('${{ steps.lint_commit_messages.outcome }}' -eq 'success') { + $content = 'No problems found.' + } else { $content = 'Commit message checker failed before producing details.' } + if ([string]::IsNullOrWhiteSpace($content) -and '${{ steps.lint_commit_messages.outcome }}' -eq 'success') { + $content = 'No problems found.' + } if ($env:GITHUB_STEP_SUMMARY) { Add-Content -LiteralPath $env:GITHUB_STEP_SUMMARY -Value $content } @@ -44,7 +51,7 @@ jobs: } # add a comment on the PR if the commit message linting failed - name: Comment on PR - if: failure() + if: steps.lint_commit_messages.outcome == 'failure' uses: marocchino/sticky-pull-request-comment@v2 with: header: Commit Comment @@ -52,9 +59,10 @@ jobs: [WARN] Commit message format issues ${{ steps.commit_message_summary.outputs.check_results }} - name: Clear PR Comment - if: success() + if: steps.lint_commit_messages.outcome == 'success' uses: marocchino/sticky-pull-request-comment@v2 with: header: Commit Comment + only_update: true hide: true hide_classify: "RESOLVED" diff --git a/Build/Agent/check-whitespace.ps1 b/Build/Agent/check-whitespace.ps1 index 858e56b63f..b0eb70f883 100644 --- a/Build/Agent/check-whitespace.ps1 +++ b/Build/Agent/check-whitespace.ps1 @@ -8,6 +8,12 @@ $ErrorActionPreference = 'Stop' $resultsLogPath = 'check-results.log' +if (Test-Path -LiteralPath $resultsLogPath) { + Remove-Item -LiteralPath $resultsLogPath -Force +} + +New-Item -ItemType File -Path $resultsLogPath -Force | Out-Null + # Import shared git helpers $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path . (Join-Path $ScriptDir 'GitHelpers.ps1') @@ -41,7 +47,7 @@ Write-Host "Base ref: $baseRef ($baseSha)" # Run git log --check and tee output to a file for later inspection. $log = git log --check --pretty=format:'---% h% s' "$baseSha.." 2>&1 -$null = $log | Tee-Object -FilePath $resultsLogPath +$null = $log | Tee-Object -FilePath $resultsLogPath -Append $log | Out-Host $problems = New-Object System.Collections.Generic.List[string] diff --git a/Build/Agent/commit-messages.ps1 b/Build/Agent/commit-messages.ps1 index 1de94f55e6..335a0a14d4 100644 --- a/Build/Agent/commit-messages.ps1 +++ b/Build/Agent/commit-messages.ps1 @@ -5,6 +5,12 @@ $ErrorActionPreference = 'Stop' $resultsLogPath = 'check_results.log' +if (Test-Path -LiteralPath $resultsLogPath) { + Remove-Item -LiteralPath $resultsLogPath -Force +} + +New-Item -ItemType File -Path $resultsLogPath -Force | Out-Null + # Import shared git helpers $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path . (Join-Path $ScriptDir 'GitHelpers.ps1') @@ -47,7 +53,7 @@ else { # Run gitlint and tee output to a file for CI summaries and local inspection. $cmd = @('gitlint', '--ignore', 'body-is-missing', '--commits', $range) Write-Host "Running: $($cmd -join ' ')" -$proc = & gitlint --ignore body-is-missing --commits $range 2>&1 | Tee-Object -FilePath $resultsLogPath +$proc = & gitlint --ignore body-is-missing --commits $range 2>&1 | Tee-Object -FilePath $resultsLogPath -Append $exit = $LASTEXITCODE $proc | Out-Host exit $exit From e95d498df6b1d7db0b531608ed74a316e77262a2 Mon Sep 17 00:00:00 2001 From: John Lambert Date: Thu, 26 Mar 2026 13:54:49 -0400 Subject: [PATCH 4/5] Handle empty commit check summary --- .github/workflows/CommitMessage.yml | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/.github/workflows/CommitMessage.yml b/.github/workflows/CommitMessage.yml index a26c530e4b..b988ab68b1 100644 --- a/.github/workflows/CommitMessage.yml +++ b/.github/workflows/CommitMessage.yml @@ -22,23 +22,34 @@ jobs: shell: pwsh run: | $resultsLogPath = 'check_results.log' + $lintSucceeded = '${{ steps.lint_commit_messages.outcome }}' -eq 'success' if (Test-Path -LiteralPath $resultsLogPath) { $content = Get-Content -LiteralPath $resultsLogPath -Raw - $commitUrl = 'https://github.com/${{ github.repository_owner }}/${{ github.event.repository.name }}/commit/' - $content = [regex]::Replace($content, 'Commit ([0-9a-f]{7,40})', { - param($match) - $sha = $match.Groups[1].Value - return "[commit $sha]($commitUrl$sha)" - }) - Set-Content -LiteralPath $resultsLogPath -Value $content -NoNewline + if ([string]::IsNullOrWhiteSpace($content)) { + if ($lintSucceeded) { + $content = 'No problems found.' + } + else { + $content = 'Commit message checker failed before producing details.' + } + } + else { + $commitUrl = 'https://github.com/${{ github.repository_owner }}/${{ github.event.repository.name }}/commit/' + $content = [regex]::Replace($content, 'Commit ([0-9a-f]{7,40})', { + param($match) + $sha = $match.Groups[1].Value + return "[commit $sha]($commitUrl$sha)" + }) + Set-Content -LiteralPath $resultsLogPath -Value $content -NoNewline + } } - elseif ('${{ steps.lint_commit_messages.outcome }}' -eq 'success') { + elseif ($lintSucceeded) { $content = 'No problems found.' } else { $content = 'Commit message checker failed before producing details.' } - if ([string]::IsNullOrWhiteSpace($content) -and '${{ steps.lint_commit_messages.outcome }}' -eq 'success') { + if ([string]::IsNullOrWhiteSpace($content) -and $lintSucceeded) { $content = 'No problems found.' } if ($env:GITHUB_STEP_SUMMARY) { From 256d564731af811568807d9aae657def3a11656c Mon Sep 17 00:00:00 2001 From: John Lambert Date: Thu, 26 Mar 2026 14:08:06 -0400 Subject: [PATCH 5/5] Move commit summary logic into helper --- .github/workflows/CommitMessage.yml | 45 ++---------- .../Agent/publish-commit-message-summary.ps1 | 69 +++++++++++++++++++ 2 files changed, 74 insertions(+), 40 deletions(-) create mode 100644 Build/Agent/publish-commit-message-summary.ps1 diff --git a/.github/workflows/CommitMessage.yml b/.github/workflows/CommitMessage.yml index b988ab68b1..64385eb20f 100644 --- a/.github/workflows/CommitMessage.yml +++ b/.github/workflows/CommitMessage.yml @@ -20,46 +20,11 @@ jobs: id: commit_message_summary if: always() shell: pwsh - run: | - $resultsLogPath = 'check_results.log' - $lintSucceeded = '${{ steps.lint_commit_messages.outcome }}' -eq 'success' - if (Test-Path -LiteralPath $resultsLogPath) { - $content = Get-Content -LiteralPath $resultsLogPath -Raw - if ([string]::IsNullOrWhiteSpace($content)) { - if ($lintSucceeded) { - $content = 'No problems found.' - } - else { - $content = 'Commit message checker failed before producing details.' - } - } - else { - $commitUrl = 'https://github.com/${{ github.repository_owner }}/${{ github.event.repository.name }}/commit/' - $content = [regex]::Replace($content, 'Commit ([0-9a-f]{7,40})', { - param($match) - $sha = $match.Groups[1].Value - return "[commit $sha]($commitUrl$sha)" - }) - Set-Content -LiteralPath $resultsLogPath -Value $content -NoNewline - } - } - elseif ($lintSucceeded) { - $content = 'No problems found.' - } - else { - $content = 'Commit message checker failed before producing details.' - } - if ([string]::IsNullOrWhiteSpace($content) -and $lintSucceeded) { - $content = 'No problems found.' - } - if ($env:GITHUB_STEP_SUMMARY) { - Add-Content -LiteralPath $env:GITHUB_STEP_SUMMARY -Value $content - } - if ($env:GITHUB_OUTPUT) { - Add-Content -LiteralPath $env:GITHUB_OUTPUT -Value 'check_results<<###LINT_DELIMITER###' - Add-Content -LiteralPath $env:GITHUB_OUTPUT -Value $content - Add-Content -LiteralPath $env:GITHUB_OUTPUT -Value '###LINT_DELIMITER###' - } + run: > + ./Build/Agent/publish-commit-message-summary.ps1 + -LintOutcome '${{ steps.lint_commit_messages.outcome }}' + -RepositoryOwner '${{ github.repository_owner }}' + -RepositoryName '${{ github.event.repository.name }}' # add a comment on the PR if the commit message linting failed - name: Comment on PR if: steps.lint_commit_messages.outcome == 'failure' diff --git a/Build/Agent/publish-commit-message-summary.ps1 b/Build/Agent/publish-commit-message-summary.ps1 new file mode 100644 index 0000000000..a3b10a0058 --- /dev/null +++ b/Build/Agent/publish-commit-message-summary.ps1 @@ -0,0 +1,69 @@ +#!/usr/bin/env pwsh +# Formats commit-message lint results for GitHub Actions summary/output usage. + +param( + [Parameter(Mandatory = $true)] + [string]$LintOutcome, + + [string]$ResultsLogPath = 'check_results.log', + + [string]$RepositoryOwner = '', + + [string]$RepositoryName = '' +) + +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version Latest + +function Get-CommitMessageSummaryContent { + param( + [Parameter(Mandatory = $true)] + [string]$Outcome, + + [Parameter(Mandatory = $true)] + [string]$LogPath, + + [string]$Owner, + + [string]$RepoName + ) + + $content = $null + $lintSucceeded = $Outcome -eq 'success' + + if (Test-Path -LiteralPath $LogPath) { + $content = Get-Content -LiteralPath $LogPath -Raw + } + + if ([string]::IsNullOrWhiteSpace($content)) { + if ($lintSucceeded) { + return 'No problems found.' + } + + return 'Commit message checker failed before producing details.' + } + + if (-not [string]::IsNullOrWhiteSpace($Owner) -and -not [string]::IsNullOrWhiteSpace($RepoName)) { + $commitUrl = "https://github.com/$Owner/$RepoName/commit/" + $content = [regex]::Replace($content, 'Commit ([0-9a-f]{7,40})', { + param($match) + $sha = $match.Groups[1].Value + return "[commit $sha]($commitUrl$sha)" + }) + } + + Set-Content -LiteralPath $LogPath -Value $content -NoNewline + return $content +} + +$summaryContent = Get-CommitMessageSummaryContent -Outcome $LintOutcome -LogPath $ResultsLogPath -Owner $RepositoryOwner -RepoName $RepositoryName + +if ($env:GITHUB_STEP_SUMMARY) { + Add-Content -LiteralPath $env:GITHUB_STEP_SUMMARY -Value $summaryContent +} + +if ($env:GITHUB_OUTPUT) { + Add-Content -LiteralPath $env:GITHUB_OUTPUT -Value 'check_results<<###LINT_DELIMITER###' + Add-Content -LiteralPath $env:GITHUB_OUTPUT -Value $summaryContent + Add-Content -LiteralPath $env:GITHUB_OUTPUT -Value '###LINT_DELIMITER###' +} \ No newline at end of file