Giter Site home page Giter Site logo

korthout / backport-action Goto Github PK

View Code? Open in Web Editor NEW
52.0 6.0 23.0 2.77 MB

Fast and flexible GitHub action to backport merged pull requests to selected branches

License: MIT License

TypeScript 89.68% JavaScript 10.32%
backport patch cherry-pick github-action bors merge-queue pull-requests forwardport

backport-action's People

Contributors

alexvermette-eaton avatar alxgrk avatar basefas avatar chillleader avatar dependabot[bot] avatar dlavrenuek avatar github-actions[bot] avatar guyav46 avatar jschmid1 avatar korthout avatar lheckemann avatar npepinpe avatar oleschoenburg avatar pihme avatar remcowesterhoud avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

backport-action's Issues

The suggested manual actions don't work in all cases

Specifically git worktree add .worktree/<branchname> <target> can fail, because the target can already be checked out in another worktree. That also fails when the main worktree has the branch checked out. The reason for this is that git does not allow you to have the same branch checked out twice.

The suggested manual actions to cherry-pick the commits should work in all cases.

Always open a PR for each backport label

When an error occurs during the execution of the backport action, we currently just comment on the original PR with the failure message. In most cases the failure is a git conflict, which needs to be resolved manually. The backport action could have already created the backport branch and opened a PR for it (although without any new commits). This would reduce the amount of manual work needed.

Tests don't run to completion on macOS

On macOS, some acceptance tests fail with the following:

Command failed with ENOENT: ./setup.sh
spawn ./setup.sh ENOENT

However, others execute the setup script just fine, which Objective-See's Process Monitor shows.


When setting shell to true and piping the stdout and stderr of the setup script, I at least saw these:

+ set -o pipefail
+ SUBJECT=setup-test-repo
+ LOCK_FILE=/tmp/setup-test-repo.lock
+ '[' -f /tmp/setup-test-repo.lock ']'
+ echo 'Script is already running'
+ exit

Wouldn't this then cause the subsequent test to fail, since the repo may or may not be created at this point?

This is a very strange issue that I can't reproduce on Linux, and may be an execa bug...?

Don't trigger on unmerged closed pull requests

The current example workflow triggers the bot when a pull request is closed (i.e. merged and closed), and on comments containing /backport.

The bot protects against backporting unmerged pull requests, and will inform about being triggered while the pull request was not yet merged by commenting on the triggering pull request.

This feels strange for pull requests that are just closed. Especially if the pull request does not have any backport labels attached.

Example
camunda/zeebe#6920 (comment)

Expected
The bot is not triggered on closing a pull request, only on merging (i.e. close with merged = true)

Please provide a git tag that points to the latest stable version

It's possible to choose the latest commit by just specifying the main branch, but it'd be nice to have a way to point to the latest stable version. The official github actions does this by manually moving their v1, v2, v3... tags to point to the latest stable versions (example). Another common way to do this is to use the git tag latest if one doesn't want to mess with multiple versions.

Add automated acceptance tests

Automated tests were added with #7, but this only tests the typescript code. Left out are the backport.sh script as well as any real git commands.

It would be better to add automated acceptance tests that verify the correct working of both the typescript and shell script code on a real git repository. The only thing that has to be faked/mocked is the github API. That API as well as the git API are unlikely to change, so such tests would be relatively stable.

Use list to reference backport PR for more metadata

This has the benefit that GitHub will show a more detailed view with title and status.

image

Successfully created backport PR #174766 for `release-22.05`.

vs

image

Successfully created backport PR for `release-22.05`:
- #174766

Possible issue with backporting after a branch has been deleted

This may just have happened in NixOS/nixpkgs#129258.

I deleted the branch, noticed that it should be backported and added the label. Since that didn't immediately work, I restored the branch and re-applied the label.

This could just be an error of impatience on my end but I wanted to make sure.

I'm not well versed enough in JS to figure out how exactly the ref to be backported is fetched here but if you're fetching the source branch from the fork, perhaps look into fetching refs/pull/$num/head on the source repo itself instead.

Support skipping merge commits

Is your feature request related to a problem? Please describe.
Repositories commonly update pull requests with changes from the base using a merge commit. But, the action does not support the cherry-picking of merge commits. So, it fails to backport.

Describe the solution you'd like
We can allow users to decide how to deal with merge commits using a new input. This input defaults to the current behavior and allows users to skip merge commits instead.

