Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GitHub Action to automatically create cherrypick PRs #10361

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions .github/workflows/cherrypick.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Create Cherrypick PR

on:
pull_request:
types:
- closed
branches:
# TODO: Extract this to an env variable?
- 'master'

env:
# TODO: Add a way to handle multiple potential cherrypick targets.
TARGET_BRANCH: '4.3'
USERNAME: 'Godot Organization'
EMAIL: '[email protected]'

jobs:
Create-cherrypick-PR:
# The cherrypick label is hardcoded because `contains()` doesn't seem to be able to use an environment variable as a second argument.
if: ${{ github.event.pull_request.merged == true && contains( github.event.pull_request.labels.*.name, 'cherrypick:4.3' ) }}
runs-on: ubuntu-latest
env:
# "Ternary" hack featured in the official docs.
# When using "Squash and merge", the commit hash is the last merge commit of the pull request merge branch.
# When using "Merge", the commit hash is the last commit to the head branch of the pull request.
# This is mildly error-prone, since in theory we could merge multiple commits without squashing.
# We are relying on human review of the generated PRs to catch that.
COMMIT_HASH: ${{ github.event.pull_request.commits > 1 && github.sha || github.event.pull_request.head.sha }}
PR_NUMBER: ${{ github.event.number }}

steps:

- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ env.TARGET_BRANCH }}

- name: Cherrypick Commit
id: cherrypick_commit
continue-on-error: true
# TODO: Maybe only fetch some branches?
run: |
git config user.name "${{ env.USERNAME }}"
git config user.email "${{ env.EMAIL }}"
git fetch
git cherry-pick -m 1 ${{ env.COMMIT_HASH }}

- name: Create Pull Request
if: steps.cherrypick_commit.outcome == 'success'
uses: peter-evans/create-pull-request@v7
with:
commit-message: 'Cherrypick to ${{ env.TARGET_BRANCH }}'
branch: 'cherrypick-${{ env.PR_NUMBER }}-${{ env.TARGET_BRANCH }}'
delete-branch: true

# Configure the commit author.
author: '${{ env.USERNAME }} <${{ env.EMAIL }}>'
committer: '${{ env.USERNAME }} <${{ env.EMAIL }}>'

# Configure the pull request.
title: 'Cherrypick ${{ env.PR_NUMBER }} to ${{ env.TARGET_BRANCH }}'
body: 'Cherrypick #${{ env.PR_NUMBER }} to ${{ env.TARGET_BRANCH }}.'
# TODO: Only add the bug or enhancement label, depending on which the original PR uses.
labels: 'bug,enhancement'

- name: Handle failure
if: steps.cherrypick_commit.outcome == 'failure'
run: |
echo "Can't automatically cherrypick. Potential causes:"
echo "- PR has multiple commits. Did you squash and merge?"
echo "- Cherrypick did not apply cleanly and can't be auto-merged."