大规模自动化移动交付

Fastlane最佳做法

大规模使用Fastlane的旅程始于为一个团队开发的iOS应用程序构建全自动连续交付系统。 这发展成两个移动应用程序: 一个由多个团队开发的Android应用程序和一个iOS应用程序。 当然,这些团队采用了不同的工具集,各种测试环境以及不同的应用程序配置。

带着我的羽毛,我被要求在两个平台上的许多应用程序中执行相同的操作,这些应用程序具有许多开发团队,许多环境和许多外部资源。 我有提到“很多”吗?

要使数十个团队的数百名开发人员的工作自动化,从而为数十种移动应用程序做出贡献,是很困难的。 团队具有不同的开发方法,架构,工具,发布节奏和门控要求。 要实现这些折衷的交付目标,就需要删除手动流程,提高自动化可靠性,并使团队能够灵活地定义和支持各种流程。

首先,让我们奠定Fastlane基础,然后深入研究解决许多不同目标的实施细节。

您可以在GitHub上找到完整的代码示例集。

访问 Scaling iOS CI / CD的4课 ,了解此过程的其他方面,包括构建可 伸缩的iOS 执行环境以及我们在此过程中面临的三个挑战(环境不一致,容量有限和CI / CD不够灵活)。

Fastlane 101 —基础知识

Fastlane是一个非常活跃的开源项目,使用Ruby实现,目前由Google赞助。 项目维护者可以迅速响应社区提出的问题,并热烈欢迎外界的贡献。 Fastlane作为统一框架,可为iOS和Android应用程序定义自动化流程。 它甚至可以更好地将流程定义与使用这些流程的项目一起移入版本控制中。

“ Fastlane是为您的iOS和Android应用自动执行Beta部署和发布的最简单方法。 🚀它可以处理所有繁琐的任务,例如生成屏幕截图,处理代码签名以及发布您的应用程序。” — Fastlane文档

Fastlane术语

  • 项目 :利用Fastlane的代码库。
  • Fastfile :包含使用Fastlane特定于域的语言(DSL)进行项目编码的文件。
  • action :在Fastfile(文档)中使用的单个可配置操作。
  • 车道 :构成一个过程的动作的集合。 通道可以调用其他通道。
  • private_lane :只能由其他通道调用的通道,不能直接在命令行(文档)上调用。
  • function :一个封装逻辑的Ruby函数,可以在单个Fastfile中重用而无需更改通道。
  • plugin :一个Ruby宝石,封装了其他现成的未提供的动作。

开发期间:

  • 构建 :使用调试构建设置
  • 二进制 :带有开发证书签名
  • 部署内部分发给测试人员的位置
  • 报告 :向开发聊天频道发送消息

发布期间:

  • 构建 :使用发布构建设置
  • 二进制 :准备发布,带有生产证书签名
  • 部署 :类似生产的分销渠道
  • 报告 :向发布聊天频道发送消息

配置方法(tl; dr:使用dotenv和lane_context。)

为了保持规模清晰,必须保持流程与该流程的配置脱钩。 通过根据持续集成的租户尽可能频繁地测试过程本身,这也可以使过程变硬。 Fastlane提供了几种动作配置方法。 直接操作配置,特殊配置文件和“ dotenv”。 我将在下面进行介绍。 tl; dr:使用dotenv和lane_context。

直接动作配置

直接在Fastfile内的action调用的参数上设置配置值可以有效地将值硬编码为一个值和一个值。 Ruby语言可以直接在Fastfile中使用以提供变体。 但是,这很快就会变成复杂的代码,而不是简单的配置。

请参阅 GitHub上的 代码示例

特殊配置文件:Appfile,Deliverfile,Scanfile

为了提供更多的灵活性,Fastlane提供了一系列配置“文件”,这些文件为主要内置操作的某些设置提供了一些配置。 当您的过程没有复杂性时,这些文件很好。 但是,随着过程的发展,这些文件可能会很快失去其用途。

这些文件不支持所有设置,并且不能配置大量的操作和插件。 最终,将需要多种配置方法,从而导致配置状态的清晰度降低。

在GitHub上 查看 代码示例

Dotenv

为了获得最大的灵活性,请使用基于环境变量的配置和相应的dotenv文件来实现配置变化。 您还可以在调用Fastlane之前在外壳程序中设置值。 但是,dotenv文件允许正确配置配置。 要使用基于环境的配置文件,请使用附加参数执行Fastlane: fastlane my_lane --env release 。 即使没有附加参数,您也可以使用默认的.env文件存储您的配置值。

