Fastlane 是 iOS 开发中的一颗明珠,有时人们并不常谈论它,因为它非常实用。幸运的是,我将通过一个冗长的演示、代码示例以及包含一个工作 Fastlane/Travis CI 项目的 GitHub 存储库来向大家介绍它。
Fastlane 是一个 Google 项目,我一直觉得它非常有用。经过一整天的研究,我终于成功使用了 Fastlane。在我看来,这个工具在实际拆分测试方面仍然非常有用。我看到有些人遗忘了一些简单的事项,就是简单的开始。所以,在这种情况下,让我们按下继续按钮,开始吧!
如果您想在开始之前 查看我的仓库,请随意!
在使用 Fastlane 时,您应该牢记,如果您要从命令行将参数传递到您的轨道,请使用以下语法
fastlane [lane] key:value key2:value2
fastlane deploy submit:false build_number:24
理论上,您可以拥有任意数量的 lanes
,因此您可以调用不同的 lanes
。例如
before_each do |lane, options|
# lane number (Montana likes # 3)
end
现在在轨道内部,您可以 INVOKE 其他轨道来实现各种其他目的,换句话说,每个轨道本质上可以具有不同的功能
error do |lane, exception, options|
if options[:debug]
puts "This is a cool lane because you're in it with Montana"
end
end
如果您长时间使用过 Fastlane
,您就会知道切换 lanes
通常被称为 lane hopping
。您可以合理地进行轨道跳转,而无需使用太多 CPU
lane :deploy do |options|
# lane 3
build(release: true) # don't forget this part! - Montana
Montana Mendy
# invoking lane 4 with a conditional
end
就像您查询任何内容一样,您可以检索返回值,在本例中,它是通过 lane callback
实现的。在 Ruby 中,轨道定义的最后一行是返回值。以下是一个示例
lane :deploy do |options|
value = calculate(value: 3)
puts value # => 5
end
lane :calculate do |options|
# ...
2 + options[:value] # This is always the return value line. - Montana
end
理论上,您永远不想到达 lane
的结尾,如果到达了,您就不会再执行很长时间了
lane :build do |options|
if cached_build_available?
UI.important 'Montana cached this Lane!'
next # Montana is skipping doing the rest of this lane
end
match
gym
end
private_lane :cached_build_available? do |options|
# ...
true
end
因此,在执行 lanes
时,您可以使用条件语句,例如 next
在 lane
和 switch
中使用,control
会返回到之前执行的轨道,因此 lanes
理论上可以来回切换。
lane :first_lane do |options|
puts "If you run: `fastlane first_lane`"
puts "You'll see this!"
second_lane
puts "Montana is in this lane!"
end
private_lane :second_lane do |options|
next
puts "Hidden!"
end
当您使用 next(lane switching
)提前停止执行 lane
时,您拥有的任何 after_each
和 after_all
块仍将按预期触发 :+1:
。这包括在您切换到的每个轨道之前被调用(通过 lane callback
)。
before_each do |lane, options|
# ...
end
所以,这是一个来自我的一个好的提醒,在执行 after_each
块时(同样,通过 lane callback
)会在调用任何轨道之后被调用。这包括在您切换到的每个轨道之后被调用。就像 after_all
一样,如果发生错误,after_each
不会被调用。在这种情况下,应该使用错误块。
在所有这些情况下,before_each
和 after_each
会被 lane callback
调用 4 次。请记住,在部署轨道之前,在切换到存档、签名和上传之前,以及在这之后,许多用户都忘记了这一点。
现在,Fastlane
具有不同的操作,这些操作可以使用共享哈希相互通信,换句话说,就是与其他 lanes
通信。您可以在(轨道、操作、插件等)中访问它
lane_context[SharedValues::BUILD_NUMBER] # Generated by `increment_build_number`
lane_context[SharedValues::VERSION_NUMBER] # Generated by `increment_version_number`
lane_context[SharedValues::SNAPSHOT_SCREENSHOTS_PATH] # Generated by _snapshot_
lane_context[SharedValues::PRODUCE_APPLE_ID] # The Apple ID of the newly created app
lane_context[SharedValues::IPA_OUTPUT_PATH] # Generated by _gym_
lane_context[SharedValues::DSYM_OUTPUT_PATH] # Generated by _gym_
lane_context[SharedValues::SIGH_PROFILE_PATH] # Generated by _sigh_
lane_context[SharedValues::SIGH_UDID] # The UDID of the generated provisioning profile
lane_context[SharedValues::HOCKEY_DOWNLOAD_LINK] # Generated by `hockey`
lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] # Generated by `gradle`
lane_context[SharedValues::GRADLE_ALL_APK_OUTPUT_PATHS] # Generated by `gradle`
lane_context[SharedValues::GRADLE_FLAVOR] # Generated by `gradle`
lane_context[SharedValues::GRADLE_BUILD_TYPE] # Generated by `gradle`
为了合理地获取有关可用轨道变量、可切换的轨道的信息,请运行 fastlane action [action_name]
或查看操作文档中生成的表格。
动态访问当前轨道的某些属性可能很有用。这些属性也在 lane_context
中可用
lane_context[SharedValues::PLATFORM_NAME] # Platform name, e.g. `:ios`, `:android` or empty (for root level lanes)
lane_context[SharedValues::LANE_NAME] # The name of the current lane preceded by the platform name (stays the same when switching lanes)
lane_context[SharedValues::DEFAULT_PLATFORM] # Default platform
它们也可以作为环境变量使用
ENV["FASTLANE_PLATFORM_NAME"]
ENV["FASTLANE_LANE_NAME"]
有时,您可能有一个轨道,该轨道是从不同的轨道或从 hopped lane
中使用的
lane :production do
# ...
build(release: true)
appstore # Deploy to the Montana's brain
# ...
end
->
lane :beta do
# ...
build(release: false)
crashlytics # Distribute to testers
# ...
end
->
lane :build do |options|
# ...
Montana likes beer
# ...
end
It probably doesn't make sense to execute the build lane directly using fastlane build. You can hide this lane using
->
private_lane :build do |options|
# ...
end
这将隐藏轨道
fastlane lanes
fastlane list
fastlane docs
此外,您不能使用 fastlane build 调用私有轨道。结果的私有轨道只能从另一个轨道使用轨道切换技术或 lane callback
调用。
一般来说,配置文件只接受为特定配置项提供的第一个值。这意味着对于以下这样的 Appfile
app_identifier "com.used.id"
app_identifier "com.ignored.id"
因此,the app_identfier
将为“com.used.id”,第二个值将被忽略。对于 for_lane
和 for_platform
配置块,此规则存在有限的例外。
所有配置文件(Appfile、Matchfile、Screengrabfile 等)都可以使用 for_lane
和 for_platform blocks
来控制(和覆盖)这些情况下配置的值。
因此,for_lane
块将在命令行上调用的轨道名称与块中指定的名称匹配时被调用。因此,对于以下这样的 Screengrabfile
对于语言环境(语言轨道):locales ['en-US', 'fr-FR', 'ja-JP']
for_lane :screenshots_english_only do
locales ['en-US']
end
for_lane :screenshots_french_only do
locales ['fr-FR']
end
如您所见,语言环境默认情况下将具有值 [‘en-US’, ‘fr-FR’, ‘ja-JP’],但仅在运行 fastlane screenshots_english_only
或 fastlane screenshots_french_only
时才具有一个值。
然后,for_platform
会根据您调用 fastlane 的平台提供类似的控制。因此,对于配置为以下这样的 Appfile
app_identifier "com.default.id"
for_lane :enterprise do
app_identifier "com.forlane.enterprise"
end
for_platform :mac do
app_identifier "com.forplatform.mac"
for_lane :release do
app_identifier "com.forplatform.mac.forlane.release"
end
end
因此,现在您可以预期在调用 Fastlane mac release 时,app_identifier
等于“com.forplatform.mac.forlane.release”。
是的,您可以这样做。我通常的做法是创建两个 fastlane 轨道,一个用于旧位置,另一个用于新位置,因此您的新脚本看起来像这样
cd old-location
fastlane old_lane
cp -r old-location new-location
cd new-location
fastlane new_lane
我的猜测是,无论您的项目范围如何,您都有不止一个 bundle
标识符来标识不同的应用程序。
请记住,使用 Fastlane,您可以设置一个新的目标,只需创建具有不同方案的相同轨道即可(或创建函数并发送正确的方案作为参数)。您还需要创建一个不同的 bundle id
。
如果您不想创建不同的目标,并且您使用的是项目中的自动签名(一些 SSO),则必须将其更改为手动签名并在其中指定配置文件。
请确保没有任何内容会与 Travis 或 Fastlane 冲突,因此它应该看起来像这样
生产
build_app(
workspace: "XXXX.xcworkspace",
scheme: "XXXXX",
......
export_options: {
method: "app-store",
signingStyle: 'manual',
provisioningProfiles: {
"bundle id": "Prod profile full name",
}
})
Ad-hoc
build_app(
workspace: "XXXX.xcworkspace",
scheme: "XXXXX",
......
export_options: {
method: "ad-hoc",
signingStyle: 'manual',
provisioningProfiles: {
"bundle id": "Montana's project",
}
})
before_all
或 after_all
?当然可以,在 Travis 和 Fastlane 中都可以做到。一种在某些 lanes
中实现此目的的方法如下所示
before_all do |lane|
if lane == :test
puts "Do something for test"
else
puts "Montana"
end
end
此外
lanes = [:test, :foo, :bar]
lanes.include?(:test) # => true
lanes.include?(:baz) # => false
因此,最终的输出将如下所示
before_all do |lane|
lanes_to_say_foo = [:test, :build, :other]
if lanes_to_say_foo.include?(lane)
puts "Montana"
end
end
祝您构建愉快!如果您有任何其他问题,请随时联系 [email protected],我会尽快在 Fastlane 中回答您的问题。