python 脚本实现XCode自动打包/上传蒲公英/钉钉机器人通知

XCode Python脚本打包

环境

python版本需求: python3
使用前请安装 requirements.text

pip install -r requirements.txt

配置脚本信息

  1. workspace 项目的路径地址
  2. project_name 项目名称
  3. scheme xcodebuild -list查看
  4. display_name显示名 发送钉钉消息时显示名字
  5. export_options_plist 导出文件配置使用文件夹中的默认 exportOptions.plist
  6. configuration 默认打release还是debug
  7. mothod 默认打出包类型 development/ad-hoc/appstore
  8. export_path 打包出archive文件导出路径
  9. apiKey蒲公英上传api_key
  10. dingdingWebHook钉钉机器人发消息地址

使用

查看打包命令
python autoarchive.py -h 
usage: Python脚本打包工具 [-h] [-c Release] [-m ad-hoc]

optional arguments:
  -h, --help            show this help message and exit
  -c Release, --configuration Release
                        该选项用来配置打包配置项类型 可选项:Debug,Release 默认:Release
  -m ad-hoc, --method ad-hoc
                        该选项用来配置打包输出类型 development,ad-hoc,app-store 默认:ad-hoc

如果要配置打包类型可以使用使用下面命令
python autoarchive.py -c release -m ad-hoc

不配置参数则走默认打包方式
python autoarchive.py

源文件下载地址:https://github.com/qqcc1388/autoarchive

其他

打包完成后会在指定的archive路径生产一个projectname名字的文件夹,每次打包通过时间来区分保存,打包的ipa文件在对应的export目录下

打包流程解析

通常我们使用XCode打包 要archive 然后导出, 然后上传到蒲公英,再然后拿到蒲公英的截图去打包群里通知打包完成,既然这些动作都是由一个个步骤完成,那么何不使用python写一个脚本来实现整个打包过程

1.clean project

cmd = 'xcodebuild clean -workspace %s -scheme %s -configuration %s' % (
        workspace, scheme, configuration)

2.build project

cmd = 'xcodebuild -workspace %s -scheme %s -configuration %s -destination %s build ' % (
        workspace, scheme, configuration,'generic/platform=iOS')

3.archive project

cmd = 'xcodebuild -workspace %s -scheme %s -configuration %s -archivePath %s -destination  %s archive' % (
        workspace, scheme, configuration, archive_path,'generic/platform=iOS')

4.export archive file

cmd = "xcodebuild -exportArchive -archivePath %s -exportPath %s -exportOptionsPlist %s -allowProvisioningUpdates" % (
        archive_file, ipa_path, export_options_plist)

以上命令是对应的xcodebuild打包命令 利用subprocess执行以上命令,等待返回结果

def build_project():
    cmd = 'xcodebuild -workspace %s -scheme %s -configuration %s -destination %s build ' % (
        workspace, scheme, configuration,'generic/platform=iOS')
    print(cmd)
    process = subprocess.Popen(cmd, shell=True)
    process.wait()
    if process.returncode == 0:
        print('%s.xcworkspace build success!' % project_name)
    else:
        print('build 失败')

导出ipa包上传到蒲公英 利用os.listdir遍历文件夹及其对应的文件,找到ipa文件

def get_ipafile():
    # 遍历ipa_path文件夹,获取.ipa文件
    file_list = os.listdir(ipa_path)
    for file in file_list:
        if file.endswith('.ipa'):
            cur_path = os.path.join(ipa_path, file)
            return cur_path

上传到蒲公英 利用requests配置对应的参数实现ipa文件上传

import time
import requests
# 官方文档
# https://www.pgyer.com/doc/view/api#fastUploadApp


