写点什么

iOS 持续集成:Xcode Server、Jenkins、Travis 和 fastlane

  • 2017-04-10
  • 本文字数:4146 字

    阅读完需:约 14 分钟

本文最初发布于 The Code Bug 博客,经原作者授权由 InfoQ 中文站翻译并分享。

我的团队去年曾两次历尽千辛万苦想要寻找一种能满足我们需求的持续集成(下文统一简称为 CI)服务器。

考虑到之前 CI 方面的体验,以及我们的 iOS 开发者提出的各种需求,我们对这种服务器的要求是必须能够:

  • 构建并签署我们的所有不同特性的应用;
  • 将我们的应用商店首选项上传至 iTunes Connect;
  • 将 IPA、dSYM,以及变更日志上传至 HockeyApp;
  • 针对发布和开发分支持续不断地运行单元测试和 UI 测试;
  • 构建每次合并请求(MR)并汇报测试结果;
  • 进行持续不断地构建和签署,以确保没有引入新的问题。

除了命令行工具,我们考虑过下面几个产品:

  • xcodebuild - 由 Apple 开发,主要用于 Xcode 的构建和测试,有时可能难以想起,但可配置程度很高。
  • fastlane - 实际上并不是一个工具,而是一组可用于构建、测试、上传至 iTunes Connect、供应配置文件管理、屏幕截图创建、dsym 上传 / 下载至主要崩溃报告平台的一系列工具。
  • xctool 和其他 - “其他”是指诸如 nomad tools 等工具,这些工具或者被弃用,或者逐渐缺少支持,或者即将被废弃。尽管 Facebook 在使用某种工具,但并不意味着这个工具依然可以得到妥善的维护。

后面的测试结果会告诉你最终被我们选中的冠军(继续读下去吧)。

与此同时,如果缺少持续不断运行所需的服务器,工具本身也毫无意义。有人推荐了几个 CI 服务器,具体如何选择,只要先决定打算将时间投入在哪里就行了。

服务器方面主要的选择包括:

  • TravisCI/CircleCI - 托管式服务器,可免费用于开源项目,可随处访问,极为强大。相比 Jenkins 可配置的选项较少,仅支持与 Github 集成。用于私有代码库的价格高昂。
  • Xcode Server - 能与 Xcode 高度集成,实际上也是唯一可用于 Xcode 的服务器,由 Apple 开发,最有可能只需要少量配置即可投入使用。
  • Jenkins - CI 服务器领域曾经的王者,有大量插件可用,可与各种其他产品集成,需要一定的配置和维护,但是非常强大。

我们的考量:

1.TravisCI

一种围绕 GitHub 开发的,非常简单的 CI 服务器。重要:如果你的代码没有托管到 GitHub,那么就很不幸了。由于价格原因,或出于安全的原因希望自行托管自己的代码,很多公司会使用 GitHub 的替代品,例如 Bitbucket 或 Gitlab。但如果你的代码托管在 Github,并且你愿意为 Travis/Circle 支付包月费用,可以在这里了解 Travis 这一流行的 iOS 库: AFNetworking

Travis 的界面更为专注于构建的生成和 Github Pull 请求。该服务提供了拆箱即用的模拟器和 Xcode 镜像(你可以指定构建所要使用的 Xcode 版本)。Travis CI 依然处于 Beta 测试阶段,可以周期性地运行作业,而 Jenkins 可是早在很久以前就提供这样的功能了。

优势:

  1. 拆箱即用,易于设置;
  2. 可配置,可根据需要维护 Xcode 和工具选项;
  3. 能与 GitHub 实现良好的集成;
  4. 提供了完善的文档,被开源社区广泛使用;
  5. 用户界面美观。

不足:

  1. 如果代码未托管在 GitHub 将无法使用;
  2. 付费计划价格高昂,构建能力有限;
  3. 相比 Jenkins,配置选项和插件数量少很多。

结论:最后,Travis以及CircleCI缺乏与 Bitbucket 和 Gitlab 的集成是我们无法接受的。我们的代码未托管到 Github,就算托管了,我们需要持续不断运行构建和测试的需求也需要更多的构建时间(时间就是金钱,一点没错,CircleCI 按照构建所进行的分钟数收费)。他们还缺乏完善的插件生态体系,这也让 Jenkins 显得更可人(我们能创建仪表板,或者在失败后重试构建 3 次,这些功能都是插件的功劳)。

2. Xcode Server

由 Apple 开发,满足 iOS(以及 macOS?)开发者 CI 需求的 CI 服务器。Xcode Server(XCS)所谓的机器人(Bot),其实就是 Jenkins 的“作业”,两者是一回事,都是预先调度好的任务。Xcode Server 在我们的项目导航界面显示的机器人是这样的:

用户可以决定是否让机器人运行单元测试或 UI 测试,可以分析甚至生成可供安装的 IPA(归档操作):

顺利执行了集成之后可以看到这样的概述信息,这可能是 XCS 最棒的功能了:

还有关于测试的概览。

