asc CLI + Skills:把 App Store Connect 发版变成可审计流水线

type
status
date
slug
summary
tags
category
icon
password
wechat_gate
notion image
如果你搜索“asc CLI App Store Connect 自动化”,真正想解决的通常不是第一次上架时少填几张表,而是把每次发版都会重复的双语元数据、截图、构建和审核检查变成一条可版本化、可复查、可重跑的流水线。
我用一个中英双语 iOS App 完整走了一遍。最后的判断很明确:asc 加 Skills 值得用,但它们解决的是发布过程的组织和执行,不会突破 Apple API 的能力边界。真正可靠的方案必须同时包含命令行、版本控制、变更预览、结果回拉,以及少量明确保留的人工步骤。

先分清:哪些工作值得自动化

“App Store 上架很繁琐”其实混合了两类工作。
第一类是低频、一次性或强人工判断的工作,例如银行税务协议、首次分类选择、App 隐私问卷。它们要么只做一次,要么错误成本很高,自动化收益有限。
第二类是每个版本都会重复的工作:
  • 多语言名称、副标题、描述、关键词和更新说明;
  • 不同语言、不同设备规格的商店截图;
  • 构建上传、版本关联、提交前检查和审核状态跟踪;
  • 发布后对线上字段和素材的复核。
后者才是 asc CLI 的主战场。Apple 官方文档也把本地化元数据、截图和版本信息拆成不同资源;asc 只是把这些资源变成了可脚本化的命令。
notion image
这张图里最重要的不是箭头,而是边界:Skill 负责组织步骤,CLI 负责执行,Apple API 决定上限,开发者负责高风险决策。

asc CLI + Skills 到底各自做什么

asc 是一个非 Apple 官方、社区维护的 Go CLI。它直接面向 App Store Connect API,支持结构化 JSON 输出、明确的退出码和适合自动化的非交互参数。我电脑核验时使用的是 asc 5.4.0
Skills 不是另一套上传工具。它更像一组给编码代理使用的操作手册:先解析 App、版本和 localization ID,再选择元数据、截图、构建或审核命令;遇到失败时,按错误类型切换到对应的排查流程。
这两层的关系可以写成一句话:
CLI 提供动作,Skill 约束动作的顺序、证据和停止条件。
这也是为什么“装了 Skill 就能一键上架”是一个错误预期。Skill 可以帮你生成双语文案、检查字符限制、安排 planapply,但它无法让 Apple 没开放的公共 API 凭空出现。

当前版本的元数据流程:先计划,再审批,再应用

早期使用 asc 时,我采用的是 pull -> 修改 -> validate -> push --dry-run -> push。当前 5.4.0 已经提供更清晰的 plan / approve / apply 工作流,推荐把 review artifact 一起保留下来。
一个最小流程如下:
如果暂时不使用 review artifact,至少先运行一次:
这里的关键不是命令数量,而是把“准备内容”和“修改线上状态”拆开。只要计划结果里出现你没有打算修改的字段,就应该停下来重新拉取,而不是继续执行。

我差点覆盖掉 5 处线上修改

这次实战里,最有价值的一次失败就发生在 dry-run
我原本只准备新增两条推广文本,预期结果是两个 add。实际预览却列出了 7 项变化,多出来的 5 项涉及中文商店名、双语描述、双语更新说明和隐私政策 URL。
原因很简单:这些字段之前在 App Store Connect 网页里改过,本地副本却停留在旧版本。如果直接推送,本地旧值会把线上新值覆盖掉。
最后采用的处理顺序是:
  1. 停止应用变更;
  1. metadata pull --force 重新拉取线上状态;
  1. 在最新副本上重新做计划;
  1. 只允许预期内的字段进入审批和应用。
这个教训后来变成了整条流水线的第一条约束:本地 Git 是发布资产的长期来源,但每次修改前仍要确认线上有没有比本地更新的人工改动。

validate 通过,不代表版本已经能提交

另一个容易误判的地方是校验范围。
当时版本 2.3.0 的两个语言都缺少 whatsNew,但元数据校验仍然返回 0 个错误、0 个警告。原因是元数据校验主要检查已有字段的结构和长度,不等于完整的提交就绪度检查。
我又逐字段检查,才发现英文关键词已经达到 99/100,而两个语言的更新说明为空。前者意味着后续新增关键词必须先删词,后者则可能直接阻断版本提交。
因此至少要保留两层门禁:
  • 内容层:检查名称、副标题、关键词、描述和更新说明是否存在且未超限;
  • 发布层:运行版本级验证,确认构建、截图、审核信息、年龄分级、定价、隐私状态等提交条件。
asc 的 Skill Pack 也明确把健康检查和发布执行拆成不同职责。一个 validator 退出成功,只能证明它覆盖的那一部分没有阻断项。

截图自动化的难点不在上传

这个 App 有 6 屏、2 种语言、4 个设备尺寸,一次发版需要处理 48 张营销图。真正耗时间的不是 API,而是如何稳定地产出同一套视觉结果。
我把截图链路拆成三层:
第一层复用了项目原有的视觉回归 harness,通过启动参数直接打开指定界面。营销截图另设 shot-* screen ID,不和视觉回归夹具混用,因为两类数据的生命周期不同:回归夹具追求绝对稳定,营销夹具需要随版本卖点变化。
notion image
这张图不是生成式 UI,而是实际流水线输出的中文营销截图。录音波形来自固定相位计算,状态栏被锁定,界面内容由专用夹具写入。