def _getCOSToken(
    api_key,
    install_type=1,
    password='',
    update_description='',
    callback=None
):
    """
    获取上传的 token
    """
    headers = {'enctype': 'multipart/form-data'}
    payload = {
        '_api_key': api_key,  # API Key
        'buildType': 'ios',  # 需要上传的应用类型,ios 或 android
        # (选填)应用安装方式,值为(1,2,3,默认为1 公开安装)。1:公开安装,2:密码安装,3:邀请安装
        'buildInstallType': install_type,
        'buildPassword': password,  # (选填) 设置App安装密码,密码为空时默认公开安装
        # (选填) 版本更新描述,请传空字符串,或不传。
        'buildUpdateDescription': update_description,
    }
    print("获取TOKE中...")
    try:
        r = requests.post(
            'https://www.pgyer.com/apiv2/app/getCOSToken', data=payload, headers=headers)
        if r.status_code == requests.codes.ok:
            result = r.json()
            print("获取TOKEN成功:%s" % result)
            if callback is not None:
                callback(True, result)
        else:
            print("获取TOKEN失败:%s" % result)
            if callback is not None:
                callback(False, None)
    except Exception as e:
        print("获取TOKEN失败:%s" % e)


def upload_to_pgyer(path, api_key, install_type=1, password='', update_description='', callback=None):
    """
    上传到蒲公英
    :param path: 文件路径
    :param api_key: API Key
    :param install_type: 应用安装方式,值为(1,2,3)。1:公开,2:密码安装,3:邀请安装。默认为1公开
    :param password: App安装密码
    :param update_description:
    :return: 版本更新描述
    """

    def getCOSToken_callback(isSuccess, json):
        if isSuccess:
            _upload_url = json['data']['endpoint']
            files = {'file': open(path, 'rb')}
            headers = {'enctype': 'multipart/form-data'}
            payload = json['data']['params']
            print("iPa包上传中...")

            try:
                r = requests.post(_upload_url, data=payload,
                                  files=files, headers=headers)

                if r.status_code == 204:
                    print("iPa包上传成功,正在获取包信息,请稍等...")
                    _getBuildInfo(api_key=api_key, json=json,
                                  callback=callback)
                else:
                    print("iPa包上传失败 %s" % r)
                    print('HTTPError,Code:' + str(r.status_code))
                    if callback is not None:
                        callback(False, None)
            except requests.exceptions.RequestException as e:
                print('iPa包上传失败:%s' % e)
        else:
            pass

    _getCOSToken(
        api_key=api_key,
        install_type=install_type,
        password=password,
        update_description=update_description,
        callback=getCOSToken_callback,
    )


def _getBuildInfo(api_key, json, callback=None):
    """
    检测应用是否发布完成,并获取发布应用的信息
    """
    time.sleep(3)  # 先等个几秒,上传完直接获取肯定app是还在处理中~
    response = requests.get('https://www.pgyer.com/apiv2/app/buildInfo', params={
        '_api_key': api_key,
        'buildKey': json['data']['params']['key'],
    })
    if response.status_code == requests.codes.ok:
        result = response.json()
        code = result['code']
        if code == 1247 or code == 1246:  # 1246	应用正在解析、1247 应用正在发布中
            _getBuildInfo(api_key=api_key, json=json, callback=callback)
        else:
            if callback is not None:
                callback(True, result)
    else:
        if callback is not None:
            callback(False, None)

上传成功后,将返回的信息push到钉钉机器人 通知对应的人查看扫码下载

def send_dingTalk(url, buildQRCodeURL, appVer, buildCreated):
    data = {
        "msgtype": "markdown",
        "markdown": {
            "text": "### 【%s(iOS)】构建成功\n构建类型:iOS\n构建版本:%s\n[下载地址](%s)\n![](%s)\n构建时间:%s" % (display_name,appVer, url, buildQRCodeURL, buildCreated),
            "title": "【%s(iOS)】构建成功" % display_name,
        },
        'at': {
            "isAtAll": False
        }
    }
    headers = {'Content-Type': 'application/json;charset=UTF-8'}
    send_data = json.dumps(data).encode('utf-8')
    print('开始发送钉钉消息...')
    ret = requests.post(url=dingdingWebHook, data=send_data, headers=headers)
    print(ret.text)
    if ret.status_code == requests.codes.ok:
        print('钉钉消息发送成功')
    else:
        print('钉钉消息失败')
posted @ 2022-10-28 15:26  qqcc1388  阅读(512)  评论(0)    收藏  举报