关于如何与 XCS 配合使用,整个互联网上只有一篇粗略的指南,此文发布在 Honza dworzky’s 。如果你想进一步了解如何配置 XCS,建议阅读此文。当然也并非偶然,Honza 现在已经加入 Apple 从事开发者工具相关的工作。

Xcode 服务器也许更了解 Xcode,但对持续集成知之甚少。该服务器可并行运行两个或更多作业(机器人),但无法接受 Git 子模块(Submodule)变更(可通过自定义脚本实现该功能)。如果你有需要持续运行,但与 Xcode 没太大关系的任务(例如每天下载 localizable.strings 的翻译),XCS 必须首先构建或测试一些内容才能执行这些操作。如果 XCS 构建失败,Apple 的“极简主义哲学”这时候就显露出来了,XCS 只能显示一些简单并且含糊的错误信息(/usr/bin codesign failed)。

最糟糕的地方在于,XCS 构建和测试之外的一切,必须使用 XCS 提供的极为有限的 API 自行创建。无法与 Gitlab/Bitbucket/Github 集成,没有可用于与无作业流程的 API 进行通信的插件。实际上,XCS唯一能做的就是在设备上运行单元测试和 UI 测试。尽管如此,如果测试失败,它也不会告诉你原因,你只能自己揣摩了。

优势:

  1. 能与 Xcode 实现良好的集成;
  2. 一切均拆箱可用;
  3. 提供了用于监视机器人的 Web 仪表板;
  4. 能创建可安装的 IPA,并能通过 Web 仪表板安装。

不足:

  1. 在一些基本任务方面有所问题,例如有子模块,需要将源代码签出时;
  2. 无法添加多个构建器节点,机器人运行速度缓慢,无法纵向扩展;
  3. 过于专注于与 XCode 本身有关的任务,无法运行其他类型的作业;
  4. 几乎无法实现与第三方的集成;
  5. 无法对构建问题进行调试;
  6. 只适合单元测试和 UI 测试。

结论:

Apple 很明显并不打算开发一种完备的 CI 服务器。也许该产品主要是以小型团队和独立开发者为目标。在针对 XCS 进行过大量试验后,我们觉得就算小型团队,也很难在合理时间里通过 XCS 进行维护、保活、调试和反馈等任务。

就算你不会遇到这类问题,XCS 也无法提供构建和测试之外的其他任何功能。上传至 iTC、供应配置文件下载和安装、上传至 Hockey app(或 Fabric)、将测试结果汇报给 Git 代码库管理者,其他各类 CI 任务都不被 XCS 支持,因此相比我们最终选择的产品,XCS 的实用性大打折扣。

3. Jenkins + fastlane

这个组合略有不同,因为需要针对 fastlane 的概念和用途进行一个简单的介绍。

Fastlane 是一组命令行工具,可供开发者构建自己的应用:

fastlane gym --scheme YourSchemeName或运行单元测试:

fastlane scan --scheme YourSchemeName或针对特定设备运行 UI 测试:

fastlane scan --scheme UITestsScheme --devices 'iPhone 5s'甚至可以上传应用进行试运行:

fastlane pilot upload --ipa PathToIpa这四个简单的操作完全满足了本文开头列出的需求。Fastlane 还有更多其他功能(例如供应配置文件下载和安装),但上面这几个命令对我们来说已经够用了。

由于 fastlane 命令非常简单并且可移植,并能通过 Fastfile 将其放入源代码控制系统,因此只需很少的工作,甚至无须任何准备,即可迁移至任何 CI 服务器,因为 Fastfile 实际上是一种应用构建、测试、分发过程中使用的“菜谱”,而服务器只不过是执行这些工作的场所。

继续说 Jenkins。Jenkins 是一种 Web 服务器,可在任何计算机(包括撰写本文所用的 MacBook)上运行。安装好后看起来是这样的:

通过使用上文介绍的 fastlane 命令,开发者可以轻松创建各种作业,例如调用相应的fastlane scan命令执行单元测试和 UI 测试。若要创建构建并上传作业,调用fastlane gymfastlane pilot即可。通过使用 GIT parameter(一种 Git 参数插件)将作业参数化,即可从任何分支触发构建:

合并请求构建器是个很有趣的用例。它可以被每个合并请求触发,执行单元测试(fastlane scan)并将结果汇报给 Gitlab。通过使用 Gitlab 插件(上文介绍的服务器均不具备),在变更推出后只需点几下按钮即可进行构建:

同时会在 Gitlab、Bitbucket 的提交旁边通过绿色对勾(或红叉)汇报结果。

借助强大的 Build Monitor View 插件,开发者可以通过下面这样美观的视图添加运行单元测试和 UI 测试的作业:

如果需要更细化的粒度,可以通过 fastlane 轻松地指定 UI 测试要使用的仿真器(fastlane scan --scheme UITestsSchema --devices 'iPhone 4S'),此外还可创建更细化的 UI 测试仪表板,将通过fastlane scan调用不同仿真器的最多六个作业汇总在一起:

其他作业可以每天使用fastlane sigh更新并下载之前供应的配置文件。处理完每个合并请求后,其他作业可以为测试者创建构建并将其上传至 hockeyApp。当新构建可用时发送包含变更日志和下载链接的可宽延通知信息?一切皆可能。

