Fastlane 自动化:屏幕截图、打包与发布

FreeGuideOnline 最新 2026-06-17

什么是 Fastlane?

Fastlane 是一套用 Ruby 编写的开源命令行工具,能够将 iOS 和 Android 应用的构建、截图、代码签名、测试、发布等繁琐任务全部自动化。只需一条命令,你就可以完成从代码到 App Store 或 Google Play 上架的所有步骤。

本教程将带你从零开始,学会用 Fastlane 实现 自动截图打包发布,彻底告别手动操作。

环境准备与安装

Fastlane 需要 Ruby 环境。macOS 已预装 Ruby,你也可以使用自带的系统 Ruby(不推荐)或通过 Homebrew 安装 rbenv 管理版本。

# 检查 Ruby 版本(需 >= 2.5.0)
ruby -v

# 如果没有安装 Homebrew,先安装:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# 安装 rbenv 和 ruby-build
brew install rbenv ruby-build

# 将 rbenv 加入 shell
echo 'eval "$(rbenv init -)"' >> ~/.zshrc
source ~/.zshrc

# 安装最新稳定版 Ruby(示例:3.2.2)
rbenv install 3.2.2
rbenv global 3.2.2

# 安装 fastlane
gem install fastlane -NV

# 验证安装
fastlane --version

安装完成后,推荐将 Fastlane 初始化在 Xcode 项目目录下,确保所有命令在项目根目录执行。

初始化 Fastlane

在工程项目根目录执行:

fastlane init

Fastlane 会自动检测项目类型(iOS/Android),并引导你完成初始设置:

  • iOS :需要提供 Apple ID 用于连接 App Store Connect 和开发者账号;
  • Android :需要提供 Google Play Console 的服务账号 JSON 文件路径。

初始化后会生成以下关键文件:

  • fastlane/Appfile:存放 App 标识符、Apple ID 或团队 ID 等全局信息。
  • fastlane/Fastfile:自动化流程的脚本定义文件,所有 lane 都写在这里。
  • fastlane/Matchfile(可选):代码签名管理配置。

现在打开 Fastfile,就可以开始编写自动化任务了。

核心自动化任务:截图

自动截图使用 snapshot 工具,它能自动在多个模拟器上运行 App、录制屏幕并保存高清截图,支持多种语言和设备。

配置 Snapshot

首先,确认你的 Xcode 项目包含 UI 测试目标(没有则需要创建一个)。Fastlane 的截图依赖 UI 测试脚本执行,你需要在测试用例中调用 Snapshot.snapshot("stepName") 来控制截图时机。

示例 UI 测试代码:

import XCTest

class SnapshotUITests: XCTestCase {
    func testTakeScreenshots() {
        let app = XCUIApplication()
        app.launch()
        
        // 主屏幕截图
        snapshot("01HomeScreen")
        
        // 进入详情页
        app.buttons["DetailButton"].tap()
        snapshot("02DetailScreen")
        
        // 关闭详情页
        app.navigationBars.buttons["Back"].tap()
    }
}

然后在 Snapfile(位于 fastlane/ 目录)中定义截图配置:

# fastlane/Snapfile
devices([
  "iPhone 15 Pro Max",
  "iPhone 15",
  "iPhone SE (3rd generation)",
  "iPad Pro (12.9-inch) (6th generation)",
  "iPad Air (5th generation)"
])

languages([
  "en-US",
  "zh-Hans",
  "ja"
])

output_directory "./fastlane/screenshots"
clear_previous_screenshots true
workspace "YourApp.xcworkspace"     # 如果有 CocoaPods 或 SPM
scheme "YourAppUITests"             # 确保是 UI 测试的 scheme

创建截图 lane

Fastfile 中添加 lane:

desc "自动生成多语言多设备截图并上传到 App Store Connect"
lane :screenshots do
  capture_screenshots(
    output_directory: "./fastlane/screenshots",
    clean: true
  )
  # 可选:直接上传截图到 App Store
  # upload_to_app_store(screenshots_path: "./fastlane/screenshots")
end

运行:

fastlane screenshots

核心自动化任务:打包

iOS 使用 gym,Android 使用 gradle。这里以 iOS 的 gym 为例,它会帮你执行 archive 并导出 .ipa 文件。

配置 Gym

大部分参数可以在 Fastfile 中直接指定,无需额外配置文件。

lane :build do
  gym(
    workspace: "YourApp.xcworkspace",
    scheme: "YourApp",
    clean: true,
    export_method: "app-store",        # 或者 ad-hoc, development, enterprise
    output_directory: "./fastlane/builds",
    output_name: "YourApp.ipa"
  )
end

参数说明:

  • workspace:如果是 CocoaPods 工程则指定 .xcworkspace,否则可省略。
  • scheme:对应的 target scheme。
  • export_method:决定证书类型,app-store 用于上架,ad-hoc 用于内部分发。
  • include_symbols:是否包含 dSYM 文件(默认 true)。
  • include_bitcode:Bitcode 支持。

打包 Android

Android 的 lane 示例:

lane :build_android do
  gradle(
    task: "assembleRelease",
    build_type: "Release",
    properties: {
      "android.injected.signing.store.file" => "keystore/release.jks",
      "android.injected.signing.store.password" => "******",
      "android.injected.signing.key.alias" => "upload",
      "android.injected.signing.key.password" => "******"
    }
  )
end

核心自动化任务:发布

