OpenHuman iOS App Store 发布实战:fastlane deliver 双 Lane、ASC API Key 与元数据资产全解
【免费下载链接】openhumanOpenHuman is an open source personal AI for Mac, Windows and Linux — local-first memory, agent orchestration, and deep research.项目地址: https://gitcode.com/GitHub_Trending/op/openhuman
OpenHuman 仓库中的 fastlane/README.md 是一份由 fastlane 自动生成的 iOS 发布操作手册,定义了push_screenshots与push_metadata两条只推送商店资产、不上传二进制的 lane。本文基于该文档,结合 Fastfile、Appfile 与fastlane/metadata、fastlane/screenshots目录的真实资产,完整讲清 OpenHuman iPhone 伴侣应用的 App Store 发布链路:认证方式、每个 deliver 参数的作用、元数据文件约定,以及如何与仓库内配套的截图生成、元数据直推脚本协同工作。
1. fastlane 目录结构总览
OpenHuman 的 iOS 发布资产集中在仓库根目录的fastlane/下,结构如下:
fastlane/ ├── Appfile # App Store Connect 应用身份配置 ├── Fastfile # 两条发布 lane 的实现 ├── README.md # fastlane 自动生成的操作手册(本文主体) ├── metadata/ │ └── en-US/ # 10 个英文商店元数据 .txt 文件 └── screenshots/ └── en-US/ # 3 张 6.9 英寸 iPhone 展示截图(1320×2868 PNG)fastlane/README.md 末尾明确注明:该文件是自动生成的,每次运行 fastlane 都会被重新生成。因此文档里的 "Available Actions" 章节内容实际上由 Fastfile 中每个 lane 的desc描述自动汇总而来——当你修改 lane 描述或增删 lane 后重新运行 fastlane,README 会同步更新。这也是为什么阅读该 README 时,真正的事实来源是 Fastfile 源码本身。
2. 前置准备:Xcode 命令行工具与 fastlane 安装
fastlane/README.md 给出的前置要求只有一步硬性操作——确保安装了最新版 Xcode Command Line Tools:
xcode-select --installfastlane 本身是 Ruby 工具链,README 指引读者参照 fastlane 官方文档完成安装(安装方式以 fastlane 官方文档为准)。在仓库日常实践中,fastlane 通常通过 Ruby bundle 运行,这也体现在 README 每条命令前[bundle exec]的可选前缀上:
[bundle exec] fastlane ios push_screenshots [bundle exec] fastlane ios push_metadata由于 Fastfile 第一行声明了default_platform(:ios),所有 lane 都定义在platform :ios do ... end块内,fastlane ios ...的平台参数是必需的调用形式。
3. 两条 Lane 的定位与差异
| Lane | 命令 | 作用(README 原文描述) |
|---|---|---|
push_screenshots | [bundle exec] fastlane ios push_screenshots | 只推送截图,不上传二进制、不更新元数据 |
push_metadata | [bundle exec] fastlane ios push_metadata | 推送元数据 + 截图,不上传二进制 |
两条 lane 的共同约束(对应 Fastfile 与 Fastfile 中完全一致的deliver配置):
skip_binary_upload: true—— 不上传 IPA;skip_app_version_update: true—— 不修改 App Store Connect 中的版本号;overwrite_screenshots: true—— 覆盖已有截图(配合先删后传语义,保证资产幂等);submit_for_review: false且run_precheck_before_submit: false—— 绝不触发提审,也不做提审预检。
两者的唯一实质差异在skip_metadata:
push_screenshots固定skip_metadata: true(Fastfile),即纯截图通道;push_metadata则读取环境变量开关:skip_metadata: ENV["ASC_FASTLANE_SKIP_METADATA"] == "1"(Fastfile),默认推送元数据,设置为1时可退化为与截图通道等价。
这种"资产推送与二进制上传分离"的设计,让商店文案/截图的迭代完全不依赖一次完整的构建上传周期。
4. 认证:App Store Connect API Key
两条 lane 的认证逻辑完全相同(Fastfile 与 Fastfile):
api_key = app_store_connect_api_key( key_id: ENV.fetch("ASC_KEY_ID"), issuer_id: ENV.fetch("ASC_ISSUER_ID"), key_filepath: ENV.fetch("ASC_KEY_PATH"), duration: 1200, in_house: false )要点说明:
- 三个环境变量均使用
ENV.fetch,即缺失时直接报错退出,而非回退默认值——这是硬依赖; duration: 1200表示为本次操作签发的 JWT 有效期 1200 秒(20 分钟),足够一次 deliver 推送流程;in_house: false表明这是标准 App Store 分发(Volume Purchase / 企业内部分发场景才会置 true)。
完整环境变量清单:
| 变量 | 必需性 | 作用 | 来源 |
|---|---|---|---|
ASC_KEY_ID | 必需 | App Store Connect API Key 的 Key ID | Fastfile |
ASC_ISSUER_ID | 必需 | API Key 的 Issuer ID | Fastfile |
ASC_KEY_PATH | 必需 | .p8私钥文件路径 | Fastfile |
ASC_APP_VERSION | 可选,默认1.0 | 指定 deliver 操作的 App Store 版本号 | Fastfile |
ASC_FASTLANE_SKIP_METADATA | 可选,1时跳过元数据 | 仅push_metadatalane 读取 | Fastfile |
注意ASC_APP_VERSION的默认值"1.0"只是占位安全值:实际操作时应当显式传入与 App Store Connect 中当前待处理版本一致的版本号,否则 deliver 会因找不到对应appStoreVersion而失败。仓库当前 app/src-tauri-mobile/tauri.conf.json 中的移动端版本为0.58.16,可作为运行时取值的参考来源(二进制上传脚本正是从这里读取MARKETING_VERSION的,见 scripts/ios-appstore-upload.sh)。
5. Appfile:应用身份三元组
fastlane/Appfile 仅三行,却锁定了整个发布身份:
app_identifier("com.tinyhumansai.openhuman") apple_id("6761229174") team_id("V76768QVFE")app_identifier与 Fastfile 中deliver(app_identifier: "com.tinyhumansai.openhuman")相互呼应,与 scripts/ios-appstore-upload.sh 中的APP_IDENTIFIER常量一致;apple_id("6761229174")是 App Store Connect 中的 Apps 数字 ID,scripts/ios-appstore-metadata.mjs 在无法通过 API Key 走 deliver 时,以同一 ID 作为默认ASC_APP_ID;team_id("V76768QVFE")是开发者团队 ID。
6. 元数据资产:fastlane/metadata/en-US 的十个文件
deliver(metadata_path: "fastlane/metadata")指向的目录包含 10 个.txt文件,每个文件对应 App Store 上的一个字段。以当前仓库内容为例:
| 文件 | 对应字段 | 当前内容摘要 |
|---|---|---|
| name.txt | 应用名 | OpenHuman |
| subtitle.txt | 副标题 | AI companion for your desktop |
| description.txt | 描述 | 定位 iPhone 为桌面应用的伴侣:扫码配对、文本/语音对话、记忆与工具锚定在桌面端 |
| keywords.txt | 关键词 | AI assistant,voice chat,desktop companion,memory,agents,productivity,automation,tools |
| promotional_text.txt | 推广文本 | 强调"配对桌面后可用手机聊天,记忆与工具锚定电脑" |
| copyright.txt | 版权 | 2026 Tiny Humans AI |
| marketing_url.txt | 营销 URL | tinyhumans.ai 下的产品页 |
| privacy_url.txt | 隐私政策 URL | GitBook 上的隐私政策页 |
| support_url.txt | 支持 URL | tinyhumans.ai 下的产品页 |
| release_notes.txt | 版本更新说明 | 首发 iPhone 伴侣版本:配对、文本消息、按住说话语音输入 |
从 description.txt 的内容可以看到,元数据本身也承载了产品定位说明:iPhone 应用刻意保持轻量,是"桌面 OpenHuman 运行时"的遥控与对话界面——配对使用短时效 QR 码,摄像头仅用于扫描配对码,麦克风仅用于按住说话(push-to-talk)。这套文案与 scripts/ios-appstore-assets.mjs 中三张截图的文案主题(配对、文本+语音、桌面锚定)是一一对应的。
7. 截图资产:命名即设备规格
deliver(screenshots_path: "fastlane/screenshots")目录下当前是en-US/的三个文件:
- iPhone_6_9_01_pair_with_desktop.png
iPhone_6_9_02_chat_and_voice.pngiPhone_6_9_03_desktop_anchored.png
文件命名遵循 fastlane 的设备展示类型约定:iPhone_6_9对应 6.9 英寸 iPhone 展示框,三张图实际尺寸均为1320×2868像素——这正是 App Store 6.9 英寸 iPhone 截图位的官方规格。配套的直推脚本 scripts/ios-appstore-metadata.mjs 默认ASC_SCREENSHOT_DISPLAY_TYPE=APP_IPHONE_67,与iPhone_6_9前缀互相印证。
截图不是手工设计的,而是由 scripts/ios-appstore-assets.mjs 用 Playwright 驱动 Chromium 渲染生成的:脚本内建三套 HTML 手机界面模板(配对页、聊天页、隐私/锚定页),以 1320×2868 视口逐页截图,输出直接写入fastlane/screenshots/en-US/。修改文案后重跑该脚本,再执行fastlane ios push_screenshots,即可完成一轮商店截图刷新,全程不碰二进制。
8. 典型操作流程
综合两条 lane 与配套脚本,一轮"只更新商店资产"的标准流程是:
# 0. 准备认证环境变量(硬依赖) export ASC_KEY_ID=XXXXXXXXXX export ASC_ISSUER_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx export ASC_KEY_PATH=/path/to/AuthKey_XXXXXXXXXX.p8 export ASC_APP_VERSION=0.58.16 # 与 App Store Connect 当前版本一致 # 1.(可选)重新生成截图 node scripts/ios-appstore-assets.mjs # 2. 推送元数据 + 截图 bundle exec fastlane ios push_metadata # 3. 或只推送截图 bundle exec fastlane ios push_screenshots若某次只想推截图而不想动元数据,可给push_metadata加开关:
ASC_FASTLANE_SKIP_METADATA=1 bundle exec fastlane ios push_metadata二进制(IPA)的构建与上传是另一条链路:scripts/ios-appstore-upload.sh 负责xcodebuild archive→ 导出 IPA →xcrun altool --upload-app上传,复用同一组ASC_KEY_ID/ASC_ISSUER_ID/ASC_KEY_PATH环境变量(仅当UPLOAD=1时校验)。从源码结构看,仓库形成了清晰的职责划分:fastlane 管商店资产,upload 脚本管二进制,scripts/ios-appstore-metadata.mjs 则提供一条不依赖 Ruby/fastlane 的纯 Node.js 直连 App Store Connect REST API 的备选通道(自行用 ES256 签发 15 分钟有效期的 JWT,执行appInfoLocalizations/appStoreVersionLocalizations的 get-or-create + PATCH,以及截图集的先删后传)。
9. 版本取值的一个注意点
当前仓库存在两个版本来源:app/package.json 为0.63.22(前端应用包),app/src-tauri-mobile/tauri.conf.json 为0.58.16(移动端 Tauri 工程)。二进制上传脚本以移动端tauri.conf.json的version作为MARKETING_VERSION(scripts/ios-appstore-upload.sh),而 Node 直推脚本的ASC_VERSION_STRING缺省值取自app/package.json(scripts/ios-appstore-metadata.mjs)。两条链路的版本锚点不同,操作时务必显式指定ASC_APP_VERSION/ASC_VERSION_STRING,避免元数据被推送到错误的appStoreVersion上。
10. 小结
- OpenHuman 的 fastlane 配置是纯资产发布型:两条 lane 均
skip_binary_upload且submit_for_review: false,发布二进制与提审在流程外由人工/脚本单独触发; - 认证统一走 App Store Connect API Key,三个
ASC_*变量为硬依赖,ASC_APP_VERSION与ASC_FASTLANE_SKIP_METADATA为可选开关; - 商店资产(10 个元数据
.txt+ 3 张 1320×2868 截图)全部入库,截图由脚本可再生,元数据与截图的推送因此是幂等、可重复的; - 需要理解"发生了什么"时,以 fastlane/Fastfile 为准,fastlane/README.md 只是其自动生成的快照。
【免费下载链接】openhumanOpenHuman is an open source personal AI for Mac, Windows and Linux — local-first memory, agent orchestration, and deep research.项目地址: https://gitcode.com/GitHub_Trending/op/openhuman
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考