Fastfile:移动开发中自动化的本质、结构与配置

作者: IT Sectr 发布日期: 2026-04-14 阅读时间: 10 分钟

Fastfile 是 Fastlane 的 Ruby 配置文件,用于定义移动应用程序构建、测试和交付的自动化方案。该文件位于项目根目录的 fastlane 目录中,包含 lanes(命名操作序列)的声明。根据 Fastlane Docs, 2025 的数据,70% 的移动项目使用 Fastfile 进行 CI/CD 流程。Fastfile 用单一的声明式流水线描述取代了数十个 bash 脚本。

要点

  • Fastfile — fastlane/ 目录中的 Fastlane Ruby 配置文件
  • Lane — 具有 action 序列和错误处理的命名方案
  • Action — 带参数的 Fastlane 内置命令(gym、scan、match、deliver)
  • Private lane — 从其他 lanes 调用的内部方案,不可直接启动
  • 参数 — 通过 option 将值传递到 lane 并通过变量访问

什么是 Fastfile 以及为什么需要它

Fastfile 是 Fastlane 的主要配置文件,使用 Ruby 编写,位于项目根目录的 fastlane 目录中。它定义了所有自动化方案(lanes),用于构建、测试、代码签名和交付应用程序。Fastfile 用单一的声明式 CI/CD 流水线描述取代了数十个 bash 脚本、Makefile 和手动指令。

当项目需要在不同的开发机器和 CI/CD 服务器上进行可重复构建时,就需要 Fastfile。与其让每个开发人员手动配置环境,Fastfile 将所有步骤固定在代码中,可以在 Git 中进行版本控制、审查并在项目间复用。统一的 Fastfile 确保开发机器上的构建与 CI/CD 服务器上的构建完全相同。

Fastfile 通过 default_platform 指令支持平台。在一个 Fastfile 中可以描述 iOS、Android 和 macOS 的方案,分组到 platform :ios 和 platform :android 块中。这对于跨平台项目特别方便,因为 iOS 和 Android 构建具有共同的部署逻辑,但使用不同的构建工具。

Fastfile 的结构:lanes、actions 和参数

Fastfile 由三个主要元素组成:平台声明(default_platform)、lane 定义和辅助函数配置。每个 lane 以关键字 lane 开头,后跟方案名称(Ruby 符号)、包含 action 序列的主体以及错误处理块 error、success 或 ensure。

Fastfile 中的 Actions 是对 Fastlane 内置函数的调用,参数为 Hash 格式。例如,gym(scheme: 'App', export_method: 'app-store') 使用指定参数启动 iOS 应用程序构建。每个 action 返回一个结果,可以存储在变量中并在后续 actions 中使用——这允许在 lane 内构建条件逻辑

Fastfile 通过 Ruby 的标准 ENV 机制支持环境变量。敏感数据(密码、令牌、密钥)不应存储在 Fastfile 中——请使用 CI/CD 系统的环境变量或添加到 .gitignore 中的 .env 文件。Fastlane 在启动时自动从 fastlane 目录加载 .env 文件。

Appfile 和 Matchfile

在 fastlane 目录中,除了 Fastfile,还有额外的配置文件。Appfile 包含应用程序标识符(app_identifier)、Apple ID 和 Team ID——这些数据会自动注入到所有 actions 中,无需在每个 lane 中重复。Matchfile 存储 match 的设置:Git 仓库 URL、配置文件类型和加密密钥。

将配置拆分到多个文件简化了具有不同环境的项目的维护。例如,可以为 staging 和 production 在 Matchfile 仓库中创建单独的分支,或通过 CI/CD 系统中的环境变量覆盖参数。

ruby
# Fastfile 基本结构
default_platform(:ios)

lane :build_and_test do
  cocoapods
  scan(scheme: 'App', devices: ['iPhone 15'])
  gym(scheme: 'App')
end

lane :deploy do
  match(type: 'appstore')
  build_and_test
  pilot(skip_waiting_for_build_processing: true)
end

Fastfile 语法:编写 lanes

Fastfile 的语法基于 Ruby DSL(领域特定语言),专门为自动化方案的可读性而设计。Lane 通过 lane :名称 do ... end 结构声明,其中名称是一个 Ruby 符号,成为从终端或 CI/CD 系统启动的 fastlane 名称命令。

在 lane 内部可以使用 Ruby 条件运算符:if、unless、case 用于逻辑分支。还可以使用 each 和 while 循环处理值数组。Fastlane 提供特殊的 before_all、after_all 和 error 块来处理 lane 生命周期事件。

