fastlane 全流程指南:用 upload_to_testflight(pilot)上传构建并管理 TestFlight 测试员
【免费下载链接】fastlane🚀 The easiest way to automate building and releasing your iOS and Android apps项目地址: https://gitcode.com/GitHub_Trending/fa/fastlane
upload_to_testflight 是 fastlane 提供的 TestFlight 集成 action,底层由pilot工具驱动。它让你在终端中完成「上传 beta 构建 → 等待处理 → 提交内/外部测试员 → 批量管理测试员与设备」的整套发布流程。读完本文,你将掌握 fastlane pilot 的全部命令、两种认证方式、关键参数与常见坑,并能在 Fastfile 中用pilot/testflight别名一键执行测试发布。
本文以仓库内 upload_to_testflight.md 为主线,结合 pilot 子工具源码展开,属于 iOS/macOS/tvOS 的 beta 分发最佳实践模块。
一、pilot 与 upload_to_testflight 是什么
pilot是从终端管理 Apple TestFlight 测试与构建的工具,支持:
- 上传并分发构建(Upload & distribute builds)
- 添加、移除测试员(Add & remove testers)
- 查询测试员与设备信息(Retrieve information about testers & devices)
- 导入 / 导出全部可用测试员(Import/export all available testers)
在 Fastfile 中,upload_to_testflightaction 会调用Pilot::BuildManager#upload完成实际上传。从 upload_to_testflight.rb 可以看到它的核心逻辑非常薄:读取 lane 上下文中的 IPA/PKG 输出路径与 changelog,然后委托给 pilot。并且它提供了三个等价的调用名——示例代码 中明确列出:
upload_to_testflight testflight # upload_to_testflight 的别名 pilot # upload_to_testflight 的别名同时 is_supported? 表明该 action 只支持:ios、:mac、:tvos三个平台。也就是说:
- 以独立 CLI 使用:
fastlane pilot <子命令> - 以 Fastfile action 使用:
upload_to_testflight/testflight/pilot
两者共享同一套参数定义 pilot/lib/pilot/options.rb 和同一套执行器(build_manager.rb、tester_manager.rb),底层通过spaceship与 App Store Connect API 交互完成构建元数据提交,通过 iTunes Transporter 上传二进制。
二、认证方式:API Key(推荐)与 Apple ID
无论执行哪个子命令,都需要先认证。pilot 支持两种方式,可通过命令参数指定,也可从项目已有 fastlane 配置中自动继承。
2.1 App Store Connect API Key(官方推荐)
只要条件允许,App Store Connect API Key 是首选认证方式,理由如下:
- 使用官方 App Store Connect API,链路稳定;
- 无需 2FA 二次验证,适合 CI 场景;
- 相比 Apple ID 登录性能更好。
指定方式有两种。使用 JSON 文件:
fastlane pilot upload --api_key_path ./path/to/api_key_info.json或直接内联 JSON 字符串:
fastlane pilot upload --api_key "{\"key_id\": \"D83848D23\", \"issuer_id\": \"227b0bbf-ada8-458c-9d62-3d8022b7d07f\", \"key_filepath\": \"D83848D23.p8\"}"从 options.rb 可以看出:
api_key_path同时支持环境变量PILOT_API_KEY_PATH与APP_STORE_CONNECT_API_KEY_PATH,且会verify_block校验文件确实存在;api_key支持环境变量PILOT_API_KEY/APP_STORE_CONNECT_API_KEY,类型为 Hash 且标记sensitive: true(不会打印到日志);- 两者都与
username互相conflicting_options,即 API Key 认证和 Apple ID 认证只能二选一。
在 Fastfile 中也可以先通过app_store_connect_api_key拿到密钥并放入 lane 上下文SharedValues::APP_STORE_CONNECT_API_KEY,此时 upload_to_testflight.rb 会自动读取,无需再传api_key(除非显式传了api_key_path)。登录链路对应 manager.rb:优先Spaceship::ConnectAPI::Token.from生成 JWT token,已有 token 则直接复用,否则退回 Apple ID 账号密码登录。
2.2 Apple ID(传统方式)
使用-u指定 Apple ID:
fastlane pilot upload -u felix@krausefx.com如果你在已有 fastlane 配置的项目中执行,username与 app identifier 会被自动推导——options.rb 会依次尝试从AppfileConfig读取:itunes_connect_id或:apple_id作为username默认值。
三、上传构建(Uploading builds)
上传新构建只需一行命令:
fastlane pilot upload它会自动在当前目录查找ipa文件(options.rb 中default_value取目录下最新的*.ipa),并尝试从 fastlane setup 中获取登录凭据。缺少的信息会交互式询问,所有可用参数可通过fastlane action pilot查看。
3.1 常用上传参数
携带更新日志:
fastlane pilot upload --changelog "Something that is new here"只上传二进制、不触发分发(相当于先只入库,之后再用distribute分发给测试员):
fastlane pilot upload --skip_submission--skip_submission对应 options.rb 中的:skip_submission(短选项-s,环境变量PILOT_SKIP_SUBMISSION,默认false)。它会中止「提交分发」这一步,但仍会尝试更新 beta 元信息。
pilot 自动完成两件「魔法」:
- 从
ipa文件中自动检测 bundle identifier; - 基于 bundle identifier 自动获取 App Store Connect 上的 AppID。
对应实现见 manager.rb:fetch_app_identifier依次取config[:app_identifier]→ 用FastlaneCore::IpaFileAnalyser/PkgFileAnalyser从包里分析 → 最后交互询问;fetch_app_platform同理支持appletvos、ios、osx、xros四种平台(app_platform参数在 options.rb 中校验)。
3.2 上传的内部流程与「等处理」机制
真正的上传在 build_manager.rb 的upload方法中完成,可以概括为 5 步:
- 参数就绪:检查 ipa/pkg 是否给出;若同时存在两者会
UI.important告警并以ipa优先(强制上传pkg需将app_platform设为osx); - 校验 changelog:当
distribute_external: true且既无changelog也无localized_build_info[:whats_new]时,交互模式会要求输入 changelog,非交互模式直接报错(check_for_changelog_or_whats_new!); - 构造上传包:
FastlaneCore::IpaUploadPackageBuilder或PkgUploadPackageBuilder在临时目录生成 Transporter 所需包结构; - Transporter 上传:
transporter_for_selected_team根据是否使用 JWT 分别构造ItunesTransporter(build_manager.rb),失败时输出 Transporter 错误详情; - 等待处理并分发:
wait_for_build_processing_to_be_complete通过FastlaneCore::BuildWatcher轮询 App Store Connect,等待构建处理完成后再调用distribute。
其中等待行为受几个参数控制:
wait_processing_interval(-k,默认 30 秒)——轮询间隔;wait_processing_timeout_duration——超时后强制停止等待并抛出异常;skip_waiting_for_build_processing(-z)——若设为 true 且未提供 changelog,上传完成即返回,完全跳过等待(适合 CI 按分钟计费的场景);若提供了 changelog,则只等到构建出现在 App Store Connect、写入 changelog 后就提前返回,见 build_manager.rb 的分支逻辑。
注意:skip_waiting_for_build_processing开启时distribute_external不生效,构建不会分发给测试员。
3.3 从 Linux 上传
无 macOS/Xcode 环境也可以在 Linux 上完成上传,前提是:
- 把包文件(
.ipa或.pkg)与AppStoreInfo.plist放在磁盘同一位置(如何生成可参考gym相关流程); - 已安装 Apple 提供的 Linux 版 Transporter;
- 设置环境变量:
export FASTLANE_ITUNES_TRANSPORTER_USE_SHELL_SCRIPT=true export FASTLANE_ITUNES_TRANSPORTER_PATH=/usr/local/itms # 或你安装 Transporter 的路径另外要注意:fastlane 会临时把上传凭证保存在$HOME/.appstoreconnect/private_keys/,上传完成后该目录中的其他文件会被清理删除,请勿在其中存放重要资料。
四、列出所有构建(pilot builds)
查看某个 app 的全部构建:
fastlane pilot builds输出会同时包含正在处理(processing)的构建与已激活(active)的构建。文档示例中的表格大致形如:
+-----------+---------+----------+ | Great App Builds | +-----------+---------+----------+ | Version # | Build # | Installs | +-----------+---------+----------+ | 0.9.13 | 1 | 0 | | 0.9.13 | 2 | 0 | | 0.9.20 | 3 | 0 | | 0.9.20 | 4 | 3 | +-----------+---------+----------+实现上,build_manager.rb 的list方法分别拉取「Processing Builds」(get_build_deliveries,只有 Version/Build 两列)与「Builds」(带betaBuildMetrics的安装数统计),再用terminal-table渲染。builds子命令在 commands_generator.rb 中注册,并复用与上传相同的参数集。
五、分发既有构建(pilot distribute)
如果你之前用--skip_submission只上传不分发,后续可以单独执行:
fastlane pilot distribute它对应:distribute_only参数(-D,环境变量PILOT_DISTRIBUTE_ONLY)。在 Fastfile 里用upload_to_testflight(distribute_only: true)也会进入纯分发分支——upload_to_testflight.rb 会先等待处理完成(除非设置skip_waiting_for_build_processing)再调用BuildManager#distribute。
分发逻辑在 build_manager.rb:
- 未指定构建时自动拉取最近上传的构建;也可用
app_version/build_number精确定位; - 分发前先更新 Beta 元信息(
update_beta_app_meta):demo account、本地化 app 信息、本地化 build 信息(what's new)、notify_external_testers等; reject_build_waiting_for_review(-b):若已有构建处于「等待审核」,先将其过期(expire!)再提交新构建;expire_previous_builds:过期除当前构建外的所有历史构建;- 向外部分发要求
groups参数(distribute_external: true但没给groups会直接报错);内部分发则默认提交给内部测试员。
六、管理 Beta 测试员(Managing beta testers)
测试员管理全部由 tester_manager.rb 负责,命令注册见 commands_generator.rb。
6.1 列出测试员(pilot list)
fastlane pilot list列出该 app 下所有内部与外部测试员,示例输出:
+--------+--------+--------------------------+-----------+ | Internal Testers | +--------+--------+--------------------------+-----------+ | First | Last | Email | # Devices | +--------+--------+--------------------------+-----------+ | Felix | Krause | felix@krausefx.com | 2 | +--------+--------+--------------------------+-----------+ +-----------+---------+----------------------------+-----------+ | External Testers | +-----------+---------+----------------------------+-----------+ | First | Last | Email | # Devices | +-----------+---------+----------------------------+-----------+ | Max | Manfred | email@email.com | 0 | | Detlef | Müller | detlef@krausefx.com | 1 | +-----------+---------+----------------------------+-----------+实际列表至少需要app_identifier(commands_generator.rb 会在缺失时直接报错),实现通过Spaceship::ConnectAPI::App#get_beta_testers查询并展示各 tester 所在 group。
6.2 添加测试员(pilot add)
pilot add会把新测试员创建到 App Store Connect 账号下,并关联到 app 的至少一个测试组;若测试员已存在则仅完成关联:
fastlane pilot add email@invite.com -g group-1,group-2如当前上下文无法自动判定 app,可显式传 app identifier(-a):
fastlane pilot add email@email.com -a com.krausefx.app -g group-1,group-2groups(-g)支持 group 名称或 group ID,可传多个。从 tester_manager.rb 可以看到:add_tester会要求必须提供 apple_id 或 app_identifier,且必须提供至少一个 group,随后group.post_bulk_beta_tester_assignments批量添加。tester 名与邮箱可用--first_name/--last_name/--email指定。
6.3 查找测试员(pilot find)
按邮箱查找某个 tester:
fastlane pilot find felix@krausefx.com输出形如:
+---------------------+---------------------+ | felix@krausefx.com | +---------------------+---------------------+ | First name | Felix | | Last name | Krause | | Email | felix@krausefx.com | | Latest Version | 0.9.14 (23 | | Latest Install Date | 03/28/15 19:00 | | 2 Devices | • iPhone 6, iOS 8.3 | | | • iPhone 5, iOS 7.0 | +---------------------+---------------------+find_tester 通过app.get_beta_testers(filter: { email: ... }, includes: "apps,betaTesterMetrics,betaGroups")查询,describe_tester借助beta_tester_metrics展示其最近安装版本与日期。
6.4 移除测试员(pilot remove)
移除某个测试员(会同时从所有内/外部组移除):
fastlane pilot remove felix@krausefx.com只想把它从特定组移除时,加groups:
fastlane pilot remove felix@krausefx.com -g group-1,group-2从 remove_tester 的实现可见:不带groups时调用tester.delete_from_apps(apps: [app])(从整个 app 移除);带groups时只对匹配的 group 执行delete_from_beta_groups。add/find/remove都支持一次处理多个邮箱(把多个邮箱作为位置参数传入,见handle_multiple)。
6.5 导出测试员(pilot export)
把全部外部测试员导出为 CSV,便于迁移到其他系统或新账号:
fastlane pilot export自定义导出路径:
fastlane pilot export -c ~/Desktop/testers.csvCSV 默认路径为./testers.csv(testers_file_path参数,-c,见 options.rb)。实际导出的表头在 tester_exporter.rb:First, Last, Email, Groups, Installed Version, Install Date。
6.6 导入测试员(pilot import)
从 CSV 批量添加外部测试员。先创建testers.csv,格式为「名, 姓, 邮箱, 组1;组2」:
John,Appleseed,appleseed_john@mac.com,group-1;group-2再执行:
fastlane pilot import或指定文件:
fastlane pilot import -c ~/Desktop/testers.csv导入实现在 tester_importer.rb:逐行读取 CSV,第 4 列的分组用;分隔并映射到groups参数,每行都会复用add_tester逻辑,最终统计成功导入数量。导出 CSV 中由pilot export生成的Groups列同样以;连接,因此可以「export → 修改 → import」完成跨账号迁移。
七、在 Fastfile 中集成 upload_to_testflight
除了 CLI,更常见的做法是写进 Fastfile。以下是 upload_to_testflight.rb 官方示例代码整理出的几种典型写法:
lane :beta do # 一行上传并分发,自动从 lane 上下文 / 目录探测 ipa 与凭据 upload_to_testflight # 只上传不分发 upload_to_testflight(skip_submission: true) # 显式指定账号、app 与 iTC provider upload_to_testflight( username: "felix@krausefx.com", app_identifier: "com.krausefx.app", itc_provider: "abcde12345" # 传给 iTMSTransporter 的 -itc_provider ) # 设置 beta 描述信息与通知策略 upload_to_testflight( beta_app_feedback_email: "email@email.com", beta_app_description: "This is a description of my app", demo_account_required: true, notify_external_testers: false, changelog: "This is my changelog of things that have changed in a log" ) end7.1 提供 Beta 审核信息(beta_app_review_info)
TestFlight 外测需要填写 Beta App 审核的联系方式与 demo 账号等信息,可用 Hash 传入:
upload_to_testflight( beta_app_review_info: { contact_email: "email@email.com", contact_first_name: "Connect", contact_last_name: "API", contact_phone: "5558675309", demo_account_name: "demo@email.com", demo_account_password: "connectapi", notes: "this is review note for the reviewer <3 thank you for reviewing" } )该 Hash 的合法 key 在 options.rb 中限定为:contact_email、contact_first_name、contact_last_name、contact_phone、demo_account_required、demo_account_name、demo_account_password、notes,其他 key 会被直接拒绝。底层 update_review_detail 会把这些字段映射为 App Store Connect 的 Beta App Review Detail 属性(如contactEmail、demoAccountRequired等)。
7.2 本地化 beta 文案(localized_app_info / localized_build_info)
不同语言地区的测试员看到的「反馈邮箱、宣传页、隐私政策、描述、What's New」可以分别配置:
upload_to_testflight( beta_app_review_info: { ... }, # 见上文 localized_app_info: { "default": { feedback_email: "default@email.com", marketing_url: "https://example.com/marketing-default", privacy_policy_url: "https://example.com/privacy-default", description: "Default description" }, "en-GB": { feedback_email: "en-gb@email.com", marketing_url: "https://example.com/marketing-en-gb", privacy_policy_url: "https://example.com/privacy-en-gb", description: "en-gb description" } }, localized_build_info: { "default": { whats_new: "Default changelog" }, "en-GB": { whats_new: "en-gb changelog" } } )localized_app_info的合法 key:feedback_email、marketing_url、privacy_policy_url、tv_os_privacy_policy_url、description;localized_build_info的合法 key:whats_new。
这些校验同样定义在 options.rb。若未使用本地化 Hash,beta_app_description/beta_app_feedback_email会被当作defaultlocale 的信息写入(见update_localized_app_review)。写入 build 的whats_new内容会先经过 sanitize_changelog:移除 emoji 与<字符(Apple 不允许),并截断超过 4000 字节的文本,末尾追加...。
7.3 导出合规与 App Clip / Routing App
如需自定义的导出合规(Export Compliance)设置:
upload_to_testflight(uses_non_exempt_encryption: true)当 App Store Connect 上尚未记录加密状态(uses_non_exempt_encryption.nil?)时,set_export_compliance_if_needed会通过patch_builds写入该字段并等待重新处理;更快的做法是在Info.plist中预先设置ITSAppUsesNonExemptEncryption。此外还支持 App Clip 的app_clip_invocations、overwrite_app_clip_invocations,以及路由类 App 的routing_app_coverage_file(需为.geojson)。
八、常见问题与实用技巧(Tips)
8.1 打开 verbose 调试输出
遇到问题时用 verbose 模式拿到更详细的日志:
fastlane pilot upload --verbose8.2 防火墙环境与 Transporter 协议
pilot 通过 iTunes Transporter 上传元数据与二进制。若身处防火墙之后,可强制指定 Transporter 传输协议:
DELIVER_ITMSTRANSPORTER_ADDITIONAL_UPLOAD_PARAMETERS="-t DAV" pilot ...在 Fastfile 的 action 场景下则先设置环境变量再调用:
ENV["DELIVER_ITMSTRANSPORTER_ADDITIONAL_UPLOAD_PARAMETERS"] = "-t DAV" pilot两个注意点:
- Apple 官方建议不要指定
-t,让 Transporter 自动探测最优传输模式。因此一旦检测到传入了t选项,pilot 会发出警告; -t只是可用附加参数之一,该环境变量中的整段字符串都会透传给 Transporter,其余参数可查阅 Transporter 用户手册按需配置。
8.3 密码含特殊字符导致的凭证报错
如果你的 Apple ID 密码包含特殊字符,pilot 可能抛出令人困惑的 "Your Apple ID or password was entered incorrectly" 错误。最简单的解决办法是改用不含特殊字符的密码。
8.4 密码存储在哪里
pilot 使用 fastlane 的 CredentialsManager 管理登录凭据(本仓库对应 credentials_manager 目录),密钥会被安全地保存在系统钥匙串中。遇到密钥库问题时也可关注 account_manager.rb 的实现。
8.5 多团队:Provider Short Name 与 Provider Public ID
- Provider Short Name:若账号属于多个 App Store Connect 团队,Transporter 可能需要
itc_provider(provider short name)才能确定上传目标。pilot 默认尝试用所选团队的 long name 反查 provider short name;如需覆盖自动检测值,显式传入itc_provider即可。用 Transporter 查询 short name 的命令为xcrun iTMSTransporter -m provider -u 'USERNAME' -p 'PASSWORD' -account_type itunes_connect -v off,结果第二列即 short names(见 options.rb); - Provider Public ID:
provider_public_id用于 altool 的--provider-public-id。当账号关联多个 provider、并使用用户名/App 专用密码认证时,Xcode 26 之后该值为必填,且会覆盖自动检测结果(见 options.rb)。
其余团队相关参数还有team_id(-q)、team_name(-r)与dev_portal_team_id,都可在多团队环境下限定目标账号。
8.6 使用 App 专用密码上传
当skip_waiting_for_build_processing与apple_id两个选项同时设置时,pilot/upload_to_testflight可通过环境变量FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD提供的 App 专用密码完成上传。只要缺其中一个选项,就会走常规 Apple 登录流程(可能需要 2FA)。
8.7 账号角色要求
构建处理完成后,pilot/upload_to_testflight会更新构建信息与测试员信息。App Store Connect 要求账号具备 "App Manager" 或 "Admin" 角色才能执行这些更新;"Developer" 角色可以上传构建,但无法更新构建信息与测试员。若你的 CI 账号是 Developer 角色,建议提升权限或改用 App Store Connect API Key。
九、完整参数速查(核心)
以下为 pilot/lib/pilot/options.rb 中定义的核心参数节选(含短选项、环境变量与默认值),可在fastlane pilot <子命令>或 Fastfile 中混用:
| 参数 | 短选项 | 环境变量 | 默认值 | 说明 |
|---|---|---|---|---|
api_key_path | — | PILOT_API_KEY_PATH/APP_STORE_CONNECT_API_KEY_PATH | — | App Store Connect API Key JSON 路径 |
api_key | — | PILOT_API_KEY/APP_STORE_CONNECT_API_KEY | — | API Key Hash(敏感信息) |
username | -u | PILOT_USERNAME | Appfile 推导 | Apple ID 用户名 |
app_identifier | -a | PILOT_APP_IDENTIFIER | 目录 ipa / Appfile 推导 | 目标 App 的 bundle id |
app_platform | -m | PILOT_PLATFORM | 包内推导 | ios/appletvos/osx/xros |
apple_id | -p | PILOT_APPLE_ID | TESTFLIGHT_APPLE_ID | App Store Connect「App 信息」中的 Apple ID(数字),会校验不能是邮箱或 bundle id |
ipa | -i | PILOT_IPA | 目录最新*.ipa | 待上传 ipa 路径(与pkg互斥) |
pkg | -P | PILOT_PKG | 目录最新*.pkg | 待上传 pkg 路径(与ipa互斥) |
changelog | -w | PILOT_CHANGELOG | — | “What to Test” 文案 |
skip_submission | -s | PILOT_SKIP_SUBMISSION | false | 只上传不分发 |
skip_waiting_for_build_processing | -z | PILOT_SKIP_WAITING_FOR_BUILD_PROCESSING | false | 跳过(或部分跳过)处理等待,适合 CI |
distribute_only | -D | PILOT_DISTRIBUTE_ONLY | false | 只分发既有构建 |
distribute_external | — | PILOT_DISTRIBUTE_EXTERNAL | false | 是否分发外部测试员(需groups) |
notify_external_testers | — | PILOT_NOTIFY_EXTERNAL_TESTERS | App Store Connect 默认 | 是否通知外部测试员 |
beta_app_description | -d | PILOT_BETA_APP_DESCRIPTION | — | Beta App 描述 |
beta_app_feedback_email | -n | PILOT_BETA_APP_FEEDBACK | — | Beta App 反馈邮箱 |
beta_app_review_info | — | PILOT_BETA_APP_REVIEW_INFO | — | 审核联系人/demo 账号 Hash |
localized_app_info | — | PILOT_LOCALIZED_APP_INFO | — | 按语言分组的 App 信息 Hash |
localized_build_info | — | PILOT_LOCALIZED_BUILD_INFO | — | 按语言分组的 build 信息 Hash |
demo_account_required | — | DEMO_ACCOUNT_REQUIRED | — | Beta 审核是否需要 demo 账号 |
uses_non_exempt_encryption | -X | PILOT_USES_NON_EXEMPT_ENCRYPTION | false | 导出合规声明 |
app_version/build_number | — | PILOT_APP_VERSION/PILOT_BUILD_NUMBER | — | 定位待分发构建 |
expire_previous_builds | — | PILOT_EXPIRE_PREVIOUS_BUILDS | false | 过期历史构建 |
reject_build_waiting_for_review | -b | PILOT_REJECT_PREVIOUS_BUILD | false | 过期「等待审核」的旧构建 |
email/first_name/last_name | -e/-f/-l | PILOT_TESTER_* | — | 测试员信息(add/find/remove 用) |
testers_file_path | -c | PILOT_TESTERS_FILE | ./testers.csv | 测试员导入/导出 CSV 路径 |
groups | -g | PILOT_GROUPS | — | 测试组名或组 ID(外部分发/加组必填) |
team_id/team_name | -q/-r | PILOT_TEAM_ID/PILOT_TEAM_NAME | Appfile 推导 | 多团队选择 |
itc_provider | — | PILOT_ITC_PROVIDER | 自动探测 | Transporter 的 provider short name |
provider_public_id | — | PILOT_PROVIDER_PUBLIC_ID | 自动探测 | altool 的 provider public ID(Xcode 26+ 多 provider 场景) |
wait_processing_interval | -k | PILOT_WAIT_PROCESSING_INTERVAL | 30 | 处理轮询间隔(秒) |
wait_processing_timeout_duration | — | PILOT_WAIT_PROCESSING_TIMEOUT_DURATION | — | 处理等待超时(秒),超时抛异常 |
app_clip_invocations | — | PILOT_APP_CLIP_INVOCATIONS | — | 为构建添加 App Clip 调用点 |
routing_app_coverage_file | — | PILOT_ROUTING_APP_COVERAGE_FILE | — | routing app 的.geojson覆盖文件 |
submit_beta_review | — | PILOT_DISTRIBUTE_EXTERNAL | true | 是否送审 |
十、相关源码与测试线索
如需深入理解各命令行为,可按如下路径继续阅读仓库:
- Action 入口与示例:fastlane/lib/fastlane/actions/upload_to_testflight.rb
- 全部参数定义:pilot/lib/pilot/options.rb
- 上传 / 等待 / 分发主流程:pilot/lib/pilot/build_manager.rb
- 登录与 App/平台探测:pilot/lib/pilot/manager.rb
- 测试员增删查:pilot/lib/pilot/tester_manager.rb
- 测试员导入导出:pilot/lib/pilot/tester_importer.rb、pilot/lib/pilot/tester_exporter.rb
- CLI 子命令注册:pilot/lib/pilot/commands_generator.rb
- 测试覆盖可参考 pilot/spec(如 build_manager_spec.rb、commands_generator_spec.rb、tester_importer_spec.rb 等)
结合文档与源码可以看到:upload_to_testflight的价值在于把「二进制上传、处理等待、元信息更新、分组分发」这条原本依赖 Xcode Organizer 或网页手动操作的链路,收敛为可脚本化、可进 CI、可参数化的一个 action——这正是 fastlane「自动化测试版发布」理念在 TestFlight 上的落点。
【免费下载链接】fastlane🚀 The easiest way to automate building and releasing your iOS and Android apps项目地址: https://gitcode.com/GitHub_Trending/fa/fastlane
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考