# This is a sample Python script. # Press to execute it or replace it with your code. # Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings. import os import re import requests from flask import Flask app = Flask(__name__) epmet_root_services = ['epmet-auth', 'epmet-gateway'] epmet_root_svc_name_reg = "^([^/]+)/.*$" epmet_module_svc_name_reg = "^epmet-module/([^/]+)/.*$" commit_regex = "^([0-9a-z]{40}) .*$" # 项目绝对路径 git_project_env = os.environ.get('JWHT_GIT_PROJECT_DIR') git_project_dir = git_project_env if git_project_env else "epmet-saas" # 上一次提交记录文件 last_deploy_commit_record = os.environ.get('JWHT_LAST_DEPLOY_COMMIT_RECORD') commit_record_file_path = last_deploy_commit_record if last_deploy_commit_record else "./lastcommit.txt" max_commit_qty = 20 def findLatestCommits(commits: list, last_commit_ver: str, max_amount: int): """ 过滤出肯能需要发布服务的提交列表 :param commits: :param last_commit_ver: :param max_amount: :return: """ rst: list = [] idx: int = 0 for c in commits: if idx > max_amount: return rst commit_ver = c.split(" ")[0] if commit_ver != last_commit_ver: rst.append(commit_ver) idx += 1 if commit_ver == last_commit_ver: return rst return rst def findModuleList(commits: str): """ 根据提交列表,找出所有需要发布的服务模块 :param commits: :return: """ service_set: set = set() for c in commits: try: rst = os.popen("cd {} && git show {} --stat --name-only|grep 'epmet-'".format(git_project_dir, c)) files = rst.readlines() for file in files: svc_name = find_service_name_from_file(file) if svc_name: # 有些文件可能是不需要发的,比如commons/clients等 service_set.add(svc_name) finally: rst.close() return service_set def find_service_name_from_file(file_rel_path: str): """ 根据提交的文件路径,找出他的服务名称 :param file_rel_path: :return: """ if file_rel_path.startswith("epmet-module/"): match = re.match(epmet_module_svc_name_reg, file_rel_path) return match.group(1) if file_rel_path.startswith("epmet-gateway") or file_rel_path.startswith("epmet-auth"): match = re.match(epmet_root_svc_name_reg, file_rel_path) return match.group(1) def read_last_commit_ver(): """ 读取上次发布到的版本号(包含) :return: """ with open(commit_record_file_path, 'rt') as lastcommit_file: line_contents = lastcommit_file.readlines() if len(line_contents) > 0: return line_contents[0] def write_last_commit_ver(new_ver): """ 写入上次发布到的版本号(包含) :return: """ with open(commit_record_file_path, 'wt') as lastcommit_file: lastcommit_file.write(new_ver) def deploy_svcs(svc_list): """ 发布服务 :param svc_list: :return: """ for svc in svc_list: rst = requests.post( "http://192.168.1.140:9610/jenkins/generic-webhook-trigger/invoke?MODULE_NAME={}&OPERATION=Deploy&token=11a600e78ec001d7864a73f7cf1555ae1a".format( svc)) print(rst.content.decode('utf-8')) def do(): # 切换分支 os.system("cd {} && git checkout dev".format(git_project_dir)) # 更新代码 os.system("cd {} && git pull".format(git_project_dir)) last_commit_ver = read_last_commit_ver() try: stream = os.popen("cd {} && git log --pretty=oneline --no-merges -20".format(git_project_dir)) commits = stream.readlines() # 根据commits找出最近提交的commits last_commits = findLatestCommits(commits, last_commit_ver, max_commit_qty) if not last_commits or len(last_commits) == 0: print("没有找到可发布的提交") return # 找到这些commits下提交的文件对应的微服务 svc_set = findModuleList(last_commits) # 记录本次发布版本号 write_last_commit_ver(last_commits[0]) # 执行jenkins远程部署 print("要发布的服务:", svc_set) deploy_svcs(svc_set) finally: stream.close() if __name__ == '__main__': do() # @app.route(rule='/on-dev-push', methods=['GET']) # def on_dev_push(): # do() # return "success" # app.run(host="0.0.0.0", port=7998, debug=True) # 多线程模式 # python main.py runserver 0.0.0.0:7999