Xcode Server教程

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。苹果建议是使用一个特定的,非管理员权限的用户,不过也可以使用当前登录的用户。在这里,可以直接选择当前登录用户。


开启Xcode Server

点击Continue后,会去配置并启动Server,完成以后,界面如下:


配置Xcode 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'。


为Bot命名

添加服务器

输入账号密码

在这里,我选择的是作为'Registered user'的身份连接到Server,然后输入当前登录用户的用户名和密码。回想一下,在开启Server的时候,我们选择的Integration User是当前登录用户。
如果选择'Guest',虽然也可以,但是之后会发现,无法对创建好的Bot进行编辑。

这一步的结果,实质上是创建了一个Xcode Server类型的Account,并添加到Xcode中。


image.png

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文件,直接用这个文件即可。


ExportOptions.plist

其实这个文件就是一个plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>compileBitcode</key><!-- 是否打开bitcode -->
    <true/>
    <key>destination</key><!-- 导出或者上传 -->
    <string>export</string>
    <key>method</key><!-- 方式development、ad-hoc、app-store -->
    <string>ad-hoc</string>
    <key>signingStyle</key><!-- 签名方式 -->
    <string>automatic</string>
    <key>stripSwiftSymbols</key>
    <true/>
    <key>teamID</key><!-- 开发者teamID -->
    <string>65XUT4T932</string>
    <key>thinning</key><!-- 是否使用app thin -->
    <string>&lt;none&gt;</string>
</dict>
</plist>

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:killers1024@192.168.1.79/Documents2"#!网络磁盘的地址

#!判断当前是否已经挂载了网络磁盘,如果挂载了,先卸载
drives_to_unmount=`df | awk '/employee@192.168.1.79/ { 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进行管理,如编辑,删除等。


image.png

查看log

点击integrate左边的三角展开菜单,选择Logs,可以查看本次集成的log,编译、版本控制、触发器的log都能看到,打包失败的时候,可以通过这些log来分析失败原因


image.png

从浏览器中访问Xcode Server

在浏览器中访问Xcode Server的地址是"https://hostname/xcode",hostname可以是ip地址、服务器的远程主机名或者本地主机名。在电脑版浏览器中可以执行开始集成、下载ipa、在Xcode中打开、下载Archive等操作,手机浏览器中只能执行开发集成、安装ipa操作。

从浏览器中访问Xcode Server

OTA安装

要使用OTA安装,必须使用hostname来访问。
1.点击 'PROFILE' 安装Xcode Server的根证书,并信任证书。
2.打开 设置 -> 通用 -> 关于 -> 证书信任设置,打开Xcode Server Root Certificate Authority。
3.点击 'INSTALL' 安装APP。


OTA安装

构建时的一些目录

/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。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,825评论 4 377
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,887评论 2 308
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,425评论 0 255
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,801评论 0 224
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,252评论 3 299
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,089评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,216评论 2 322
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 31,005评论 0 215
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,747评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,883评论 2 255
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,354评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,694评论 3 265
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,406评论 3 246
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,222评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,996评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,242评论 2 287
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 36,017评论 2 281

推荐阅读更多精彩内容