From 54685a55a175016424737cc22d055bff049a1582 Mon Sep 17 00:00:00 2001 From: Ryan Hughes Date: Fri, 18 Sep 2026 12:55:18 -0400 Subject: [PATCH] PR check fails when the PR changes no files relative to its base A PR whose diff against its base is empty has already landed some other way, typically a sync PR carrying the same bump or a merge from master that swallowed it. Merging it records a change that isn't one and could mask a real mistake. result now fails with a message saying to close it. --- .github/workflows/build-pr.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 59d12bf..c80927a 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -36,6 +36,7 @@ jobs: matrix: ${{ steps.list.outputs.matrix }} count: ${{ steps.gate.outputs.count }} trusted: ${{ steps.gate.outputs.trusted }} + empty: ${{ steps.list.outputs.empty }} steps: # Same rule as the build job: bin/build-matrix comes from base, the # package directories from the PR head. @@ -78,6 +79,17 @@ jobs: echo "matrix=$matrix" >> "$GITHUB_OUTPUT" echo "planned=$(jq '.include | length' <<<"$matrix")" >> "$GITHUB_OUTPUT" jq -r '.include[] | "\(.package) \(.arch) -> \(.channels)"' <<<"$matrix" + # A PR whose diff against its base is empty changes nothing: its + # content already landed some other way (a sync PR beat it, or a + # merge from master swallowed it). Merging it would record a change + # that isn't one. Flag it so `result` fails rather than passes. + if [[ "${{ github.event_name }}" == pull_request ]]; then + total=$(git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}" | wc -l) + echo "empty=$([[ $total -eq 0 ]] && echo true || echo false)" >> "$GITHUB_OUTPUT" + echo "files changed vs base: $total" + else + echo "empty=false" >> "$GITHUB_OUTPUT" + fi - id: gate env: STATUS: ${{ steps.vouch.outputs.status || 'dispatch' }} @@ -170,4 +182,10 @@ jobs: echo "::error::Builds were not run: author is not vouched. Add to .github/VOUCHED.td or apply the 'build-approved' label." exit 1 fi + # Nothing to merge: the PR's diff against its base is empty. Its + # change already landed elsewhere. Close it rather than merge it. + if [[ "${{ needs.changes.outputs.empty }}" == "true" ]]; then + echo "::error::This PR changes no files relative to its base. Its content is already on the target branch; close it instead of merging." + exit 1 + fi [[ "${{ needs.build.result }}" == "success" || "${{ needs.build.result }}" == "skipped" ]]