1. 程式人生 > 實用技巧 >持續整合十 APP包測試環境更新的自動化過程

持續整合十 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

cssbootstrap.min.css jsbootstrap.jsjquery.min.jsjquery.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)