''' @File: publish_module.py @Description: Moudle Publish Script @Author: leon.li(l2m2lq@gmail.com) @Date: 2020-02-11 15:08:46 ''' import platform import os import time import argparse import sys import subprocess import glob import re import shutil import json import requests import urllib import qtciutil from dingdinghelper import DingDingHelper dingding_cfg = { "msgurl": "https://oapi.dingtalk.com/robot/send?access_token=e02a2c7de529ca83ba5d4e6f6c37b31f53152b3dc54d30653ed2235723027651", "corpid": "ding428c9b6bb8962a4d35c2f4657eb6378f", "corpsecret": "L8v6TYuSnjq8VsErPiCoJdWU19T5Embn1P8KW7IyO3_FkJw_ZLPqdKt6blQwwd34", "spaceid": 483476421 } def _parser_readme(readme_filepath): if not os.path.isfile(readme_filepath): raise qtciutil.QtCiUtilError("No %s found." % readme_filepath) with open(readme_filepath, 'r', encoding='utf-8') as f: content = f.read() m = re.search(r'^#(.*)\n', content) if not m: raise qtciutil.QtCiUtilError('The README file is not in the right format.') return m[1] def _parser_changelog(changelog_filepath): if not os.path.isfile(changelog_filepath): raise qtciutil.QtCiUtilError("No %s found." % changelog_filepath) with open(changelog_filepath, 'r', encoding='utf-8') as f: content = f.read() m = re.search(r'^##\s*(\d+\.\d+.\d+)\s.*\n((.+\n)+)', content) if not m: raise qtciutil.QtCiUtilError('The CHANGELOG file is not in the right format.') return (m[1], m[2]) def _parser_module_config(module_json_filepath): if not os.path.isfile(module_json_filepath): raise qtciutil.QtCiUtilError("No %s found." % module_json_filepath) with open(module_json_filepath, 'r', encoding='utf-8') as f: content = f.read() moduleconf_json = json.loads(content) tmp_name = moduleconf_json.get('module_name', '') hook = moduleconf_json.get('hook', '') database_names = [] if (hook != ''): param = urllib.parse.urlencode({'module_name': tmp_name}, quote_via=urllib.parse.quote) r = requests.get(hook, params=param) if (r.status_code != 200): exit(1) database_names = [] hook_ret = r.json() hook_data = hook_ret.get('data', {}) for key in hook_data: urls = key.split('/') urls.reverse() database_names.append(urls[1]) return ', '.join(database_names) def package(): """ TopMES-6.1.1-rc.2-upgrade-202002052311.zip |--TopMES-6.1.1-rc.2-upgrade-202002052311.pkg |--CHANGELOG.md |--README.md """ dist_dir = os.path.join(ci_script_dir, '../dist/') os.environ["PATH"] = os.environ['QT_BIN'] + os.pathsep + os.environ["PATH"] package_name = '{name}-{version}-upgrade-{dt}'.format( name=module_name, version=version, dt = time.strftime("%Y%m%d%H%M") ) archive_dir = os.path.join(ci_script_dir, '../archive/') packaging_dist = os.path.join(ci_script_dir, '../archive/%s/' % package_name) if os.path.isdir(archive_dir): shutil.rmtree(archive_dir, ignore_errors=True) os.makedirs(packaging_dist) package_program_filepath = '' package_config_filepath = os.path.join(ci_script_dir, 'upgrade-package-{}.json'.format(platform.system().lower())) # modify release_note module_json_filepath = os.path.join(ci_script_dir, '../module.json') with open(module_json_filepath, 'r', encoding= 'utf-8') as f: moduleconf_content = f.read() moduleconf_json = json.loads(moduleconf_content) moduleconf_json['version'] = version moduleconf_json['change_log'] = changelog moduleconf_json['is_module'] = 1 moduleconf_json['remark'] = 'Update package is automatically published by CI.' with open(package_config_filepath, 'r', encoding= 'utf-8') as f: package_config_content = f.read() content_json = json.loads(package_config_content) content_str = json.dumps(moduleconf_json, ensure_ascii=False) content_json['release_note'] = content_str with open(package_config_filepath, 'w', encoding='utf-8') as f: json.dump(content_json, f, ensure_ascii=False, indent=4) package_output_filepath = "%s/%s.pkg" % (packaging_dist, package_name) if platform.system() == 'Windows': package_program_filepath = dist_dir + "/topikm/qt5.6.3-win32-msvc2015/bin/TopUpgradePackager.exe" elif platform.system() == 'Linux': package_program_filepath = dist_dir + "/topikm/qt5.6.3-linuxx86_64/bin/TopUpgradePackager" package_args = [ package_program_filepath, '-c', package_config_filepath, '-d', package_output_filepath, '-H', 'yes' ] pinfo = subprocess.run(package_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) if pinfo.returncode != 0: raise qtciutil.QtCiUtilError("package failed. %s" % pinfo.stdout.decode('utf-8')) # Copy README.md and CHANGELOG.md shutil.copy(os.path.join(ci_script_dir, '../README.md'), packaging_dist) shutil.copy(os.path.join(ci_script_dir, '../CHANGELOG.md'), packaging_dist) # upload to database upload_program_filepath = '' if platform.system() == 'Windows': upload_program_filepath = dist_dir + "/topikm/qt5.6.3-win32-msvc2015/bin/PackageUploaderPlus.exe" elif platform.system() == 'Linux': upload_program_filepath = dist_dir + "/topikm/qt5.6.3-linuxx86_64/bin/PackageUploaderPlus" upload_args = [ upload_program_filepath, '-u', package_output_filepath, module_json_filepath ] pinfo = subprocess.run(upload_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) if pinfo.returncode != 0: print(pinfo.returncode) print(pinfo.stderr) print(pinfo.stdout) raise qtciutil.QtCiUtilError("upload failed. %s" % pinfo.stdout.decode('utf-8')) os.chdir(os.path.join(ci_script_dir, '../archive/')) if platform.system() == 'Linux': shutil.make_archive(package_name, 'gztar', base_dir=package_name) archive_filepath = os.path.join(os.getcwd(), package_name + ".tar.gz") elif platform.system() == 'Windows': shutil.make_archive(package_name, 'zip', base_dir=package_name) archive_filepath = os.path.join(os.getcwd(), package_name + ".zip") else: raise qtciutil.QtCiUtilError('This platform is currently not supported.') return archive_filepath def sendToDingding(archive_filepath): ding = DingDingHelper() ding.msgurl = dingding_cfg["msgurl"] ding.corpid = dingding_cfg["corpid"] ding.corpsecret = dingding_cfg["corpsecret"] r = requests.get("http://139.196.104.13:9181/api/_/dingding/getCookie") if r.status_code != 200: exit(1) r_data = json.loads(r.content) ding.cookie = r_data["data"].rstrip() spacepath = '/topmes/update/{os}/{module_name}/'.format( module_name = module_name, os = platform.system().lower() ) ding.upload_file(archive_filepath, dingding_cfg["spaceid"], spacepath) msg = [] msg.append("{module_name} {version} {os} 发布".format( module_name =module_name, version = version, os = platform.system() )) msg.append(changelog) msg.append("模组升级包已上传至钉盘目录{dir}下。".format(dir=spacepath)) if len(database_name) > 0: msg.append("已自动上传到以下数据库:\n{dbname}\n可在产品中点击系统->模组版本查看,若失败请手动升级。".format(dbname=database_name)) print('\n'.join(msg)) ding.send_msg('\n'.join(msg)) if __name__ == "__main__": global ci_script_dir global module_name global version global changelog global database_name ci_script_dir = os.path.dirname(os.path.realpath(__file__)) module_name = _parser_readme(os.path.join(ci_script_dir, '../README.md')).strip() print("module_name: %s" % module_name) changelog_info = _parser_changelog(os.path.join(ci_script_dir, '../CHANGELOG.md')) version = changelog_info[0] print("version: %s" % version) changelog = changelog_info[1] print("changelog: %s" % changelog) database_name = _parser_module_config(os.path.join(ci_script_dir, '../module.json')) archive_filepath = package() print("archive_filepath: %s" % archive_filepath) sendToDingding(archive_filepath)