Lane 参数通过 options 哈希传递。当运行 fastlane build --option_name value 时,该值进入 lane 内的 options[:option_name]。可以通过 optional: true 和 type 验证设置默认值,以控制传递参数的类型。

ruby
# 带参数和条件逻辑的 Lane
lane :build do |options|
  scheme = options[:scheme] || 'App'
  export_method = options[:export_method] || 'development'

  match(type: export_method)

  if export_method == 'appstore'
    gym(scheme: scheme, export_method: 'app-store')
    pilot(skip_waiting_for_build_processing: true)
  else
    gym(scheme: scheme, export_method: export_method)
  end
end

iOS 交付的 Fastfile 示例

一个完整的 iOS 项目 Fastfile 包括用于依赖安装、测试、构建以及部署到 TestFlight 和 App Store 的 lanes。让我们看一个示例,涵盖从提交到发布到 TestFlight 进行内部测试的典型 CI/CD 过程。

ruby
# 用于 iOS CI/CD 交付的 Fastfile
default_platform(:ios)

before_all do
  cocoapods(try_repo_update_on_error: true)
  setup_travis if ENV['TRAVIS']
end

lane :tests do
  scan(
    scheme: 'App',
    devices: ['iPhone 15', 'iPad Pro 12.9'],
    output_directory: './test_reports'
  )
end

lane :build_appstore do
  match(type: 'appstore', readonly: true)
  gym(
    scheme: 'App',
    export_method: 'app-store',
    include_bitcode: true
  )
end

lane :deploy_testflight do
  build_appstore
  pilot(
    skip_waiting_for_build_processing: true,
    distribute_external: false
  )
  slack(
    message: '构建已上传到 TestFlight 进行内部测试'
  )
end

在此示例中,before_all 块在每个 lane 之前执行并安装依赖项。tests lane 在两台设备上运行 UI 和 Unit 测试。build_appstore lane 通过 match 签署代码并构建带有 bitcode 的 IPA。deploy_testflight lane 组合所有步骤以完成完整交付。

多目标部署

具有多个目标(主应用、watchOS、widget、Notification Service Extension)的项目需要为每个目标设置单独的 lanes。在 Fastfile 中可以创建一个通用的 :deploy_target lane,它接受方案名称和构建路径作为参数。这使得可以通过 fastlane deploy_target scheme:Widget 为所有扩展运行部署。

为了组织多个目标,在 lane 内使用方案数组和 each 循环。Fastlane 通过 parallel: true 标志支持多个方案的并行构建,这减少了具有扩展的应用程序的 CI/CD 流水线总时间。

Android 构建的 Fastfile 示例

Android 项目的 Fastfile 使用 gradle action 运行 Gradle 任务和 supply action 发布到 Google Play。与 iOS 不同,Android 不需要 match,但使用 Keystore 进行签名,Keystore 存储在仓库之外并通过环境变量传递。

ruby
# 用于 Android CI/CD 构建的 Fastfile
default_platform(:android)

lane :build_release do
  gradle(task: 'clean')
  gradle(task: 'bundleRelease')
  gradle(task: 'assembleRelease')
end

lane :deploy_internal do
  build_release
  supply(
    track: 'internal',
    aab: 'app/build/outputs/bundle/release/app-release.aab',
    release_status: 'completed'
  )
end

签署 Android 应用程序,请在 build.gradle 中配置 signingConfigs 并通过环境变量传递 Keystore 参数:ANDROID_KEYSTORE_PATH、ANDROID_KEYSTORE_PASSWORD、ANDROID_KEY_ALIAS 和 ANDROID_KEY_PASSWORD。Fastlane 自动使用系统 apksigner 签署构建的 AAB 或 APK。

在 Fastfile 中签署 Android

要在 Fastfile 中配置 Android 签名,请使用 sign_android action 或依赖 build.gradle 中的 signingConfigs。Fastlane 通过 Gradle 与 apksigner 集成——将 SIGNING_CONFIG 标志传递给 gradle 任务会使用环境变量中的参数激活签名。这允许在将 AAB 文件上传到 Google Play Console 之前对其进行签名。

为了在 CI/CD 中安全存储 Keystore,请使用 Base64 编码和环境变量。Fastlane 支持 setup_keystore action,它从变量解码 Keystore 并在 before_all 阶段保存到临时文件。lane 完成后,临时文件会自动删除以防止证书泄露。

使用 private lanes 和组

