自动创建 GitLab Merge Request
最近规范代码提交流程,所有提交必须走 GitLab 的 Merge Request。
所以就很烦,每一个功能改动都要提交三份 MR(test/uat/master),一系列操作下来,人都麻了…
此时就要祭出杀器 Python大法
库选择
站在巨人的肩膀上
目前有一个现成的库: python-gitlab
实现方式
- 选择代码库
- 选择项目
- 使用传入的参数创建 MR
- 添加命令行快捷指令
具体实现
工具文件
辅助工具,获取当前工作空间中的git 分支名称,用来快速合并分支用。
1 2 3 4 5 6 7 8 9 10 11
| import subprocess
def get_git_branch(folder_path): try: process = subprocess.Popen(["git", "-C", folder_path, "rev-parse", "--abbrev-ref", "HEAD"], stdout=subprocess.PIPE) branch_name = process.stdout.read().strip().decode('utf-8') return branch_name except: return None
|
主文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| import gitlab import argparse from get_git_branch import get_git_branch
def main(): parser = argparse.ArgumentParser(description="Create a merge request using python-gitlab") parser.add_argument("-s", "--source", help="Source branch") parser.add_argument("-m", "--title", help="Merge request title")
parser.add_argument("-t", "--target", help="Merge target")
args = parser.parse_args()
gl = gitlab.Gitlab(url='https://address.gitlab.com', private_token='my token')
project = gl.projects.get(40)
current_branch = get_git_branch('当前的项目工作目录')
source_branch = args.source or current_branch
if args.target is None: return print('请输入目标分支,-t = test|uat|master|all, 可同时输入多个')
target_branches = ['test', 'uat', 'master']
for target_branch in target_branches: if target_branch in args.target or 'all' in args.target: merge_request = project.mergerequests.create({ "source_branch": source_branch, "target_branch": target_branch, "title": args.title, "description": "" })
print(f"{merge_request.target_branch} Merge request created: {merge_request.web_url}")
if __name__ == '__main__': main()
|
用法
1
| python3 main.py [-s xxx] -t xxx -m "xxx"
|
其中 -s 为可选,-t 为字符串,如果想发到哪个分支就包含哪些分支字符串,如 “test|uat”,或者使用 “all”
添加系统快捷指令(alias)
通过 alias 添加快捷命令,以 zsh 为例,如果不知道这是啥,自行百度一下哈。
1 2 3 4
| vim .zshrc
alias cm="python3 /Users/zhukejin/work/tools/gitlab/main.py"
|
用法
1
| cm -t uat -m "merge uat"
|
完事
手动 dog
更新:用了几天后,感觉少了点什么东西…
获取最近一次提交的 message
新建辅助文件 get_git_message.py
1 2 3 4 5 6
| import subprocess
def get_latest_commit_message(folder_path): result = subprocess.run(["git", "-C", folder_path, "log", "-1", "--pretty=%B"], stdout=subprocess.PIPE) return result.stdout.decode("utf-8")
|
主文件中引入此方法,并添加逻辑:
1 2 3 4 5 6 7 8 9 10 11 12 13
| message =args.title or get_latest_commit_message(work_path)
... ...
merge_request = project.mergerequests.create({ "source_branch": source_branch, "target_branch": target_branch, - "title": args.title, + "title": message, "description": "" })
|
这样每次连 ‘-t xxx’ 都不用写了(前提是git message 提交要规范)
添加二次确认
因为执行后就直接提交了, 万一写错了怎么办?很慌。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| user_input = input(f''' 提交信息为:
source: {source_branch} target: {args.target} message: {message}
是否确认提交 MR?请输入 y/n ? ''')
if user_input.lower() == 'y': for target_branch in target_branches: if target_branch in args.target or 'all' in args.target: merge_request = project.mergerequests.create({ "source_branch": source_branch, "target_branch": target_branch, "title": message, "description": "" })
print(f"{merge_request.target_branch} Merge request created: {merge_request.web_url}") else: print("取消提交")
|
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| import gitlab import argparse from get_git_branch import get_git_branch from get_git_message import get_latest_commit_message
work_path = '/Users/work/lbank-front'
def main(): parser = argparse.ArgumentParser(description="Create a merge request using python-gitlab") parser.add_argument("-s", "--source", help="Source branch") parser.add_argument("-m", "--title", help="Merge request title")
parser.add_argument("-t", "--target", help="Merge target")
args = parser.parse_args()
gl = gitlab.Gitlab(url='https://gitlab.ex.com/', private_token='xxx')
project = gl.projects.get(40)
current_branch = get_git_branch(work_path)
source_branch = args.source or current_branch
message =args.title or get_latest_commit_message(work_path)
if args.target is None: return print('请输入目标分支,-t = test|uat|master|all, 可同时输入多个')
target_branches = ['test', 'uat', 'master']
user_input = input(f''' 提交信息为:
source: {source_branch} target: {args.target} message: {message}
是否确认提交 MR?请输入 y/n ? ''')
if user_input.lower() == 'y': for target_branch in target_branches: if target_branch in args.target or 'all' in args.target: merge_request = project.mergerequests.create({ "source_branch": source_branch, "target_branch": target_branch, "title": message, "description": "" })
print(f"{merge_request.target_branch} Merge request created: {merge_request.web_url}") else: print("")
if __name__ == '__main__': main()
|