Fastlane - 移动开发自动化之道

阅读 1091
收藏 31
2016-09-26
原文链接:mp.weixin.qq.com

本文为『移动前线』群在8月11日的分享总结整理而成,转载请注明来自『移动开发前线』公众号。

嘉宾介绍

邢天宇,8年研发和管理经验,早期担任过前端工程师和后端工程师(Ruby),10年初开始涉足移动端(MeeGo,Andriod,iOS)。热衷开源,崇尚高效。目前在【更美】担任技术负责人,负责研发团队管理及移动端基础架构工作。

本人一直认为:在程序的世界里,一切重复性的,流程化的工作都可以交给自动化去完成。

在移动开发中也是如此:其实写代码只是我们开发过程中的一部分,除此之外我们还需要进行编译,打包,上传,部署,库管理,版本控制等等Coding之外的杂事,而正是这些乏味而重复的工作占用了我们宝贵的时间。

所以在“懒人”遍布的工程师世界中,总会有人想尽办法做出改变,于是这些“懒人”们乐此不疲的造出许多美妙的轮子,既方便了自己,又帮助了他人,让这个世界变得更加美好。

今天就给大家介绍其中一个轮子:Fastlane,这个Github上的明星项目截止到目前共获得1万多个Star,并且还有1500多个Fork。

Fastlane在我们团队中的推广和应用

怎么样,听起来是不是很牛?不过先别急,在进入正题之前,我想跟大家简单分享一下我们移动团队在开展持续测试和持续交付工作中的一些心得体会。

大家都知道,最近几年,随着智能手机的普及,移动端不仅要承载更多业务场景的实现,并且还要应对不断变化业务需求。这就要求我们移动团队能够迅速响应变化,快速的迭代。那么随之而来的问题就是如何保障在不牺牲质量的前提下,尽可能的提升速度,我认为这一切需要建立在高质量的持续测试和持续交付体系之上。

但是移动端本身兴起的时间就比较短,各方面的成熟度也有所欠缺,能够拿来用的工具更是少之又少,随着业务深度广度的增加,迭代速度的加快,诸如证书管理,打包,上传,发布这类重复而毫无技术含量的工作逐渐占用了大家的时间,团队内部对此诟病不已。

所以我们的架构团队从去年初就一直在寻找这样的一种工具,一种解决方案,旨在彻底解放工程师的“双手”。

刚开始我们尝试使用Jenkins+Fir搭建了一套持续测试的环境,流程如下图:

说实话,效果还是可以的,至少在一定的时期内满足了我们的要求,但是Jenkins本身只是一个通用的CI流程管理系统,本身并不提供诸如ITC提包和Meta内容管理,签名,证书管理等等和移动端业务紧密结合的场景,而且配置的过程相当繁琐。

去年年底的时候,机缘巧合之下,我们在Github上发现了Fastlane,看了Readme后感觉有戏,于是决定尝试一下。其实刚开始的时候,我们也只是用Fastlane来解决iOS团队内证书同步和上传ITC的问题,但是随着深入的研究,发现其实Fastlane能做的更多,于是我们将其逐步应用到iOS端的更多的场景,比如:私有Pod的发布,代码的静态检查,UIAutomation测试等等,接着又推广到Andriod平台,完成诸如私有AAR的发布,Monkey测试等等一系列任务。现在可以说Fastlane已经变成了我们工作中密不可分的一部分。

另外,Fastlane本身也可以和Jenkins,Circle等主流CI系统做很好的集成,并且由于主要的CI流程都由Fastlane来管理和执行,所以从根本上降低了这些系统配置的复杂度。

Fastlane简介

说了这么多,我们回到今天的主角身上,首先先简单介绍一下:Fastlane是用Ruby语言编写的一套自动化工具集和框架,每一个工具实际都对应一个Ruby脚本,用来执行某一个特定的任务,而Fastlane核心框架则允许使用者通过类似配置文件的形式,将不同的工具有机而灵活的结合在一起,从而形成一个个完整的自动化流程。

到目前为止,Fastlane的工具集大约包含170多个小工具,基本上涵盖了打包,签名,测试,部署,发布,库管理等等移动开发中涉及到的内容。

关于这些工具的描述和使用可以看这里:

https://docs.fastlane.tools/actions/Actions/

如果这些工具仍然没有符合你需求的,没有关系,得益于Fastlane本身强大的Action和Plugin机制,如果你恰好懂一些Ruby开发的话,可以很轻易的编写出自己想要的工具。

其实真正官方出品的工具大约占一半左右,剩下的都是Github社区成员贡献的,本人有幸也贡献过其中一个。(这里建议移动开发工程师还是需要学习一门脚本语言的,比如Ruby)

Fastlane的安装非常简单,和Cocoapods一样,Fastlane也可以通过RubyGems来安装,如果你的电脑上有Ruby环境的话,那么只需要执行如下命令,即可完成:

gem install fastlane

移动客户端持续测试和持续交付的常见场景及痛点

