16

In my gitlab project there are 3 main branches: develop, stage and master.

Each time when updated code is pushed to develop branch, I have to merge it to stage branch and then merge it again to master branch manually.

This doesn't seem efficient.

Is there any way to merge branches automatically when there is no conflict?

Furthermore, it is possible to use a file named "gitlab-ci.yml " for auto merge something like

# merge develop branch to stage branch
merge-to-stage:
    only:
    - develop
    script:
    - merge (develop) to (stage) << something like this

# merge stage branch to master branch when the job above is completed
stage-to-master:
    only:
    - stage
    script:
    - merge (stage) to (master) << something like this

Please give me your kind advice.

Terkwood
  • 39
  • 2
  • 6
Jin Park
  • 371
  • 1
  • 9
  • 23

1 Answers1

18

There is no way to automate this within GitLab. But you can automate this using GitLab CI.

Be aware that the GitLab CI Runners are independent from GitLab and just get a local copy of a Git repository. So your CI script wont be able to run git merge & git push out of the box.

What you need to do is set up a SSH connection from the GitLab CI Runner to your GitLab instance. Use a before script for this. There are several answers on StackOverflow and a good blog post on GitLab how to achive this.

merge-job:
  before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - ssh-add <(echo "$GIT_SSH_PRIV_KEY")
    - mkdir -p ~/.ssh
    - cat gitlab-known-hosts >> ~/.ssh/known_hosts

Then run your Git commands like git merge. Then push.

merge-to-stage:
  only:
    - develop
  script:
    # If this is the last job you can stay here, otherwise better clone the repo into a working directory
    # git clone <URL> <working-directory> && cd <working directory>
    - git checkout stage
    - git merge develop
    - git push origin stage

The schema of your next pipeline jobs depend on what you mean with when there is no conflict. In your example code you merge all stage branches into the higher branch (feature to develop, develop to stage, stage to main). If so, then you should make sure that there is a merge job for each stage and these merge jobs are placed at the end of the pipeline. Then the merge won't happen if there was a CI error or a merge conflict before.

Alternatively you could also have just one job, which uses GitLabs push options. With these options you may create merge requests for your feature branch which are automatically merged and closed when a CI Pipeline is successful. This strategy would only merge your feature branch changes and not the whole stage branches.

merge-to-stage-branches:
  only:
    - <feature branch names that are no WIP anymore>
  script:
    # <scripts to merge feature into develop>
    git push -o merge_request.create -o merge_request.target=develop -o merge_request.merge_when_pipeline_succeeds
    # <repeat merge for each stage branch>
    # <repeat push for each stage branch> 
pixelbrackets
  • 1,958
  • 19
  • 28
  • 2
    What a wonderful replay. Thank you I will directly go and try your solution to my gitlab – Jin Park May 18 '21 at 10:06
  • The pipeline is generally triggered by a commit, Is there a way to specify to merge the currently committed code ? I have a case when I do 2 consecutive commits, while I expect them to merge their respective codes, they both merge the last commit instead! – Enissay Mar 12 '22 at 21:20