Xcode Server是苹果官方提供的持续集成方案,在Xcode 9之前就已经存在,不过需要在Mac App Store下载并安装OS X Server(付费软件),使用起来比较繁琐。在Xcode 9中,Xcode Server被内置在了Xcode中,于是整个CI环境搭建过程也大大的简化了。
Xcode Server的优势
1.免费
2.支持OTA安装
3.和手动打包使用相同的证书
需要的工具
为了使用此教程,你需要:
- 一台Mac,并安装Xcode 9.0或者更高的版本
- 苹果开发者账号
搭建基本的持续集成环境
接下来我们要搭建一个基本的持续集成环境,这个集成环境可以:
- 拉取制定仓库的特定分支的代码
- 指定触发CI的条件
- 执行Archive操作,并导出Ad-Hoc签名的安装包
- 将此安装包上传到79服务器,供测试人员去下载安装
第1步,开启Xcode Server
打开Xcode->Preferences->Server & Bots,点击显示为OFF的开关,输入管理员密码后,在弹出的窗口中选择Integration User。苹果建议是使用一个特定的,非管理员权限的用户,不过也可以使用当前登录的用户。在这里,可以直接选择当前登录用户。
点击Continue后,会去配置并启动Server,完成以后,界面如下:
至此,Xcode Server就已经启动了。可以根据自己的需要,对Server进行配置,暂时我们不用修改任何设置。
第2步,添加Bot
2.1 在Xcode中打开项目,点击Product->Create Bot...
要创建Bot,必须在打开项目的状态下,否则'Product->Create Bot...'项是灰色的,无法点击。
2.2 连接到服务器
在弹出窗口中,可以为Bot命名,然后从下拉框中选择'Add New Server...'。
在接下来的界面中,从列表中选择Server,然后点击'Next'。
然后,输入用户名,密码,点击'Add'。
在这里,我选择的是作为'Registered user'的身份连接到Server,然后输入当前登录用户的用户名和密码。回想一下,在开启Server的时候,我们选择的Integration User是当前登录用户。
如果选择'Guest',虽然也可以,但是之后会发现,无法对创建好的Bot进行编辑。
这一步的结果,实质上是创建了一个Xcode Server类型的Account,并添加到Xcode中。
2.3连接到代码仓库
首先你的项目要使用git,Xcode能直接读取你的项目的仓库信息。在下面的界面中,点击Sign In...,输入git账号密码登陆之后,可以从下拉框中选择具体的分枝,然后点击Next。
2.4设置构建配置
Scheme: 选择要构建哪个scheme,被构建的scheme必须是共享的。所以如果scheme是未共享的状态,请保持'Share and commit scheme'被选中,Xcode会自动设置scheme为共享状态。
Actions:指定要执行哪些动作。一共有3类,Analyze(代码静态分析),Test(测试), Archive(打包)。
针对Export,需要选择'Use Custom Export Options Plist',因为如果使用默认选项,打出来的包总是用iPhone Developer的证书进行的签名,无法打出Ad-Hoc类型的包。
至于ExportOptions.plist,可以通过下面的办法得到:手动执行Product->Archive,然后导出Ad-Hoc安装包,在导出的目录中,就包含了一个ExportOptions.plist文件,直接用这个文件即可。
其实这个文件就是一个plist
compileBitcode
destination
export
method
ad-hoc
signingStyle
automatic
stripSwiftSymbols
teamID
65XUT4T932
thinning
<none>
2.5设置构建触发器
可以选择的类型:周期性构建,每次提交构建,手动构建。这里我们选择手动构建。
下面可以勾选升级Xcode之后自动构建。
另外还可以设置每次构建前是否Clean。
2.6选择设备类型
可以选择的类型:iOS设备和模拟器、iOS设备、模拟器,这里我们选iOS设备
2.7为你的服务器配置签名和证书
这里我们选择自动证书管理,只需要登录开发者账号密码。下面还有一个自动注册设备可以勾选。
但是实际操作中,我们发现一些坑
1.服务器上必须要安装根证书p12
2.每次注册新设备之后,必须要手动打包生成provisioning profile,才能打包成功
当然,我们也可以选择手动管理证书,然而自动证书管理能省掉很多工作量,所以还是推荐自动管理证书。
2.8配置环境变量
1.首先可以添加传递给xcodebuild的参数,支持的参数可以通过终端输入'xcodebuild --help'来查询
2.可以添加自定义的环境变量,这些环境变量可以在后面的脚本中使用
2.9配置触发器
点击左下方的加号,弹出菜单。在这里我们可以添加构建前执行的脚本、构建后执行的脚本,以及邮件相关的触发器
构建前执行的脚本,一般会修改Build号,或者执行CocoaPods相关的操作。
上面的脚本会自动把Build号修改成当前时间。
触发器代码的运行环境其实就是终端,它的当前目录是工程目录的上一级目录。脚本可以使用我们在前一步中添加的环境变量,也能使用一些Xcode Server定义的环境变量
我们来解释一下上面的代码:
1.cd到工程目录
2.用agvtool修改Build号
3.提交代码到git服务器
构建后执行的脚本,一般会把打好的包上传至服务器、蒲公英等,下面是我们的上传脚本:
#!/bin/sh
PRODUCT_PATH="${XCS_PRODUCT}" #!ipa文件所在的路径
WNL_VERSION=`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString"
./Calendar/CalendarOS7/CalendarOS7-Info.plist` #!获取版本号
filename="WNL_V${WNL_VERSION}_`date +%y%m%d%H%M`.ipa"#!新的文件名
tempPath="Desktop/tmp"#!临时目录地址,用来挂载网络磁盘
server="//employee:[email protected]/Documents2"#!网络磁盘的地址
#!判断当前是否已经挂载了网络磁盘,如果挂载了,先卸载
drives_to_unmount=`df | awk '/[email protected]/ { print $9 }'`
if [ "$drives_to_unmount" != "" ]
then
umount ${drives_to_unmount}
fi
mkdir -p ~/${tempPath}#!创建临时文件夹
mount -t smbfs ${server} ~/${tempPath}#!挂载网络磁盘
mkdir -p ~/${tempPath}/ios主包/${WNL_VERSION}#!创建打包文件夹
cp ${PRODUCT_PATH} ~/${tempPath}/ios主包/${WNL_VERSION}/${filename}#!将ipa复制到打包文件夹下
umount ~/${tempPath}#!卸载磁盘
echo 上传成功
创建构建后脚本时,你需要选择什么情况下执行,这里我们选择编译警告、成功、所有问题被解决时执行。
点击Done,一个基本的Bot就配置好了,第一次的Integration自动开始。在集成结束的时候,打包出的IPA文件会被上传到我们的服务器。
查看集成的结果并管理Bots, Integrations
在Xcode中,转到Report Navigator,选择Bot或是某次集成,在右侧的窗口区域,可以查看集成结果,触发一次新的集成,保存ipa,安装ipa,保存archive,在Organizer中显示archive,上传到App Store,以及对Bots进行管理,如编辑,删除等。
查看log
点击integrate左边的三角展开菜单,选择Logs,可以查看本次集成的log,编译、版本控制、触发器的log都能看到,打包失败的时候,可以通过这些log来分析失败原因
从浏览器中访问Xcode Server
在浏览器中访问Xcode Server的地址是"https://hostname/xcode",hostname可以是ip地址、服务器的远程主机名或者本地主机名。在电脑版浏览器中可以执行开始集成、下载ipa、在Xcode中打开、下载Archive等操作,手机浏览器中只能执行开发集成、安装ipa操作。
OTA安装
要使用OTA安装,必须使用hostname来访问。
1.点击 'PROFILE' 安装Xcode Server的根证书,并信任证书。
2.打开 设置 -> 通用 -> 关于 -> 证书信任设置,打开Xcode Server Root Certificate Authority。
3.点击 'INSTALL' 安装APP。
构建时的一些目录
/Library/Developer/XcodeServer/IntegrationAssets:这个目录会保存所有的Bot的每一次的集成结果,IPA文件,符号文件都可以在目录中找到。
~/Library/Caches/XCSBuilder/Bots/xxx/:xxx代表一个Bot的ID,在该目录下的Source目录,存放的是从仓库中拉到的代码。
常见的坑
1.单独使用一台Mac来作为打包服务器,不然一打包,你就别想敲代码了,卡到你怀疑人生。
2.打包速度慢。经过多次观察,我发现打包有一个过程Process Warning非常缓慢。我们的项目之前有大概2500个警告,后来我把警告减少到100个以内,打包时间从30多分钟提升到10分钟,减少了三分之二的时间。
3.编译成功,但是导出失败。基本都是证书问题,Xcode Server不能自动生成profile,去服务器手动打包一次生成profile,然后再用Xcode Server打包,就能成功过打包了。
4.打包过程中不要修改系统时间。这个是真的坑,Xcode Server一次只能打一个包,正在打包的时候再点其它Bot的打包,会显示前面有一个集成正在运行,要等执行完了才能开始打包,如果打包过程中修改了系统时间,即使前面一个包打完了,后面的也不会开始,重启都不行,只能重装Xcode。