自动创建 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()
 
 
  |