无需在Fastfile中引用通过环境变量配置的变量,操作将自动拾取它们! 另外,请注意,直接在操作上配置的任何值都将取代所有漂亮的dotenv值。

使用环境变量时,复杂的数据类型(例如数组或映射)可能会很棘手。 避免开发需要复杂输入的操作或实施基本解析器以使配置易于管理。 只有一个 开箱即用的操作和现有的插件中很少有这种情况,但是值得一提。

请参阅 GitHub上的 代码示例

dotenv配置值层次结构

首先要注意的是, 始终会加载默认的.env文件,然后根据命令行上指定的内容加载其他文件。

当不传递任何特定的环境文件以在命令行上加载时(例如fastlane my_lane ),根据有关变量加载的dotenv规则,同名的系统环境变量将优先于默认.env文件中设置的值。订购。 当您希望执行环境控制或更改某些配置时,这很方便。

当在命令行上传递特定环境时,Fastlane通过使用Dotenv.overload稍微更改规则。 和以前一样,同名的系统环境变量优先于默认.env文件中的值。 然后,最后加载的.env文件中的值优先于所有其他值。

尽管这些规则有细微差别,但它们是有限的。 其他配置模型可以具有各种程序设计。 一旦适当扩展了配置模型,团队就可以开始构建和控制自己的流程。

请参阅 GitHub上的 代码示例

Fastlane插件拥抱创新

拥有大量开发团队和项目的大型组织通常需要为其各自的自动化流程提供非常相似的功能(例如,安全扫描,代码质量扫描,工件交付等)。 此外,允许团队掌控自己的流程,可能会导致整个组织内Fastlane实施方式各异而又相似。

团队使用其他项目的副本创建新项目,并使用复制和粘贴功能。 这些常见的开发实践导致各种困难,例如,使项目保持最佳实践的最新状态,纠正重大故障以及保持一致的支持(仅举几例)。 无法发现不同团队开发的可用功能也阻碍了功能的采用。

幸运的是,Fastlane已将其覆盖! Fastlane在2016年下半年增加了一个强大的插件架构,社区对此做出回应,在214个现成的fastlane操作中添加了350个插件(大约2/1/2019)。 使用Fastlane插件开发进一步的功能有助于缓解成长中的烦恼。 如果新功能是针对特定业务的,并且/或者尚未在开源Fastlane插件库中创建功能,请执行以下操作: 该功能需要开发。 采用Fastlane插件的演化开发生命周期可带来最佳结果。

Fastlane插件开发生命周期

首先,需要此功能的开发人员直接在Fastfile中添加功能,以实现最快的反馈周期。 当功能变得复杂并依赖于其他库或更详细的配置时,这是相当有限的。

直接在Fastfile中开发功能

随着功能开发的继续,代码将移至项目的fastlane文件夹中的actionshelpers文件夹。 在此,将动作代码转换为实际动作类,并对输入和输出进行布局和固化。 在此阶段,代码将继续与应用程序一起交付,并从Fastfile调用作为正式操作。 实际上,不可能在原始代码库之外共享此功能。 但是,现在代码已正确格式化为插件,并且可以通过gem传递动作以与其他使用者共享。

在GitHub上 查看 代码示例

随着与其他代码库共享动作的需求越来越大,使用Fastlane new_plugin命令最终确定了名称和元数据文件。 然后,动作和帮助程序文件将从项目中移出,进入样板结构。 开发人员按照文档中的其余步骤完成转换为可发布的gem。

在GitHub上 查看 代码示例

最后,就像其他Fastlane插件一样,开发人员将已发布的gem集成到任何项目(包括原始项目)中。

在开发不会开源的插件时,确保它们在易于发现的地方进行开发非常有价值。 一个单独的Github组织工作得很好。

版本漂移

将功能打包到可共享的插件中(在Fastlane情况下为Ruby gem),有助于集中重复数据删除工作并提供安全且有目的的更新策略。 在外部维护并推广以适应许多需求的宝贵功能将不可避免地导致消费者数量的增加。 消费者有责任确保他们定期更新。 版本漂移的问题不是Fastlane独有的。 这是产生或使用外部库的软件开发中常见的问题。

结论

事实证明,本文中详述的技术在允许大量团队为大量应用程序做出贡献的同时非常成功,同时又使其既灵活又易于支持。 与命令执行器进行编码和分离的过程导致需要使用各种工具进行试验,而无需进行大量重构。 最后,在进一步集中化的同时仍将注意力集中在可扩展性和所有权上,将为开发人员创造更多机会,使他们能够快速,轻松地实现流程自动化。