Fastlane 提供了多个工具上传应用到商店。

  • iOSdeliver 上传元数据、截图、ipa 到 App Store Connect;pilot 管理 TestFlight。
  • Androidsupply 上传 APK/AAB 到 Google Play。

上传到 App Store Connect(iOS)

前提:已生成 app-store 类型的 ipa,并且 App 在 App Store Connect 上创建完成。

lane :release do
  deliver(
    username: "apple_id@example.com",   # 如果 Appfile 中设置了可省略
    ipa: "./fastlane/builds/YourApp.ipa",
    submit_for_review: false,           # 是否自动提交审核
    automatic_release: true,            # 通过审核后自动发布
    skip_metadata: false,               # 是否跳过元数据上传
    skip_screenshots: false,            # 是否跳过截图上传
    app_version: get_version_number(xcodeproj: "YourApp.xcodeproj"),
    overwrite_screenshots: true,        # 覆盖现有截图
    precheck_include_in_app_purchases: false
  )
end

你可以将截图和打包的产物直接传入 deliver

lane :screenshots_build_release do
  capture_screenshots
  gym(export_method: "app-store")
  deliver(
    ipa: lane_context[SharedValues::IPA_OUTPUT_PATH],
    screenshots_path: "./fastlane/screenshots",
    force: true
  )
end

TestFlight 内部测试分发

使用 pilot 上传构建版本并自动分发给测试员:

lane :testflight do
  build_app(export_method: "app-store")
  upload_to_testflight(
    skip_waiting_for_build_processing: false,
    distribute_external: true,
    groups: ["Beta Testers"],
    changelog: "自动化构建,包含最新功能"
  )
end

发布到 Google Play(Android)

lane :deploy_android do
  gradle(task: "bundleRelease")  # 生成 AAB
  upload_to_play_store(
    track: 'internal',          # 轨道:internal, alpha, beta, production
    aab: './app/build/outputs/bundle/release/app-release.aab',
    release_status: 'completed' # draft, completed, halted
  )
end

整合成完整工作流

一个典型的 iOS 发布流水线可以这样写:

lane :full_release do |options|
  # 1. 拉取最新代码、更新依赖
  cocoapods if File.exist?("Podfile")
  
  # 2. 更新构建号(可选)
  increment_build_number(xcodeproj: "YourApp.xcodeproj")
  
  # 3. 执行单元测试
  run_tests(workspace: "YourApp.xcworkspace",
            scheme: "YourApp",
            clean: true)
  
  # 4. 生成所有截图
  capture_screenshots
  
  # 5. 打包 App Store 版本
  gym(workspace: "YourApp.xcworkspace",
      scheme: "YourApp",
      export_method: "app-store",
      include_symbols: true)
  
  # 6. 上传截图、ipa 并提交审核
  deliver(
    ipa: lane_context[SharedValues::IPA_OUTPUT_PATH],
    screenshots_path: "./fastlane/screenshots",
    submit_for_review: true,
    automatic_release: false,
    force: true
  )
  
  # 7. 通知团队(可接入 Slack 等)
  slack(message: "🎉 #{options[:app_name]} 已成功提交审核!",
        slack_url: "https://hooks.slack.com/services/...")
end

执行:

fastlane full_release app_name:"我的 App"

对于 Android,流程类似,只需替换对应工具。

常见问题与技巧

如何管理代码签名?

iOS 强烈推荐使用 match,它能将证书和描述文件加密存储在私有 Git 仓库中,团队成员自动同步。

fastlane match init
fastlane match appstore

然后在 Fastfile 的打包 lane 前加入:

before_all do
  match(type: "appstore")
end

Android 推荐将签名文件放在安全路径,通过环境变量或 Gradle 配置引用。

避免在 CI 中频繁输入 Apple ID 密码

使用 App Store Connect API 密钥(推荐)或 Fastlane 的 FASTLANE_SESSION 环境变量。

  • API 密钥:在 App Store Connect 生成 API Key,下载 p8 文件,设置环境变量 APP_STORE_CONNECT_API_KEY_KEY_IDAPP_STORE_CONNECT_API_KEY_ISSUER_IDAPP_STORE_CONNECT_API_KEY_KEY 指向密钥内容或路径。
  • 会话 Cookie:运行 fastlane spaceauth -u apple@id.com 获取 session 字符串,设置 FASTLANE_SESSION

如何仅在特定条件下执行某些步骤?

使用 Ruby 条件判断:

if options[:skip_tests] == false
  run_tests(...)
end

调用时:fastlane release skip_tests:true

调试输出

在 lane 中添加:

puts "当前版本:#{get_version_number(xcodeproj: "YourApp.xcodeproj")}

或者运行 fastlane 时加 --verbose 参数查看详细日志。

性能优化

  • 截图前使用 xcodebuild -resolvePackageDependencies 预下载 SPM 依赖。
  • 使用 scan 测试时添加 try_count: 3 自动重试。
  • 在 CI 中缓存 gemsPodsDerivedData 以加速构建。

总结

通过 Fastlane,你只需一份 Fastfile 即可将截图、打包、发布的整个流程串联起来。从手动操作几分钟到一键执行,不仅杜绝了人为失误,也为持续集成打下了坚实基础。

推荐把常用的 lane(如 testflightscreenshots)保存为项目共享配置,任何团队成员都可以快速触发。随着项目迭代,你可以继续添加 lint 检查、代码覆盖率统计、自动生成更新日志等高级能力,让 Fastlane 成为真正的自动化中枢。