Skip to content

Instantly share code, notes, and snippets.

@Lorac
Last active January 12, 2018 21:43
Show Gist options
  • Save Lorac/f0fbcaacbb4f646da4fb172722e0afb6 to your computer and use it in GitHub Desktop.
Save Lorac/f0fbcaacbb4f646da4fb172722e0afb6 to your computer and use it in GitHub Desktop.
Create merge request on Gitlab
#!/usr/bin/env python3
import os
import argparse
import tempfile
import getpass
import keyring
from pathlib import Path
from subprocess import call
from gitlab import gitlab, GitlabGetError
from git import Repo
from git import BadName
GITLAB_HOST = "YOUR_HOST"
EDITOR = os.environ.get('EDITOR', 'vi')
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Create a merge requests based on the current branch.')
parser.add_argument('branch', help='Remote branch to merge into')
parser.add_argument('--local-branch', '-l', help='Local branch to use')
parser.add_argument('--assign', '-a', help='Assign someone(username) to the merge request ', dest='assignee')
parser.add_argument('--title', '-t', help='Add custom message to the merge request ', dest='title')
parser.add_argument('--remote', '-r', help='Select different remote "(default: %(default)s)"', dest='remote', default="gitlab")
parser.add_argument('--description', '-d', help='Invoke $EDITOR to add a description to your merge request', default=False, action='store_true')
token = keyring.get_password("gitlab-createmr", getpass.getuser())
if not token:
print("Create a token here: {}".format(GITLAB_HOST + "/profile/personal_access_tokens"))
print("Enter default GitLab token (scope: api): ")
token = getpass.getpass(prompt="Token : ")
keyring.set_password("gitlab-createmr", getpass.getuser(), token)
else:
token = keyring.get_password("gitlab-createmr", getpass.getuser())
gl = gitlab.Gitlab(GITLAB_HOST, token, api_version='4')
args = parser.parse_args()
merge_request = {}
folder_abs_path = os.getcwd()
folder_name = folder_abs_path.split('/')[-1]
repo = Repo(folder_abs_path)
if (args.description):
with tempfile.NamedTemporaryFile() as fp:
call([EDITOR, fp.name])
merge_request['description'] = fp.read().decode("utf-8")
if (args.assignee):
username = args.assignee
users = gl.users.list(search=username)
if (len(users) == 1):
merge_request['assignee_id'] = users[0].id
else:
print("Username not found {0}".format(username))
print("Continuing anyway...will not assign merge request")
if args.local_branch:
branch_name = args.local_branch
if branch_name not in repo.branches:
repo.create_head(branch_name)
else:
branch_name = repo.active_branch.name
if (args.title):
merge_request['title'] = args.title
else:
try:
merge_request['title'] = repo.commit('HEAD').message
except BadName:
print("Empty repository, no commit")
exit(1)
project_path = repo.remotes[args.remote].url[:-4].split(':')[1]
try:
print("Fetching {}...".format(project_path))
project = gl.projects.get(project_path)
except GitlabGetError:
print("Project {} doesn't exist".format(project_path))
exit(1)
merge_request['source_branch'] = branch_name
merge_request['target_branch'] = args.branch
merge_request['remove_source_branch'] = True
print("Pushing {0}, in project {1}".format(branch_name, project_path))
repo.remotes[args.remote].push(branch_name)
print("Creating merge request with source branch {0}, target branch {1}".format(branch_name, args.branch))
project.mergerequests.create(merge_request)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment