Fastlane 自动化:屏幕截图、打包与发布
什么是 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 提供了多个工具上传应用到商店。
- iOS :
deliver上传元数据、截图、ipa 到 App Store Connect;pilot管理 TestFlight。 - Android :
supply上传 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_ID、APP_STORE_CONNECT_API_KEY_ISSUER_ID、APP_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 中缓存
gems、Pods、DerivedData以加速构建。
总结
通过 Fastlane,你只需一份 Fastfile 即可将截图、打包、发布的整个流程串联起来。从手动操作几分钟到一键执行,不仅杜绝了人为失误,也为持续集成打下了坚实基础。
推荐把常用的 lane(如 testflight、screenshots)保存为项目共享配置,任何团队成员都可以快速触发。随着项目迭代,你可以继续添加 lint 检查、代码覆盖率统计、自动生成更新日志等高级能力,让 Fastlane 成为真正的自动化中枢。