持续集成十 APP包测试环境更新的自动化过程
在jenkins里面添加APP打包的任务
打包的脚本由开发提供,打完包将包上传到测试服务的文件下载站点里面,并更新线下资源包的下载地址
IOS 打包需要再苹果电脑上执行,所以将一台苹果电脑作为jenkins的从属节点,该任务只在苹果电脑上执行
测试部门提供一个上传下载的文件服务站点
python flask
from flask import Flask, render_template, send_from_directory, request, jsonify from werkzeug.utils import secure_filename import os import sys import io import glob import time import operator from dbhelper import MySqlForConfig import urllib.parse sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') app = Flask(__name__) app.config['MAX_CONTENT_LENGTH'] = 50 * 1024 * 1024 # ALLOWED_EXTENSIONS = set(['txt', 'png', 'jpg', 'xls', 'JPG', 'PNG', 'zip', 'gif', 'GIF']) _menu = os.path.abspath('.') down_menu = ['apk', 'iosRe', 'androidRe'] db_config = {'host': '', 'user': '', 'password': '', 'database': '', 'port': "", 'charset': "utf8"} # 测试环境的数据库配置 @app.route('/') @app.route('/<_type>/download') def _main(_type=None): """下载列表""" if _type in down_menu: my_folder = os.path.join(_menu, _type) if not os.path.exists(my_folder): os.makedirs(my_folder) pattern = '*.*' os.chdir(my_folder) maps_list = [] for f_name in glob.glob(pattern): if os.path.isfile(f_name): maps = dict() maps['name'] = urllib.parse.quote(f_name) time_tup = time.localtime(os.path.getctime(f_name)) maps['crateTime'] = time.strftime('%Y-%m-%d %H:%M:%S', time_tup) maps['size'] = os.path.getsize(f_name) / 1024 maps_list.append(maps) maps_list = sorted(maps_list, key=operator.itemgetter('crateTime'), reverse=True) return render_template("download.html", files=maps_list, _contents=_type) else: return 'Hello World!' @app.route('/<_type>/download/<filename>') def download(_type, filename): """下载""" try: if _type in down_menu: my_folder = _menu + '/' + _type + '/' return send_from_directory(my_folder, filename, mimetype='application/octet-stream') else: return jsonify({"errno": "1", "errmsg": "路径不正确"}) except Exception as e: print(e.__str__()) return jsonify({"errno": "1", "errmsg": e.__str__()}) @app.route('/<_type>/upload', methods=['POST'], strict_slashes=False) def upload(_type=None): """上传""" if _type in down_menu: file_dir = os.path.join(_menu, _type) if not os.path.exists(file_dir): os.makedirs(file_dir) try: f = request.files['file'] f_name = secure_filename(f.filename) # 获取后缀名,可进行上传文件类型的控制 if f_name not in ['apk', 'wgt']: return jsonify({"errno": "1", "errmsg": "文件类型不正确"}) f.save(os.path.join(file_dir, f.filename)) # 保存文件到目录 upload_update(dict(request.form), f.filename) # 更新文件的下载地址到测试环境 return jsonify({"errno": "0", "errmsg": u"success"}) except Exception as e: return jsonify({"errno": "1", "errmsg": e.__str__()}) else: return jsonify({"errno": "1", "errmsg": "路径不正确"}) def upload_update(data, filename): """python3.6 dict()form表单 value值是list; python3.8 dict()form表单 value值是string""" if 'isUpdateVersion' in data.keys() and data['isUpdateVersion'][0]: v_code = data['version'][0] plat = data['plat'][0] if plat == "android": down_url = 'http://10.101.68.1:5000/androidRe/download/' + filename elif plat == "ios": down_url = 'http://10.101.68.1:5000/iosRe/download/' + filename else: down_url = "" if down_url != "": update_app_version(down_url, v_code, plat) def update_app_version(down_url, version_number, plat_code): if plat_code == "android": project_code = 1 elif plat_code == "ios": project_code = 2 else: project_code = "" description = "版本更新:" + str(version_number) if project_code != "": db = MySqlForConfig(db_config) update_sql = """UPDATE AppVersion set FileUrl='%s',VersionNumber='%s',Description='%s' WHERE ProjectCode='%s';""" % (down_url, version_number, description, project_code) # 将热更新的地址更新到测试数据库 db.exec_sql(update_sql) if __name__ == '__main__': app.run(debug=True, host='10.101.68.1', port=5000)
页面html
css bootstrap.min.css js bootstrap.js jquery.min.js jquery.qrcode.min.js
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>下载</title> <link href="/static/css/bootstrap.min.css" rel="stylesheet"/> <script type="text/javascript" src="/static/js/jquery.min.js"></script> <script type="text/javascript" src="/static/js/bootstrap.js"></script> <script type="text/javascript" src="/static/js/jquery.qrcode.min.js"></script> </head> <body> <div style="width: 90%;margin-left: 5%;margin-top: 15px"> <table class="table table-striped table-hover table-bordered apk-list"> <thead> <tr> <th>文件名称</th> <th>创建时间</th> <th>文件大小 Kb</th> <th>下载二维码</th> </tr> </thead> <tbody> {% for file in files %} <tr> <td class="download-uri"><a href="/{{ _contents }}/download/{{ file['name'] }}">{{ file['name'] }} </a></td> <td>{{ file['crateTime'] }} </td> <td>{{ file['size'] }} </td> <td class="qr-code">生成下载二维码</td> </tr> {% endfor %} </tbody> </table> </div> <script> $('.apk-list .qr-code').on('click', function () { const ele = $(this); const shown = ele.data('popover_shown'); const content = $('<div class="popover-content"></div>').qrcode(location.origin + ele.siblings('.download-uri').children('a').attr('href')); content.children('canvas').css({width: 220, height: 220}); ele.popover('destroy'); ele.popover({ placement: 'bottom', html: true, content: content, trigger: 'manual ' }); if (shown != 1) { ele.popover('show'); ele.data('popover_shown', 1); } else { ele.popover('hide'); ele.data('popover_shown', 0); } }) </script> </body> </html>
测试一下上传
import requests data = {"version": "2.2.3", "plat": "ios", "isUpdateVersion": True} url = "http://10.101.68.2:5000/iosRe/upload" files = {"file": open("D:/TestPlat/Books/resourceIOS/__ios2.2.3.wgt", "rb")} r = requests.post(url, data=data, files=files) print(r.status_code) print(r.text)