SuperAPI AI 工具集

asc-ad-hoc-distribution

部署与运维

查看项目

更新于 10-15 15:11

技能介绍

用途

asc-ad-hoc-distribution 用于把已有的 iOS 归档(.xcarchive)转换为面向已注册设备的私有、可验证的安装链接,适用于不走 TestFlight 或 App Store 的私有发布测试分发场景。当构建需要经由 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

工作流选择

  • 端到端、基于哈希授权的运行:使用 plan -> apply -> resume/status -> verify,从 .xcarchive 开始。
  • 若调用方已持有 ad hoc IPA,并希望分别操作底层边界,则使用 inspect -> prepare -> publish。

安全护栏

分发规格(spec)、设备文件、PKCS#12 身份、密码文件、运行状态和确切的安装链接产物都应视为私密资料,须排除在 Git 之外并要求仅属主权限。

不得把 S3 凭据或预签名 URL 写入分发规格、命令输出、日志、issue 或聊天。应使用 ASC_S3_ACCESS_KEY_ID、ASC_S3_SECRET_ACCESS_KEY 及可选的 ASC_S3_SESSION_TOKEN,或标准 AWS SDK 凭据链。

plan 为只读操作,可能在 ready: false 的情况下以成功状态退出;继续前应先检查类型化的阻断项(blockers)与影响清单(effects)。

apply 可以注册缺失的设备、创建安全的 App ID 与后继 ad hoc 描述文件、写入本地产物并发布不可变对象。只有在用户授权确切的 plan hash 与影响清单之后才能运行。

该编排工作流支持对已有 S3 兼容存储桶的私有访问。它不会创建存储桶、修改策略、删除旧构建、安装应用或启动应用。

输入漂移、不可变对象冲突、签名材料过期或私有链接过期,都需要重新生成计划,不得强行推进旧运行。

前置条件

  • 已存在的 iOS .xcarchive,且仅含一个主应用 target。内嵌应用、扩展、Watch 应用和 App Clip 会使 v1 计划无法就绪。
  • 本地 iOS 分发用 PKCS#12 身份,以及可选的受保护密码文件。
  • 受保护的 strict-v1 设备文件,例如:
{"schemaVersion":1,"devices":[{"name":"Test iPhone","udid":"DEVICE_UDID","platform":"IOS"}]}
  • App Store Connect 认证,且可访问设备、Bundle ID、证书和描述文件。
  • 已存在的 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 以及所有 metadata 字段均为可选。省略密码文件意味着 PKCS#12 必须使用空密码。规划前先保护配置与密钥输入:

chmod 600 ".asc/distribution/config.json" ".asc/distribution/devices.json"
chmod 600 ".asc/signing/distribution.p12" ".asc/secrets/distribution-p12-password"

2. 只读规划(plan)

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、签名有效期、目标位置以及完整有序的影响清单。当 ready 为 false 时,解决阻断项并重新生成计划,不能仅凭退出码推断就绪状态。

3. 执行经授权的精确计划(apply)

在批准确切影响后,传入完整的 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 是一种 bearer 凭据,仅存储在运行完成后报告的、仅属主可读的链接产物中,只应通过经批准的私有渠道共享给目标测试者。

底层 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

inspect 默认省略原始设备 UDID,除非显式需要 --include-devices。prepare 绝不覆盖已有 bundle,只会复用完全等价的 bundle。私有发布是默认方式,只把确切的预签名链接写入权限为 0600 的链接产物。公开发布是另一条显式路径,使用 --access public --public-base-url;它假定匿名读取已配置完成,且从不更改存储策略。

适用场景与限制

适用于团队内部按渠道(如 pull-request-42)向已注册设备分发测试构建的私有安装链接,并需要发布、恢复与验证能力的情况。限制包括:仅支持单一主应用 target 的归档;不创建存储桶、不修改策略、不删除旧构建;不负责安装或启动应用;输入漂移、不可变对象冲突、签名材料或私有链接过期都要重新规划。其他未在资料中说明的功能、收费、平台或价格信息暂未提供。