swiftship/internal/skills/data/features/asc-testflight-orchestration/SKILL.md
End-to-end release workflows for TestFlight and App Store including build, archive, export, upload, and distribution. Use when asked to publish, submit, distribute to TestFlight, or submit to App Store.
npx skillsauth add abdullah4ai/apple-developer-toolkit asc-testflight-orchestrationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
If the user only asks to add/invite a beta tester (NOT build + upload), skip the full workflow. Follow these steps in exact order:
# 1. Check if there are any builds available
asc builds list --app "APP_ID" --limit 3 --output json
If NO builds exist: Tell the user they need to upload a build first. Offer to run the full build+upload workflow (Step 1-9 below). Do NOT add testers without a build.
If builds exist: Continue with external testing below.
External testing works for any email — the tester does NOT need to be an App Store Connect team member. However, external testing requires Beta App Review before the tester can install.
# 2. List existing external groups, or create one
asc testflight beta-groups list --app "APP_ID" --output json
asc testflight beta-groups create --app "APP_ID" --name "Beta Testers"
# 3. Assign the latest build to the external group
asc builds add-groups --build "BUILD_ID" --group "GROUP_ID"
# 4. Add the tester to the group (works for any email)
asc testflight beta-testers add --app "APP_ID" --email "[email protected]" --group "Beta Testers"
Now you MUST ask the user for confirmation before submitting for Beta App Review. Say:
"I've added [email protected] to the Beta Testers group. To complete the invitation, this build needs to be submitted for Beta App Review (Apple reviews it, typically < 24 hours). Once approved, the tester will automatically receive a TestFlight invitation email. Shall I submit for Beta App Review?"
Wait for the user's response. Only proceed if they confirm:
# 5. Submit for Beta App Review (only after user confirms)
asc testflight review submit --build "BUILD_ID" --confirm
# 6. Check review status
asc testflight review submissions list --build "BUILD_ID"
Do NOT call asc testflight beta-testers invite for external testers — it will fail with "Tester has no installable build" until Beta App Review is approved. Once approved, the tester automatically receives the invitation.
Internal testing is only for people who are already App Store Connect team members. Internal groups auto-receive all builds and testers get instant access (no review). Use this only when the user explicitly asks for internal testing or the tester is a known team member.
asc testflight beta-groups create --app "APP_ID" --name "Internal Testers" --internal
asc testflight beta-testers add --app "APP_ID" --email "[email protected]" --group "Internal Testers"
asc testflight beta-testers invite --app "APP_ID" --email "[email protected]"
Do NOT use asc builds add-groups for internal groups — they auto-receive all processed builds.
xcodebuild archive + xcodebuild -exportArchive (see asc-xcode-build skill).asc auth login or ASC_* env vars).ASC_APP_ID or pass --app explicitly.asc publish testflight --app <APP_ID> --ipa <PATH> --group <GROUP_ID>[,<GROUP_ID>]--wait, --notify, --platform, --poll-interval, --timeoutasc publish appstore --app <APP_ID> --ipa <PATH> --version <VERSION>--wait, --submit --confirm, --platform, --poll-interval, --timeoutThis is a MANDATORY step-by-step workflow. When the user asks to publish/build/upload to TestFlight, you MUST execute ALL steps below in order. Do NOT skip any step. Do NOT claim the app is "already on TestFlight" without verifying. Do NOT stop after planning — execute the commands.
# Find .xcodeproj or .xcworkspace
find . -maxdepth 2 -name "*.xcworkspace" -o -name "*.xcodeproj" | head -5
If a project.yml exists (XcodeGen project), always regenerate the .xcodeproj first:
xcodegen generate
This ensures all build settings (CFBundleIconName, icon assets, etc.) are current in the .xcodeproj.
If a .xcworkspace exists, use -workspace flag. Otherwise use -project flag.
# List available schemes
xcodebuild -list
Pick the main app scheme (not tests, not UI tests).
# Get current build settings
xcodebuild -showBuildSettings -scheme "SCHEME" | grep -E "CURRENT_PROJECT_VERSION|MARKETING_VERSION"
Also check the latest build on ASC:
asc builds list --app "APP_ID" --limit 3 --output json
If the local build number is not higher than the latest uploaded build, increment it:
# Find the project.pbxproj or xcconfig and update CURRENT_PROJECT_VERSION
Check if ITSAppUsesNonExemptEncryption is set. If not, add it to avoid encryption compliance issues:
# Check in Info.plist or build settings
grep -r "ITSAppUsesNonExemptEncryption" . --include="*.plist" --include="*.pbxproj"
If missing, add ITSAppUsesNonExemptEncryption = NO to the app's Info.plist.
xcodebuild clean archive \
-scheme "SCHEME" \
-configuration Release \
-archivePath /tmp/APP_NAME.xcarchive \
-destination "generic/platform=iOS" \
-allowProvisioningUpdates \
AUTHENTICATION_KEY_PATH AUTH_FLAGS_IF_AVAILABLE
If API key authentication flags are provided in the system prompt, include them:
-authenticationKeyPath <path>-authenticationKeyID <id>-authenticationKeyIssuerID <issuer>This step MUST succeed. If it fails, diagnose the error and fix it before proceeding.
cat > /tmp/ExportOptions.plist << 'PLIST'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>app-store-connect</string>
<key>destination</key>
<string>upload</string>
</dict>
</plist>
PLIST
If you know the team ID, add it:
<key>teamID</key>
<string>TEAM_ID</string>
xcodebuild -exportArchive \
-archivePath /tmp/APP_NAME.xcarchive \
-exportPath /tmp/APP_NAME_Export \
-exportOptionsPlist /tmp/ExportOptions.plist \
-allowProvisioningUpdates \
AUTHENTICATION_KEY_PATH AUTH_FLAGS_IF_AVAILABLE
This step MUST succeed. The IPA file will be at /tmp/APP_NAME_Export/APP_NAME.ipa.
asc builds upload --app "APP_ID" --ipa "/tmp/APP_NAME_Export/APP_NAME.ipa"
Wait for the upload to complete.
After upload, the build needs time to process on Apple's servers:
# Check if the build is processed
asc builds latest --app "APP_ID" --output json
If the build is still processing, wait and check again. Use asc builds info --build BUILD_ID to check status.
# 1. Create an external group and assign the build
asc testflight beta-groups create --app "APP_ID" --name "Beta Testers"
asc builds add-groups --build "BUILD_ID" --group "GROUP_ID"
# 2. Add tester to the group (works for any email)
asc testflight beta-testers add --app "APP_ID" --email "[email protected]" --group "Beta Testers"
Now ask the user for confirmation before submitting for Beta App Review:
"I've added the tester to the Beta Testers group. To complete the invitation, this build needs to be submitted for Beta App Review (typically < 24h). Once approved, the tester will automatically receive a TestFlight invitation. Shall I submit?"
# 3. Submit for Beta App Review (only after user confirms)
asc testflight review submit --build "BUILD_ID" --confirm
# 4. Check submission status
asc testflight review submissions list --build "BUILD_ID"
Do NOT call beta-testers invite for external testers — it fails with "Tester has no installable build" until review is approved. Once approved, testers automatically receive the TestFlight invitation.
# Verify the build is on TestFlight
asc builds info --build "BUILD_ID" --output json
Report to the user:
For App Store (not TestFlight), attach the build to a version and submit:
# Attach build to version
asc versions attach-build --version-id <VERSION_ID> --build <BUILD_ID>
# Submit for review
asc submit create --app <APP_ID> --version <VERSION> --build <BUILD_ID> --confirm
# Check or cancel submission
asc submit status --id <SUBMISSION_ID>
asc submit cancel --id <SUBMISSION_ID> --confirm
macOS apps are distributed as .pkg files, not .ipa.
asc builds upload \
--app <APP_ID> \
--pkg <PATH_TO_PKG> \
--version <VERSION> \
--build-number <BUILD_NUMBER> \
--wait
Notes:
--pkg automatically sets platform to MAC_OS..pkg, use asc builds upload --pkg + attach/submit steps.Same as iOS flow:
asc builds list --app <APP_ID> --limit 5
asc versions attach-build --version-id <VERSION_ID> --build <BUILD_ID>
asc review submissions-create --app <APP_ID> --platform MAC_OS
asc review items-add --submission <SUBMISSION_ID> --item-type appStoreVersions --item-id <VERSION_ID>
asc review submissions-submit --id <SUBMISSION_ID> --confirm
Same as iOS flow, use appropriate --platform: VISION_OS or TV_OS.
Before submitting to App Store, verify:
VALID (not processing)See asc-submission-health skill for detailed preflight checks.
After distribution, these commands manage TestFlight access:
asc testflight beta-groups list --app "APP_ID" --paginateasc testflight beta-groups create --app "APP_ID" --name "Beta Testers" (external, default)asc testflight beta-groups create --app "APP_ID" --name "Internal Testers" --internal (team members only)asc testflight beta-testers list --app "APP_ID" --paginateasc testflight beta-testers add --app "APP_ID" --email "[email protected]" --group "Beta Testers"asc testflight beta-testers remove --app "APP_ID" --email "[email protected]"asc builds test-notes create --build "BUILD_ID" --locale "en-US" --whats-new "Test instructions"asc builds test-notes update --id "LOCALIZATION_ID" --whats-new "Updated notes"asc testflight review submit).beta-testers invite for external testers — it fails before review approval. Testers are auto-invited once approved.asc builds add-groups for internal groups — they auto-receive builds.--paginate on large groups/tester lists.--help to verify flags for the exact command.testing
Use for 3D games: racing, 3D sports, board games, marble maze, tower defense, bowling. SceneKit + SceneView architecture, 3D scene hierarchy, physics, game loop, primitives, materials, cameras, particles, audio.
documentation
Game UI patterns: SwiftUI HUD overlays on SpriteKit, menus (main/pause/game-over), virtual joystick/d-pad, score displays, health bars, tutorial onboarding.
tools
Download free game sprites/textures/3D models and generate procedural assets. Covers nw_download_asset tool, texture factories, sprite atlas organization, 3D model loading, and programmatic asset creation.
testing
Use for 2D games: arcade, puzzle, sports, ping pong, platformer, shooter, 2D racing. SpriteKit + SpriteView architecture, scene hierarchy, physics, game loop, audio, particles, game feel.