Private lanes(私有方案)是不能直接从命令行调用但可以从 Fastfile 内部的其他 lanes 调用的 lanes。Private lane 通过 private_lane :名称 do ... end 结构声明,用于封装没有意义作为独立方案的重复步骤。

Private lanes 非常适合分组重复逻辑:安装依赖项、配置环境、发送通知。例如,可以创建一个 :setup_signing private lane,从多个部署 lanes 中调用,但不应对开发人员直接可用,以避免错误。

ruby
# Private lane 和分组
default_platform(:ios)

private_lane :setup_signing do |options|
  match(
    type: options[:type],
    readonly: true,
    verbose: false
  )
end

lane :beta do
  setup_signing(type: 'adhoc')
  gym(export_method: 'ad-hoc')
  pilot(distribute_external: true)
end

lane :release do
  setup_signing(type: 'appstore')
  gym(export_method: 'app-store')
  deliver(
    force: true,
    submit_for_review: true
  )
end

通过 platform 块分组 lanes 允许在单个 Fastfile 中分离 iOS 和 Android 方案。platform :ios do ... end 和 platform :android do ... end 结构隔离相应平台的 lanes,而公共 private lanes 可以放在平台块之外以复用。

向 lanes 传递参数

Fastfile 的参数机制使 lanes 变得灵活和可复用。参数在启动时通过命令行传递:fastlane build scheme:App export_method:appstore。在 lane 内部,值通过 options 哈希访问,该哈希作为参数传递给 lane 块。

Fastlane 支持通过 OptionalHash 进行验证的类型化参数。可以设置值的类型(String、Boolean、Integer)、默认值和描述以自动生成文档。环境变量也可作为参数传递的替代方式,适用于 CI/CD 系统。

ruby
# 带类型验证的参数
lane :build do |options|
  gym(
    scheme: options[:scheme],
    export_method: options[:export_method] || 'development',
    include_bitcode: options[:include_bitcode] || false,
    output_name: options[:output_name]
  )
  slack(message: "构建 #{options[:scheme]} 已完成")
end

# 运行:fastlane build scheme:MyApp export_method:appstore

建议为所有可选参数使用默认值,以便可以在不显式指定每个参数的情况下运行 lane。对于必需参数,请在 lane 开头检查值是否存在,如果不存在则通过 UI.user_error! 中断执行并显示清晰的错误消息。

常见问题

移动开发中的 Fastfile 是什么?

Fastfile 是 Fastlane 的 Ruby 配置文件,定义了用于构建、测试和交付 iOS 和 Android 应用程序的自动化方案。该文件位于 fastlane 目录中,包含 lanes——用于 CI/CD 流程的命名操作序列。

如何为 iOS 编写简单的 Fastfile?

在项目根目录创建 fastlane 目录和 Fastfile 文件。添加 default_platform(:ios),声明名为 :build 的 lane,在其中调用 cocoapods 安装依赖项和 gym 进行构建。通过项目根目录终端中的 fastlane build 运行。

Private lane 与普通 lane 有何不同?

Private lane 通过 private_lane 而不是 lane 声明,不能直接从命令行调用。它只能从 Fastfile 内部的其他 lanes 调用。用于封装没有意义作为独立方案的重复步骤。

如何向 Fastfile lane 传递参数?

参数通过命令行传递:fastlane build scheme:App,在 lane 内通过 options 哈希访问。可以使用 || 运算符设置默认值,对于必需参数,在 lane 开头通过 raise 或 UI.user_error! 检查是否存在。

Fastfile 应位于项目中的什么位置?

Fastfile 必须位于项目根目录的 fastlane 目录中。示例:/Users/user/projects/MyApp/fastlane/Fastfile。Fastlane 在从项目根目录启动时自动找到该文件。同一目录中还可以包含 Appfile、Matchfile 和其他配置文件。

总结

  • Fastfile — 定义移动应用程序 CI/CD 方案的 Fastlane Ruby 配置文件
  • Lane — 命名方案,组合一系列 actions,支持参数和错误处理
  • Private lane — 用于封装重复逻辑的私有方案,不可直接启动
  • iOS Fastfile 包含 before_all、测试(scan)、构建(gym)和部署(pilot、deliver)的 lanes
  • Android Fastfile 使用 gradle action 进行构建,使用 supply action 发布到 Google Play
  • 参数通过命令行传递,通过 options 哈希访问,支持默认值
  • Fastfile 与项目一起在 Git 中进行版本控制,确保团队所有机器上的可重复构建

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读