如何轻松和安全地构建的满足合规要求的智能产品,实现业务需求?4月26日,告诉你答案! 了解详情
写点什么

Fastlane 实战(五):高级用法

  • 2016 年 12 月 15 日
  • 本文字数:3840 字

    阅读完需:约 13 分钟

经过前 4 篇文章的基础知识和不同的场景介绍后,相信大家已经对 Fastlane 有了一个较为完整的认识,同样,今天我还是结合几个实际的场景,来讲讲 Fastlane 的一些高级用法。

前言

软件开发就像是完成一件艺术品一样,是一个循序渐进,不断打磨的过程。刚开始的时候由于我们对某个语言或框架了解的不够充分,所以往往只停留在实现功能的阶段,而不会过多的考虑到是否能够有更好的特性和更高效的方法来解决问题。

随着编程经验的积累和对语言框架的日益了解,发现之前写过的很多代码其实都存在不少问题,都有不少优化和提升的空间,于是出于责任心和对编程的热爱,我们一定会花时间不断的重构和优化代码,直到自己满意为止。

使用 Fastlane 的过程也同样如此,在第一次发现了这样一个新工具时,心中莫名的兴奋,于是不管三七二十一,立刻就动手使用了,然后随着使用的场景增多,问题也逐渐凸显了出来,于是我们开始探寻 Fastlane 的一些高级用法,以便更高效,更优雅的解决问题。

前置和后置 Action

一般情况,我们在处理 iOS 的自动化流程时,会面临着单元测试,库编译发布,APP 打包等等多种不同的场景,而 APP 打包又需要区分不同的环境,比如:Test,Adhoc 和 AppStore,而这些场景和环境的处理方式是有所不同的,所以针对每种情况,我们都需要编写对应的 Lane,比如我们新建一个名叫ios_fastfile的文件,内容如下:

复制代码
# 单元测试的 Lane
lane :test do |options|
git_pull
cocoapods
xctest
end
# AdHoc 环境打包的 Lane
lane :adhoc do |options|
git_pull
cocoapods
increment_build_number
gym
upload_to_fir
end
# AppStore 环境打包的 Lane
lane :appstore do |options|
git_pull
cocoapods
increment_build_number
gym
deliver
end

当然以上的这个些 Lane 都是简写,只是个示意,实际情况会复杂的多。从这些 Lane 中我们可以看到,每个流程其实都有前置的条件:

  1. git pull 最新的代码
  2. 更新最新的 cocoapods 依赖

所以,大家肯定会问,是否有类似 Ruby on Rails 中 controller 的前置过滤器之类的机制,能够方便的处理这个情况。答案是肯定的,类似这样,在一个 Fastfile 中,每个 Lane 共有的前置流程的情况,我们可以借助 Fastlane 提供的 before_all 方法来处理,在ios_fastfile中我们增加如下的代码:

复制代码
before_all do |lane, options|
git_pull
cocoapods
end

before_all 顾名思义,就是在在执行每个方法之前首先执行的代码,使用 before_all 我们可以将ios_fastfile的代码就可以简化为:

复制代码
before_all do |lane, options|
git_pull
cocoapods
end
# 单元测试的 Lane
lane :test do |options|
xctest
end
# AdHoc 环境打包的 Lane
lane :adhoc do |options|
increment_build_number
gym
upload_to_fir
end
# AppStore 环境打包的 Lane
lane :appstore do |options|
increment_build_number
gym
deliver
end

嗯,看上去代码简化不少,而且以后要添加公用的前置代码,都可以放在 before_all 中进行处理,维护起来非常方便。

另外,Lane 本身和使用到的 Options 参数们也可以很方便的传递给 before_all 方法,这样可以更加方便的处理各种特殊情况,比如:有的 Lane 没有处理 git_pull 的流程,那么我们只需要在方法中加一个判断即可。

当然,除了 before_all 之外,Fastlane 还提供 after_all 来处理共有的后置逻辑,比如:我们在所有的 lane 之后,要通过 Slack 或 Hipchat 通知到相关的工程师们,那么我们就可以把这些 action 写在 after_all 方法中。

复制代码
after_all do |lane,options|
slack(message: "fastlane was successful", success: true)
end

