Skip to content

feat: add automated backport workflow #14738

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ayagmar
Copy link

@ayagmar ayagmar commented May 31, 2025

Add GitHub Actions workflow for automatic PR backporting with intelligent branch detection, conflict handling, and comprehensive error reporting. Supports multiple branch naming patterns and provides detailed feedback via comments.

Fixes : #14496

🔧 Requirements

Enable "Allow GitHub Actions to create and approve pull requests" in repository settings is enabled

🚀 Usage

  1. Add backport labels to your PR (e.g., backport/v1.0, backport/13.1)
  2. Merge the PR
  3. Workflow automatically creates backport PRs to target branches
  4. Review and merge the generated backport PRs

🏷️ Supported Label Format

  • backport/1.0 → looks for branch_1_0, release/1.0, v1.0, etc.
  • backport/13.1 → looks for branch_13_1, release/13.1, v13.1, etc.
  • Case-insensitive: Backport/ also works

🧪 Testing :

Tested with multiple scenarios:

  • ✅ Single successful backport
  • ✅ Multiple backports (mixed success/failure)
  • ✅ Missing target branches (graceful failure)
  • ✅ Cherry-pick conflicts (manual resolution guide)
  • ✅ Duplicate PR detection

Created A pull request to main, with two labels. backport/existing_branch and backport/branch_does_not_exist
{0AC14E21-C311-468F-836E-91B50DFB7683}
PR is created to the existing branch
{9F4B2AEC-EED0-4C46-A401-615E7EFB4D2D}
Comment is added on main PR to specify one branch was not found
Logs
{09066F7F-C7D4-4E8D-8198-7BD1C9809B0A}

Add GitHub Actions workflow for automatic PR backporting with intelligent branch detection, conflict handling, and comprehensive error reporting. Supports multiple branch naming patterns and provides detailed feedback via comments.
Copy link

This PR does not have an entry in lucene/CHANGES.txt. Consider adding one. If the PR doesn't need a changelog entry, then add the skip-changelog-check label to it and you will stop receiving this reminder on future updates to the PR.

Copy link
Contributor

@stefanvodita stefanvodita left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this contribution @ayagmar, this will be great to have!

What do you think of merging this first with the actual operations disabled, i.e. logging only, to see that ie behaves as expected? I've had a lot of issues previously with workflows I'd tested on my fork that behaved differently in the main repo. Plus, it will be good for us to observe it "in the wild" for a bit to make sure it's configured in a way that is most helpful.

Secondly, I'm wondering how we make it so people use it. Can we pick up the version to backport to from the CHANGES file or from the milestone? We recently added a bot that reads that file and determines the right release, which usually corresponds to the branch we'd want to backport to. Not saying that we have to do this right away, but otherwise I'm worried people who would like to use this workflow will simply forget to add a label. Maybe we could add a comment to the PR when it's opened? This would be after out initial logging-only testing phase.

Just to make sure - this is not related to the OpenSearch workflow mentioned on the issue, is it?

Once again - thank you for putting this together!

MERGE_COMMIT_SHA: ${{ github.event.pull_request.merge_commit_sha }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
run: |
set -e
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a very large bash script: instead of being inline, could it be factored out to a separate .sh file?

practically this can make the file easier to manage, e.g. syntax highlighting, run shellcheck on it if we need, etc.

@rmuir
Copy link
Member

rmuir commented May 31, 2025

Did you evaluate any existing actions? The first that comes to mind is https://github.com/carloscastrojumo/github-cherry-pick-action which is on the apache infrastructure approved list: https://github.com/apache/infrastructure-actions/blob/main/actions.yml

(I haven't even looked or tried to do any comparison myself)

Copy link
Contributor

@vigyasharma vigyasharma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! It'll make merging and back-porting PRs a lot easier for committers.

I don't know much about github actions, so my comments are mostly from my observations while merging and back-porting changes in Lucene. I'm intrigued by rmuir@'s comment about the cherry-pick action, wonder if that makes things simpler.

Thank you, for tackling this @ayagmar ! Looking forward to a state where I won't have to manually cherry-pick and run gradle check on my machine for back-porting!

Comment on lines +209 to +233
# Get individual commits from the PR instead of merge commit
echo "🔍 Getting PR commits..."
PR_COMMITS=$(echo "$PR_DATA" | jq -r '.commits[].oid' | tr '\n' ' ')
echo "📝 PR commits: $PR_COMMITS"

if [ -z "$PR_COMMITS" ]; then
echo "❌ No commits found in PR"
create_comment "❌ **Backport to \`$target\` failed**

Could not find individual commits in PR #${PR_NUMBER}."
add_label "backport-failed"
failure_count=$((failure_count + 1))
continue
fi

# Cherry-pick each commit individually
cherry_pick_success=true
for commit in $PR_COMMITS; do
echo "🍒 Cherry-picking commit: $commit"
if ! git cherry-pick -x "$commit" 2>&1; then
echo "❌ Failed to cherry-pick $commit"
cherry_pick_success=false
break
fi
done
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to cherry-pick each commit individually instead of the merged commit. How PRs are merged in Lucene depends on what committers think make sense. For some of them, the full git history is retained, for others changes are squash merged.


# Define templates in order of preference
declare -a target_branch_templates=(
"branch_{{version_us}}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like Stefan's suggestion of using the milestone label to find backport branch. We already have a bot to put that label based on CHANGES entry!

In Lucene, a change meant for 10.3.0 will be back-ported into branch_10x. Generally, our back-port branches follow the naming scheme branch_{MAJOR_VERSION}x. Would that match any of the branch templates defined here?

@stefanvodita stefanvodita added the skip-changelog Apply to PRs that don't need a changelog entry, stopping the automated changelog check. label Jun 3, 2025
@ayagmar
Copy link
Author

ayagmar commented Jun 5, 2025

Hello everyone, thanks for all feedback, I will try to address them one by one over the weekend
BR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
skip-changelog Apply to PRs that don't need a changelog entry, stopping the automated changelog check.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Backport Bot
4 participants