iOS打包自动化实践(三)

上一篇:iOS打包自动化实践(二)

自动打包项目优化

本篇文章介绍了jenkins email通知、使用swift脚本自动升级build号、自动上传蒲公英并自动发送链接到钉钉群等功能。

添加E-mail通知

1、安装Jenkins插件:系统管理-管理插件中,搜索"Email-ext plugin"和"Email-ext Template Plugin"并安装。

2、在"系统设置"中找到"邮件通知"和"Extended E-mail Notification", 163邮箱配置如图(注意:如果邮箱开启了客户端授权码,需要填写授权码而不是密码, 即"设置 -->POP3/SMTP/IMAP-->客户端授权密码"):

iOS打包自动化实践(三)_第1张图片
邮箱.png

3、在项目配置的"构建后操作"中,添加"Editable Email Notification",在"Project Recipient List"中填写需要收取邮件的邮箱地址,"Default Content"中可以直接使用jenkins的全局环境变量, "${BUILD_STATUS}", "${BUILD_URL}"等,填写

\${SCRIPT, template="groovy-text.template"}

可以收到基本信息,也可以点击如图链接,查看所有可用的环境变量并在邮件内容中使用。

iOS打包自动化实践(三)_第2张图片
环境变量.png

4、点击"Adcanced Settings-Add Trigger",可以设置发送邮件的触发时机,设置"Send To"为"Recipient List".

5、点击保存,完成。

自定义Email内容

适用场景: 需要在脚本中生成log并发送邮件。比如脚本中有打包,下载metadata,上传ipa三步,当任务build失败时,我们需要在邮件中打印log来快速定位是哪一步出了问题。原理是先在shell中把log写入文件,再把文件内容读取到邮件的内容中。

1、在"Execute shell"中把log写入文件:

echo "test log" > /file/path/logFile.txt

2、在"Editable Email Notification-Default Content"中写如下代码:

${FILE,path="/file/path/logFile.txt"}

自动升级build号和自动获取版本号

由于swift是可以用来写脚本的,再加上iOS程序猿都比较熟悉swift语法,因此这里自动升级build号的工作我编写了一个简单的swift脚本来实现,十分的方便,这里语法不多介绍了大家都会,简单介绍下如何把swift脚本跑起来。

1、创建modifyBuildNumber.swift文件, 并将其放在远程CI机器上。

2、文件头部添加代码, 指定编译器:

#!/usr/bin/env xcrun swift

3、接下来就可以愉快的编写swift代码了,通过读取并修改info.plist中的CFBundleVersion字段来达到自动升级build号的功能。若修改失败,执行代码"exit(1)", 修改成功不执行或者执行代码"exit(0)"。

4、在shell中执行swift脚本并获取swift脚本执行结果:

#获取swift脚本路径
modify_build_number_script="file/path/modifyBuildNumber.swift"

#修改脚本权限为可执行
chmod +x $modify_build_number_script

#获取脚本执行结果
RESPONSE=`$modify_build_number_script`

#判断上一条命令是否执行成功。
if [ $? -ne 0 ]; then
    echo "swift脚本执行失败:$RESPONSE" 
fi

在swift脚本中执行print命令打印的log, 会作为swift脚本的执行结果,并赋值给RESPONSE这个变量。(但是我发现通过这种方式只能获取一行,对于目前的需求肯定是够用了。不过如果大家有更好的办法欢迎评论告诉我).

自动获取版本号更加的简单,使用swift脚本直接读取info.plist中的CFBundleShortVersionString字段,并使用print命令打印,在shell中直接使用变量获取swift脚本执行结果即可(获取的版本号主要用于deliver命令)。

自动触发打包任务

实现了自动修改build号和自动获取版本号的功能之后,是不是发现这个系统需要人工操作的地方更少了?接下来介绍如何自动触发打包上传任务。

我们公司使用了TestFlight进行内测期间的回归测试工作,因此一旦有新的代码合并进入release-test分支,就需要打包上传到TestFlight。这个功能利用jenkins也很好实现。

1、进入任务的配置界面,在"构建触发器"栏中勾选Poll SCM,并填写代码:"* * * * *", 这代表每分钟jenkins自动检测一次你在"源码管理-Branches to build"栏中填写的分支是否有代码变化,一旦有变化即触发自动打包。

2、检测时间间隔可以自行调整,比如"H * * * *":每小时检测一次,"H */2 * * *":每两小时检测一次。

3、上传到iTC之后,testFlight每次都会询问是否修改了加密协议,不能自动发布testflight版本,这时需要在info.plist中加入字段"App Uses Non-Exempt Encryption", 值设置为NO。 即可实现每次上传之后都会自动触发testflight版本发布。

jenkins中的全局环境变量"BUILD_CAUSE"代表了触发原因,值为"SCMTRIGGER"时表示自动触发,"MANUALTRIGGER"表示手动触发。

