使用jenkins有将近三四个月了,为了支持iOS打包,网上有开源的工具集fastlane,就简单总结一下,使用的心得和过程中遇到的坑。。。。
一、打包
下载fastlane,就三个命令:
sudo gem update --system sudo gem install bundler sudo gem install fastlane
可以查看一下 fastlane -v的版本,我们打包主要用到gym和上传命令pilot,其他工具略有研究,但是未深入,还要提醒,我都是用的命令行格式,未使用官方推荐的Fastfile的方式,主要是我对ruby不够了解,因为我也是个大菜鸟。附上打包命令。
gym打包,需要讲解的不多,DEVELOPMENT_TEAM等等解释,可以详细看这里https://dpogue.ca/articles/cordova-xcode8.html
需要提醒的是 xcpretty_report_josn可以输出oclint需要的xcpretty执行之后的内容,这里可以oclint集成到一起。
DEVELOPER_DIR="/Applications/Xcode.app" gym --workspace ${workspace_path} --scheme ${scheme} --clean true --configuration ${configuration} --xcargs "PRODUCT_BUNDLE_IDENTIFIER='${bundle_id}' DEVELOPMENT_TEAM='${DEVELOPMENT_TEAM}' PROVISIONING_PROFILE_SPECIFIER='${PROVISIONING_PROFILE_SPECIFIER}'" --export_method ${export_method} --archive_path ${archive_path} --codesigning_identity "${rightDistributionSign}" --xcpretty_report_json "${json_path}" --export_options ${ExoptionPlist} --output_directory ${ipa_path} --output_name ${ipa_name} || exit
二、集成
讲讲其他遇到的坑和解决方案。
由于主要使用fastlane中gym打包,但是这次需要注意的我们的需求是:
- 需要分别打inhouse,adhoc,appstore的包
- inhouse和adhoc作为内测,需要更换显示图标,加上内测字样。
- inhouse包需要上传蒲公英(之前选择的Fir因为部分收费要求放弃了),需要跟slack对接,并且自动推送。
1、分别打三种包,对证书和rightProvision了解的不够透彻?
解决:把三种证书都从开发那里要过来,然后将自己的APPLE ID升级到开发者Admin状态,就具有了三种证书的使用权限,然后跟开发一一对接,对每个包分别对应的证书了解并整理,打包的时候一一对应上就好。这个过程中,收获的是对xcodebuild的method参数有更深的了解,其实inhouse,adhoce,appstore分别对应的打包方式是enterprise,ad-hoc,app-store。
2、需要更换inhouse的图标?
解决:之前想通过是打包的时候指向不同的target,后来的解决方案是直接替换。
for file in os.listdir(appIconPath): if ".png" in file: for appicon in os.listdir(replaceAppIconPath): if file == appicon: shutil.copy(replaceAppIconPath+'/'+appicon, appIconPath+'/'+file)
但是需要注意的是像素和尺寸需要保持一致,设计同学的帮忙很必要。
3、和slack对接
解决:其实我觉得slack真的非常好用,因为它提供了各种整合持续集成的api,这里特别佩服我们老大对这块内容的重视,slack和jenkins集成非常方便。
只是网速有点不靠谱。slack api地址:https://api.slack.com/docs/message-guidelines
附上我写的脚本,借助slack web api推送信息到slack,并且可以取出jenkins中执行者的信息:
#coding=utf-8 import sys import time import requests import re from slacker import Slacker def send(job_url, job_name, starters, build_timestamp, workspace, build_cause, git_branch, change_log, text, userid): """执行结果推送slack,可选个人和channel""" api_token = "xxxx" slack = Slacker(api_token, 100) data = [{ "fallback": "Required plain-text summary of the attachment.", "color": "#36a64f", "fields": [ { "title": "Job name", "value": job_name, "short": True }, { "title": "Build Trigger", "value": starters, "short": True }, { "title": "Build Time", "value": build_timestamp, "short": True }, { "title": "Build Workspace", "value": workspace, "short": True }, { "title": "Root Build Cause", "value": build_cause, "short": True }, { "title": "GIT_BRANCH", "value": git_branch, "short": True }, { "title": "Job url", "value": job_url, }, { "title": "CHANGE_LOG", "value": change_log, } ], "footer": "XX公司", "ts": time.time() } ] try_times = 0 while try_times < 5: try: slack.chat.post_message(userid, text=text, attachments=data) return "push to slack failed" except Exception as e: time.sleep(50) try_times += 1 if try_times >= 5: raise Exception('push to slack failed') def get_content(job_url): """取出console log全部内容""" url = job_url + "consoleText/api/json" headers = { "Content-Type": "application/json", "Accept": "application/json" } response = requests.get(url, auth=("xx", "xx")) assert response.status_code == requests.codes.ok return response.content def get_trigger(result): """取出构建者""" trigger_user = re.findall(r"Started by", result) trigger_other = re.findall(r"Triggered by", result) starters = "" if len(trigger_user) > 0: starters = re.findall(r"Started by(.*)", result)[0].lstrip() elif len(trigger_other) > 0: starters = re.findall(r"Triggered by(.*)", result)[0].lstrip() return starters if __name__ == '__main__': if len(sys.argv) >= 2: job_url = sys.argv[1] job_name = sys.argv[2] build_timestamp = sys.argv[3] workspace = sys.argv[4] build_cause = sys.argv[5] git_branch = sys.argv[6] text = sys.argv[7] userid = sys.argv[8] change_log = sys.argv[9] result = get_content(job_url) starters = get_trigger(result) result = get_content(job_url) starters = get_trigger(result) send_userid = ["#xx", userid] for i in send_userid: send(job_url, job_name, starters, build_timestamp, workspace, build_cause, git_branch, change_log, text, i)
然后构造请求,发送即可,详细不表。
4、因为我们app两个平台用的xcode版本不一致,需要升级到xcode8,需要将自动管理改为手动管理证书。
sed -i '' 's/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/g' "$project_path/project.pbxproj"
5、pod install总是出现问题,分析可能是因为网络或者本机pod安装有问题。
若是pod问题,可以通过升级gem解决。
sudo gem update --system sudo gem install -n /usr/local/bin cocoapods
最后
我知道我写的可能并不好,排版可能也不漂亮,但是是我们已经落地在用的工程,后续再加上持续集成jenkins中遇到的问题,请大家轻拍。谢谢。
再附上我们推送的截图。
本文暂时没有评论,来添加一个吧(●'◡'●)