- name
- app-store-connect-cli
- description
- Automate iOS/macOS App Store Connect workflows - TestFlight, builds, submissions, screenshots, and metadata with the asc CLI
- triggers
- ["upload build to testflight","submit app to app store","manage app store screenshots","check app review status","list testflight builds","sync app metadata to app store","automate app store connect workflow","get app store analytics"]
# App Store Connect CLI (asc)
> Skill by [ara.so](https://ara.so) — Devtools Skills collection.
Fast, scriptable CLI for the App Store Connect API. Automate TestFlight, builds, submissions, signing, analytics, screenshots, subscriptions, and more. JSON-first, no interactive prompts - perfect for CI/CD and automation.
## Installation
```bash
# Homebrew (macOS/Linux)
brew install asc
# Install script
curl -fsSL https://asccli.sh/install | bash
# Verify installation
asc version
asc --help
```
For Windows, download signed binaries from the [releases page](https://github.com/rorkai/App-Store-Connect-CLI/releases/latest).
## Authentication
### Generate API Keys
1. Visit https://appstoreconnect.apple.com/access/integrations/api
2. Create a new API key with appropriate role (Admin for full access)
3. Download the `.p8` private key file
4. Note the Key ID and Issuer ID
### Configure Authentication
**Interactive environments (with keychain):**
```bash
asc auth login \
--name "MyApp" \
--key-id "$ASC_KEY_ID" \
--issuer-id "$ASC_ISSUER_ID" \
--private-key /path/to/AuthKey.p8 \
--network
```
**CI/CD or headless environments:**
```bash
asc auth login \
--bypass-keychain \
--name "MyCIKey" \
--key-id "$ASC_KEY_ID" \
--issuer-id "$ASC_ISSUER_ID" \
--private-key /path/to/AuthKey.p8
```
**Repo-local credentials:**
```bash
asc auth login \
--local \
--bypass-keychain \
--name "LocalKey" \
--key-id "$ASC_KEY_ID" \
--issuer-id "$ASC_ISSUER_ID" \
--private-key /path/to/AuthKey.p8
```
### Validate Authentication
```bash
# Check auth status
asc auth status --validate
# Run diagnostics
asc auth doctor
# List active profile
asc auth list
```
## Core Commands
### Apps Management
```bash
# List all apps
asc apps list --output table
asc apps list --output json --pretty
# Get specific app info
asc apps info view --app "1234567890" --output json
# Search apps
asc apps list --output json | jq '.data[] | select(.attributes.name | contains("MyApp"))'
```
### Builds
```bash
# Upload IPA to App Store Connect
asc builds upload --app "1234567890" --ipa /path/to/MyApp.ipa
# List builds
asc builds list --app "1234567890" --output table
asc builds list --app "1234567890" --limit 10 --sort -uploadedDate
# Get next build number
asc builds next-build-number --app "1234567890" --version "1.2.3"
# Get build details
asc builds get --id "BUILD_ID" --output json
```
### TestFlight
```bash
# Publish to TestFlight
asc publish testflight \
--app "1234567890" \
--ipa /path/to/MyApp.ipa \
--group "Internal Testers" \
--wait
# List TestFlight groups
asc testflight groups list --app "1234567890" --output table
# Add testers to group
asc testflight testers add \
--group "GROUP_ID" \
--email user@example.com
# List feedback
asc testflight feedback list \
--app "1234567890" \
--paginate \
--output json
# List crashes
asc testflight crashes list \
--app "1234567890" \
--sort -createdDate \
--limit 10
# Get crash logs
asc testflight crashes log --submission-id "SUBMISSION_ID"
```
### App Store Submissions
```bash
# Full publish workflow (upload + attach + submit)
asc publish appstore \
--app "1234567890" \
--ipa /path/to/MyApp.ipa \
--version "1.2.3" \
--submit \
--confirm
# Stage release (without submitting)
asc release stage \
--app "1234567890" \
--version "1.2.3" \
--build "BUILD_ID" \
--copy-metadata-from "1.2.2" \
--dry-run
# Validate readiness
asc validate --app "1234567890" --version "1.2.3"
# Check submission status
asc submit status --version-id "VERSION_ID"
# Monitor status with auto-refresh
asc status --app "1234567890" --watch
# Cancel submission
asc submit cancel --version-id "VERSION_ID" --confirm
```
### Versions
```bash
# List versions
asc versions list --app "1234567890" --output table
# Create new version
asc versions create \
--app "1234567890" \
--version "1.3.0" \
--platform "IOS"
# Get version details
asc versions get --id "VERSION_ID" --output json
```
### Metadata & Localization
```bash
# List localizations
asc localizations list \
--app "1234567890" \
--type app-info \
--output table
# Initialize metadata directory structure
asc metadata init \
--dir ./metadata \
--version "1.2.3" \
--locale "en-US"
# Apply metadata from directory
asc metadata apply \
--app "1234567890" \
--version "1.2.3" \
--dir ./metadata \
--dry-run
# Audit keywords (ASO checks)
asc metadata keywords audit \
--app "1234567890" \
--version "1.2.3" \
--blocked-terms-file ./blocked-terms.txt
# Sync metadata between versions
asc metadata sync \
--app "1234567890" \
--from-version "1.2.2" \
--to-version "1.2.3" \
--locale "en-US"
```
### Screenshots
```bash
# Plan screenshot layout
asc screenshots plan \
--app "1234567890" \
--version "1.2.3" \
--review-output-dir ./screenshots/review
# Apply screenshots
asc screenshots apply \
--app "1234567890" \
--version "1.2.3" \
--review-output-dir ./screenshots/review \
--confirm
# Upload screenshots for specific locale
# First, get version localization ID
asc localizations list \
--version "VERSION_ID" \
--output json \
--locale "en-US" | jq '.data[0].id'
# Then upload
asc screenshots upload \
--version-localization "VERSION_LOCALIZATION_ID" \
--path ./screenshots/en-US \
--device-type "IPHONE_65" \
--replace
# List existing screenshots
asc screenshots list \
--version-localization "VERSION_LOCALIZATION_ID" \
--output table
```
### Review Status
```bash
# Check review status
asc review status --app "1234567890"
# Run review diagnostics
asc review doctor --app "1234567890"
```
### Signing & Certificates
```bash
# List certificates
asc certificates list --output table
# List provisioning profiles
asc profiles list --output table
# List bundle IDs
asc bundle-ids list --output table
# Register new bundle ID
asc bundle-ids create \
--identifier "com.example.myapp" \
--name "My App" \
--platform "IOS"
```
### Xcode Integration
```bash
# Archive project
asc xcode archive \
--project MyApp.xcodeproj \
--scheme "MyApp" \
--archive-path ./build/MyApp.xcarchive
# Export IPA
asc xcode export \
--archive-path ./build/MyApp.xcarchive \
--export-options-plist ./ExportOptions.plist \
--export-path ./build/output
```
### Xcode Cloud
```bash
# List workflows
asc xcode-cloud workflows list --output table
# Trigger workflow from PR
asc xcode-cloud run \
--workflow-id "WORKFLOW_ID" \
--pull-request-id "123"
# Rerun existing build
asc xcode-cloud run \
--source-run-id "BUILD_RUN_ID" \
--clean
# Get build run details
asc xcode-cloud build-runs get --id "BUILD_RUN_ID" --output json
```
## Workflows
### Workflow Configuration
Create `.asc/workflow.json` for reusable workflows:
```json
{
"workflows": {
"testflight_beta": {
"description": "Build and deploy to TestFlight",
"steps": [
{
"name": "get_next_build",
"command": "builds next-build-number",
"args": {
"app": "1234567890",
"version": "{{VERSION}}"
},
"capture": "BUILD_NUMBER"
},
{
"name": "archive",
"command": "xcode archive",
"args": {
"project": "MyApp.xcodeproj",
"scheme": "MyApp",
"archive-path": "./build/MyApp.xcarchive"
}
},
{
"name": "export",
"command": "xcode export",
"args": {
"archive-path": "./build/MyApp.xcarchive",
"export-options-plist": "./ExportOptions.plist",
"export-path": "./build/output"
}
},
{
"name": "publish",
"command": "publish testflight",
"args": {
"app": "1234567890",
"ipa": "./build/output/MyApp.ipa",
"group": "Internal Testers",
"wait": true
}
}
]
},
"appstore_release": {
"description": "Submit to App Store",
"steps": [
{
"name": "validate",
"command": "validate",
"args": {
"app": "1234567890",
"version": "{{VERSION}}"
}
},
{
"name": "publish",
"command": "publish appstore",
"args": {
"app": "1234567890",
"ipa": "./build/output/MyApp.ipa",
"version": "{{VERSION}}",
"submit": true,
"confirm": true
}
}
]
}
}
}
```
### Run Workflows
```bash
# Validate workflow
asc workflow validate
# Dry run
asc workflow run --dry-run testflight_beta VERSION:1.2.3
# Execute workflow
asc workflow run testflight_beta VERSION:1.2.3
# Execute App Store release
asc workflow run appstore_release VERSION:1.2.3
```
## CI/CD Integration
### GitHub Actions
```yaml
name: TestFlight Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Install asc
run: brew install asc
- name: Configure Auth
run: |
echo "${{ secrets.ASC_PRIVATE_KEY }}" > AuthKey.p8
asc auth login \
--bypass-keychain \
--name "CI" \
--key-id "${{ secrets.ASC_KEY_ID }}" \
--issuer-id "${{ secrets.ASC_ISSUER_ID }}" \
--private-key ./AuthKey.p8
- name: Build and Deploy
run: |
asc workflow run testflight_beta VERSION:1.2.3
env:
ASC_BYPASS_KEYCHAIN: "1"
```
### GitLab CI
```yaml
deploy_testflight:
stage: deploy
tags:
- macos
script:
- brew install asc
- echo "$ASC_PRIVATE_KEY" > AuthKey.p8
- |
asc auth login \
--bypass-keychain \
--name "GitLab CI" \
--key-id "$ASC_KEY_ID" \
--issuer-id "$ASC_ISSUER_ID" \
--private-key ./AuthKey.p8
Auf GitHub ansehen