适用于iOS应用程序的Bitrise Fastlane集成

有关如何将fastlane(iOS和Android的CD工具)集成到Bitrise中以及如何在 Bitrise 上运行相同命令的 逐步指南

Moses Kim的来宾帖子。 原始帖子出现在 Shakuro博客上

本文基于对移动开发人员Sergey Laschuk和Ruslan Krohalev的采访。 摩西是Shakuro数字产品代理商的作家。 他喜欢研究技术,体验设计和武术。

在自动化测试以及构建Web和移动应用程序的部署方面,有几种完善的持续集成服务。 然而,Bitrise在2017年获得了广泛的宣传,并拥有在2018年获得更多关注的所有好机会。

什么是Bitrise

Bitrise是一个主要致力于移动开发的持续集成平台。 持续集成(CI)是在特定的时间表上将开发人员构建副本合并到共享主线的一种普遍接受的做法。 换句话说,这是一个用于版本控制和复制部署的工作流,而不会失去对开发过程的跟踪。

Bitrise允许创建包含构建步骤的多个工作流程。 一个应用程序可以为其定义多个工作流程,还可以使用webhook来指定为哪个触发器(webhook)选择了哪个工作流程。 映射到工作流程的触发器使用预定义的工作流程启动构建。

对构建步骤进行编程,以执行由命令行脚本实现的各种功能。 记录所有虚拟机构建步骤,以保留工作流每一步的信息。

我们与Bitrise合作的项目

Bitrise允许Jira集成,这对我们来说是个不错的选择,因为要实现的所有功能,时间跟踪和估算都是由我们公司的Jira运行的。

构建自动化

到目前为止,我们已经在两个主要的移动开发项目上使用了Bitrise,其中一个是已经在App Store上运行的iOS应用程序。 凭借每天生成的新版本,Bitrise可以自动将主版本更改货件自动交付给App Store测试。 工作流还配置为仅在实施更改后才交付新的版本。 因此,产品负责人仅收到有关已发货的重要产品的信息。

测试自动化

新功能会自动进行测试,如果发现错误,则不会提供任何构建。 最新的Bitrise功能之一允许在设备模拟器上运行功能用户测试。 如果这些单元测试中的任何一个失败,则通知将直接发送给开发人员。

对于我们的一个iOS应用,每天都会从项目GitHub存储库上的提交收集所有消息。 在本周或冲刺结束时,或在具有里程碑意义的情况下,产品负责人(客户)提出了对修补程序的描述以及添加到内部版本的新功能。 提交随附的文件中列出了所有功能和修复。 这些描述的组合由Bitrise自动化。

总而言之,每次上传到TestFlight最多需要1个小时。 但是,由于它是由Bitrise虚拟机完成的,因此对我们来说不算什么。

什么是快车道

Fastlane是适用于iOS和Android的持续交付工具。 Fastlane是用红宝石编写的工具,可以通过红宝石宝石安装。 与Bitrise一样,Fastlane也有构建步骤,称为“动作”。 每个动作都是必须执行才能获得某种结果的任务。

可以将所有Fastlane动作收集到称为Lanes的单个实体中。 泳道就像Bitrise中的工作流。 当在Fastlane中运行通道时,如果任何一个操作执行不正确,则会执行该通道中的每个操作,并且构建失败。 通道在称为Fastlife的文件中定义。

在所有类似方面,Bitrise和Fastlane并不冲突且彼此重复,但是正如我们发现的那样,Fastlane可以大大补充Bitrise在移动开发项目中的参与。

因此,在我们的情况下,Bitrise从各个步骤和工作流中组装构建,并利用脚本收集消息并形成构建描述,而Fastlane用于自动化两个子功能:

  • 自动生成描述信息。
  • 自动化的图标版本标志更新。

Bitrise Fastlane集成

假设您在iTunes Connect和developer.apple.com上拥有一个包含所有应用程序ID和规定的iOS项目,这就是将Fastlane集成到Bitrise工作流程的方法:

  1. 安装fastlane。

2.导航到项目目录:

cd  

3.初始化项目的快速通道配置:

 fastlane init 

4.输入您的Apple ID和密码,以验证iTunes Connect上是否存在具有正确应用ID的应用。

5.如果您是developer.apple.com和iTunesConnect上多个团队的成员,请指定您的团队。

注意:请准备好您的iTunes Connect团队ID,因为以后需要它*。

6.导航到./fastlane/Appfile ,检查文件是否包含正确的信息( pp_identifierapple_id, team_id )。 *输入itc_team_id

7.导航到./fastlane/Fastlane并应用以下更改:

7.1保留fastlane init指定的fastlane init

7.2同样适用于default_platform 。 对于iOS项目,它必须是default_platform :ios

7.3由于before_all取消了所有依赖关系管理,因此将before_all块保留为空。

7.4除去所有lane ,只有我们需要的一个。

7. 5清空after_allerror块,因为所有其他步骤将由Bitrise处理。

8.配置您的车道。

9.在“ gym”操作中指定供应配置文件(请参见下面的示例)。

10.通过ENV['VAR_NAME']使用环境变量(请参见下面的示例)。

11. Fastfile的示例:

 fastlane_version "2.66.2" 
