diff --git a/.github/workflows/mergify-ready.yml b/.github/workflows/mergify-ready.yml index 604fb7f9dd2..86439df95f4 100644 --- a/.github/workflows/mergify-ready.yml +++ b/.github/workflows/mergify-ready.yml @@ -77,14 +77,43 @@ jobs: fixup_commits= for commit in $(git rev-list $BASE_SHA..$HEAD_SHA); do - case $(git show --pretty=format:%s -s $commit) in fixup\!*|squash\!*) + case $(git show --pretty=format:%s -s $commit) in fixup\!*|squash\!*|amend\!*) fixup_commits="$fixup_commits\n$commit" ;; esac done if [ -n "$fixup_commits" ]; then - echo "Error: fixup/squash commits found in $BASE_LABEL..$HEAD_LABEL" + echo "Error: fixup/squash/amend commits found in $BASE_LABEL..$HEAD_LABEL" echo -e "$fixup_commits" exit 1 fi + + no-fixup-commits: + runs-on: ubuntu-latest + if: >- + github.event_name == 'pull_request' && + github.event.pull_request.draft == false && + github.event.pull_request.base.ref == 'master' && + contains(github.event.pull_request.labels.*.name, 'automerge:rebase') && + !contains(github.event.pull_request.labels.*.name, 'bypass:linear-history') + + env: + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check for fixup commits + id: fixup-commits + run: | + if [[ $(git rev-list "$BASE_SHA".."$HEAD_SHA" --grep="^\(fixup\|amend\|squash\)! " | wc -l) -eq 0 ]]; then + echo "No fixup/amend/squash commits found in commit history" + else + echo "fixup/amend/squash commits found in commit history" + exit 1 + fi diff --git a/.mergify.yml b/.mergify.yml index 59ae3bb3cc5..3aa2ba8b403 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -21,6 +21,12 @@ queue_rules: - label=proto:expect-breakage merge_conditions: - base=master + # Rebase PRs with fixup commits are allowed to enter the merge queue but + # should not be allowed to merge if there are leftover fixup commits after rebase + - or: + - label=bypass:linear-history + - check-success=no-fixup-commits + - check-skipped=no-fixup-commits # Require integration tests before merging only - or: - label=bypass:integration @@ -45,6 +51,12 @@ queue_rules: - label=proto:expect-breakage merge_conditions: - base=master + # Rebase PRs with fixup commits are allowed to enter the merge queue but + # should not be allowed to merge if there are leftover fixup commits after rebase + - or: + - label=bypass:linear-history + - check-success=no-fixup-commits + - check-skipped=no-fixup-commits # Require integration tests before merging only - or: - label=bypass:integration @@ -65,6 +77,9 @@ pull_request_rules: conditions: - base=master - label=automerge:rebase + - or: + - '#commits-behind>0' + - linear-history actions: queue: merge_method: merge @@ -76,3 +91,15 @@ pull_request_rules: actions: queue: merge_method: squash + - name: rebase and autosquash + conditions: + - base=master + - label=automerge:rebase + - '#commits-behind=0' + - or: + - -linear-history + - check-failure=no-fixup-commits + - -draft + actions: + rebase: + autosquash: true