你是否曾经试着为你的iOS项目搭建一台支持持续集成的服务器,从我的个人经验而言,这可不是一个轻松的活。你需要准备一部Mac,安装好全部所需的软件和插件。你要负责管理所有的用户账户并提供安全保护。
原本你想节省的时间,最终你会发现你花费了大量的时间去维护这台服务器。不过如果你的项目托管在GitHub上,现在有了新的希望:Travis CI。该服务可以为你的项目提供持续集成的支持,也就意味着它会负责好托管一个项目的所有细节。在Ruby的世界中,Travis CI已久负盛名。从2013年4月开始,Travis也开始支持iOS和Mac平台。
在这篇文章中,我会向你展示如何一步步为你的项目集成Travis。不仅包括编译项目和进行单元测试,还能够将你的应用投送到你所有的测试设备上。为了演示,我在GitHub上放了一个示例项目。在这篇文章的最后,我会教你如何用Travis去定位程序中的错误。
GitHub集成
我最喜欢Travis的一点就是他与GitHub的Web UI集成的非常好。譬如pull请求。Travis会为每次请求都执行编译操作。如果一切正常,pull请求在GitHub上看起来就像这样:
万一编译不成功,GitHub页面会相应的改变颜色给予提醒:
链接Travis和GitHub
让我们看一下如何链接你的GitHub项目到Travis。使用你的GitHub账号登陆Travis。对于私有工作目录,你需要注册一个Travis专业版账号。
登陆成功后,你就可以为你的项目打开Travis支持。找到属性页面,在此列出了你的所有GitHub项目。不过要注意,如果你此后创建了一个新的工作目录,要使用Sync now按钮进行同步。Travis只会偶尔更新你的项目列表。
现在只需要打开这个开关就可以为你的项目添加Travis服务。以后你会看到Travis会和你的GitHub项目设置相关联。下一步应该告诉Travis当它收到项目改动之后该做什么。
轻量级的项目配置
Travis CI需要你的项目的一些基本信息。在你项目的根目录创建一个名叫.travis.yml的文件,内容如下:
1 |
language: objective-c |
Travis编译器运行在虚拟机环境下.已经使用Ruby,Homebrew,CocoaPods和一些编译脚本进行过配置。上述的配置项已经足够编译你的项目了。
预装的编译脚本会分析你的Xcode项目,编译项目下的所有Target。如果所有文件都没有编译错误测试也没有跳出项目就编译成功了。现在可以将你的改动Push到GitHub看看能成功编译。
虽然这看起来好像很简单,不过对你的项目不一定适用。几乎没有什么文档来指导用户如何配置默认的编译行为。举个栗子, 有一次我没有用模拟器的SDK导致检查应用签名时发生了错误。如果刚刚那个最轻量级的配置对你的项目不适用的话,让我们来看一下如何用定制的编译命令来适用Travis。
定义编译命令
Travis使用命令行来编译你的项目。因此,第一步就是使项目能够在本地编译。作为Xcode命令行工具的一部分,Apple提供了xcodebuild命令。
打开你的终端输入:
1 |
xcodebuild –help |
这会列出xcodebuild可用的所有参数。如果命令执行不成功,确保你的命令行工具已经成功安装。通常一个常见的编译命令看起来像这样:
1 |
xcodebuild -project {project}.xcodeproj -target {target} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO |
使用iphonesimulator SDK是为了避免应用签名错误。这是必须的一步直到我们稍后引入证书为止。通过设置ONLY_ACTIVE_ARCH=NO我们可以确保在模拟器的架构下编译。你也可以设置额外的属性。用man xcodebuild来阅读文档。
对于使用CocoaPods的项目,你需要指定workspace和scheme。
1 |
xcodebuild -workspace {workspace}.xcworkspace -scheme {scheme} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO |
Schemes是由Xcode自动生成的,但这在服务器上不会发生。确保所有的scheme都被设为shared并加入到工作目录中。否则它只会在本地工作而不会被Travis CI识别。
我们的示例项目下的.travis.yml文件现在应该看起来像这样:
1 2 3 |
language: objective-c script: xcodebuild -workspace TravisExample.xcworkspace -scheme TravisExample -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO |
运行测试
通常对于测试来说你会使用如下的命令(注意test属性)
xcodebuild test -workspace {workspace}.xcworkspace -scheme {test_scheme} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO
不幸的是xcodebuild并不能支持多target以及iOS的应用测试。苹果已经在着手解决这个问题,不过我建议使用Xctool来代替。
Xctool
Xctool是来自Facebook的命令行工具,他可以帮助你更加轻松快捷的编译测试你的应用。他的彩色输出信息比xcodebuild更加简洁直观,结构清晰。同时还添加了对逻辑测试,应用测试的支持。
Travis中已经预装了xctool。要在本地测试的话,需要用Homebrew先安装xctool:
1 2 3 |
brew update brew install xctool |
用法非常简单,xctool 使用跟 xcodebuild相同的参数:
xctool test -workspace TravisExample.xcworkspace -scheme TravisExampleTests -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO
这要这些命令在本地能正常工作,我们就可以把他们添加到.travis.yml文件里:
language: objective-c
script:
– xctool -workspace TravisExample.xcworkspace -scheme TravisExample -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO
– xctool test -workspace TravisExample.xcworkspace -scheme TravisExampleTests -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO
目前我们所添加的配置已经足够编译一个框架类的应用。我们能够保证项目可以正常编译并通过测试。但对于真正的iOS应用来说,我们希望在真实的物理设备上进行测试。很显然,我们要借助Travis来帮我们自动部署。整个过程的第一步,我们需要给我们的应用签名。
应用签名
为了在Travis中给我们的应用签名,我们需要准备好所有必要的证书和配置文件。就像每个iOS开发人员知道的那样,这可能是最困难的一步。后面我们将写一些脚本来帮助我们在服务器上给应用签名。
证书和配置文件
- 苹果全球开发者关系认证
从苹果的配置页面中下载或者从你的Keychain中导出,将它保存到你的项目目录下scripts/certs/apple.cer这个位置。
2. iPhone发布证书 + 私钥
如果你还没有一个iPhone发布证书你需要创建一个。登陆你的苹果开发者账号,你可以跟随下面的步骤创建一个生产环境的新证书(Certificates > Production > Add > App Store and Ad Hoc)。确保你已经下载并安装了这个证书。以后你可以在你的Keychain中找到它,还有一个捆绑的私钥。现在打开你Mac上的Keychain应用:
右击证书选择导出将其放在scripts/certs/dist.cer路径,在导出捆绑的私钥,保存到scripts/certs/dist.p12。可以根据你的需要设置一个密码。
Travis需要知道你的私钥密码,我们需要将其储存在某个地方。显然我们不想用简单的文本来存储这个密码。我们可以利用Travis的安全环境变量。打开终端进入包含.travis.yml文件的目录。首先用gem install travis命令安装Travis gem。安装完成后你就可以用以下命令添加密码:
travis encrypt “KEY_PASSWORD={password}” –add
这样就可以安装一个叫做KEY_PASSWORD的加密环境变量到你的.travis.yml配置文件。在任何可以被Travis CI执行的脚本中都可以使用这个变量。
3. iOS 移动设备备案文件(发布用)
如果你还没有一个发布用的移动设备备案文件。根据你的开发者账号类型,你可以选择Ad Hoc或者In House两种不同的备案文件(Provisioning Profiles > Distribution > Add > Ad Hoc or In House).下载将其保存到scripts/profile/目录下。
我们需要在Travis中访问此备案文件,所以我们需要将此文件的名字存储为一个全局变量。譬如我们可以将其命名为TravisExample_Ad_Hoc.mobileprovision,像这样添加:
1 2 3 4 5 |
env: global: - APP_NAME="TravisExample" - 'DEVELOPER_NAME="iPhone Distribution: {your_name} ({code})"' - PROFILE_NAME="TravisExample_Ad_Hoc" |
这里还有两个声明的全局变量。APP_NAME通常指的就是你的项目主target的名字。DEVELOPER_NAME里是你在项目主target下Xcode Build Settings 中Code Signing Identity > Release里面看到的名字。最后搜索一下你应用的Ad Hoc或者In House配置文件,将其中的黑体文字全部去掉。根据你设置的不同,在一些属性的方括号里面可能不会有任何信息。
加密证书和备案文件
不过你的GitHub权限是公开的。你可能会想要给你的证书和备案文件加密,因为他们包含了你应用的重要信息。如果你使用的是一个私有目录,你可以跳过这一小节。
首先我们需要想出一个密码来加密我们所有的文件。在下面的例子中,我们使用foo这个单词,你完全可以将其替换为使用于你项目的更安全的密码。在命令行中需要使用openssl来加密这些敏感文件:
1 2 3 |
openssl aes搭建一台支持持续集成的服务器,从我的个人经验而言,这可不是一个轻松的活。你需要准备一部Mac,安装好全部所需的软件和插件。你要负责管理所有的用户账户并提供安全保护。
原本你想节省的时间,最终你会发现你花费了大量的时间去维护这台服务器。不过如果你的项目托管在GitHub上,现在有了新的希望:Travis CI。该服务可以为你的项目提供持续集成的支持,也就意味着它会负责好托管一个项目的所有细节。在Ruby的世界中,Travis CI已久负盛名。从2013年4月开始,Travis也开始支持iOS和Mac平台。 在这篇文章中,我会向你展示如何一步步为你的项目集成Travis。不仅包括编译项目和进行单元测试,还能够将你的应用投送到你所有的测试设备上。为了演示,我在GitHub上放了一个示例项目。在这篇文章的最后,我会教你如何用Travis去定位程序中的错误。 GitHub集成 我最喜欢Travis的一点就是他与GitHub的Web UI集成的非常好。譬如pull请求。Travis会为每次请求都执行编译操作。如果一切正常,pull请求在GitHub上看起来就像这样: 万一编译不成功,GitHub页面会相应的改变颜色给予提醒: 链接Travis和GitHub 让我们看一下如何链接你的GitHub项目到Travis。使用你的GitHub账号登陆Travis。对于私有工作目录,你需要注册一个Travis专业版账号。 登陆成功后,你就可以为你的项目打开Travis支持。找到属性页面,在此列出了你的所有GitHub项目。不过要注意,如果你此后创建了一个新的工作目录,要使用Sync now按钮进行同步。Travis只会偶尔更新你的项目列表。 现在只需要打开这个开关就可以为你的项目添加Travis服务。以后你会看到Travis会和你的GitHub项目设置相关联。下一步应该告诉Travis当它收到项目改动之后该做什么。 轻量级的项目配置 Travis CI需要你的项目的一些基本信息。在你项目的根目录创建一个名叫.travis.yml的文件,内容如下:
Travis编译器运行在虚拟机环境下.已经使用Ruby,Homebrew,CocoaPods和一些编译脚本进行过配置。上述的配置项已经足够编译你的项目了。 预装的编译脚本会分析你的Xcode项目,编译项目下的所有Target。如果所有文件都没有编译错误测试也没有跳出项目就编译成功了。现在可以将你的改动Push到GitHub看看能成功编译。 虽然这看起来好像很简单,不过对你的项目不一定适用。几乎没有什么文档来指导用户如何配置默认的编译行为。举个栗子, 有一次我没有用模拟器的SDK导致检查应用签名时发生了错误。如果刚刚那个最轻量级的配置对你的项目不适用的话,让我们来看一下如何用定制的编译命令来适用Travis。 定义编译命令 Travis使用命令行来编译你的项目。因此,第一步就是使项目能够在本地编译。作为Xcode命令行工具的一部分,Apple提供了xcodebuild命令。 打开你的终端输入:
这会列出xcodebuild可用的所有参数。如果命令执行不成功,确保你的命令行工具已经成功安装。通常一个常见的编译命令看起来像这样:
使用iphonesimulator SDK是为了避免应用签名错误。这是必须的一步直到我们稍后引入证书为止。通过设置ONLY_ACTIVE_ARCH=NO我们可以确保在模拟器的架构下编译。你也可以设置额外的属性。用man xcodebuild来阅读文档。 对于使用CocoaPods的项目,你需要指定workspace和scheme。
Schemes是由Xcode自动生成的,但这在服务器上不会发生。确保所有的scheme都被设为shared并加入到工作目录中。否则它只会在本地工作而不会被Travis CI识别。 我们的示例项目下的.travis.yml文件现在应该看起来像这样:
运行测试 通常对于测试来说你会使用如下的命令(注意test属性) xcodebuild test -workspace {workspace}.xcworkspace -scheme {test_scheme} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO 不幸的是xcodebuild并不能支持多target以及iOS的应用测试。苹果已经在着手解决这个问题,不过我建议使用Xctool来代替。 Xctool Xctool是来自Facebook的命令行工具,他可以帮助你更加轻松快捷的编译测试你的应用。他的彩色输出信息比xcodebuild更加简洁直观,结构清晰。同时还添加了对逻辑测试,应用测试的支持。 Travis中已经预装了xctool。要在本地测试的话,需要用Homebrew先安装xctool:
用法非常简单,xctool 使用跟 xcodebuild相同的参数: xctool test -workspace TravisExample.xcworkspace -scheme TravisExampleTests -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO 这要这些命令在本地能正常工作,我们就可以把他们添加到.travis.yml文件里: language: objective-c script: – xctool -workspace TravisExample.xcworkspace -scheme TravisExample -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO – xctool test -workspace TravisExample.xcworkspace -scheme TravisExampleTests -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO 目前我们所添加的配置已经足够编译一个框架类的应用。我们能够保证项目可以正常编译并通过测试。但对于真正的iOS应用来说,我们希望在真实的物理设备上进行测试。很显然,我们要借助Travis来帮我们自动部署。整个过程的第一步,我们需要给我们的应用签名。 应用签名 为了在Travis中给我们的应用签名,我们需要准备好所有必要的证书和配置文件。就像每个iOS开发人员知道的那样,这可能是最困难的一步。后面我们将写一些脚本来帮助我们在服务器上给应用签名。 证书和配置文件
从苹果的配置页面中下载或者从你的Keychain中导出,将它保存到你的项目目录下scripts/certs/apple.cer这个位置。 2. iPhone发布证书 + 私钥 如果你还没有一个iPhone发布证书你需要创建一个。登陆你的苹果开发者账号,你可以跟随下面的步骤创建一个生产环境的新证书(Certificates > Production > Add > App Store and Ad Hoc)。确保你已经下载并安装了这个证书。以后你可以在你的Keychain中找到它,还有一个捆绑的私钥。现在打开你Mac上的Keychain应用: 右击证书选择导出将其放在scripts/certs/dist.cer路径,在导出捆绑的私钥,保存到scripts/certs/dist.p12。可以根据你的需要设置一个密码。 Travis需要知道你的私钥密码,我们需要将其储存在某个地方。显然我们不想用简单的文本来存储这个密码。我们可以利用Travis的安全环境变量。打开终端进入包含.travis.yml文件的目录。首先用gem install travis命令安装Travis gem。安装完成后你就可以用以下命令添加密码: travis encrypt “KEY_PASSWORD={password}” –add 这样就可以安装一个叫做KEY_PASSWORD的加密环境变量到你的.travis.yml配置文件。在任何可以被Travis CI执行的脚本中都可以使用这个变量。 3. iOS 移动设备备案文件(发布用) 如果你还没有一个发布用的移动设备备案文件。根据你的开发者账号类型,你可以选择Ad Hoc或者In House两种不同的备案文件(Provisioning Profiles > Distribution > Add > Ad Hoc or In House).下载将其保存到scripts/profile/目录下。 我们需要在Travis中访问此备案文件,所以我们需要将此文件的名字存储为一个全局变量。譬如我们可以将其命名为TravisExample_Ad_Hoc.mobileprovision,像这样添加:
这里还有两个声明的全局变量。APP_NAME通常指的就是你的项目主target的名字。DEVELOPER_NAME里是你在项目主target下Xcode Build Settings 中Code Signing Identity > Release里面看到的名字。最后搜索一下你应用的Ad Hoc或者In House配置文件,将其中的黑体文字全部去掉。根据你设置的不同,在一些属性的方括号里面可能不会有任何信息。 加密证书和备案文件 |