使用Fastlane和Ansible进行iOS连续部署-第1部分

注意:本文已发布在Moonpig Engineering官方博客上。 在这里阅读

在担任Photobox Group的前一职务时,我参与了为iOS部署设置持续集成服务器并为他们配置Ansible的iOS应用程序DevOps实践。 我们使用带有TeamCity的mac Mini服务器的自托管CI解决方案。 在这两部分的文章中,我们将看到我们如何结合Fastlane和Ansible实现iOS应用程序的持续交付。

持续交付(CD)和DevOps实践加快了向最终用户交付新功能的速度。 iOS应用程序开发的快节奏世界可能会受益于DevOps实践,从而可以快速,轻松地将应用程序发布到生产环境中。

在iOS世界中,发布很困难。 它涉及复杂的步骤,例如代码签名以及处理Apple开发和发行证书。 这可能是一个容易出错且耗时的过程。 通过从Xcode本地构建,测试和存档iOS应用程序来完成手动发布。 然后,已存档的.ipa文件需要上传到iTunes Connect。 理想情况下,我们希望使用持续集成(CI)来自动执行此过程,该过程无需人工干预即可将每次提交或合并推送到Apple Beta测试服务TestFlight的主分支。 在本文中,我们将说明如何使用构建自动化工具Fastlane实现持续部署。

Fastlane提供CD最常见的业务收益,但也为其他工程团队带来收益,包括:

  • 消除针对DevOps的DIY,并专注于构建本地iOS功能。
  • 每次合并后,新版本都会自动上载到iTunes Connect。
  • 自动执行重复的升级或设置新CI服务器计算机的任务。
  • 通过源代码管理所有基础结构。
  • 开发人员计算机和CI服务器具有相同的配置。

挑战性

以前,发布我们的应用是一项使命。 部署是一天的马拉松比赛。 我们遵循了本地计算机上传统的,耗时的手动发布方式。 从Xcode构建,测试,存档和上传iOS应用程序非常耗时。 发布中最痛苦的部分涉及下载与分发证书关联的正确的配置文件。 如果我们在上载到iTunes Connect或在生产中的版本中发现问题,则重复此过程将更加痛苦。

为了简化发布过程,我们必须克服以下挑战:

  • 自动化分析,构建,测试,存档并将iOS应用程序上传到iTunes Connect的过程
  • 设置持续集成服务器以使用自动生成
  • 在需要时自动执行重置CI服务器设置的过程(例如,当Xcode版本更改或任何Apple API更改时)
  • 从代码或称为代码的基础架构驱动iOS CI基础架构
  • 确保iOS开发人员计算机和CI服务器上的软件配置相同。 说不可以在我的机器上使用

我们结合使用Fastlane,TeamCity和Ansible工具解决了这些问题。 这些代码段仅供参考,让我们开始吧。

使用Fastlane构建自动化

诸如xcodebuild之类的Apple命令行开发人员工具是一种强大的方法,可用来编写任何我们想自动化的脚本。 但是,我们正在编写的命令可能非常冗长和繁琐。 Fastlane是Apple命令行工具的包装,使构建自动化更加容易。 有一系列Fastlane工具可用于自动执行各种iOS开发任务,例如,“扫描”用于运行测试,“健身房”用于构建应用程序,“飞行员”用于将应用程序上传到TestFlight。

自动化Swift版本检查

自动构建过程的第一步是确保使用正确的软件版本(例如Swift和Ruby)以干净的状态启动CI构建。 Fastlane提供一个before_all步骤,该步骤在所有其他通道之前运行。 您可以阅读有关高级Fastlane的更多信息,以配置此步骤。 我们编写了自定义Fastlane操作,以检查Swift check_swift_version的版本并检查Swift Toolchain check_swift_toolchain。 编写自定义Fastlane动作非常简单。 我们的before_all步骤如下所示:

  before_all做|车道,选项| 
sure_git_status_clean
fastlane_version“ 2.20.0”
check_swift_version(版本:“ Apple Swift版本3.1”)
check_swift_toolchain
clear_derived_data
结束

这样可以确保每个构建都以干净状态和正确版本的工具开始; 以前的版本没有剩余。

自动化XCTest

我们使用Apple的XCTest Framework编写单元和UI测试。 Fastlane通过将xcodebuild中的所有选项包装在Fastlane的“扫描”工具中,使配置XCTest变得容易。 Xcode具有新功能,例如用于测试的构建和无需构建的测试,这意味着我们可以使用.xctestrun文件进行一次构建并进行多次测试。 我们有一个Scanfile,其中存储了所有常见配置,如方案,工作空间和构建配置。 我们的示例车道如下所示:

 车道:build_app_for_testing做 