对于每个 Lane 在执行过程中,如果遇到错误,我们也需要通过 Slack 或 Hipchat 等工具通知到大家,此时,我们可以在 Fastfile 中添加一个全局的 error 方法:

复制代码
error do |lane, exception|
slack(message: exception.message, success: false)
end

引用机制

当一项新的技术在团队内部引入的时候,往往会从一个非主业务的项目中进行灰度尝试。我们也不例外,所以我们首先将 Fastlane 引入到我们的医生版的 iOS 客户端中,使用一段时间感觉不错之后,就推广到了 Android 平台和用户版客户端中,最后引入到各种私有库项目的管理中。目前大约涉及到了 30 多个项目,在这个过程中,我们发现了两个问题:

  1. 由于我们自定义了很多 action,那么这些 action 都需要拷贝到各个项目的 fastlane 目录中,这样就导致了一个维护的问题,即:添加或修改任意的自定义 action,都需要去各个项目中处理一遍。
  2. 我们目前的项目按类型分为 4 种:iOS App,iOS Pod 库,Android App,Android AAR 库,对于同样的项目类型,lane 的处理流程基本上是一样的,所以每个相同类型的项目的 Fastfile 基本上都是一致的,这就带来了和 1 一样的问题:如果要修改任意一个项目的 Fastfile,那么就意味着同样也得修改其它同类型项目中 Fastfile,因为这些 Fastfile 都是放在各自项目目录下的 fastlane 文件夹中的。

刚开始项目比较少的时候,手工还可以处理,当项目逐渐增多的时候,问题就愈发严重了,不但要改的地方多,而且还容易出错,于是我们思考是否有能够由一种引用的机制存在,能够在顶层维护一份公用的 action 和 fastfile,这样在项目中只需要引入这些顶层的文件们就能解决上面的问题。

经过仔细研究 Fastlane 的特性之后,我们发现这个问题早就在其作者的考虑之中了。Fastlane 不但提供了引用机制 import,还提供了远程引用模式,即:import_from_git。

有了这个机制之后,我们不但可以在将自定义 action 们和 Fastfile 们统一管理,而且还可以放在 git 上进行远程分布式管理,其带来的好处就是:各个项目只需要在自己的 Fastfile 的顶部进行引用声明即可:

复制代码
# 远程 Git 引用:
import_from_git(url: 'https://github.com/GengmeiRD/Fastfiles', branch: 'master')
lane :appstore do |options|
# ...
end
{1}

这样,每次执行 fastlane 的命令时,首先会从 git 上将需要的文件 clone 这个项目到本地的临时文件夹中,然后再执行相关命令。当然,如果某个项目中,你不想使用远端上的某个 lane,而是需要自定义一份,那么只需要在项目中的 Fastfile 中复写这个 lane 即可:

复制代码
# 远程 Git 引用:
import_from_git(url: 'https://github.com/GengmeiRD/Fastfiles', branch: 'master')
# 复写发布项目的 lane
lane :do_deliver_app do |options|
# ...
end

当然,如果你觉得远程管理这些 action 和 fastfile 们比较麻烦的话,同样可以使用本地引用进行管理,fastlane 提供了两个命令,分别用来引入本地的 Fastfile 和 action 目录:

复制代码
import "../GeneralFastfile"
actions_path '../custom_actions_folder/'
lane :appstore do |options|
# ...
end

我们将团队内部使用到的远程 action 和 Fastfile 管理已经发布到了 github 上,有兴趣的同学可以参考:
https://github.com/GengmeiRD/Fastfiles

上下文常量

在使用 Fastlane 的过程中,我们往往需要一些和上下文相关的常量,比如:AppStore 的账号和密码,ipa 和 dsym 文件的输出的地址,模拟器或设备的 UDID 等等。这些常量如果直接写死在 Fastfile 中显然是不利于维护的。所以我们可以考虑使用以下的方式来处理:

使用 dotenv

首先使用 gem 安装 dotenv ,然后新增一个.env 文件,然后将所有用到的常量定义在里面,比如:

复制代码
WORKSPACE=YourApp.xcworkspace
ITUNESCONNECT_ACCOUNT=your-itunesconnect-account

然后在 fastfile 中使用 ENV 进行调用:

复制代码
lane :appstore do |options|
increment_build_number
gym(workspace: ENV['WORKSPACE'])
deliver(username: ENV['ITUNESCONNECT_ACCOUNT'],)
end

最后将这个.env 文件拷贝到和 Fastfile 的同级目录即可。当然如果有常量需要在多个项目中公用的话(比如:iTunesConnect 的账号),可以建立一个软连接指向同一个.env 文件,然后在目录中创建一个.env.default 文件,放置本项目下专属的常量。

使用 export 命令

如果你使用的是 Mac 或 linux 操作系统,可以在系统的环境的变量中使用 export 命令直接定义系统级别的常量,当然为了不和其它常量冲突,建议增加一个 FASTLANE 前缀,比如:

复制代码
#set env vars
export FASTLANE_WORKSPACE="<YourApp.xcworkspace>"
export FASTLANE_ITUNESCONNECT_ACCOUNT="<your-itunesconnect-account>"

调用方法和使用.env 一样。

复制代码
lane :appstore do |options|
increment_build_number
gym(workspace: ENV['FASTLANE_WORKSPACE'])
deliver(username: ENV['FASTLANE_ITUNESCONNECT_ACCOUNT'],)
end

结语

以上的几个高级用法只是笔者在使用过程中遇到的一隅,更多的惊喜还等待大家自己去探索去发现,官方文档中有全面的介绍: https://docs.fastlane.tools/advanced/

Fastlane 是一个持续维护,快速发展的工具,从笔者的第一篇文章到现在,短短两个月的时间,Fastlane 已经发布了 20 多个版本,在 Github 上新增了 2000 多个 star,同时又多了 100 多位工程师加入到了 Contributors 的大家庭中。事实再次证明优秀的开源项目总能得到大家的认可,关注和参与。

本文是 Fastlane 实战系列的第五篇文章也是最后一篇,希望这个系列的文章能够真正帮助大家了解 Fastlane,也希望看完这个系列的文章后,有更多的同学借助 Fastlane 和各种自动化工具来提升自己的效率,毕竟重复性的劳动和流程化的工作就交给机器们去做吧。

最后祝大家使用 Fastlane 愉快。


感谢徐川对本文的审校。

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

2016 年 12 月 15 日 16:214832

评论 1 条评论