default_platform :ios
platform :ios do
before_all do
end
desc "Submit a new Beta Build to Apple TestFlight"
lane :beta do
# Add a badge to app icon. This will actually overwrite images, so be careful.
# More info: https://github.com/HazAT/fastlane-plugin-badge & https://github.com/HazAT/badge
add_badge(
alpha: true,
shield: "v#{ENV['XPI_VERSION']}-#{ENV['XPI_BUILD']}-grey"
)
#build app
gym(
export_method: "app-store",
export_options: {
provisioningProfiles: {
"app.bundle.id" => "Your Provision Profile Name",
}
},
scheme: "YourSchemeName")
# Upload build to testflight & set field "what's new"
pilot(
changelog: ENV['WHATS_NEW_MESSAGE']
)
end
after_all do |lane|
# This block is called, only if the executed lane was successful
end
error do |lane, exception|
end
 end 

12.要将项目上传到App Store,请使用Fastlane deliver工具的Deliverfile 。 但是,由于我们仅将其上传到TestFlight,因此该文件无关紧要。

13.通过gem使用插件(如果有)。 为此,请安装它:

 sudo gem install bundler 

14.在项目目录中使用特定内容创建Gemfile 。 在下面的示例中,我们添加了“徽章”插件。

 source "https://rubygems.org" 
gem "fastlane"
gem "fastlane-plugin-badge", git: "https://github.com/HazAT/fastlane-plugin-badge"

15.安装/更新gem:

 sudo bundle update 

16.将新文件推送到Git存储库。

17.在您的Bitrise工作流程中,设置以下参数:

17.1激活SSH key (RSA private key) –使用您的凭据访问Git。

17.2 Git Clone Repository –拉分支。

17.3 Certificate and profile installer –供应配置文件的关键步骤。 请在Bitrise上的工作流编辑器中查看“代码签名”选项卡。 上载App Store和开发提供配置文件,开发和分发证书。

17.4 Run CocoaPods install –安装,更新和运行CocoaPods(如果您的项目使用它们),并且您没有将Pod文件提交到存储库中。

17.5如果您的项目迅速检查代码的格式,请Brew install 。 将swiftlint指定为“要安装/升级的公式的名称”,然后为“如果先前已安装,则升级公式”选择“是”。

17.6 Set Xcode Project Build Number –增加Info.plist内部版本号。 一个不错的解决方案是将内部版本号字段添加到$BITRISE_BUILD_NUMBER 。 这将使TestFlight中的内部版本号与Bitrise上的内部版本号同步。

17.7 Xcode Project Info –将版本和内部版本号从Info.plist提取到环境变量。

17.8 Xcode Test for iOS –确保新版本的单元测试通过。

17.9 fastlane —运行fastlane。 指定必须运行的通道。 在上面的示例中,它是beta。 检查Working directory参数,并确保它是正确的。

17.10 Script 'push build number changes'是一个脚本,用于Script 'push build number changes'推回到Git中:

 git commit ./MetroApp/Metro/**/Info.plist -m "[version update] [ci skip]" 
git push origin "$BITRISE_GIT_BRANCH"

Git tag –将有关新版本的标签添加到当前分支。 Tag to set on current commit的标签是标签字符串本身。 在我们的示例中,示例为exampleapp-testflight-$XPI_VERSION-$XPI_BUILD.

18.转到工作流编辑器中的“秘密”选项卡,然后添加FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORDFASTLANE_PASSWORD变量。 将它们的值指定为您在Appfile作为apple_id输入的Apple帐户的密码。

19.确保已将正确的配置文件和证书上载到工作流编辑器的“代码签名”选项卡。 在运行该页面上提到的工具之前,请确保至少已将一次构建手动上传到TestFlight。

这种集成使我们的iOS应用程序构建可以在45-50分钟内完成组装,而大部分时间都花在了在App Store和TestFlight上进行处理。

到目前为止,我们使用的最方便的功能之一是允许与GitHub,Jira或其他一些进度跟踪工具集成的工作流交互。 合并之前,已实现的任务将在项目分支中进行测试。 我们过滤测试并在此之后合并主版本,这意味着任务可以关闭。

另一种选择是将任务传递给测试工程师,以将构建合并到阶段。 每个新的合并都是一个新版本。 在分阶段进行所有工作之后,经理会知道这些构建中的哪一个是最合适的,并且可以选择发布。 这还不是完全自动化,但是Bitrise Fastlane组合是发布应用程序构建的一种好方法。

有用的Bitrise脚本

该脚本收集提交消息并将其导出到Jira票证。 在此脚本中,分支的前缀等于吉拉票证的前缀(例如MET-66)。 该脚本将消息导出到名为WHATS_NEW_MESSAGE的Bitrise环境变量:

 #!/usr/bin/env bash 
 # fail if any commands fails 
set -e
#debug log
set -x
 # get previous tag 
PREVIOUS_TAG=$( git describe --abbrev=0 --match "*metro*" )
 # get commit messages from previous tag and extract only uniqu task identifiers from them 
# this will leave something like this:
# MET-1
# MET-3
# MET-89
TASK_IDS=$( git log --pretty=oneline "$PREVIOUS_TAG"..."$BITRISE_GIT_BRANCH" | sed 's/m/M/g' | sed 's/e/E/g' | sed 's/t/T/g' | grep -E '.*(MET-[0-9]+).*' | sed -E 's/.*(MET-[0-9]+).*/\1/' | sort | uniq )
 # check, that there are new feature-branches merged 
if [ $TASK_IDS -ge 4 ]
then
echo "Found no new merges. Exciting..."
exit 1
fi
 # transform task ids into Jira links 
MESSAGE=$( echo "$TASK_IDS" | sed 's|\(.*\)|http://j.shakuro.com/browse/\1 (\1)|' )
 echo "Processed changelog:" 
echo "$MESSAGE"
 # export message as a global variable into Bitrise environment 
envman add --key WHATS_NEW_MESSAGE --value "$MESSAGE"