Jenkins项目实战之-MacOS High Sierra自动化打包方案的填坑之旅
前面我介绍了如何在android和iOS实现公司内部app的自动化打包构建的过程。这里写一个关于这个app自动化打包平台从想法到实践再到放机房平稳运行的一个回忆录。总的来说,在jenkins上实现android打包比较顺序,一直没有什么大问题;iOS上实现自动化打包就填了很多坑,查找了很多资料,失败了很多次,看过很多构建失败的日志,回过头来,mac上实现iOS自动打包就一个填坑之旅。下面主要是一些回忆过程中印象深刻的点,记录下来,希望对有需要的人提供参考和帮助。
一 一个测试人员的打包自动化构建思路
我得到的打包需求是这样的:实现Android和iOS自动化打包,支持打不同环境的安装包,打包结束支持邮件或者钉钉群发提醒给相关人员,点击提醒能跳转到安装包保存路径去下载,如果失败,提供日志查看方式。
1. 硬件设备
因为打包服务最终要形成一个机房的主机服务,同时要支持Android和iOS打包,这里建议,选择苹果设备。我选择了Mac mini2,8G i5 1TB硬盘,JD好像4600RMB,我尝试过在普通PC台式电脑安装过黑苹果,最终还是选择购买Mac mini主机,黑苹果主要是在iOS上打包失败,这个部分在iOS介绍。所以,以下是硬件设备清单。
-- Mac mini 主机一台
-- 显示屏,键鼠,连接器(绿联连接器带usb线,可能电压不够,VGA插上没有信号,所以用上了USB先)
-- U盘 8GB ,重装mac系统,拷贝文件等
2. 打包方案介绍
1). Jenkins平台,这不解释
2). 如何实现参数化构建,利用shell脚本的case语句
3). 相关配置文件替代
4). tomcat 7配置一个web文件下载服务
5). 邮件提醒
6). 钉钉提醒
Jenkins平台需要安装相关插件,不在重复介绍,有需要看前面文章。上面步骤2)和3)是联动的。例如我打不同环境测试包,主要是配置文件中某些值或不同。我之前也考虑过直接利用相关脚本去修改配置文件里相关的参数的值。但是这个证明效率不高,经常失败,shell 和python修改配置文件都尝试过。最后直接来简单暴力的,整个配置文件完整替换。例如我配置文件在A,那么我手动准备三份配置文件A1表示测试环境文件,A2表示准生产环境文件,A3表示线上环境文件。结合shell case语句,用户选择什么打包后台环境,就利用linux命令去拷贝对应的A文件去到代码对应A文件路径。做完了这个文件替换任务后,才开始做打包相关工作,这部分都利用相关插件。
提供下载服务,因为本身mac mini就是一台服务器。我选择tomcat 7版本是有原因的,我在tomcat设置了一个docbase的路径,点击可以跳转到这个路径的web页面。所以,打包生成包之后,需要shell命令去把包拷贝到docbase指定的文件夹下。为什么要拷贝呢,我们每次打包都会执行clean操作,不拷贝的话,clean会把前面一次构建的包给删除。tomcat9上同样的配置操作,没有实现docbase在web打开的效果,具体原因不清楚。相关docbase配置,请看前面android打包第二篇内容。
提醒,jenkins提供了邮件提醒,这个很好实现,我前面文章也介绍了如何配置邮件模板。这里重点说下钉钉机器人,钉钉支持根据创建机器人的token id,然后给这个接口发送json数据,就可以往钉钉群发提醒消息。好在,已经有人开发了钉钉提醒的插件在jenkins社区。这个插件对我来说,有一个缺陷。我需要打包成功提醒,点击就可以跳转到我配置的tomcat的docbase页面,这样其他人就可以点击下载。如果打包失败,点击提醒标题就应该跳转到当前失败构建的jenkins地址,这个功能默认是插件实现了。下一篇文章,我会介绍如何针对这个缺点进行二次开发这个钉钉插件。由于钉钉提醒实现了,目前我都抛弃了邮件提醒,很多人没有看邮件的习惯,但是钉钉是公司的办公软件,人人都会看到机器人的提醒,这个提醒效率比邮件要高。
二 Android打包
Android打包比较顺利,基本上没有出现什么错误。如果一定要说有,那就是第一次构建,会根据配置文件提到的一些依赖库进行在线下载。例如根据maven下载各种库到本地,才能支持编译和打包任务。这个过程,可能有一个坑,那就是需要连接v*n才能下载一些Google的库。第二个要注意,你下载的gradle版本要和你们开发写入配置文件的版本一样,我试过最新gradle版本,大体上没有问题,有时候日志来看有些报错信息,但是不影响打包构建。
三 iOS打包
最折腾的就是在iOS打包,最开始的时候,我初步实现了在一台mac 笔记本上打包成功。由于这台笔记本很久,空间只有128G,没法同时支持android和iOS在一个机器上打包,所以不能当做服务器来用。这就有了PC机安装黑苹果的想法,比较新买苹果设备,公司可能审批不过。
好不容易安装上了黑苹果,基本能用,就是显卡驱动和其他驱动没搞定,但是不影响使用。android在黑苹果顺利配置成功,结果iOS失败,黑苹果安装的系统是macos 10.12.6,失败的根本原因就是没有login.keychain文件,但是系统有一个login.keychain-db文件。由于在keychain和profile这个上传界面不支持上传login.keychain-db文件。网上有人说,直接拿login.keychain-db该名称为login.keychain,上传问题解决了,但是构建还是失败。
这个报错,让我浪费了一个星期时间都没有解决,网上根本没有人遇到图中的两个报错。网上大部分都是在旧系统打包。根本没有在最新MacOS High Sierra打包成功的文章介绍。由于当时无法判断login.keychain文件没有是不是黑苹果的原因。最后还是买了一台mac mini的主机盒子。
mac mini主机盒子配置失败记录
前面提到,我安装了tomcat 7版本,然后把jenkins.war拷贝到了tomcat下的webapp目录,启动tomcat之后就相当于启动了jenkins。当时没有注意jenkins的启动后解压的路径是/var/root/.jenkins/,而我当前mac用户名称是mac,也就是家目录是/Users/mac/。新买的mac mini开机,已查看系统,发现是macos 10.12.5,还是当前用户没有这个login.keychain文件。心里咯噔一下,继续配置jenkins和tomcat环境。结果打包还是失败,还是上面这个错误。两天后,查资料,还是无法解决这个问题。然后,下决定,把mac系统降级,这样就肯定有login.keychina文件。因为,我们只有这个方法可以实施,总不可能等jenkins社区更新相关插件能支持上传login.keychain-db吧。关于mac如何降级,看看这个工具介绍os x el capitan,如何制作U盘系统启动,自己网上查资料。
降级后的Mac mini
很高兴,降级后终于可以看到有login.keychian文件。这些先配置iOS打包环境,不管android,iOS能成功,这个任务就完成了80%。继续按照java jdk,xcode,jenkins和tomcat。我依然是采用tomcat下放jenkins.jar,jenkins解压路径依然是/var/root/.jenkins/, 构建打包,还是失败,还是上面失败的图片,依然是这两行报错。想了很久,心都累了,突然脑袋想到这两句报错的真正含义。就是出在jenkins解压后路径是/var/root/.jenkins。由于jenkins打包会去拷贝login.keychian文件到项目工程的根目录,当前用户没有权限去操作/var/root/.jenkins目录。试过了给这个目录和目录下所有文件添加 777权限,构建还是失败。这个时候,突然想起来,我最初还是构建成功的是,利用java -jar jenkins.war环境,也就是说tomcat下挂jenkins.war和java -jarjenkins.war启动生成的解压路径是完全不同。通过java -jar jenkins.jar生成的解压路径是/users/mac/.jenkins/
1)jenkins单独启动,占用端口8080,java -jar jenkins.war 方式启动
2)Tomcat修改启动端口变成8088,docbase访问地址是http://localhost:8088/download
其中 http://localhost:8088/download/iOS表示iOS打包下载路径,http://localhost:8088/download/android/表示android打包下载路径,http://localhost:8088/download/oldbuilds表示放旧的包,我每次构建之前,都会把/android或者/iOS上一次构建拷贝过来的包给剪切到/oldbuilds文件夹。这样就有一个好处,构建成功提醒,用户点击会跳转下载页面,里面只有一个安装包。
关于login.keychain解锁失败的错误
有时候上面报错的这张截图差不多位置提示无法解锁的提示。我遇到这个问题是,由于,我们app开发者账号添加了公司内部新的iphone手机到白名单记录,造成profile和证书不匹配。我打包这台机器不是管理证书的主机,是一个从机器。所以,需要在主机导出相关证书文件,然后在mac mini重新配置证书,这个问题就解决。
关于打包导出的证书
如果看导出的签名的profile文件呢,这个profile文件是需要upload在jenkins插件的。mac mini自动化打包前台是,需要安装一个xcode软件,需要打开当前你这个项目的工程,而且勾选自动管理签名,勾选Edit Scheme 菜单里要勾选Share。下面这张图是在本机xcdoe软件上打包导出过程的截图(xcode版本9.1)
通过点击上面箭头,可以打开你本地profile文件夹,告诉你哪个profile文件是可用的。这样你就可以上传这个profile文件到jenkins中的keychain和profile管理那个界面。
关于我这种打包的缺点
缺点主要在于,我是拉取源码后,拷贝本地提前做好的配置文件去替换刚刚拉取代码后的一个配置文件。如果开发动了这个配置文件,而没有告诉我,那么打包就可能失败后者造成拉取代码失败的假象。所以,需要和开发约定好,shell脚本拷贝替代的配置文件,只放打包配置相关的代码,不能放其他代码。我就因为这个原因,在iOS打包失败过。原因就是开发在我调用替换的配置文件新加了内容,而我是用的配置文件去覆盖了刚拉取下的新的配置文件。解决方法就是,把相关打包配置单独提出到一个新配置文件,以后开发都不能动里面的内容。
上面的打包方案在macOS High Sierra成功实现,我们是先降级系统版本,拿到login.keychian文件,然后再升级到最新系统macOS High Sierra,因为我需要升级到xcode9来打包支持iphone x,所以这里必须要升级到最新版本的系统。当然,如果直接在最新系统,通过login.keychain-db重命名为login.keychian文件上传这种方式我没有尝试过,确实不知道结果。还有jenkins安装方式,我是通过jenkins.war方法,网上也有jenkinks.dmg
这个方法会在当前系统新建一个jenkins的用户,这种情况下会不是出现文中报错的情况,我也不知道。如果花了很多时间还没有实现,建议参考我的方案,至少可以成功实现。