I'm very new to gitlab and gitlab CI and I have put a pipeline in place that is successfully completing.
My master and development branches are protected so a merge request is required so that another dev in the group can review the code and comment before merging.
I was wondering if it is possible to generate this merge request at the end of this pipeline. Is there a setting for this in the gitlab repository or do I have to create a script to achieve this?
Side note :
Just before posting this I came across this section of the gitlab docs
I'm using gitlab-runner 11.0.0 on ubuntu 18.04

- 6,986
- 16
- 73
- 121
3 Answers
In order to achieve my simple needs, I simply added a final stage to my pipeline which essentially executes a bash script adapted from this post.
EDIT: As requested by @Yuva
# Create a pull request on pipeline success
create_merge_request:
stage: createMR
tags:
- autoMR
script:
- 'echo Merge request opened by $GITLAB_USER_NAME '
- ~/commit.sh
and in commit.sh
#!/bin/bash
# This script was adapted from:
# https://about.gitlab.com/2017/09/05/how-to-automatically-create-a-new-mr-on-gitlab-with-gitlab-ci/
# TODO determine URL from git repository URL
[[ $HOST =~ ^https?://[^/]+ ]] && HOST="${BASH_REMATCH[0]}/api/v4/projects/"
# The branch which we wish to merge into
TARGET_BRANCH=develop;
# The user's token name so that we can open the merge request as the user
TOKEN_NAME=`echo ${GITLAB_USER_LOGIN}_COMMIT_TOKEN | tr "[a-z]" "[A-Z]"`
# See: http://www.tldp.org/LDP/abs/html/parameter-substitution.html search ${!varprefix*}, ${!varprefix@} section
PRIVATE_TOKEN=`echo ${!TOKEN_NAME}`
# The description of our new MR, we want to remove the branch after the MR has
# been closed
BODY="{
\"project_id\": ${CI_PROJECT_ID},
\"source_branch\": \"${CI_COMMIT_REF_NAME}\",
\"target_branch\": \"${TARGET_BRANCH}\",
\"remove_source_branch\": false,
\"force_remove_source_branch\": false,
\"allow_collaboration\": true,
\"subscribed\" : true,
\"title\": \"${GITLAB_USER_NAME} merge request for: ${CI_COMMIT_REF_SLUG}\"
}";
# Require a list of all the merge request and take a look if there is already
# one with the same source branch
LISTMR=`curl --silent "${HOST}${CI_PROJECT_ID}/merge_requests?state=opened" --header "PRIVATE-TOKEN:${PRIVATE_TOKEN}"`;
COUNTBRANCHES=`echo ${LISTMR} | grep -o "\"source_branch\":\"${CI_COMMIT_REF_NAME}\"" | wc -l`;
# No MR found, let's create a new one
if [ ${COUNTBRANCHES} -eq "0" ]; then
curl -X POST "${HOST}${CI_PROJECT_ID}/merge_requests" \
--header "PRIVATE-TOKEN:${PRIVATE_TOKEN}" \
--header "Content-Type: application/json" \
--data "${BODY}";
echo "Opened a new merge request: WIP: ${CI_COMMIT_REF_SLUG} for user ${GITLAB_USER_LOGIN}";
exit;
fi
echo "No new merge request opened"

- 6,986
- 16
- 73
- 121
-
1can you please share the gitlab-ci.yml code snippet for automatic MR creation please. – Yuva Oct 10 '19 at 12:19
-
@Yuva I'm afraid I handed over the project to ops who have since taken over that side of operations and this was a **proof of concept** at the time so this is no longer used. – Dark Star1 Oct 11 '19 at 09:54
-
4no problem, thanks, I was able to do it by using the git api commands "git push origin HEAD:dev -o merge_request.create -o merge_request.target=master -o merge_when_pipeline_succeeds. Please refer here for Murali's solution:https://stackoverflow.com/questions/58322235/gitlab-ci-yml-to-create-merge-reqeust/58327480#58327480 – Yuva Oct 11 '19 at 10:21
-
@Yuva Thanks for the link, though at the time of posting, I don't think that API feature was present. – Dark Star1 Oct 11 '19 at 10:39
Short Answer: Sure - anything's possible. GitLab has a great API (including creating an MR). But I think going that route is bad form. You should utilize GitLab as it's designed. You're starting your Merge Request too late. Start it before you begin any work and your Merge Request will remain open the entire duration of your branch.
Long Answer: This is the ideal GitLab workflow:
- Someone creates an ISSUE against a repository. Maybe a feature request, maybe an actual problem, whatever - someone wants something changed, so it's an 'issue'
- Developer opens the issue and clicks CREATE MERGE REQUEST
- This generates an Merge Request (MR), a matching branch, and ties it back to the issue
- Developer works the branch, pushing changes as they go
- Developer gets a passing pipeline and hits "Resolve WIP" on that merge request page when they're ready for the customer to preview the work and/or another developer to code review.
- From here, have that reviewer either click MERGE when done reviewing or even better, turn on APPROVALS in repository settings and set the people or groups of people you want reviews from.
- Next to the merge button, be sure to delete the source branch (for sanity), and merged code will automatically close the issue - and link all 3 elements together.
This is fundamentally backward from the way GitHub works (which I came from) where you don't have to tell people what you're working on.
- Pull Requests on GitHub are created when the work is finished and you want to merge into master.
- Merge Requests on GitLab are created when the work is beginning and you want to tell the world you're about to embark on working on a feature. This allows for people to do a quick shutdown if it's not needed or prevents multiple devs from duplicating effort.
EDIT: It sounds like you're interested in leveraging the API. There's a python package called 'python-gitlab' actually that works decently http://python-gitlab.readthedocs.io/en/stable/gl_objects/mrs.html
import gitlab
import os
origin = "https://gitlab.example.com"
# Private token is set as an env var
gl = gitlab.Gitlab(origin, private_token, api_version='4')
gl.auth()
def create_merge_request(origin, private_token):
mr = project.mergerequests.create({'source_branch': 'cool_feature',
'target_branch': 'master',
'title': 'merge cool feature',
'labels': ['label1', 'label2']})
mr.assignee_id = gl.users.get(2).id # Assign it to coworker
def lookup_last_pipeline(origin, private_token):
current_pipeline_id = os.environ['CI_PIPELINE_ID']
pipelines = gl.projects.get(os.environ['CI_PROJECT_ID']).pipelines.list()
for pipeline in pipelines:
if pipeline.status == 'success' and pipeline.id == current_pipeline_id:
create_merge_request()
This is of course an example, you'll have to adapt it to your precise needs.

- 1,169
- 1
- 9
- 16
-
Thank you for your insight but our workflow requires that merge requests are issued after successful downstream merges and tests on the feature branches. So I'd just like to be able to create the merge requests automatically post pipeline success, and possibly automatically send out emails to the rest of the members so that someone may pick up the task and review it. – Dark Star1 Jun 30 '18 at 09:19
-
Yes I was interested in leveraging the API and I've found a way to do so. Thanks for the help. – Dark Star1 Jul 03 '18 at 20:35
Another approach it to:
- not use GitLab API
- get the patch represented by the code checked out by the pipeline
- use an email(!), since GitLab 11.5 (Nov. 2018)
Open a merge request with a patch via email
GitLab has supported opening a merge request via email for a long time, but before sending the email the branch must already exist on the server. Now you can open a merge request with only an email by attaching one or more patch files (
.patch
).Patch files are the standard for sharing and transmitting changes between systems. In future releases of GitLab we will build on this foundation for distributed merge requests, which will allow merge requests between GitLab instances, and other Git hosting tools too.
See documentation and issue.