Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when apple-release-engineer is about to build the signed distributable (TestFlight build / notarized DMG / internal package) from merged-to-main code (after apple code review + SIT Audit pass and merge, before apple-qa-engineer runs E2E/UAT). Provides the applicability gate, pre-flight checks, lane execution per channel, notarization, real-output smoke test, hand-off, and the release-report skeleton. Pairs with deployment.md §7 "Apple 发布" contract and slash /agf-apple-release.
.claude/skills/pcliangx-agf-releasing-apple/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 81% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 1429% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 51% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 103% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 99% | 0% |
把合并到 main 后的干净代码构建成签名分发包,冒烟自检通过后交接 apple-qa-engineer。本 skill 是 apple-release-engineer 的分步 runbook;契约 SSOT 是 deployment.md §7,流水线决策是 ADR-009。
满足以下全部才进入构建:
apple-release-engineer(deploy-only,不修业务源码;apple/fastlane/ 配置是可写域)。apple/ 工程)。Web docker UAT → 归 deploy-engineer;小程序体验版 → 归 miniapp 轨。均不适用。/agf-apple-release 手动触发),且 PRD 已声明渠道。任一不满足 → 不构建,SendMessage product-lead 说明缺什么。
git status 无未提交改动,记录构建 commit SHA(git rev-parse --short HEAD)。xcodebuild -version / bundle exec fastlane --version 正常返回。.p8)路径 / key id / issuer id 经环境变量可达;match 仓可访问(fastlane match 能同步证书 + profile)。任何 .p8 / .p12 / .mobileprovision 都不得出现在 git 工作区(scan-secrets / pre-commit 兜底)。versioning.md;build number 在该渠道单调递增。任一不勾 → 不构建,先 SendMessage product-lead 解决先决条件。
bashcd apple && bundle exec fastlane <lane>
| lane | 渠道 | 关键动作 | |---|---|---| | beta | TestFlight 内测 | match(type: appstore) → build_app → pilot(上传 + 等待处理完成) | | release_appstore | App Store 上架 | match → build_app → deliver(含元数据 / 截图 / 提审包) | | release_dmg | macOS 直发 | match(type: developer_id) → build_app → notarize(notarytool + API key)→ DMG 打包(hdiutil / create-dmg) | | release_internal | 企业 / 内部 | macOS:Developer ID 包内部散发;iOS in-house lane 仅在 Enterprise 会籍就位后启用(ADR-009) |
notarize 等待完成后才继续,禁止跳过等待声明成功。只接受真实证据,拒绝 "构建 exit 0 就算" / "应该能装":
bash spctl -a -vv /path/to/App.app # 期望 "accepted ... Notarized Developer ID" hdiutil attach <dmg> && open App.app # 干净用户目录实际启动 贴 spctl 真实输出 + app 启动后关键路径点查(主窗口出现 / 核心视图可达)。
pilot 上传完成 + App Store Connect 处理状态到 "Ready to Test"(贴 fastlane 输出的 build 号 + 状态行)deliver 校验通过输出(元数据 / 截图齐全),不实际点提交(提审动作由 product-lead 确认后执行)。任一非预期 → gate = ❌ 构建失败。
冒烟范围说明:冒烟只证明"包出得来、装得上、跑得起",不是 E2E——AC 验收归 apple-qa-engineer。冒烟暴露代码层缺陷(启动即崩 / 核心视图白屏),采集证据退回 product-lead,不自己改 apple/App*。
✅ 构建成功(冒烟通过) —— 前置全过 + lane 完成 + 公证/处理完成 + 冒烟真实证据。❌ 构建失败 —— 任一环节失败;报告标明签名/公证/打包配置问题(自己重跑)还是代码问题(退回 PL → apple-dev)。不发明新 verdict 词表(保 CLAUDE.md「Verdict 词表 4 套」硬事实)。
报告落盘后立即(不等用户问)SendMessage product-lead:
SendMessage({to: "product-lead", message: "发布构建完成: [功能名]\n报告: docs/deploy/[feature]-apple-[YYYY-MM-DD].md\n渠道/lane: [lane]\n分发包: [TestFlight build 号 / DMG 路径]\n构建 commit: [SHA]\n结果: ✅ 构建成功(冒烟通过) / ❌ 构建失败", summary: "Apple 发布构建: [功能名]"})✅ → PL 触发 apple-qa-engineer 对该分发包跑 E2E;❌ → PL 决策重跑(配置)/ 退回 apple-dev(代码)。
落到 docs/deploy/<feature>-apple-<YYYY-MM-DD>.md(pool=1,无 agf-matrix frontmatter):
`markdown# Apple 发布报告 — [Feature] - **Date**: YYYY-MM-DD - **Releaser**: apple-release-engineer ([model name]) - **构建 commit (merged main)**: [short SHA] - **渠道 / lane**: [beta | release_appstore | release_dmg | release_internal] - **Target**: [macos | ios | universal] - **版本**: [marketing version] ([build number]) ## 分发包定位(交给 apple-qa-engineer 作测试目标) | 项 | 值 | |---|---| | TestFlight build 号 / DMG 路径 | ... | | 安装方式 | TestFlight 邀请 / DMG 挂载 | ## 前置检查 - [x] main 干净(commit [SHA]) - [x] 工具链可用(xcodebuild / fastlane 版本) - [x] 签名材料就位(match 同步成功;无 .p8/.p12 入库) - [x] 渠道已声明 + 版本号就绪 ## Lane 执行
bundle exec fastlane <lane> (贴关键输出:match 同步 / build_app 产物 / pilot 或 notarize 完成行)
## 冒烟证据(真实输出,非 dry-run)
- **公证/处理状态**:(贴 spctl -a -vv 输出 / TestFlight "Ready to Test" 状态行)
- **实际启动点查**:(装包启动 + 关键路径可达的证据)
## Release Gate
**Verdict**: ✅ 构建成功(冒烟通过) / ❌ 构建失败
(失败时:问题归类 = 签名/公证/打包配置(自己重跑) / 代码(退回 product-lead → apple-dev)+ 证据)
## Hand-off
✅ → SendMessage product-lead(附分发包定位)→ PL 触发 apple-qa-engineer E2E
❌ → SendMessage product-lead(附失败定位)→ PL 决策重跑 / 退回 apple-dev任一不行 → 不要声明构建成功,回去补。
.p8 / .p12 / match 密码写进任何入库文件 —— 环境变量 / Keychain only。apple/App* —— 越界;采证退回 PL → apple-dev。| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 9,555 | 11,291 | +18% | 1 | 1 | 0% | 1,379 | 4,164 | +202% | 0 | 0 | — |
case-02 | fail→pass | 10,159 | 6,522 | -36% | 1 | 1 | 0% | 1,782 | 3,233 | +81% | 0 | 0 | — |
case-03 | fail→pass | 4,436 | 5,815 | +31% | 1 | 1 | 0% | 209 | 3,196 | +1429% | 0 | 0 | — |
case-04 | fail→pass | 17,687 | 10,976 | -38% | 1 | 1 | 0% | 2,852 | 4,299 | +51% | 0 | 0 | — |
case-05 | fail→fail | 4,114 | 7,340 | +78% | 1 | 1 | 0% | 237 | 2,736 | +1054% | 0 | 0 | — |
case-06 | fail→fail | 15,743 | 7,641 | -51% | 1 | 1 | 0% | 2,520 | 2,556 | +1% | 0 | 0 | — |
case-07 | fail→pass | 9,371 | 5,171 | -45% | 1 | 1 | 0% | 1,518 | 3,085 | +103% | 0 | 0 | — |
case-08 | fail→pass | 8,847 | 6,273 | -29% | 1 | 1 | 0% | 1,677 | 3,329 | +99% | 0 | 0 | — |
case-09 | pass→pass | 9,935 | 6,083 | -39% | 1 | 1 | 0% | 1,628 | 3,238 | +99% | 0 | 0 | — |
case-10 | fail→pass | 12,399 | 6,053 | -51% | 1 | 1 | 0% | 1,937 | 3,300 | +70% | 0 | 0 | — |
case-11 | fail→pass | 10,824 | 3,546 | -67% | 1 | 1 | 0% | 1,760 | 2,808 | +60% | 0 | 0 | — |
case-12 | fail→pass | 7,980 | 3,645 | -54% | 1 | 1 | 0% | 1,198 | 2,842 | +137% | 0 | 0 | — |
case-13 | fail→pass | 6,875 | 2,598 | -62% | 1 | 1 | 0% | 1,184 | 2,646 | +123% | 0 | 0 | — |
case-14 | pass→pass | 7,759 | 2,923 | -62% | 1 | 1 | 0% | 1,232 | 2,712 | +120% | 0 | 0 | — |
case-15 | fail→pass | 10,979 | 1,872 | -83% | 1 | 1 | 0% | 1,919 | 2,540 | +32% | 0 | 0 | — |
case-16 | fail→pass | 8,566 | 1,795 | -79% | 1 | 1 | 0% | 1,381 | 2,487 | +80% | 0 | 0 | — |
case-17 | fail→pass | 9,199 | 2,010 | -78% | 1 | 1 | 0% | 1,504 | 2,537 | +69% | 0 | 0 | — |
case-18 | fail→pass | 7,543 | 2,110 | -72% | 1 | 1 | 0% | 995 | 2,484 | +150% | 0 | 0 | — |
case-19 | pass→pass | 13,531 | 2,304 | -83% | 1 | 1 | 0% | 2,131 | 2,577 | +21% | 0 | 0 | — |
case-20 | pass→pass | 10,062 | 3,128 | -69% | 1 | 1 | 0% | 1,491 | 2,755 | +85% | 0 | 0 | — |
case-21 | fail→fail | 4,968 | 1,365 | -73% | 1 | 1 | 0% | 696 | 2,416 | +247% | 0 | 0 | — |
case-22 | fail→pass | 8,575 | 2,079 | -76% | 1 | 1 | 0% | 1,230 | 2,572 | +109% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 19 counted toward the lift figure. The other 3 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +64 percentage points is the difference between those two pass rates over the 19 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.