Fastlane本身能做的事情很多,但是其中一个最为重要的作用就是能够无缝嵌入在持续测试和持续交付体系中。

下面,为了便于大家理解,我拿iOS为例,举几个我们在移动开发过程中常常会遇到的场景:

场景一

当一个迭代开发测试结束,服务器端上线之后,我们会使用Testflight进行线上跟测,一般会执行如下流程:

  1. 执行Git Pull命令,拉最新的代码到本地

  2. Pod Install安装最新的依赖库

  3. 在Xcode中将Build Version增加

  4. 在Xcode点击Archive编译并打包

  5. 选择输出一个iOS AppStore模式的ipa文件

  6. 通过Application Loader将IPA上传到ITC(TestFlight)

  7. 然后等待ITC Process完成后,登录上去选择刚才的Build进行TestFlight测试

  8. 由于修改了版本号,所以需要将代码Commit和Push一下

如果线上跟测发现有问题,那么需要修复完毕后重复上面的8个步骤。其实做过这件事的同学应该都有体会,顺利的话差不多一次得30分钟吧,如果某一次Build Version忘记增加了,那么前面的工作就白做了。在我们团队早期的时候,由于自动化体系尚未建立,我们有一个同事专门负责此事,在线上跟测的这两天,他有半天时间几乎干不了别的,基本上都在打包上传,说出来都是泪。

场景二

随着业务的发展,产品线的增加,我们需要将APP拆分为若干个基础组件和业务组件,以便跨APP使用,并且方便管理维护(这又是另外一个大的议题,就不在此赘述了)。每个组件都由一个私有Pod来管理,Pod的发布和更新也成为了我们日常工作的一部分,对于这些Pod,一般我们团队内部的原则是:谁制作,谁管理,谁发布,Pod的负责人我们内部称之为库管,这件事也就分担到了每个库管身上,库管发布一个Pod的流程大约如下:

  1. 增加Podspec中的版本号

  2. 执行pod lib lint命令进行库验证

  3. Git Commit代码

  4. Git Push代码到远端

  5. 打一个Git Tag

  6. 将Tag Push到远端

  7. 执行pod repo push命令发布库到私有仓库

如果只有两三个库的话,并且库的更新频率较低的时候,每次手动来处理还好。但是当库逐渐增多的时候这件事就变得相当麻烦,尤其是当顶层的库依赖底层库的时候,那么升级一个库,影响面将远远超过其本身,通过人工的方式处理的话,整个过程会变得相当痛苦。

说到这里,我相信但凡是操作过的同学,应该都对此深有感触。

所以我们来看看针对以上这两个场景,如何使用Fastlane来解决。

其实说起来也不难,首先在项目下执行:

fastlane init

然后跟随配置引导,填写App和ITC相关信息,然后Fastlane会在项目目录下创建一个fastlane目录,里面包含所有和此项目相关的配置,剩下要做的就是将以上的流程配置在fastlane目录下的Fastfile中,

场景一的Fastfile(可以忽略HipChat部分): 

场景二的Fastfile(可以忽略HipChat部分): 

对于Fastlane的配置,官方提供的文档中会有更详细的描述:

https://docs.fastlane.tools/getting-started/ios/setup/

配置完这个脚本后,剩下的事就很轻松写意了。针对场景一我们在项目目录下,用终端执行如下命令即可:

fastlane do_deliver_app 
project:Gengmei 
scheme:Gengmei-AppStore 
version:6.3.0 
build:201609011530 
...

同理,针对场景二我们在项目目录下,用终端执行如下命令即可:

fastlane do_release_lib project:GMUtil version:0.1.4

任何复杂的流程,基本上一个命令全部搞定,是不是很方便。

另外,为了能够让Fastlane的各种命令更加傻瓜话,可视化,我们基于Fastlane内核,使用Ruby on Rails框架开发了一款适用于移动端持续测试和持续发布的系统Jaguar。Jaguar本身和Gitlab,Sentry,Jira,HipChat,Maven等等内部系统进行打通,从而形成一个完整的自动化体系。

这样对于大部分的自动化流程,Jaguar会通过各种定时任务或WebHook自动触发;少部分需要人工操作的,工程师们也只需要点一个按钮就能完成了。

这里附上一个Jaguar的截图: 

使用Fastlane的感受,踩坑的简单回顾

使用了Fastlane这么长的时间,我最深的感受就是:Fastlane真正的将工程师从各种无聊而又必须要做的重复性劳动和流程化工作中解放出来,专注于业务或架构本身,使得整个开发效率,测试效率,运维效率大大提升。

在使用Fastlane的过程中,有一些小的注意事项,也和大家分享一下:

由于Fastlane本身更新频率比较高,大约1-2周一次,那么如果最近的几个版本都没有升级的话,建议仔细阅读一下这几次更新的Release Notes,否则有可能会出现一些奇奇怪怪的Bug,比如: 在1.87版本升级到1.88的时候,如果不在Fastfile中加入如下两行:

ENV['FASTLANE_EXPERIMENTAL_TRANSPORTER_AVOID_SHELL_SCRIPT'] = '1'
ENV['SPACESHIP_LOGIN_ENCODING_IDENTITY'] = '1'

那么,上传ITC的时候,就会报错,而且从报错中并不能看到具体原因,最后经过各种折腾终于在Github上的issue中找到了原因:Spaceship这个工具增加了一个小的特性而导致的Bug。

另外,大家在使用Fastlane的过程中,如果遇到了问题,建议直接在Github上提issue,Fastlane的作者和社区工程师们会非常迅速的做出响应,而且会非常热心的帮你解决问题,当然大家提问题的时候要尽量描述清楚,该贴代码帖代码,该截图的截图。

发散思维,Fastlane不只专属于移动端

虽然Fastlane本身是为移动而生的,但是如果我们发挥一下想象力的话,就会发现,其实也可以把后端,前端的持续集成和持续交付流程整理出来,然后也统一交给Fastlane来管理(当然这个过程中肯定需要自定义一些Plugin或Action的)

比如:我们团队目前正计划先把PC站的UI自动化测试流程集成进来:

  1. 执行Git Pull命令,拉最新的代码

  2. 使用pip安装Requirements

  3. 混淆压缩前端Javascript和CSS

  4. 重启Django服务

  5. 使用Selenium执行UI自动化测试

  6. 收集测试结果,发邮件给QA团队

对应的Fastfile如下(简写,还未真正使用): 

这样以来,一个团队内的客户端,前端,后端的持续集成和持续交付就能够统一部署,统一管理,统一维护,从而在基础设施上能够尽可能满足团队对自动化的需求,何乐而不为呢。

结语

本次分享只是带大家领略了一下Fastlane的风采,针对诸如:如何自定义Action,Plugin,如何在Andriod平台上使用的细节,如何应用在自动化测试场景,以及一些Fastlane的高级用法等,我会在接下来的一段时间内做出相应的整理,形成文章,以供大家参考。

由于本人的水平有限,难免会有错误和疏漏,也欢迎各位同学指正,如果大家在Fastlane的使用上,有更好的案例,也欢迎交流和分享。

最后,附上一个我们团队正在使用到的Fastfile脚本和一些自定义Actions:https://github.com/GengmeiRD/Fastfiles

另外,Fastlane也提供了一些国外团队的Example:https://github.com/fastlane/examples

QA节选

Q:Testflight很不稳定,为什么从FIR转到Testflight?

A:我用了这么久,感觉Testflight还是比较稳定的,另外我们测试环境下还是用Fir,在生产环境线上跟测的时候才会使用Testflight(可以理解为预发布)。

Q:Fastlane一次执行多个命令,如果命令执行失败,如何快速定位问题或者说如何确定是哪个命令出错?你的架构图里有日志解析服务,是否与这个有关?

A:一般情况下,可以看对应的log,里面会有详细的出错描述。

Q:大型的移动项目中,一般会涉及到插件化的开发,当然很多公司使用的使用 module 上传maven,主工程引用。不管是哪种, 都会涉及到多工程的协同。比如我们要发包,需要各个工程都更新代码,然后是插件工程编译发包,最后是主工程编译发包。那Fastlane 可以处理的这种情况么?

A:这个我们也正在考虑中,目前能做到的只是aar文件的发布。

Q:我之前在做Fastfile时候写一些action遇到点问题,例如写latest_testflight_build_number总是报错,有没有办法可以捕捉错误?是不是要学Ruby语言?

A:需要一些Ruby的基础,建议学习一下,Ruby本身并不难。

Q:是不是项目一定要用pod,如果没有用pod的是不是会有问题?

A:不是,如果用carthage管理的,一样可以。

Q:有没有试着用于React Native?会有问题吗?

A:虽然没有用过,但是从原理上来说,不会有问题的

Q:Jaguar有没有开源,github地址是什么?

A:计划之中,只不过目前成熟度还没有达到我的预期,另外需要剥离一些实际的业务,争取年底之前开源出来。

Q:如果想自建一个发布平台有什么建议么或者有什么主意的地方?建这么一个平台要多少人力成本?

A:建议直接用Ruby来写了,可以和Fastlane做无缝集成。我们建立Jaguar大约投入了1个半工程师,前前后后不到一个月的时间。

Q:服务器数量和配置需求?

A:我们用了一台Mac Mini就搞定了。

Q:请问你们实际应用中是用了一台mac mini专门作为服务器吗? fastlane工作中资源占有量是怎么样的?你们大概一天要运行多少次fastlane脚本。小公司用程序员的开发用mac,拿一部分资源做服务器就可以是吧?

A:是的,一台Mac Mini,Fastlane本身开销很小,主要是xcbuild等命令比较耗资源,我们大概每天跑20-25次左右。用个人Mac没有问题的。

Q:现在你们iOS项目从开始编译到QA收到版本多长时间?

A:看项目的大小了,一般5分钟-10分钟不等,Android的会快一些。

扫描二维码关注移动开发前线,发现更多移动开发好文章!

评论