扫描(
build_for_testing:是的,

结束
  desc“无需构建和生成代码覆盖范围即可运行单元测试” 
车道:run_test_without_building do
扫描(
test_without_building:是的,

xcov(
方案:“ our_test_scheme”,
派生的数据路径:“ ./ build”,
output_directory:“ ./ build / reports / coverage /”,
skip_slack:是

结束

自动化结构部署

我们使用Fabric在团队内部测试调试或临时构建。 我们并不总是需要使用Fabric或Crashlytics进行测试,因此我们仅在需要时进行构建。 当开发人员在提交消息中放入#fabric时,构建将推送到Crashlytics。 有一个快速通道操作将构建推送到Crashlytics,我们只需要提供我们的API_TOKEN和GROUP。 我们的车道看起来像这样:

 车道:distribute_to_crashlytics做 
commit_message = last_git_commit [:message]
如果commit_message.include? “#布”
如果是is_ci,则为递增编号(build_number:build_number)?
健身房(
export_method:“临时”,
配置:“ AdHoc”,

crashlytics(组:“ photobox-pr-reviewers”,注释:commit_message)
其他
将“ ===”暂时跳过Crashlytics构建。=====“
结束
结束

自动化TestFlight部署

苹果公司的TestFlight是对iOS应用进行Beta测试的好方法。 我们使用TestFlight测试要发布到App Store的发行候选版。 自动执行TestFlight构建的过程涉及很多事情:

  • 确保禁用Xcode自动签名
  • 从Info.plist文件获取当前版本和内部版本号
  • 增加特定版本的内部版本号
  • 使用正确的方案,配置文件和证书将构建上传到TestFlight
  • 将构建版本变更提交回主源存储库
  • 在Github上创建和推送标签
  • 创建Github将资产( .ipa )上传到Github版本
  • 发送Slack通知,告知新版本已通过发行说明上载到TestFlight

有很多事情要做! 幸运的是,Fastlane为每个任务提供了动作或插件。 我们使用get_version_number_from_plist插件获取应用程序的当前版本,并使用Fastlane操作Latest_testflight_build_number获取当前的内部版本号。 我们使用increment_build_number操作来增加版本的内部版本号,并使用“发布”配置来构建我们的应用程序。 然后,我们使用Pilot将其上传到TestFlight。 需要注意的一件事是,increment_build_number操作更改了Info.plist文件,我们需要将其提交回源代码以进行将来的构建。 为了提交此文件,我们使用commit_version_bump操作。 Gym现在可以用于构建应用程序。 构建成功上传后,我们会向团队生成一条Slack消息。

我们的示例TestFlight通道如下所示:

 车道:distribute_to_testflight做|选项| 
scheme =“ our_app”
版本= get_version_number_from_plist(xcodeproj:“ our_project.xcodeproj”,目标:“ our_target”,build_configuration_name:“ Release”)
current_build_number = Latest_testflight_build_number(版本:版本)
crement_build_number(
内部版本号:当前内部版本号+​​ 1

testflight_build = current_build_number + 1
健身房(
方案:方案,
export_method:“应用商店”,
配置:“发布”,


飞行员(
skip_submission:否,
Distribution_external:否,
skip_waiting_for_build_processing:是
  slack_message(message:“:airplane:新的版本上传到testflight:版本#{version}&内部版本号:#{testflight_build}”,成功:true,有效载荷:{“ Build Date” => Time.new.to_s, 
“按...构建” =>“ iOS CI服务器”,})
  add_git_tag( 
标签:“#{version}-#{testflight_build}”
  push_to_git_remote( 
远程:“来源”,
local_branch:“开发”,
remote_branch:“开发”,
标签:真

结束

在Github上自动发布

作为我们代码审查过程的一部分,工程师必须在GitHub上创建功能分支,并在构建功能后针对“ develop”分支(主分支)创建拉取请求。 拉取请求必须经过我们的SwiftLint规则和代码审查过程。 拉取请求合并到主分支后,它将触发我们的自动化测试。 如果所有测试均通过,则构建版本将使用递增的构建编号上传到TestFlight。

这意味着到主分支的每个合并都将进入TestFlight,然后可以升级任何内部版本以进行发布。 一旦选择了候选发布版本,诸如.ipa或.dSYM之类的资产就会上传到Github,存储来自先前发行版的工件以及更改日志以供参考。 我们使用Fastlane操作set_github_releases来自动化该过程。

通过此过程,我们几乎实现了针对iOS应用程序的全自动CD过程。

下一个挑战

没有持续集成,就不可能持续交付。 以上所有构建自动化脚本都是从TeamCity CI服务器自动触发的。

在下一篇文章中,我们将讨论在维护CI服务器时面临的挑战,以及如何使用Ansible解决配置管理问题和iOS CI Server的快速设置。 继续阅读第2部分

像XCBlog的 XCTEQ 发布的帖子一样 您可能还喜欢我们的一些服务,例如访客博客或Mobile DevOps(CI / CD)或测试自动化。 Github 搜索我们的 服务 ,开源项目, 或者在 Twitter Facebook Youtube LinkedIn 上关注我们 下载我们的 XCBlog iOS应用程序以离线阅读博客。

X CTEQ 一家专门从事基于Mobile DevOps,CI / CD,Mobile,AI / ML的测试自动化Checkout XCTEQ产品和服务的公司, 网址 http://www.xcteq.co.uk 或写信给我们info@xcteq.co。英国..