发布
用户头像
您好,有个问题想要请教一下,不知道您能否看到。我在Linux机器上使用fastlane match ,出现错误:/var/lib/gems/2.3.0/gems/fastlane-2.131.0/fastlane_core/lib/fastlane_core/ui/interface.rb:141:in `user_error!': [!] Could not locate the provided keychain. Tried: (FastlaneCore::Interface::FastlaneError)
/root/Library/Keychains/login-db
/root/Library/Keychains/login.keychain-db
/root/Library/Keychains/login
/root/Library/Keychains/login.keychain
/home/www/login-db
/home/www/login.keychain-db
/home/www/login
/home/www/login.keychain
这个问题该如何解决,不胜感激
展开
2019 年 09 月 18 日 18:25
回复
没有更多了
  • 如何构建高效的 Flutter App 打包发布环境?

    在今天的分享中,我与你介绍了如何通过Travis CI,为我们的项目引入了持续交付能力。

    2019 年 10 月 3 日

  • Fastlane 实战(一):移动开发自动化之道

    本人一直认为:在程序的世界里,一切重复性的,流程化的工作都可以交给自动化去完成。 在移动开发中也是如此:其实写代码只是我们开发过程中的一部分,除此之外我们还需要进行编译,打包,上传,部署,库管理,版本控制等等Coding之外的杂事,而正是这些乏味而重复的工作占用了我们宝贵的时间。 所以在“懒人”遍布的工程师世界中,总会有人想尽办法做出改变,于是这些“懒人”们乐此不疲的造出许多美妙的轮子,既方便了自己,又帮助了他人,让这个世界变得更加美好。 今天就给大家介绍其中一个轮子:Fastlane,这个Github上的明星项目截止到目前共获得1万多个Star,并且还有1500多个Fork。

  • Facebook 怎样实现代码提交的原子性?

    Facebook开发者最常使用两种Git工作流:使用一个分支,完成所有需求开发;使用多个分支,每个分支支持一个需求开发。

    2019 年 10 月 23 日

  • 特别放送 | Go Modules 实战

    今天,我通过一个具体的案例,带你一步步学习Go Modules的常见用法以及操作方法。

    2021 年 9 月 21 日

  • Etsy 如何实现移动应用的持续集成

    Etsy的工程师Nassim Kammah在Velocity大会上分享了Etsy实现移动应用开发的持续集成经验。Etsy混合使用了自动化和人工流程,坚持web开发中的相同原则,并且使用了很多相同工具。Nassim还分享了Etsy如何处理移动应用开发带来的特殊挑战。

  • 知乎 iOS 基于 CocoaPods 实现的二进制化方案

    客户端的代码量也越来越大,编译一次项目的时间也越来越长。减少编译时间成了一个不得不面对的问题。framework,没法实现「一次编译,处处使用」的目标。

  • Android 中的单元测试

    由 于Instrument Test使用和运行的不便,在Android项目中对代码添加测试变得非常困难。本文基于项目实践,描述了在实际项目中如何借助于MVP模式和 Robolectric框架,实现逻辑和视图的分离,为代码添加有效完备的单元测试,并简单介绍了Robolectric的实现原理以及如何对其进行扩 展。

  • 构建 iOS 持续集成平台(二)——测试框架

    持续集成理念经过10多年的发展,已经成为了业界的标准。而对于iOS领域来说,因为技术本身相对比较年轻和苹果与生俱来的封闭思想,在持续集成方面的发展相对滞后一些,但是,随着越来越多的iOS开发者的涌入,以及各个互联网巨头加大对iOS开发的投入,诞生了一大批非常好用的持续集成工具和服务,本文的目的就是介绍一下如何有效的利用这些类库,服务快速构建一个iOS开发环境下的持续集成平台。

  • 有赞零售移动 CI/CD 实践

    如何根据现有的团队规模,在有限的资源下,快速搭建稳定可靠的持续集成与交付系统,本文给出了有赞的实践与思考。

  • 使用代码为 Xcode 工程添加文件

    这几天在持续更新 DKNightVersion 这个仓库, 我对这个框架投入了很多的时间和精力.

  • 如何进行高效的 Rails 单元测试

    在笔者开发的系统中,有大量的数据需要分析,不仅要求数据分析准确,而且对速度也有一定的要求的。没有写测试代码之前,笔者用几个很大的方法来实现这种需求。结果可想而知,代码繁杂,维护困难,难于扩展。借业务调整的机会,笔者痛定思痛,决定从测试代码做起,并随着不断地学习和应用,慢慢体会到测试代码的好处。本文忠实的记录了在这个过程中所获得的经验,介绍了如何进行高效的Rails单元测试。

  • 快速构建持续交付系统(三):Jenkins 解决集成打包问题

    通过今天这篇文章,我和你分享了如何快速安装和配置一套有效的Jenkins系统,以及如何打通Jenkins与GitLab之间的访问通道。

    2018 年 9 月 25 日

  • 用 psake 来简化自动化脚本的构建

    psake是一个集成了PowerShell的用来创建自动化脚本的工具,其2.01版本集成了PowerShell2.0。Ayende Rahien正使用它来创建Rhino工具。

  • Fastlane 实战(四):自动化测试篇

    测试覆盖着整个软件开发的生命周期。从需求评审开始,测试工程师就要介入了解需求,并编写用例;开发过程中,研发工程师们会针对测试用例,编写单元测试;开发完毕后,测试工程师介入进行集成测试;上线后还需要进行线上跟测,追踪Bug。所以可以看出,测试对于软件的重要性不言而喻,毕竟可靠的质量才是产品的基本竞争力。

  • CocoaPods 1.0 及相应 Mac 版 App 正式发布,Podfile 的使用方式发生改变

    CocoaPods于近日发布了CocoaPods 1.0正式版,并公开了相应Mac版本的App。CocoaPods 1.0相对以前的版本做了较大的改进,加入了自动反集成,通过将框架集成至实际项目来检查可用性等一系列新特性,更改了Podfile的使用方式。CocoaPods还提供了相应的Mac版App,该App可以帮助开发者方便地为项目添加或编辑Podfile文件,并支持语法高亮。

  • ORM:CURD 神器 GORM 包介绍及实战

    今天,我来详细讲解下GORM的基础知识,并介绍iam-apiserver是如何使用GORM,对数据进行CURD操作的。

    2021 年 8 月 3 日

  • 环境特定的构建工具:Grunt、Gulp 和 Broccoli

    项目的开发、分期和产品版本之间可能会有巨大的改变,这是我们需要基于环境以及特定目标信息改变资源(脚本、样式、模板)、生成标记或者其他内容路径的原因之一。很幸运的是,在Grunt、Gulp和Broccolli生态系统中已经有很多构建工具能够帮助我们完成这些工作。不久之前来自于Google Chrome开发者关系团队的工程师Addy Osmani对解决该问题的三种方式(字符串替代、条件注释和模板变量)做了对比。

  • 有赞 iOS- 基于二进制的编译提效策略

    本文来自《2019年有赞技术大礼包》系列。

  • Spark 灰度发布在十万级节点上的实践

    本文介绍了顶级互联网公司数万节点下 Spark 的 CI 与 CD & CD 灰度发布实践。包含如何维护源代码,如何维护 Release 多版本,开发版与正式版,以及如何实现灰度发布,如何进行 hotfix 等。为了提高本文内容的可借鉴性,隐去了公司特有内容,只保留通用部分 。

  • 特别放送 | 给你一份 Go 项目中最常用的 Makefile 核心语法

    今天,我会重点介绍Makefile规则和一些Makefile核心语法知识,帮助你编写一个高质量的Makefile。

    2021 年 6 月 28 日

发现更多内容

食堂就餐卡系统设计

J.Smile

极客大学架构师训练营

架构第一周-学习总结

J.Smile

极客大学架构师训练营

极客时间<<架构师训练营>>第一周作业

好名字

极客大学架构师训练营 作业 第0期

课后总结-20200606

caibird1984

你现在极有可能是一个「铁锤人」

非著名程序员

读书笔记 程序员 提升认知 认知提升

ARTS week 04

刘昱

内向的程序员如何改变自己,试试摆地摊吧

陆陆通通

程序员 摆地摊 诚信人生

架构师训练营--第一周学习总结

花花大脸猫

极客大学架构师训练营

S型曲线 - 第一曲线

石云升

S型曲线 第一曲线 连续性创新

学习总结

Mr.Monkey

第一周总结 - 架构文档

孙志平

游戏夜读 | 研发运营怎么分成?

game1night

食堂就餐卡系统架构设计

武鹏

架构师训练营--第一周作业

花花大脸猫

极客大学架构师训练营

这个神器让你拥有最佳的打印阅读体验

非著名程序员

chrome 程序员 效率工具 插件

「架构师训练营」第1周学习总结

guoguo 👻

极客大学架构师训练营

java程序员从小工到专家成神之路(2020版)

程序那些事

Java 学习 Java 25 周年

JDK 15 JAVA 15的新特性展望

程序那些事

Java JVM Java 25 周年 新特性

架构师(week1)总结

满山李子

架构师训练营第一周总结

Raymond

陈虻语录(摘)

YoungZY

读书

LeetCode | 3. Roman to Integer 罗马数字转整数

Puran

算法 LeetCode arts

架构师训练营-架构方法:架构师如何做架构

Pontus

极客大学架构师训练营

陆强作业

Mr.Monkey

架构方法论学习总结

架构师训练营第1周——学习总结

在野

极客大学架构师训练营

中台迷局丨只做IT的中台是个神棍

人称T客

如何设计电商行业亿级用户秒杀系统

奈学教育

大数据

SaaS:小企业向左、大企业向右

人称T客

当选择越来越多,我们为什么反而越来越不开心

董一凡

生活 情感

日志标准化解析的关键内容

secisland

日志 态势感知 关联分析 解析规则 标准化

Fastlane实战(五):高级用法_语言 & 开发_邢天宇_InfoQ精选文章