20160815

周末看了《大话测试 2》突然有想法把公司的 IOS 打包做一下自动打包和分发,于是今天就开始行动啦!整个过程有点波折,也遇到了不少问题,记录下来分享给大家。

背景

CI(持续集成)是现在非常流行的软件开发实践,可以自动化的持续打包部署代码或者安装包,减少了手工干预,大大的提高了工作效率。因此,不论如何,都需要对它做一些了解和实践。

每次开发完,我们要做的是先找开发打包,打完包后拿来放到 fir.im 上,再生成二维码,最后把二维码做到我们内部分发的网站上分发,然后才能开始测试。整个流程很长,如果当天有很多小问题不断的修复,那感觉真是坑爹,一两个小时时间就浪费在这个过程上。使用 CI 能够很好的解决这个问题。

环境

我使用的是现在使用比较普遍的 Jenkins。打包的对象是 IOS。所以首先,你必须有一个 Mac。


操作系统:Mac OS X EI Caption 10.11.5

Jenkins 版本:2.17


安装

Jenkins 的安装非常简单了,只要直接安装 DMG 就行了。安装完毕之后,进入http://localhost:8080就可以看到 Jenkins 的配置界面了,由于是 Web 端配置,所以使用起来非常友好。

一下两个命令可能会经常用到,由于安装 Jenkins 的时候,默认是自动启动的,有时候为了减少不必要的资源消耗,可以关闭 Jenkins。

Start Jenkins: sudo launchctl load /Library/LaunchDaemons/org.jenkins-ci.plist
Stop Jenkins: sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist

第一条命令是启动,第二条命令是关闭。

工作流

本次使用 Jenkins 的工作流如下图所示(Jenkins 不仅仅只有这些功能,这些只是本次使用的功能)

Jenkins工作流

构建工程

使用 Jenkins 部署打包 IOS 程序有一个最大的前提,就是你必须要有一个 Mac,否则免谈。

Jenkins 的安装就不说了,百度一下一大堆,首先要新建一个自由风格的项目。

项目配置

项目名称和描述都是给自己看的,因此可以凭自己的喜好填写,只要自己能看得懂即可。接下来的构建方式我并没有使用,因为对我来说确实用不到,应用打包完成上传 fir.im 之后,基本上这个包就可以丢弃了。有需要的可以按需选择。

源码管理,我选择 SVN,其他也是一样的,配置仓库地址和账户。

Credentials是用户,右侧的 ADD 按钮可以添加用户,其他项默认配置即可。

构建触发器也是非必须选项,如果不配置则需要手工触发,我这里配置 5 分钟检查一次代码仓库。

具体的配置规则百度即可。

接下来是 Xcode 的配置,IOS 打包有两种方式,一种是命令行打包,直接写打包脚本即可。另一种是 Jenkins 的 Xcode 插件来实现打包。我使用的是 Xcode 插件来配置,因为我们的开发说他对项目的工程架构有做过改动,我也尝试过一下使用命令行,由于对 shell 一窍不通,所以还是放弃了。

Target是构建的目标。如果留空,那么就会构建所有的目标。

Clean before build这个选项建议勾选,构建之前最好 Clean 一下,至于为什么,我也不知道,我们开发之前打包的时候没有 Clean,有时候会出一些莫名其妙的 bug。

Configuration此处填写 Release 或者 Debug,指的是 IOS 打包的类型,Debug 版本还是 Release 版本。

Pack application and build .ipa需要打钩,因为我们需要打包成 ipa 文件来安装。

ipa filename pattern打包成 ipa 文件的名称,就是最终的 xxx.ipa。

Output directory打包输出的路径,我这里填写的${WORKSPACE}指的是/Users/Shared/Jenkins/Home/workspace

其他项我使用的都是默认的,需要的请自己研究,项目右侧的问号都有很明确的提示,唯一不爽的就是提示都是英文的。。。。。

这部分应该算是比较重要的地方,因为这里是配置打包签名的地方。

首先需要在钥匙串访问中找到开发者证书对证书进行权限开放,否则 Jenkins 无法获取证书。

然后在配置项中做如下配置。

Keychain path是固定填写${HOME}/Library/Keychains/login.keychain

Keychain password指的是你的授权密码,不是证书密码。

