# Automatic cascading branch merging in GitHub

If we are using [Gitflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) in our projects, once the release is ready to be shipped, sooner or later, it will be merged with the `develop` branch. The task is simple and could be handled manually, but what if we have something a bit more complex, like two or more active release branches? A change in a previous release has to be cascaded to the next one until it reaches the `develop` branch. And to all this, add a merge conflict during the process. [Gitflow automerge](https://github.com/raulnq/git-flow-automerge) is a [GitHub Actions](https://docs.github.com/en/actions) to help us to automate those cases.

## Features

- Merge a `release` branch to the next one until reaching the `develop` branch. The branches need to follow the [Semantic Versioning](https://semver.org/) guidelines.
- Open a pull request if there is a conflict during the merging.

## Usage

```yaml
name: automerge
on:
  push:
    branches:
      - 'release/**'

  workflow_dispatch:
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2        
      - name: AutoMerge
        uses: raulnq/git-flow-automerge@v0.4.1
        with:
          github_token: ${{ secrets.AUTOMERGE_TOKEN }}
          release_branch_type: 'release'
          develop_branch: 'develop'
``` 

- `release_branch_type`: Release branch prefix, default value: `release`
- `develop_branch`: Develop branch name, default value: `develop`
- `github_token`: We can use the `${{ secrets.GITHUB_TOKEN }}`, but there is a limitation explained [here](https://docs.github.com/en/actions/security-guides/automatic-token-authentication) about creating recursive workflow runs. Instead, we can create a [Personal Access Token (PAT)](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) in an account with write access to the repository and then add a [secret](https://docs.github.com/en/actions/security-guides/encrypted-secrets) in our repository with that value.

## Scenarios

To test the action, we created a repository with a secret on it (from the PAT):

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1667830446425/zICGUBQGo.png align="left")

```powershell
git clone https://github.com/raulnq/github-actions-sandbox.git
cd github-actions-sandbox
```

Add a file `.github\workflows\automerge.yml` with the following content:

```yaml
name: automerge
on:
  push:
    branches:
      - 'release/**'
  workflow_dispatch:
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2        
      - name: AutoMerge
        uses: raulnq/git-flow-automerge@v0.4.1
        with:
          github_token: ${{ secrets.AUTOMERGE_TOKEN }}
          release_branch_type: 'release'
          develop_branch: 'develop'
```
Commit and push the changes:

```powershell
git add .
git commit -m 'adding workflow'
git push origin main
```
### Automerge from a `release` to the `develop` branch

Create and push the `develop` branch:

```powershell
git checkout -b develop
git push origin develop
```

Create and push the `release/1.0.0` branch:

```powershell
git checkout -b release/1.0.0 develop
git push origin release/1.0.0
```

Create, make a commit and push the `feature/myFeatureA` branch:

```powershell
git checkout -b feature/myFeatureA 
git commit -m 'featurea A: change 1' --allow-empty
git push origin feature/myFeatureA 
```

Create a pull request from `feature/myFeatureA` to `release/1.0.0`:

![first-pr.PNG](https://cdn.hashnode.com/res/hashnode/image/upload/v1667833596164/4h8AxRAuw.PNG align="left")

Merge the pull request and go to the `Actions` tab:

![first-automerge.PNG](https://cdn.hashnode.com/res/hashnode/image/upload/v1667834398536/rRf6fbyv_.PNG align="left")

### Pull request created because merge conflict

Switch to `develop` and pull the last changes:

```powershell
git checkout develop
git pull origin develop
```

Create a file and push the changes:

```powershell
"Hi" >> Hi.txt
git add .
git commit -m 'new file' 
git push origin develop
```

Switch to `feature/myFeatureA` and pull the last changes:

```powershell
git checkout feature/myFeatureA 
git pull origin feature/myFeatureA
```

Create a file and push the changes:

```powershell
"Hello" >> Hi.txt
git add .
git commit -m 'new file' 
git push origin feature/myFeatureA
```

Create a pull request from `feature/myFeatureA` to `release/1.0.0`, merge it, and go to the `Actions` tab, now a pull request was created:

![second-merge.PNG](https://cdn.hashnode.com/res/hashnode/image/upload/v1667835586913/ioSp3awEk.PNG align="left")

Fix the merge conflict in the pull request before continuing.

### Cascading automerge until reaching `develop` branch

Switch to `develop` and pull the last changes:

```powershell
git checkout  develop
git pull origin develop
```

Create and push the multiple `release` branches:

```powershell
git checkout -b release/1.0.1 develop
git push origin release/1.0.1
git checkout -b release/1.1.0 develop
git push origin release/1.1.0
git checkout -b release/2.0.0 develop
git push origin release/2.0.0
```

Create, make a commit and push the `feature/myFeatureA` branch:

```powershell
git checkout feature/myFeatureA 
git commit -m 'featurea A: change 2' --allow-empty
git push origin feature/myFeatureA
```

Create a pull request from `feature/myFeatureA` to `release/1.0.0`, merge it and go to the `Actions` tab:

![cascade.PNG](https://cdn.hashnode.com/res/hashnode/image/upload/v1667837144385/2S0hQmlhl.PNG align="left")

Thanks, and happy coding.
