Browse Source

Skip redundant push builds for branches with an open PR

A branch with an open PR was built twice per push, once by the push
trigger and once by the pull_request trigger, doubling the Actions cost
of every PR iteration. The pull_request run is the canonical one (it
tests the merge with the base branch), so a small gate job now asks the
API whether the pushed branch has an open PR whose base would fire the
pull_request trigger and skips the push build if so. Pushes to master
and release/* are exempt because their runs publish packages; PRs
targeting other branches are ignored because they never trigger a
pull_request build that could replace the push one.

Filtering fork PRs in the on: section instead was considered and
rejected: trigger-level filters cannot see whether an open PR exists,
and skipping the pull_request runs would have lost merge testing.

Assisted-by: Claude:claude-fable-5:Claude Code
pull/3942/head
Siegfried Pammer 2 months ago committed by Siegfried Pammer
parent
commit
d8a68e36e4
  1. 24
      .github/workflows/build-frontends.yml
  2. 26
      .github/workflows/build-ilspy.yml

24
.github/workflows/build-frontends.yml

@ -10,7 +10,31 @@ permissions: @@ -10,7 +10,31 @@ permissions:
contents: read
jobs:
# Skip push builds for branches whose open PR (base master/release/*) already builds
# them via the pull_request trigger. Pushes to master/release/* always build.
gate:
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
run: ${{ steps.check.outputs.run }}
steps:
- id: check
env:
GH_TOKEN: ${{ github.token }}
run: |
prs=0
case "$GITHUB_EVENT_NAME/$GITHUB_REF_NAME" in
push/master|push/release/*) ;;
push/*) prs=$(gh api -X GET "repos/$GITHUB_REPOSITORY/pulls" -f state=open \
-f head="$GITHUB_REPOSITORY_OWNER:$GITHUB_REF_NAME" \
--jq 'map(select(.base.ref == "master" or (.base.ref | startswith("release/")))) | length') ;;
esac
echo "run=$([ "$prs" = 0 ] && echo true || echo false)" >> "$GITHUB_OUTPUT"
build:
needs: gate
if: needs.gate.outputs.run == 'true'
runs-on: ubuntu-latest
steps:

26
.github/workflows/build-ilspy.yml

@ -15,8 +15,32 @@ env: @@ -15,8 +15,32 @@ env:
StagingDirectory: buildartifacts
jobs:
# Skip push builds for branches whose open PR (base master/release/*) already builds
# them via the pull_request trigger. Pushes to master/release/* always build (they publish).
Gate:
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
run: ${{ steps.check.outputs.run }}
steps:
- id: check
env:
GH_TOKEN: ${{ github.token }}
run: |
prs=0
case "$GITHUB_EVENT_NAME/$GITHUB_REF_NAME" in
push/master|push/release/*) ;;
push/*) prs=$(gh api -X GET "repos/$GITHUB_REPOSITORY/pulls" -f state=open \
-f head="$GITHUB_REPOSITORY_OWNER:$GITHUB_REF_NAME" \
--jq 'map(select(.base.ref == "master" or (.base.ref | startswith("release/")))) | length') ;;
esac
echo "run=$([ "$prs" = 0 ] && echo true || echo false)" >> "$GITHUB_OUTPUT"
Build:
name: Desktop (Windows)
needs: Gate
if: needs.Gate.outputs.run == 'true'
permissions:
packages: write # for dotnet nuget push
runs-on: windows-2025-vs2026
@ -283,6 +307,8 @@ jobs: @@ -283,6 +307,8 @@ jobs:
# [Platform("Win")]. ILSpy.Tests.Windows runs only in the Windows job by design.
Desktop:
needs: Gate
if: needs.Gate.outputs.run == 'true'
strategy:
fail-fast: false
matrix:

Loading…
Cancel
Save