注意:${HOME}目录指的是 Jenkins 的根目录,也就是/Users/Shared/Jenkins,如果你的 jenkins 是新装的,你会发现 Library 目录中压根就没有 Keychains 目录。你需要去/Users/SvenWeng/Library目录下把 Keychains 目录复制过来。

Xcode Project File是项目的地址,xxx.xcodeproj 的地址。

Build output directory是构建后的输出地址,我这里设置于 ipa 文件地址一致。

注意:如果你的项目是使用.workspace。请使用Xcode Workspace File,留空Xcode Project File.

到此,Xcode 插件的配置就完成了。

构建后执行

这里我使用了Post-Build Script Plug-in插件。

进入我们构建后的目录,使用 fir-cli 的命令把打包后的 ipa 文件上传到 fir.im 上,其中-T参数是使用 fir.im 的 token,可以注册后登陆 fir.im 查看自己的 token。-Q参数是上传完毕之后把对应的二维码下载到当前目录下。

下方还有一个勾选项Execute script only if build succeeds。构建成功才执行这个命令,也就避免了重复上传的问题。

邮件通知

我使用的是 Jenkins 自带的邮件功能,看勾选的结果是构建失败才会发送邮件,经过我自己的测试,构建成功也能收到邮件,不过我配置的 163 服务邮箱经常坑爹的拒绝我使用 smtp 发送邮件。

邮件的内容还是比较人性化的,比如如果档次构建 SVN 有变动,Jenkins 会把变动日志和打包的日志一起发给你,比如这样

至此,整个构建就结束了,可以手工触发来看看结果。

蓝色表示构建成功,红色表示构建失败。

一些注意点

配置过程中总是会出这样那样奇奇怪怪的错误。我整理了一下我自己遇到的问题。

好吧,其实我也不太了解,翻译上是计划名称。其实这个是 Xcode 的一个配置(不知道这么说准确不准确)。进入方式:Xcode menu > Product > Scheme > Edit scheme点击Manage Scheme

被我框起来涂掉的地方就是 Scheme 名称。

这个报错还是由于证书的问题,Xcode 工程的证书放在/Users/SvenWeng/Library/MobileDevice/Provisioning Profiles这里,而 Jenkins 的根目录是没有这个东西的,之前我放的是一个错的证书,所以导致了这样的报错。需要把工程证书拷贝到 Jenkins 根目录下的Library中。

这个报错是由于你解锁keychain的密码不正确,在配置项中需要配置授权密码(也就是你的 mac 的登录密码),而不是证书的密码。

这个报错很明显了,我的工程使用的是.xcodeproj,而不是.scworkspace,因此在 Xcode 插件配置的时候需要配置Xcode Project File而不是Xcode Workspace File

这个报错也很明显了,是 SVN 配置的有问题。

这个报错是 target named 指定错误,检查一下 Xcode 的工程是否有相关配置,我报这个错是因为正确的名字是 xxx_iOS,而我打成了 xxx_IOS,就是一个大小写的区别。

后续

后续可以做的事很多啦,比如写个 Python 脚本来处理本地的文件,把打包的内容做一下归档,然后生成的二维码通过 FTP 方式上传到内部的分发网站上。编写自动化单元测试,每次代码改动的时候做一下自动化测试,把 Android 客户端也用这种方式自动打包出来等等。。。。

总结

持续集成看上去很高大上,其实走一遍流程,也并不是那么困难,困难的地方 Jenkins 都帮你处理好了。

配置的时候如果是 IOS 开发人员,或者对 IOS 有一定的了解,那么配置起来应该是非常快的,否则最好有一个人来指导你,今天配置的时候我们的 IOS 开发总能在关键点上给一个方向,省去很多时间,不然现在可能都还配不出来,很多报错网络上找不到,即使找到了,大多也是英文的,虽然看得懂,但是看起来总是有点不爽。

耐心,耐心,耐心,在配置过程中一定会有各种各样奇奇怪怪的报错,有时候看起来很烦,但是一定要有耐心,多静下心来想想,多看看日志,日志的报错一般来说都是非常清晰准确的。

多尝试,配置完就构建一次,反正构建失败了,电脑不会爆炸,世界也不会毁灭。整个配置过程构建失败了 30 次,直到第三十一次才构建成功。

当完成之后,可以省去很多很多很多处理这些杂事的时间。


↙↙↙阅读原文可查看相关链接,并与作者交流