关于 asc-ad-hoc-distribution
asc-ad-hoc-distribution 是一项技能,使用实验性的 `asc distribute` 工作流,将现有 iOS 归档包私密分发给已注册设备。它涵盖授权规划、发布、恢复和验证,并强调保护签名材料与安装链接。
主要功能
- 01规划并授权分发影响
- 02发布到现有 S3 兼容存储桶
- 03恢复运行并查看状态
- 04验证已发布构建及其获取情况
- 05提供独立的 IPA 发布流程
适用场景
- 01向已注册测试人员分发 iOS 构建
- 02在分发前审查副作用
- 03恢复或验证分发运行
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ rorkai/ app-store-connect-cli-skills --skill asc-ad-hoc-distribution安装后在 Claude Code 中输入/asc-ad-hoc-distribution确认已加载。
详细介绍
ASC ad hoc 分发
使用实验性的 asc distribute 工作流,将现有 iOS 归档转换为供已注册设备使用的私有、已验证安装链接。如果构建应通过 Apple 托管的分发方式发布,请改用 TestFlight 或 App Store 发布技能。
操作前确认已安装的契约:
asc distribute --help
asc distribute plan --help
asc distribute apply --help
asc distribute resume --help
asc distribute status --help
asc distribute verify --help
选择工作流
- 对于从
.xcarchive开始、端到端且经过哈希授权的运行,使用plan->apply->resume/status->verify。 - 仅当调用方已拥有 ad hoc IPA,并希望分别操作较低级别的边界时,才使用
inspect->prepare->publish。
安全限制
- 将分发规范、设备文件、PKCS#12 身份、密码文件、运行状态和确切的安装链接产物视为私有信息。不要将它们提交到 Git,并要求仅所有者可访问的权限。
- 切勿将 S3 凭证或预签名 URL 放入分发规范、命令输出、日志、问题单或聊天中。请使用
ASC_S3_ACCESS_KEY_ID、ASC_S3_SECRET_ACCESS_KEY和可选的ASC_S3_SESSION_TOKEN,或标准 AWS SDK 凭证链。 plan只读,且可能成功退出并返回ready: false。继续之前,请检查类型化阻塞项和影响。apply可以注册缺失的设备、创建安全的 App ID 和后续 ad hoc 配置描述文件、写入本地产物并发布不可变对象。只有在用户授权确切的计划哈希和影响清单后才能运行。- 编排后的工作流支持私有访问现有的 S3 兼容存储桶。它不会创建存储桶、更改策略、删除旧构建、安装应用或启动应用。
- 输入发生变化、不可变对象冲突、签名材料过期或私有链接过期时,都需要新计划。不要强行继续旧运行。
前置条件
- 一个现有的 iOS
.xcarchive,且只有一个主应用目标。嵌入式应用、扩展、Watch 应用和 App Clips 会导致 v1 计划无法就绪。 - 一个本地 iOS 分发 PKCS#12 身份,以及可选的受保护密码文件。
- 一个受保护的 strict-v1 设备文件。例如:
{"schemaVersion":1,"devices":[{"name":"Test iPhone","udid":"DEVICE_UDID","platform":"IOS"}]}
- 具有设备、Bundle ID、证书和配置描述文件访问权限的 App Store Connect 身份验证。
- 一个现有的 S3 兼容存储桶和有效凭证。
1. 创建私有分发规范
相对路径以规范所在目录为基准。规范不会插值环境变量,也不接受凭证。一个具有代表性的私有配置如下:
{
"schemaVersion": 1,
"devicesFile": "devices.json",
"signing": {
"identity": {
"format": "pkcs12",
"path": "../signing/distribution.p12",
"passwordFile": "../secrets/distribution-p12-password"
},
"minimumValidityDays": 7,
"maxMutations": 32
},
"publication": {
"endpoint": "https://objects.example.com",
"downloadEndpoint": "https://downloads.example.com",
"region": "auto",
"bucket": "ios-builds",
"prefix": "team/app",
"addressingStyle": "path",
"urlTtl": "24h",
"downloadGrace": "1h",
"verifyTimeout": "30s"
},
"metadata": {
"title": "App",
"channel": "pull-request-42",
"sourceRevision": "abc123",
"sourceUrl": "https://example.com/team/app/commit/abc123"
}
}
passwordFile、certificateSha256、downloadEndpoint 和每个元数据字段都是可选的。省略密码文件意味着 PKCS#12 必须使用空密码。规划前请保护配置和机密输入:
chmod 600 ".asc/distribution/config.json" ".asc/distribution/devices.json"
chmod 600 ".asc/signing/distribution.p12" ".asc/secrets/distribution-p12-password"
2. 规划但不进行更改
asc distribute plan \
--archive-path ".asc/artifacts/App.xcarchive" \
--config ".asc/distribution/config.json" \
--plan ".asc/distribution/plan.json" \
--state-dir ".asc/distribution/runs" \
--output json
检查 ready、planHash、签名有效性、目标位置和完整的有序 effects 清单。如果 ready 为 false,请解决阻塞项并创建新计划。不要仅凭退出代码推断是否就绪。
3. 应用确切的授权计划
确切影响获得批准后,传入完整的 64 位字符哈希:
PLAN_HASH="$(jq -er '.planHash' ".asc/distribution/plan.json")"
asc distribute apply \
--plan ".asc/distribution/plan.json" \
--confirm "$PLAN_HASH" \
--output json
缺失、格式错误或不匹配的确认会在产生副作用前被拒绝。成功表示发布和实时获取验证已完成;这并不表示设备已安装或启动应用。
4. 检查、恢复和验证
使用返回的 runId:
asc distribute status --run "RUN_ID" --state-dir ".asc/distribution/runs" --output json
asc distribute resume --run "RUN_ID" --state-dir ".asc/distribution/runs" --output json
asc distribute verify --run "RUN_ID" --state-dir ".asc/distribution/runs" --timeout 30s --output json
status 仅在本地运行,并且对 running、recoverable 和 blocked
状态的运行均会成功;请根据类型化字段而非说明文字进行分支判断。resume 会在重试前重新验证持久化证据,绝不会盲目重复远程写入。verify 为只读操作,但会执行实时获取。只有当用户要求在已连接的设备上观察匹配的已安装 Bundle、版本和构建版本时,才添加 --device "DEVICE_SELECTOR";此观察无法证明 IPA 字节一致。
确切的私有安装 URL 是持有者凭证,仅存储在已完成运行所报告的所有者私有链接文件中。只能通过经批准的私密渠道将其分享给指定测试人员。
较低层级的 IPA 工作流
当签名和导出已完成时,使用此流程。将 prepare 返回的确切 bundleDir 传递给 publish:
asc distribute inspect --ipa ".asc/artifacts/App.ipa" --output json
asc distribute prepare --ipa ".asc/artifacts/App.ipa" --channel "pull-request-42" --output json
asc distribute publish \
--bundle-dir ".asc/distribution/com.example.app/1.2-42-IPA_SHA_PREFIX" \
--endpoint "https://objects.example.com" \
--region "auto" \
--bucket "ios-builds" \
--prefix "team/app" \
--receipt ".asc/publishes/app-1.2-42.json" \
--link-path ".asc/publishes/app-1.2-42-link.json" \
--output json
除非明确需要 --include-devices,否则 inspect 不会提供原始设备 UDID。prepare 绝不会覆盖 Bundle,并且只会复用完全等效的 Bundle。默认采用私有 publish,并且只将确切的预签名链接写入权限为 mode 0600 的链接文件。公开发布是单独的显式流程,使用 --access public --public-base-url;它假设匿名读取权限已配置完成,并且绝不会更改存储策略。