iOS脚本系列之一键打包上传到蒲公英

日常开发中,我们经常会遇到为其他人员安装测试包的情况,早期的时候,都是用的最笨的方法,把每个人的手机拿过来,一个一个的为他们安装,这个过程确实即浪费时间,又浪费精力。

后来出现了一些持续继承的工具,比如jenkins,以及一些测试包分发的平台 蒲公英fir.im,能够通过网页安装ipa包。

通过jenkins我们能够配置,一键打包,上传到上面的分发平台,并且发邮件通知人员安装。其实jenkins不过是给我们提供了一个可视化的配置界面,底层还是组合调用各种脚本命令行来完成工作的。

今天这篇文章我们就来实现通过一个脚本来完成一键打包上传蒲公英,并发送邮件提醒测试人员的整套流程

Build

打包过程使用xcodebuild命令,支持

  • debug,release环境
  • workspace或普通工程打包

Build命令

1
xcodebuild

参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//build project
-project name.xcodeproject
-target Name
-all targets

//build workspace

-workspace xxx.xcworkspace
-scheme myScheme

//configuration

-configuration Debug/Release/或自定义的configuration

//输出目录 build workspace 默认的build 输出目录在系统develop 目录里面,可以通过设置 CONFIGURATION_BUILD_DIR 来重定向输出目录,注意这个目录一定要用绝对路径,不然一直报链接错误

CONFIGURATION_BUILD_DIR=/xxx/build

//build之前clean

clean build

完整用例

build Project

build 工程默认输出的build 目录是在当前文件夹的build 里面

1
xcodebuild -project name.xcodeproj -target target1 -configuration Debug clean build

build Workspace

需要指定CONFIGURATION_BUILD_DIR

1
xcodebuild -workspace XXX.xcworkspace -scheme "scheme1"  -configuration Debug clean build CONFIGURATION_BUILD_DIR=/Users/name/Desktop/宿舍购/project/tmp

打包ipa

上一步将项目build成功得到了app文件,接下来需要将app文件打包成ipa。
通常ipa文件我们可以将其后缀名改为zip通过zip的方式解压,解压之后得到一个Payload文件夹,里面就是我们的app文件。

打包ipa的方式有多种,我们这里使用最简单的压缩命令。

假设我们得到的app文件为test.app,通过如下命令打包为ipa

1
2
3
4
mkdir -p ipa/Payload
cp -r test.app ipa/Payload/
cd ipa
zip -r test.ipa *

上传蒲公英

上传蒲公英的过程也是非常简单,蒲公英为我们提供了现成的接口,我们只需要通过curl命令上传即可

1
curl -F "file=@$IPA_NAME" -F "uKey=$PUGONGYING_UKEY" -F "_api_key=$PUTONGYONG_API_KEY" http://www.pgyer.com/apiv1/app/upload

上传成功后,蒲公英会解析包的基本信息,比如版本号,名字,包的下载地址(扫码),直接安装地址等等以json的形式返回。我们需要将这些信息解析出来。后面发邮件的时候会做为邮件内容

所以我们的命令变成了如下

1
2
UPLOAD_CMD='curl -F "file=@$IPA_NAME" -F "uKey=$PUGONGYING_UKEY" -F "_api_key=$PUTONGYONG_API_KEY" http://www.pgyer.com/apiv1/app/upload'
UPLOAD_RESULT=$(eval $UPLOAD_CMD)

这样上传的结果就保存到了UPLOAD_RESULT变量中了

解析json获取属性
由于本人对shell并不熟悉,这里解析json获取属性用了非常简单粗暴的方式,即通过字符串匹配,截取,得到某个key对应的属性,如果有高手,希望能告知,shell语言如何正确的解析json

1
2
3
4
5
6
7
8
9
10
appKey=`echo $UPLOAD_RESULT | grep -o  '"appKey":"[0-9a-zA-Z]\{4,\}"' | tr '\"' ' ' | sed 's/[ ]//g' | sed 's/appKey://'`

shortUrl=`echo $UPLOAD_RESULT | grep -o '"appShortcutUrl":"[0-9a-zA-Z]\{4,\}"' | tr '\"' ' ' | sed 's/[ ]//g' | sed 's/appShortcutUrl://'`

installUrl="http://www.pgyer.com/"$shortUrl
directIntallUrl="itms-services://?action=download-manifest&url=https://ssl.pgyer.com/app/plist/"$appKey

appVersion=`echo $UPLOAD_RESULT | grep -o '"appVersion":"[1-9][.0-9]\{1,\}"' | tr '\"' ' ' | sed 's/[ ]//g' | sed 's/appVersion://'`

appBuildVersion=`echo $UPLOAD_RESULT | grep -o '"appBuildVersion":"[0-9a-zA-Z]\{1,\}"' | tr '\"' ' ' | sed 's/[ ]//g' | sed 's/appBuildVersion://'`

由于后面发送邮件使用python脚本,与shell不在一个上下文环境,所以这里的变量需要导出才能在python里面获取到

1
2
3
4
5
export appName
export appKey
export appVersion
export appBuildVersion
export appShortcutUrl

python发送邮件

首先在shell命令行调用python脚本

1
2
pythonPath=$CURRENT_PATH"/sendMail.py"
python $pythonPath

python脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# coding=utf-8
import time
import json
import mimetypes
import os
import smtplib
from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart


# 运行时环境变量字典 用于获取前面导出的变量
environsDict = os.environ


mail_receiver = ['xxxxxx.com','xxxxxx.com']

#根据不同邮箱配置 host,user,和pwd
mail_host = 'smtp.exmail.qq.com'
mail_user = 'xxxxx'
mail_pwd = 'xxxx'
mail_to = ','.join(mail_receiver)

msg = MIMEMultipart()


appName = environsDict['appName']
appKey = environsDict['appKey']
appVersion = environsDict['appVersion']
appBuildVersion = environsDict['appBuildVersion']
appShortcutUrl = environsDict['appShortcutUrl']



timeStr=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
environsString = '<h3>本次打包相关信息</h3><p>'
#environsString += '<p>ipa 包下载地址 : ' + ipa_file_tomcat_http_url + '<p>'
environsString += '<p>应用名称 : ' + str(appName) + ' <p>'
environsString += '<p>打包时间 : ' + timeStr + ' <p>'
environsString += '<p>版本号 : ' + str(appVersion) + ' <p>'
environsString += '<p>Build号 : ' + str(appBuildVersion) + ' <p>'
environsString += '<p>你可从蒲公英网站在线安装 : ' + 'http://www.pgyer.com/' + str(appShortcutUrl) + '<p>'
environsString += '<li><a href="itms-services://?action=download-manifest&url=https://ssl.pgyer.com/app/plist/' + str(appKey) + '">点我直接安装</a></li>'
message = environsString
body = MIMEText(message, _subtype='html', _charset='utf-8')
msg.attach(body)
msg['To'] = mail_to
msg['from'] = mail_user
msg['subject'] = '最新打包文件' + timeStr

try:
s = smtplib.SMTP()
s.connect(mail_host)
s.login(mail_user, mail_pwd)

s.sendmail(mail_user, mail_receiver, msg.as_string())
s.close()

print 'send email success'
print 'mail send ',mail_receiver
except Exception, e:
print e