From a404ba683b6cfad9eaa8e429e18908df6e9961d5 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Tue, 6 Oct 2026 10:52:35 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=B7(ci)=20rebase=20a=20pull=20request?= =?UTF-8?q?=20from=20a=20checkbox=20of=20its=20description?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Contributors often have to rebase their branch on main by hand, even when nothing conflicts. Add a "Rebase" checkbox to the pull request template: ticking it triggers a workflow that rebases the branch on its base branch through the update-branch API. The workflow unticks the box first so the edit cannot trigger it again, then comments the outcome. When the branch conflicts with its base, it says the rebase is not possible and has to be done manually. It uses pull_request_target so it works on pull requests from forks, which is safe because the pull request code is never checked out or run. --- .github/PULL_REQUEST_TEMPLATE.md | 4 ++ .github/workflows/rebase-pull-request.yml | 53 +++++++++++++++++++++++ CHANGELOG.md | 1 + 3 files changed, 58 insertions(+) create mode 100644 .github/workflows/rebase-pull-request.yml diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index ef109e6d8..d59170b88 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -7,6 +7,10 @@ Describe the purpose of this pull request. * [ ] item 1... * [ ] item 2... +## Rebase + +* [ ] Rebase this pull request on its base branch (tick to rebase automatically, only possible without conflict) + ## External contributions Thank you for your contribution! 🎉 diff --git a/.github/workflows/rebase-pull-request.yml b/.github/workflows/rebase-pull-request.yml new file mode 100644 index 000000000..acabdff0b --- /dev/null +++ b/.github/workflows/rebase-pull-request.yml @@ -0,0 +1,53 @@ +name: Rebase Pull Request + +# Ticking the "Rebase" checkbox of the pull request description rebases the +# branch on its base branch, only if it applies without conflict. +# +# `pull_request_target` gives a token able to write on pull requests coming +# from forks. It is safe here because the pull request code is never checked +# out nor run, and the description is only read through the environment. +on: + pull_request_target: + types: [edited] + +permissions: + pull-requests: write + +# One run per pull request, never cancelled: a rebase must not be interrupted. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} + cancel-in-progress: false + +jobs: + rebase: + runs-on: ubuntu-latest + if: contains(github.event.pull_request.body, '[x] Rebase this pull request') + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + PR_NUMBER: ${{ github.event.pull_request.number }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + steps: + - name: Untick the checkbox + # First, so that the edit of the description cannot run this again. + run: | + gh api "repos/$GH_REPO/pulls/$PR_NUMBER" --jq .body > body.md + sed -i -E 's/\[[xX]\] (Rebase this pull request)/[ ] \1/' body.md + gh api -X PATCH "repos/$GH_REPO/pulls/$PR_NUMBER" -F body=@body.md > /dev/null + + - name: Rebase on the base branch + run: | + # Only rebases if HEAD_SHA is still the head of the branch. + if gh api -X PUT "repos/$GH_REPO/pulls/$PR_NUMBER/update-branch" \ + -f update_method=rebase -f expected_head_sha="$HEAD_SHA" \ + > result.txt 2>&1; then + message=":white_check_mark: The branch has been rebased on its base branch. Its commits were rewritten, so \`git pull --rebase\` before pushing again, and note that the signatures of the rebased commits are lost." + elif grep -qi "conflict" result.txt; then + message=":x: The rebase is not possible because of conflicts with the base branch. It has to be done manually." + elif grep -qi "no new commits" result.txt; then + message=":information_source: The branch is already up to date with its base branch." + else + message=":warning: The automatic rebase failed (for a pull request from a fork, the option \"Allow edits by maintainers\" must be enabled). It has to be done manually." + cat result.txt + fi + gh pr comment "$PR_NUMBER" --body "$message" diff --git a/CHANGELOG.md b/CHANGELOG.md index e6b5005e9..1d6d4233e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to - 👷(ci) lint, typecheck, build and test the collaboration server (yhub) - 👷(ci) check the load-test tooling: swarm, canary, k6 and dashboards - 👷(ci) cancel the superseded runs of a pull request +- 👷(ci) rebase a pull request from a checkbox of its description - ✨(backend) add mention endpoint with cooldown-limited email notification #2447 - 🚩(setting) add feature flag on Duplicate with Children #2721