Effortless Backporting: Simplify Your Development Workflow with git-backporting
Tags: productivity, git, automation, githubactions
Published: 2023-07-18 12:45:07

In today's software projects, it's common to have multiple branches or releases that require maintenance simultaneously. If you've ever worked on such projects, you're likely familiar with the repetitive and tedious task of propagating changes from the main branch to other active branches. This process, usually known as "backporting", can be time-consuming and error-prone. At Red Hat, we encountered this challenge and developed a possible solution that can benefit you too.

## Understanding Backporting
Trying to better define what problem we tried to provide a solution for, the backporting is the process of moving changes, typically commits, from one branch to another. The primary purpose is to transfer specific changes or a set of changes from a main branch to a maintained release one. This approach enables development teams to keep multiple branches in sync and ensure that critical updates and bug fixes are propagated to all necessary branches. Therefore, this practice could become crucial for many development teams, in the open-source world and beyond.

The backporting process involves several steps that can often be repetitive and tedious. However, with the right tool, these steps can be automated to streamline the workflow and save valuable time:

1. _Identification of changes_: The process begins by identifying the specific changes or commits that need to be backported from the main branch to the target branch. This may involve analyzing the differences between branches or selecting specific commits associated with bug fixes, feature enhancements, or security patches.
2. _Branch checkout_: The tool then checks out the target branch, which is the branch that will receive the backported changes.
3. _Creating a new branch_: To avoid modifying the original target branch directly, users usually create a new branch specifically for the backported changes. This allows for easier review and testing of the changes before they are merged into the target branch.
4. _Applying the changes_: Then users would have to apply the identified changes to the newly created backporting branch. This typically involves cherry-picking the selected commits or applying the necessary patches to ensure that the changes are correctly integrated.
5. _Pull/Merge request creation_: Finally open a new pull request (in the case of GitHub) or merge request (in the case of GitLab) from the backporting branch to the target branch, the one that should receive the backporting changes. This facilitates the review and approval process by team members, ensuring that the changes are properly validated before being merged.

By automating these steps, developers could significantly improve the maintenance of multiple branches at the same time.

## Introducing git-backporting
Recognizing the repetitive and tedious nature of the backporting process, we developed _git-backporting_ — an open-source project that provides a seamless solution for automating the backporting of pull requests on GitHub and merge requests on GitLab. This powerful tool streamlines the process by automating the backporting key steps we defined in the previous section, reducing errors, and saving developers valuable time and effort.

Starting from a pull request (or a merge request on Gitlab) and the target branch, the tool handles the creation and management of a dedicated branch for backporting and automates the process of applying the identified changes to the provided target branch. It performs cherry-picking of selected commits and takes care of pushing the backporting branch remotely.

Once the changes are applied, _git-backporting_ automatically generates a new pull request (for GitHub) or merge request (for GitLab) containing the backported changes. This simplifies the review and approval process, enabling team members to provide feedback and ensure the quality of the changes before merging.

In addition to these core steps, _git-backporting_ offers customizable options to adapt to specific requirements. Users can designate a local folder for repository checkout, define the merge strategy, tailor the title and body of the backporting pull request, and more. These options provide flexibility and enable developers to align the tool with their preferred workflows.

## Git Backporting by Examples
To provide a clearer understanding of how _git-backporting_ can be utilized in different scenarios, let's explore a few examples that highlight its versatility. These examples showcase both the usage through the CLI and integration as part of a GitHub action.

### CLI example
Suppose you want to backport changes from a pull request with the URL `https://github.com/example/repo/pull/42` to the `v2` branch. The simplest command you could run to accomplish the goal, using _git-backporting_ through the CLI, could be something like the following one:

```bash
$ git-backporting --target-branch v2 --pull-request https://github.com/example/repo/pull/42 -a *****
```

This command triggers the backporting process, automatically cloning the repository (info taken from the pull request url, i.e., `https://github.com/example/repo`), checking out the `v2` branch, cherry-picking the changes from the specified pull request to a new branch automatically created from the checked-out target branch, and creating a new pull request with the backported changes.

Note that, as this is the easiest command that could be executed, all other options, like merging strategy and pull request title and body, are initialized using the default values. You can find all defaults in the [inputs](https://github.com/kiegroup/_git-backporting_#inputs) section of the README in the GitHub repository of the tool.

### GitHub Action example
To further improve the automation we developed a GitHub action that automatically incorporates the _git-backporting_ tool, this way you can easily integrate the tool as part of your GitHub workflows.

For example, the following configuration creates a pull request against branch v1 once the original one is merged, provided that the label backport-v1 is applied:

```yaml
name: Automated Backporting using Git Backporting

on:
  pull_request_target:
    types:
      - closed
      - labeled

jobs:
  backporting:
    name: "Backporting"
    # Only react to merged PRs for security reasons.
    # See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target.
    if: >
      github.event.pull_request.merged
      && (
        github.event.action == 'closed'
          && contains(github.event.pull_request.labels.*.name, 'backport-v1')
        || (
          github.event.action == 'labeled'
          && contains(github.event.label.name, 'backport-v1')
        )
      )
    runs-on: ubuntu-latest
    steps:
      - name: Backporting
        uses: kiegroup/git-backporting@main
        with:
          target-branch: v1
          pull-request: ${{ github.event.pull_request.url }}
          auth: ${{ secrets.GITHUB_TOKEN }}
```

These examples demonstrate the flexibility and convenience of _git-backporting_ in different usage scenarios. Whether you prefer using the CLI or integrating it into your GitHub workflow, the tool empowers you to streamline the backporting process by simplifying repository cloning, cherry-picking changes, and creating pull requests with ease.

If you are interested in real and concrete examples, you can explore the [@kiegroup](https://github.com/kiegroup) organization. We have created a [composite action](https://github.com/kiegroup/kie-ci/blob/main/.ci/actions/backporting/action.yml) using the _git-backporting_ tool, which is meant to be triggered when a pull request with specific labels formatted as `backport-<branch>` is merged or labeled after merge. Additionally, you can refer to an example workflow utilizing this composite action at https://github.com/kiegroup/droolsjbpm-build-bootstrap/blob/main/.github/workflows/pr-backporting.yml. These examples showcase practical usage of _git-backporting_ in a real-world context.

## Limitations
While the _git-backporting_ tool offers powerful automation for backporting, it's essential to be aware of its current limitations and potential future extensions.

- Dependency on GitHub and GitLab: The tool is tightly coupled with GitHub and GitLab as the primary git management services. Expanding support for other popular services, such as Bitbucket or Gerrit, would be valuable for users on different platforms.

- Right now with _git-backporting_ you can backport just pull/merge requests, therefore a possible improvement could be to backport a set of commits even if no original pull request exists.

- At the time of writing there is no way to resolve conflicts interactively (as this was not our primary purpose), in case there is at least one conflict the tool will break and let users continue manually from the cloned repository.

## References
To learn more about _git-backporting_ and explore its capabilities, you can refer to the following resources:

- GitHub repository: https://github.com/kiegroup/git-backporting
- CLI documentation: https://github.com/kiegroup/git-backporting#cli-tool 
- GitHub action documentation: https://github.com/kiegroup/git-backporting#github-action
- Kiegroup organization: https://github.com/kiegroup

## Conclusion
The _git-backporting_ tool offers an invaluable solution for automating the backporting process of pull requests, simplifying the workflow for developers working with multiple active branches or versions. By leveraging _git-backporting_'s capabilities, users can save time, reduce errors, and ensure efficient propagation of changes between branches. With ongoing development, future enhancements and the help from community, _git-backporting_ has the potential to become a very useful tool for software development teams.