Jenkins 可通过增加构建器节点的方式进行纵向扩展,这个功能竟然是免费的,因此也值得一提。Jenkins 唯一的不足在于由于是免费的,用户需要自行托管并维护。该产品的界面一直不怎么美观。除此之外,该产品的插件、稳定性、可靠性,以及与各类第三方服务的集成能力都是顶尖的。

结论

就算小团队也可以使用fastlane让 iOS 应用的开发过程(构建、上传、测试)实现自动化。配置可运行这些 fastlane 命令的 Jenkins 服务器,操作过程并不难,随后再也不需要专门指定一个团队成员盯着终端长达数小时时间关注这些命令的运行。良好且透明的错误处理机制是 fastlane 的主要目标之一,通过与 Jenkins 服务器配合使用,将能为团队提供一个强大的解决方案。Fastlane 完善的文档和已获证实的稳定性,以及大量的插件,使得 Jenkins 可以帮你将更多不同流程实现自动化。所有工作一键点击即可完成。Xcode Server 的差距太大,其他 CI 服务器功能没这么强大(仅支持 Github),因此 Jenkins 顺利成为我们首选的 CI 服务器。

附注:我依然在试图让 Xcode Server 成为我们 CI 环境的一份子,我打算通过它在物理设备上运行 UI 测试。XCS 是否能胜任至少这一个任务,或者彻底被我们卸载,结果还有待观察。

作者 The Code Bug 阅读英文原文 iOS Continous integration: Xcode Server, Jenkins, Travis and fastlane


感谢徐川对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017-04-10 17:356132
用户头像

发布了 283 篇内容, 共 123.5 次阅读, 收获喜欢 63 次。

关注

评论

发布
暂无评论
发现更多内容

DOM操作

Jason199

js DOM事件 6月月更

mysql中的查询计划及sql语句性能分析:explain

乌龟哥哥

6月月更

SRE Lesson One -- Day1 准备你的工作环境

耳东@Erdong

SRE 6月月更 SRE Lesson One

C语言数据的储存

未见花闻

6月月更

K8S学习笔记--《开篇词|迎难而上,做云原生时代的弄潮儿》

IT蜗壳-Tango

容器 k8s IT蜗壳教学 6月月更

Hoo虎符研究院 | 币圈后浪D/Bond一个基于ERC-3475标准开发的去中心化债券生态系统平台

区块链前沿News

Hoo 虎符交易所

如何提高远程办公的效率?| 社区征文

石云升

远程办公 6月月更 初夏征文

Java 中的Comparator使用技巧

Nick

Java stream 6月月更 Comparator nullsFirst

Ajax入门教程

倔强的牛角

ajax 6月月更

应用配置管理,基础原理分析

Java 微服务 构架

如何写出同事看不懂的Java代码?

码农参上

后端 Java’

在线JSON转YAML工具

入门小站

工具

Discourse 新用户可插入媒体的数量

HoneyMoose

InfoQ 极客传媒 15 周年庆征文|分布式设计介绍

No Silver Bullet

6月月更 InfoQ极客传媒15周年庆 分布式设计

接口测试(apipost、jmeter和python脚本)——测试工具

Xd

Java 后端 接口测试

【LeetCode】 移除字母异位词后的结果数组Java题解

Albert

LeetCode 6月月更

MySql 过滤查询(以字母开头,以数字开头,非数字开头,非字母开头)

迷彩

数据库 MySQL 数据库 6月月更

军体拳代码

工程师日月

6月月更

Java 使用 char[] Array 还是 String 存储字符串

HoneyMoose

深挖数据价值,2022隐私计算大赛开启!

Jessica@数牍

隐私计算 大数据技能大赛 隐匿查询性能优化 隐私求交性能优化

全面双录倒计时,融云助力泛金融业务办理高效合规可回溯

融云 RongCloud

linux之我常用的20条命令( 之三)

入门小站

Linux

在线文本列表批量添加行号工具

入门小站

工具

Java Core 「13」ReentrantReadWriteLock 再探析

Samson

学习笔记 Java core 6月月更

一条命令开启监控之旅!

TanCloud探云

开源 监控系统

Python 设计模式:单例模式

宇宙之一粟

Python 单例模式 6月月更

如何使用物联网低代码平台进行设备调试?

AIRIOT

低代码 物联网 低代码开发

Eureka的TimedSupervisorTask类(自动调节间隔的周期性任务)

程序员欣宸

Java SpringCloud 6月月更

PingCAP 入选 2022 Gartner 云数据库“客户之声”,获评“卓越表现者”最高分

极客天地

Any to Any 实时变声的实现与落地丨RTC Dev Meetup

RTE开发者社区

音频 RTC Dev Meetup 生态专栏 语音处理

设计微博系统中“微博评论”高性能高可用计算机构

Fan

架构师实战营

iOS持续集成:Xcode Server、Jenkins、Travis和fastlane_DevOps & 平台工程_The Code Bug_InfoQ精选文章