两个具体坑,比框架选择更重要

第一个坑是波形动画。harness 为了保证视觉回归稳定,会关闭 UIKit 动画;原来的波形先被重置为直线,再依赖 Core Animation 起伏,所以截图里只剩一条横线。
最终没有重新打开动画,而是按原动画的振幅区间和相位差计算静态变换:
这样得到的是原动画某一帧的确定性结果,每次截图完全一致。
第二个坑是音频缺失。语音笔记没有本地音频文件时,详情页会显示“录音仅在原设备”的降级提示,营销截图中的音频卡片就被顶掉了。解决办法是在 DEBUG 夹具里运行时合成一段 AAC,让真实的波形提取逻辑有输入,而不是伪造一张看起来像界面的图片。
这两个改动都只存在于 DEBUG 路径,不给生产代码增加长期依赖。

截图上传必须按“替换事务”来设计

旧版本的经验是:截图上传属于追加操作,如果不先删除旧图,48 张会变成 96 张。当前 asc 5.4.0 已提供 --replace,但它仍然应该先预览,再确认。
对于大批量图片,只看命令返回“成功”并不够。我的验收条件是:
  • 本地文件名声明的尺寸与 PNG 实际像素一致;
  • Apple 返回的 sourceFileChecksum 与本地 MD5 一致;
  • 每张图的 assetDeliveryState.state 最终为 COMPLETE
  • 语言、设备类型、显示顺序与计划一致。
那次实际上传约 61 MB,耗时十一分钟。耗时不是问题,缺少结果校验才是问题。
Apple 当前文档也说明,如果不同设备尺寸的 UI 相同,可以只提供最高分辨率截图,由系统缩放到较小尺寸。是否继续维护四套尺寸,应该根据排版差异决定,而不是把“48 张”当成永远不变的规定。

App 隐私标签是必须正视的边界

Apple 官方要求开发者在 App Store Connect 中说明数据处理实践,并由账号持有人、管理员或 App Manager 等角色维护和发布。当前公开文档仍然把这套流程描述为 App Store Connect 网页中的问卷与发布操作。
asc 提供过 web privacy 路径,但这类能力依赖经过认证的网页会话,不等于公共 App Store Connect API。对于隐私声明这种合规信息,我的选择是:
  • 可以用工具读取、生成计划和提醒差异;
  • 不把私有网页端点的成功响应当成已经发布的证明;
  • 最终状态在 App Store Connect 页面人工确认;
  • 数据实践变化时,由了解 SDK、后端和第三方采集行为的人负责答案。
这不是保守过度。Skill 的价值之一,就是在证据不足时停下来,而不是继续自动点击。

Skill Pack 要不要全部安装

不建议因为看到“25 个 Skills”就全部装进全局目录。
对一个原生 StoreKit、双语发布的 iOS App,真正高频的通常是:
  • CLI 基础和 ID 解析;
  • 元数据同步与本地化;
  • 更新说明和 ASO 检查;
  • 截图流水线;
  • 构建、TestFlight、发布编排;
  • 提交健康检查和崩溃排查。
Apple Ads、RevenueCat、macOS notarization 等能力,如果项目根本不用,只会增加代理选择工具时的上下文负担。
安装方式也要考虑可回滚性。直接执行全局安装会把多个目录平铺进 Skills 目录;使用插件或命名空间管理,卸载和升级边界通常更清楚。唯一的代价是插件可能跟随主分支,而钉住 commit 的安装方式更利于供应链审查。
所以判断标准不是“哪个更先进”,而是你更看重可卸载性,还是固定版本的可审计性。

一套我会继续使用的最小发布流程

最终保留下来的流程不追求“一条命令全做完”,而是把不可逆操作放在明确的门后:
  1. auth doctor 检查凭据和本地配置;
  1. 解析 App、版本、构建和 localization ID;
  1. 从线上拉取元数据,生成 Git diff;
  1. 校验字段,再生成 review plan;
  1. 生成或更新真实截图,核对尺寸与顺序;
  1. 对元数据和截图分别执行 dry-run;
  1. 人工确认计划后应用;
  1. 回拉元数据,并用 checksum 核验截图;
  1. 运行提交就绪度检查;
  1. 对隐私问卷等高风险边界保留人工确认。
这套流程看起来比“自动点完所有页面”多了几步,但它减少的是返工和不可见风险。自动化真正有价值的地方,不是点击更快,而是让每次发布都能回答三个问题:准备改什么、实际改了什么、线上最终是什么。

结论

如果你的 App 每次发版都要维护多语言元数据和多组截图,asc CLI + Skills 值得投入。它能把重复劳动变成文件、命令和审查记录,让变更进入 Git,也让代理有机会按证据推进任务。
但不要把它包装成“一键上架”。元数据、截图、构建、审核和隐私声明仍然是不同资源;工具的校验也有覆盖边界。一个可靠的发布系统,必须同时拥有自动化速度和人工停止权。

参考资料

你在 App Store 发版里最想自动化的是元数据、截图,还是提交前检查?欢迎在评论区写下你遇到的具体阻塞点,这些经验也许能帮到其他海内外开发者。
写 AI,写成长,偶尔写投资。 关注沐风,不定期更新,全是干货。
2026.09.20 09:12 沪 · 赵巷