fortunto2/solo-factory/ios-release
Claude Code and agent skill by fortunto2/solo-factory
- community
Checking that the SKILL.md file is still in the repository.
Ship an iPhone/iOS app to testers (TestFlight) or to the App Store, or push an update to an app already listed there. Use when the user says "make the iOS app available to testers", "TestFlight link", "publish to the App Store", "upload the build", "submit for review", "App Store Connect", "ASC", "upload a new version", or wants store attribution set up (campaign links, `ct` tokens, App Analytics, an in-app counter and the matching App Privacy declaration). CLI-first via the `asc` tool (official App Store Connect API) — the browser is a fallback for the few things the API cannot do. Pair with the `ios-app` skill for the build/signing/archive checklist.
Install
npx vskill@latest install fortunto2/solo-factory/ios-releaseSKILL.md
ios-release — ship iPhone via CLI
Everything runs through `asc` (App Store Connect CLI — official API, JWT-signed). The browser is a fallback for the handful of flows Apple never exposed publicly — see references/browser.md.
Sibling skill: `android-release`. Build/signing/archive details live in `ios-app`. There is no APK-style sideload on iOS — testers install via TestFlight.
Golden rules:
- Never submit for review without the user's explicit OK — outward-facing and hard to reverse.
TestFlight internal-tester rollout is low-risk (no Apple review); a prior "set it up" covers it.
- Dry-run before every mutation. The high-level commands take
--dry-run; add--confirmonly
after the printed plan matches what the user asked for.
- `asc validate` is the source of truth, not your reading of the ASC web UI. Its ordered
remediation plan is the task list — fix the first item, re-validate, repeat.
- Confirm flags with `--help` before running. The CLI moves fast; don't trust memory.
- **No App Review without an end-to-end walk on a physical iPhone running the newest iOS the code
branches on** — the largest #available(iOS N in the sources. Install the exact build being submitted (TestFlight or a device install), walk the main flow to its result, leave the app once mid-task, and keep a receipt. See End-to-end gate.
End-to-end gate — before every submission
A green suite and a working simulator do not mean the build works on the phones it ships to. The case that made this a rule: a background-task handler written as a closure inside a @MainActor type compiled with an executor check, and the system ran it off the main thread. It trapped seconds after the main button, only on iOS 26. The simulator never runs background tasks, the unit test that called the handler off-main stayed green with the defect planted, and the dev phone ran iOS 18, so the #available(iOS 26 branch had never executed before the store. That version crashed about ten times as often as the one before it in its first week.
What the walk must be, and what the receipt proves:
| rule | read from | ||
|---|---|---|---|
| device | physical, never a simulator | xcrun devicectl list devices --json-output f → hardwareProperties.reality == "physical" | |
| iOS | major ≥ the newest #available(iOS N in the sources | the same JSON, deviceProperties.osVersionNumber | |
| build | the one being submitted is the one installed | devicectl device info apps --device ID --bundle-id B --include-all-apps → bundleVersion | |
| walk | the main flow to its result, plus leaving the app mid-task | the walker's own words |
Read the first three off the device, never from a flag or a memory, and write them to a receipt file per build, committed beside the release metadata.
Make it a gate, not a habit. A habit fails on the night it matters. Put a PreToolUse hook on Bash that refuses asc … review submit, submissions-submit, submit create and release run / publish appstore … --submit unless a receipt exists for the build being submitted. Resolve a --build-id with asc builds info --build-id ID (→ attributes.version). Let a --dry-run and TestFlight's own --submit through. Parse the shell line with quotes respected, so a commit message that mentions the command is not mistaken for it. Check it against a known answer before trusting it: the dev phone on an older iOS must be refused, and a live review submit aimed at a fake asc on PATH must be stopped.
When no phone on the newest iOS is at hand, the release waits, or goes to an external TestFlight group with such phones first. It never goes to App Review on the strength of the simulator.
Setup (once per machine)
The key comes from ASC → Users and Access → Integrations → App Store Connect API → Team Keys → + → role App Manager (Admin also works). The .p8 downloads exactly once. asc auth login copies the key material into the macOS Keychain, so the file can be deleted afterwards. Env-var fallbacks, CI setup and per-repo profiles: references/asc-cli.md.
Routing
| Intent | Go to | |
|---|---|---|
| Get a build to testers | A. TestFlight | |
| Ship a new app to the Store | B. App Store | |
| New version of a listed app | C. Update | |
| Crashes, feedback, testers, reviews | D. After release | |
| App Review rejected the version | E. Rejection | |
| Where installs and money come from | F. Analytics | |
asc validate reports blockers | references/readiness.md | |
| Description, keywords, ASO, What's New | references/metadata-aso.md | |
| Screenshots — capture, frame, upload | references/screenshots.md | |
| Archive, export, signing, CI pipeline | references/build-upload.md | |
| Create the app record, App Privacy | references/browser.md | |
| Flags, auth, IDs, command discovery | references/asc-cli.md |
Open every session on an unfamiliar app with the dashboard:
App registry. Before asking the user for app IDs, review contacts, copyright or store URLs, look for an ios-apps.yaml in their knowledge base or repo root (rg -l "asc_auth|bundle_id" --glob "*.yaml"). Releases need the same handful of values every time; a registry means asking once. Keep that file in a private repo — it holds a phone number and email that App Review sees but the store never shows.
A. MINIMAL — TestFlight
One command covers upload, processing wait, and group assignment:
No .ipa yet? asc xcode archive + asc xcode export build one — see references/build-upload.md.
Then:
- Internal testers (≤100, must be Users on the ASC team) — no review, available in minutes.
- External testers / public link — needs a short Beta App Review plus the export-compliance
answer. Add --submit --confirm to trigger that review.
Monitor:
⚠️ BETA_CONTRACT_MISSING (422) on upload = check ASC → Agreements are all Active (Paid + Free Apps). If they are and it still fails, it's an Apple-side backend bug — contact support, don't just wait it out.
B. FULL — App Store submission
The version sits in "Prepare for Submission" until a checklist is complete. Drive that checklist from validate, never from clicking around the web UI.
Starting from an .ipa with nothing staged, asc publish appstore collapses steps 3–4:
Do not mix lanes. Once a lane has created a review submission, inspect it (asc submit status --version-id "VERSION_ID") and continue in that same lane.
Success = the version's appStoreState / reviewSubmission.state reads WAITING_FOR_REVIEW.
What validate enforces
Metadata lengths · required localizations · review details · primary category · attached and processed build · encryption declaration · content rights · pricing schedule and territory availability (a separate required item — the classic miss) · screenshot presence and sizes · age rating. Repair recipes for each: references/readiness.md.
App Privacy is not in the public API — use asc web privacy or the browser. See references/browser.md.
What validate does NOT catch — check these by hand before submitting
A clean asc validate is not a clean review. These pass validation and get the version rejected:
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/ios-release/SKILL.md
Popularity
- Repository stars
- 18
- Repository forks
- 3
- 7-day trend score
- 15
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/fortunto2/solo-factory/ios-release)