Describe alternatives you've considered
Alternatively, the mainline flag can be used to decide how to cherry-pick the merge commit. We consider this a separate feature request which is covered by #341. If you have a need for that, please let us know there.

Improve error message on workflow file changes

GitHub actions are not allowed to push changes to GitHub action workflow files. When you attempt to backport a pull request with this action that includes changes to a workflow file you'll see an error message that the push failed with exit code 1.

This error code is not helpful enough. We can include the reason for the error and the manual instructions to cherry pick the commits by hand.

Support glob patterns in `target_branches` input

Some users want to automatically backport a pull request to a dynamically defined set of target branches.

For example, in #343 the request was to backport to all branches matching the feature/* pattern.

A workaround is available by adding an additional step in the workflow to expand the pattern into the branch refs:

- uses: actions/checkout@v3
  with:
    # Fetch all branches
    fetch-depth: 0
- id: branches
  shell: bash
  # list all banches, filtering for 'feature/*', and cutting off remotes/origin/
  # then finally substitute newlines for spaces
  run: |
    branches=$(git branch --list --all | grep 'origin/feature/' | cut -c 18- )
    space_delimited=${branches//$'\n'/ }
    echo "BRANCHES=${space_delimited}" >> $GITHUB_OUTPUT
- uses: korthout/backport-action@v1
  with:
    # now you can use the branches output in the backport-action
    target_branches: ${{ steps.branches.outputs.BRANCHES }}

However, it would be great to support this directly in the target_branches input as:

- uses: actions/checkout@v3
  with:
    # Fetch all branches
    fetch-depth: 0
- uses: korthout/backport-action@v1
  with:
    target_branches: 'feature/*'

Note that a deep checkout (fetch-depth:0) is required to fetch all branches.

Use pull_request_target

For contributions from forked repositories, pull_request_target is needed so that GITHUB_TOKEN has write access to the repo.

That means though that the default checked out code is from base, so it needs to cherry-pick things correctly.

Port origin PR labels to backport PR

Allow a set of labels to be automatically applied onto the backport PR.

Use case for us (NixOS/nixpkgs) would be labels like Severity: Security, which also applies to the backport PR and right now needs to be remembered to be applied when the PR gets created.

Mention the need for permissions

As recommended by GitHub, I've set read-only permissions for actions by default. This was preventing backport-action from working, since it needs to be able to create commits/PRs and therefore needs:

    permissions:
      contents: write
      pull-requests: write

Baseref is sometimes not found

I've seen this message a couple of times in situations where I did not expect it.

Like in camunda/zeebe#8038 (comment)

Backport failed for stable/1.2, because 1 or more of the commits are not available.

Please cherry-pick the changes locally.
Note that rebase and squash merges are not supported at this time.
For more information see zeebe-io/backport-action#46.

On further inspection of the logs of the workflow run, I noticed that the baseref is not a known commit.

Working on label backport stable/1.1
Found target in label: stable/1.1
From https://github.com/camunda-cloud/zeebe
 * branch                  stable/1.1 -> FETCH_HEAD
 * [new branch]            stable/1.1 -> origin/stable/1.1
Start backport to backport-8038-to-stable/1.1
fatal: git cat-file: could not get object info
exitcode(6): Backport failed for `stable/1.1`, because 1 or more of the commits are not available.

This is very hidden, but exitcode 6 means that the cat-file check on the baseref failed. We should also improve error messages, but that's a different topic.

The baseref is not yet directly fetched, something that should've been done in #162.

Feature request : backport to all open feature branches

It would be nice to be able to backport to all feature branches currently open named eg 'feature/*'.
The configuration would be something like:

  • from: main
  • to: feature/*
    for example.

This would create a PR on each feature/* branch.

PR commits are cherry-picked instead of the squashed commit

Hey just testing this for our repo and I am seeing that squashed PRs cherrypick using the commits on the PR branch, not the final squash commit. I saw this ticket but it has been closed

#46

I've not really dug into it yet but is it possible on a squash commit to grab that commit and cherrypick using that?

Don't create pull requests twice

With backport trigger on comment enabled, it's possible to trigger the backport bot twice for the same label. Which may result in double pull requests.

The bot should be made a bit more "smart" and be able to find-out which pull requests it already created.

Support rebase/squash merges

Currently the action does not support rebase (and squash) merges.

Specifically, this action was build to deal with octopus merges. It does this by looking at the common ancestor of the head and base refs. But after a rebase the branch no longer points to the same head ref, which then ends up not being fetched by the action on checkout.

We should implement an alternative strategy to find all commits merged by the pull request.

UPDATE: With v1 the action no longer looks for the common ancestor, so it should support rebase/squash merges now. Please reach out if you've tried this out (both success and failure stories are appreciated), as I'd like to know whether we can consider this to be supported nowadays.

Add backport failed label

It would be useful to automatically add a label when the backport failed, to make it easier to track which backports need to be handled manually.

Improve error messages

Currently errors are represented with error codes. It would be helpful to have a human readable description for the error codes.

PRs created by backport-action should trigger the CI

Is your feature request related to a problem? Please describe.
PRs created by the backport-action do not trigger the CI for the PR.
Triggering the CI, especially for backports, is important to verify the integrity of the PR.

Describe the solution you'd like
I do not know of a good solution on how to achieve that, but for starters, an entry in the README outlining examples on how to overcome this, would be great.

Describe alternatives you've considered
See https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#triggering-further-workflow-runs

Bot should sign its commits

The backport-action cherry-picks the commits, it keeps the author of the original commit and commits it using a special git user (currently github-actions[bot] <github-actions[bot]@users.noreply.github.com>), but it does not sign these commits. On github this means that these commits are labeled as unverified.

Feature request: allow specifying mainline

Allow specifying a default mainline to use when cherry picking and if supplied use it, i.e. git cherry-pick 1234567 -m 1. Since this action can be used in very specific workflows (like my use case!), this could be a useful option to specify.

Example:

steps:
      - uses: actions/checkout@v3
      - name: Create backport pull requests
        uses: korthout/backport-action@v1
        with:
           default_mainline: 1

Use PAT in eat-your-own-dogfood workflow

I noticed that pull requests created by the backport-action don't trigger the CI

That is because by default the backport-action uses GITHUB_TOKEN which cannot trigger other workflows. We can overcome this by setting the token input of the backport-action with a PAT.

Allow custom PR templates

https://github.com/zeebe-io/backport-action/blob/186066470a540eb4a8d2b1bed1e8e12ab12b8120/src/backport.ts#L212

At the time of writing this action uses a constant backport PR body. Would it be possible to make it configurable?

Specifically the use case I have here is that the backport PRs the action opens are themselves subject to further actions, but GitHub won't let an action run an action so the required checks on the backport PRs are never triggered.

One hacky but very lightweight workaround for this issue is to just have the reviewer close and immediately reopen the PR to trigger the CI, so ideally I'd like the backport PR description to include a note to reviewers that they can just close and reopen the PR to trigger CI. Eventually I might add a /ci command or similar that is slightly less hacky, but I'd still like to document that in the PR body.

Automatically backport a closed PR to specific branches

I don't think this possible at the moment. But is it possible to add a property that specifies the branches to backport to? Our PR's always get backported to the same branch for a length of several months, so to specify the backport branches once in the workflow is much simpler than relying on individuals to add labels on every individual commit.

User bot comments "Must have admin rights to Repository"

camunda/zeebe has been using this action for quite some time successfully. Recently, we switched the default github token for a PAT by configuring github_token. After the switch, the action still successfully opened backport PRs, but commented:

Must have admin rights to Repository.

The logs show that this is because the action tries to request reviewers for the PR:

Create PR for backport-9410-to-stable/1.3
Create PR: # Description
Backport of #9410 to `stable/1.3`.

relates to #9387
Request reviewers: 
Must have admin rights to Repository.
Create comment: Must have admin rights to Repository.

Note that the PAT has the public_repo scope.

Label original PR when backport PR is merged

Currently when using this action my team has a habit of adding a backported label to the original PR (i.e. the PR labelled backport some-branch once the backport PR(s) are merged. This helps us get an idea of when we can cut a new release if we're waiting on several PRs to be backported.

I'm not sure how feasible it would be to actually build, but it would be really nice if this action was able to label PRs that had been successfully backported into all of the desired branches.

Improve manual instructions

We should be able to simplify the manual instructions that are commented when the action is unable to backport the pull request (e.g. due to conflicts).

  • make sure the relevant commits are available locally by adding a fetch of the pull request git fetch origin refs/pull/<number>/head
  • no need to determine the common ancestor anymore,
    instead just use a shorthand for ^<base> and <head> (i.e. <base>..<head>): git cherry-pick -x <base>..<head>

Backport a merged PR

Currently the backport action only supports backporting as part of the merge event of the PR. However, sometimes you forgot to backport a PR or the need to backport it arrises after the PR was already merged. Backporting a merged PR should be supported.

To trigger the backport we can consider that the user writes a comment like /backport. Labels can still be used to define which branches to backport the PR onto.

Unable to eat dogfood

At the moment, this repo cannot eat its own dog food because backports will always run into conflicts.

This problem is caused by how GitHub Actions are supposed to be distributed: the artifacts are part of the repo. Each change to the source code leads to changes in the artifacts. These changes are generally committed as part of the pull request that introduces the changes. If multiple changes have been made on the main branch, the artifacts differ from that of previously released versions. Then, these commits cannot be cherry-picked automatically due to conflicts.

I see two potential solutions:

  1. don't build the new artifacts in the pull request, but build them automatically with a separate GitHub Action. Note that this action would have to be run on main and release branches to produce artifact changes automatically, commit and push these changes. Additionally, the action should not run on its own commit pushes. One upside to this is that authors no longer need to think about building the artifacts locally and provide them along with the rest of the pull request.
  2. split the source from the produced artifacts into separate repositories. This seems extreme because it makes it harder for users to find the source code. This does not have my preference.

Automate release process

Creating new releases has become a bit tedious, and I might forget some of the steps:

  • update version in package.json
  • tag commit
  • move existing major/minor tags
  • create release on GitHub

Let's automate this with some GitHub Action(s).

Speed regression when using fetch-depth = 1

There seems to be a speed regression between using fetch-depth = 0 and fetch-depth = 1 alongside #162.

We use this action on Nixpkgs, which is a very large repository. When using v0.5.0 with fetch-depth = 0, our checkout takes ~5m, while the actual backport takes ~15s. Unexpectedly, when switching to v0.8.0 and the default fetch-depth value (1), our checkout takes ~10s, and the backport can take over 10m.

Using the logs, I've tracked the points where time is spent the most down to these three lines:
https://github.com/zeebe-io/backport-action/blob/7078123ca60e45c3452ca61d534dbd55c5319fec/src/backport.ts#L68-L69
https://github.com/zeebe-io/backport-action/blob/7078123ca60e45c3452ca61d534dbd55c5319fec/src/backport.ts#L95

which is all fetching. Is there anything that can be done to improve this? It seems weird to me that selectively fetching the history as done here can take double the time that fetching the entire history does. Thanks!

backport label regex

It would be useful to be able to configure the label name with a regex that extracts the branch name:

backport_label_pattern: '^backport-to-(.*)$'

Prepare for a v1 release

This action has been around for some time now and is actively used by multiple large and very active projects. It has been tested in production for long enough. It's time to remove the This project is still in an early development stage note at the top of the README and release v1 of the backport action.

What should be included in v1?

IMO, a v1 release should come with a major feature or large change to the project. The main feature of the v1 release of the backport action might as well be performance (or energy efficiency). While investigating a performance regression, we researched how to use shallow clones and fetch-depth to optimize the git clone (via actions/checkout), and the git fetches to the bare minimum. These lead to small improvements for small projects and should lead to large improvements for repositories with a long history. This performance improvement is not yet production ready, but we could easily turn it into a release candidate which we can battle-test before releasing v1.

I started this project originally together with @pihme to solve a specific problem for the Zeebe team: to automatically backport pull requests merged with octopus commits. Over time, the action has also found usages outside of Camunda. To improve the visibility, I'd like to publish the action on the GitHub Marketplace. Therefore, I will move this repo under my personal account github.com/korthout. There, I will be able to take more control over the project and work towards releasing it more often.

Checklist

  • clean up the code from korthout-fetch-depth #296
  • create a release candidate v1-rc1
  • update the README to announce release candidate and repo ownership move
  • battle test for one month, releasing more candidates if needed, e.g. v1-rc2
  • move repo to personal account after battle testing is completed
  • rename master to main
  • remove the memo from the README
  • release v1, v1.0, and v1.0.0 (switch to full semantic versioning after this)
  • publish to marketplace

Add automated tests

Without any tests it is more difficult to add new features without breaking current behaviour. We should add write some tests

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.