打包脚本的版本管理

项目优化到这一步我们发现脚本越来越长,而且增加了几个swift脚本,还有ExportOptions.plist文件,已经略显庞大。而且脚本直接写在jenkins的"Execute shell"中很不安全,一旦误删前功尽弃。这时可以考虑给所有的打包脚本和工具放在一个单独的Git仓库中,每次触发构建时拉取最新的脚本和项目代码,进行打包。这样做方便自动打包项目的维护和移植。

1、使用Execute shell中的代码建立archive_upload.sh文件,并把ta和刚刚建立的swift脚本,ExportOptions.plist文件放在一起,单独建立git仓库。

2、在"Jenkins-插件管理"中下载插件"Multiple SCMs Plugin"

3、在项目配置页面,"源码管理"中勾选"Multiple SCMs",分别配置项目git地址和脚本git地址,并通过"Additional Behaviours-Check out to a sub-directory"分别建立下级文件夹。

4、修改Execute shell为:

#!/bin/sh

root_path=`pwd`
project_path="$root_path/ProjectPath"
script_path="$root_path/AutoPackScripts/archive_upload.sh"

chmod +x $script_path

#执行脚本
$script_path\
    --projectPath $project_path\
    --zhHans $release_notes_zhHans\
    --zhHant $release_notes_zhHant\

5、给archive_upload.sh脚本增加参数解析功能,shell脚本的参数数量和名称是可以任意拓展的。在archive_upload.sh中添加如下代码即可解析:

while [ -n "$1" ]
do
    case "$1" in
    --projectPath)
        #工程目录
        project_path=$2
        shift
        ;;
    --zhHans)
        #简中发版文案
        release_notes_zhHans=$2    
        shift
        ;;
    --zhHant)
        #繁中发版文案
        release_notes_zhHant=$2
        shift
        ;;
    *)
        ;;
    esac
    shift
done

企业包自动上传至蒲公英并自动发送下载链接到钉钉群

到现在我们的项目已经可以自动打release包上传到iTC了,那么自动打企业包只需要更换证书和修改ExportOptions.plist文件即可,这里不多介绍,直接介绍如何自动上传到蒲公英并发送二维码到钉钉群的功能。

假设你的项目已经可以成功打出企业签名的包并且导出了ipa

1、在Jenkins-插件管理中安装插件"Upload to pgyer".

2、在项目配置的"构建"中,点击"添加构建步骤-Upload to pgyer", 并填写api_key,在"file wildcard"中填写导出的ipa路径.

iOS打包自动化实践(三)_第3张图片
蒲公英配置.png

3、在你的钉钉群中添加机器人,并复制其webhook链接。

4、在jenkins上创建一个新的任务"DingTalk_Sender", 直接在"Execute shell"中写如下代码:

#!/bin/sh

curl 'https://oapi.dingtalk.com/robot/send?access_token=xxx' \
   -H 'Content-Type: application/json' \
   -d '
  {     "msgtype": "link", 
        "link": {
        "text":"测试", 
       "title": "测试", 
        "picUrl": "", 
        "messageUrl": "https://www.pgyer.com/xxxx"
    }
    
  }'

curl填你的机器人的webhook链接, messageUrl字段填写你的项目在蒲公英的地址。

4、回到你的打包上传任务中,在"构建后操作"中,添加"Build other projects",填写"DingTalk_Sender".这样就使两个任务相关联,执行完上传后即自动执行DingTalk_Sender任务。

FAQ

1、邮箱配置时,发送测试邮件报错:javax.mail.authenticationfailedexception: 535,有两种可能:

  • 密码填写错误
  • 邮箱开启了客户端授权码,但是密码没有填写授权码而是填写了邮箱密码

2、邮箱配置成功且测试邮件发送成功,但是build成功之后发送邮件时控制台输出显示:Connection error sending email, retrying once more in 10 seconds...并且发送邮件失败。

在jenkins的系统设置中找到"Extended E-mail Notification",并按照之前的配置重新配置一遍。

Note also that depending on your plug-in set up, you may have another place to configure SMTP server. For example under "Manage Jenkins" -> "Configure System" -> "E-mail Notification".

That is not needed for this particular plug-in but it may lead you think you have everything done, while it is not :)

3、配置多个SCM之后,只要有一个仓库发生变化都会触发Poll SCM自动构建,如何使其忽略某个仓库?

在"源码管理"中,在该仓库下的'Advanced clone behaviors'中,选择'Polling ignores commits in certain paths',并在'Excluded Regions'中填写'.*'。

iOS打包自动化实践(三)_第4张图片
忽略某个repo.png

下一篇:iOS打包自动化实践(四)

你可能感兴趣的:(iOS打包自动化实践(三))