asc-ad-hoc-distribution
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseASC ad hoc distribution
ASC 临时分发
Use the experimental workflow to turn an existing iOS archive
into a private, verified install link for registered devices. Use TestFlight or
the App Store release skills instead when the build should go through Apple-hosted
distribution.
asc distributeConfirm the installed contract before acting:
bash
asc distribute --help
asc distribute plan --help
asc distribute apply --help
asc distribute resume --help
asc distribute status --help
asc distribute verify --help使用实验性的工作流,将现有的iOS归档文件转换为供已注册设备使用的私有验证安装链接。如果构建需要通过Apple托管的分发渠道,请改用TestFlight或App Store发布工具。
asc distribute执行操作前请确认已安装的合约:
bash
asc distribute --help
asc distribute plan --help
asc distribute apply --help
asc distribute resume --help
asc distribute status --help
asc distribute verify --helpChoose the workflow
选择工作流
- Use ->
plan->apply/resume->statusfor an end-to-end, hash-authorized run starting from anverify..xcarchive - Use ->
inspect->prepareonly when the caller already owns the ad hoc IPA and wants to operate the lower-level boundaries separately.publish
- 若要从开始执行端到端的哈希授权流程,请使用
.xcarchive->plan->apply/resume->status流程。verify - 当调用方已拥有临时IPA,并希望单独操作底层环节时,仅使用->
inspect->prepare流程。publish
Guardrails
操作规范与防护
- Treat the distribution spec, devices file, PKCS#12 identity, password file, run state, and exact install-link artifact as private. Keep them out of Git and require owner-only permissions.
- Never put S3 credentials or presigned URLs in the distribution spec, command
output, logs, issues, or chat. Use ,
ASC_S3_ACCESS_KEY_ID, and optionalASC_S3_SECRET_ACCESS_KEY, or the standard AWS SDK credential chain.ASC_S3_SESSION_TOKEN - is read-only and may exit successfully with
plan. Inspect the typed blockers and effects before continuing.ready: false - can register missing devices, create safe App IDs and successor ad hoc profiles, write local artifacts, and publish immutable objects. Run it only after the user authorizes the exact plan hash and effect inventory.
apply - The orchestrated workflow supports private access to an existing S3-compatible bucket. It does not create buckets, change policies, delete old builds, install the app, or launch it.
- Input drift, an immutable-object conflict, expired signing material, or an expired private link requires a new plan. Do not force the old run forward.
- 请将分发配置文件、设备文件、PKCS#12身份证书、密码文件、运行状态以及确切的安装链接产物视为私有信息。请勿将其存入Git,且仅允许所有者拥有访问权限。
- 切勿将S3凭证或预签名URL放入分发配置文件、命令输出、日志、问题工单或聊天内容中。请使用、
ASC_S3_ACCESS_KEY_ID以及可选的ASC_S3_SECRET_ACCESS_KEY,或标准AWS SDK凭证链。ASC_S3_SESSION_TOKEN - 是只读操作,即使返回
plan也可能成功退出。请在继续操作前检查明确的阻塞项和影响。ready: false - 可以注册缺失的设备、创建安全的App ID和后续临时配置文件、写入本地产物并发布不可变对象。仅在用户授权确切的计划哈希和影响清单后再执行该操作。
apply - 编排后的工作流支持对现有S3兼容存储桶的私有访问,但不会创建存储桶、修改策略、删除旧构建、安装应用或启动应用。
- 输入漂移、不可变对象冲突、签名材料过期或私有链接过期时,需要创建新计划。请勿强行推进旧流程。
Preconditions
前置条件
- An existing iOS with one main app target. Embedded apps, extensions, Watch apps, and App Clips make the v1 plan not ready.
.xcarchive - A local iOS distribution PKCS#12 identity and optional protected password file.
- A protected strict-v1 devices file. For example:
json
{"schemaVersion":1,"devices":[{"name":"Test iPhone","udid":"DEVICE_UDID","platform":"IOS"}]}- App Store Connect authentication with access to devices, Bundle IDs, certificates, and profiles.
- An existing S3-compatible bucket and valid credentials.
- 存在包含一个主应用目标的iOS 文件。嵌入式应用、扩展、Watch应用和App Clips会导致v1计划无法就绪。
.xcarchive - 本地iOS分发PKCS#12身份证书和可选的受保护密码文件。
- 受保护的strict-v1设备文件。例如:
json
{"schemaVersion":1,"devices":[{"name":"Test iPhone","udid":"DEVICE_UDID","platform":"IOS"}]}- 具备访问设备、Bundle ID、证书和配置文件权限的App Store Connect认证。
- 已存在的S3兼容存储桶和有效凭证。
1. Create the private distribution spec
1. 创建私有分发配置文件
Relative paths resolve from the spec directory. The spec does not interpolate
environment variables or accept credentials. A representative private config is:
json
{
"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"
}
}passwordFilecertificateSha256downloadEndpointbash
chmod 600 ".asc/distribution/config.json" ".asc/distribution/devices.json"
chmod 600 ".asc/signing/distribution.p12" ".asc/secrets/distribution-p12-password"相对路径从配置文件目录解析。配置文件不会插值环境变量或接受凭证。一个典型的私有配置如下:
json
{
"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"
}
}passwordFilecertificateSha256downloadEndpointbash
chmod 600 ".asc/distribution/config.json" ".asc/distribution/devices.json"
chmod 600 ".asc/signing/distribution.p12" ".asc/secrets/distribution-p12-password"2. Plan without mutation
2. 执行无变更计划
bash
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 jsonInspect , , signing validity, destination, and the complete
ordered inventory. Resolve blockers and create a new plan when
is false. Do not infer readiness from exit code alone.
readyplanHasheffectsreadybash
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检查、、签名有效性、目标地址以及完整的有序清单。当为false时,请解决阻塞项并创建新计划。请勿仅通过退出码推断就绪状态。
readyplanHasheffectsready3. Apply the exact authorized plan
3. 应用已授权的确切计划
After approval of the exact effects, pass the full 64-character hash:
bash
PLAN_HASH="$(jq -er '.planHash' ".asc/distribution/plan.json")"
asc distribute apply \
--plan ".asc/distribution/plan.json" \
--confirm "$PLAN_HASH" \
--output jsonMissing, malformed, or unequal confirmation is rejected before side effects.
Success means publication and live fetch verification completed; it does not
mean a device installed or launched the app.
在确认确切影响后,传入完整的64位哈希值:
bash
PLAN_HASH="$(jq -er '.planHash' ".asc/distribution/plan.json")"
asc distribute apply \
--plan ".asc/distribution/plan.json" \
--confirm "$PLAN_HASH" \
--output json缺失、格式错误或不匹配的确认信息会在产生副作用前被拒绝。操作成功意味着发布和实时获取验证已完成,但不代表设备已安装或启动应用。
4. Inspect, resume, and verify
4. 检查、恢复和验证
Use the returned :
runIdbash
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 jsonstatusrunningrecoverableblockedresumeverify--device "DEVICE_SELECTOR"The exact private install URL is a bearer credential stored only in the
owner-private link artifact reported by the completed run. Share it only with
the intended tester through an approved private channel.
使用返回的:
runIdbash
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 jsonstatusrunningrecoverableblockedresumeverify--device "DEVICE_SELECTOR"确切的私有安装URL是仅存储在已完成流程报告的所有者私有链接产物中的承载凭证。请仅通过经批准的私有渠道与指定测试人员分享。
Lower-level IPA workflow
底层IPA工作流
Use this lane when signing and export are already complete. Pass the exact
returned by to :
bundleDirpreparepublishbash
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 jsoninspect--include-devicespreparepublish--access public --public-base-url当签名和导出已完成时使用此流程。将返回的确切传入:
preparebundleDirpublishbash
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 jsoninspect--include-devicespreparepublish--access public --public-base-url