app-store-connect-cli

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

App Store Connect CLI (asc)

App Store Connect CLI(asc)

Skill by 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.
ara.so提供的技能——Devtools Skills合集。
一款面向App Store Connect API的快速、可脚本化CLI工具。可自动化TestFlight、构建、提交、签名、分析、截图、订阅等操作。优先支持JSON格式,无交互式提示——非常适合CI/CD和自动化场景。

Installation

安装

bash
undefined
bash
undefined

Homebrew (macOS/Linux)

Homebrew(macOS/Linux)

brew install asc
brew install asc

Install script

安装脚本

curl -fsSL https://asccli.sh/install | bash
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).
asc version asc --help

Windows用户请从[发布页面](https://github.com/rorkai/App-Store-Connect-CLI/releases/latest)下载签名二进制文件。

Authentication

身份验证

Generate API Keys

生成API密钥

  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
  1. 访问 https://appstoreconnect.apple.com/access/integrations/api
  2. 创建一个具有合适权限的新API密钥(如需完整访问权限请选择Admin角色)
  3. 下载
    .p8
    私钥文件
  4. 记录密钥ID(Key ID)和发行者ID(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
交互式环境(支持钥匙串):
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或无头环境:
bash
asc auth login \
  --bypass-keychain \
  --name "MyCIKey" \
  --key-id "$ASC_KEY_ID" \
  --issuer-id "$ASC_ISSUER_ID" \
  --private-key /path/to/AuthKey.p8
仓库本地凭据:
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
undefined
bash
undefined

Check auth status

检查认证状态

asc auth status --validate
asc auth status --validate

Run diagnostics

运行诊断

asc auth doctor
asc auth doctor

List active profile

列出活跃配置文件

asc auth list
undefined
asc auth list
undefined

Core Commands

核心命令

Apps Management

应用管理

bash
undefined
bash
undefined

List all apps

列出所有应用

asc apps list --output table asc apps list --output json --pretty
asc apps list --output table asc apps list --output json --pretty

Get specific app info

获取特定应用信息

asc apps info view --app "1234567890" --output json
asc apps info view --app "1234567890" --output json

Search apps

搜索应用

asc apps list --output json | jq '.data[] | select(.attributes.name | contains("MyApp"))'
undefined
asc apps list --output json | jq '.data[] | select(.attributes.name | contains("MyApp"))'
undefined

Builds

构建版本

bash
undefined
bash
undefined

Upload IPA to App Store Connect

上传IPA到App Store Connect

asc builds upload --app "1234567890" --ipa /path/to/MyApp.ipa
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
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"
asc builds next-build-number --app "1234567890" --version "1.2.3"

Get build details

获取构建版本详情

asc builds get --id "BUILD_ID" --output json
undefined
asc builds get --id "BUILD_ID" --output json
undefined

TestFlight

TestFlight

bash
undefined
bash
undefined

Publish to TestFlight

发布到TestFlight

asc publish testflight
--app "1234567890"
--ipa /path/to/MyApp.ipa
--group "Internal Testers"
--wait
asc publish testflight
--app "1234567890"
--ipa /path/to/MyApp.ipa
--group "Internal Testers"
--wait

List TestFlight groups

列出TestFlight测试组

asc testflight groups list --app "1234567890" --output table
asc testflight groups list --app "1234567890" --output table

Add testers to group

向测试组添加测试人员

asc testflight testers add
--group "GROUP_ID"
--email user@example.com
asc testflight testers add
--group "GROUP_ID"
--email user@example.com

List feedback

列出反馈

asc testflight feedback list
--app "1234567890"
--paginate
--output json
asc testflight feedback list
--app "1234567890"
--paginate
--output json

List crashes

列出崩溃记录

asc testflight crashes list
--app "1234567890"
--sort -createdDate
--limit 10
asc testflight crashes list
--app "1234567890"
--sort -createdDate
--limit 10

Get crash logs

获取崩溃日志

asc testflight crashes log --submission-id "SUBMISSION_ID"
undefined
asc testflight crashes log --submission-id "SUBMISSION_ID"
undefined

App Store Submissions

App Store 提交

bash
undefined
bash
undefined

Full publish workflow (upload + attach + submit)

完整发布工作流(上传+关联+提交)

asc publish appstore
--app "1234567890"
--ipa /path/to/MyApp.ipa
--version "1.2.3"
--submit
--confirm
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
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"
asc validate --app "1234567890" --version "1.2.3"

Check submission status

检查提交状态

asc submit status --version-id "VERSION_ID"
asc submit status --version-id "VERSION_ID"

Monitor status with auto-refresh

自动刷新监控状态

asc status --app "1234567890" --watch
asc status --app "1234567890" --watch

Cancel submission

取消提交

asc submit cancel --version-id "VERSION_ID" --confirm
undefined
asc submit cancel --version-id "VERSION_ID" --confirm
undefined

Versions

版本管理

bash
undefined
bash
undefined

List versions

列出版本

asc versions list --app "1234567890" --output table
asc versions list --app "1234567890" --output table

Create new version

创建新版本

asc versions create
--app "1234567890"
--version "1.3.0"
--platform "IOS"
asc versions create
--app "1234567890"
--version "1.3.0"
--platform "IOS"

Get version details

获取版本详情

asc versions get --id "VERSION_ID" --output json
undefined
asc versions get --id "VERSION_ID" --output json
undefined

Metadata & Localization

元数据与本地化

bash
undefined
bash
undefined

List localizations

列出本地化信息

asc localizations list
--app "1234567890"
--type app-info
--output table
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"
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
asc metadata apply
--app "1234567890"
--version "1.2.3"
--dir ./metadata
--dry-run

Audit keywords (ASO checks)

审核关键词(ASO检查)

asc metadata keywords audit
--app "1234567890"
--version "1.2.3"
--blocked-terms-file ./blocked-terms.txt
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"
undefined
asc metadata sync
--app "1234567890"
--from-version "1.2.2"
--to-version "1.2.3"
--locale "en-US"
undefined

Screenshots

截图管理

bash
undefined
bash
undefined

Plan screenshot layout

规划截图布局

asc screenshots plan
--app "1234567890"
--version "1.2.3"
--review-output-dir ./screenshots/review
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
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

首先,获取版本本地化ID

asc localizations list
--version "VERSION_ID"
--output json
--locale "en-US" | jq '.data[0].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
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
undefined
asc screenshots list
--version-localization "VERSION_LOCALIZATION_ID"
--output table
undefined

Review Status

审核状态

bash
undefined
bash
undefined

Check review status

检查审核状态

asc review status --app "1234567890"
asc review status --app "1234567890"

Run review diagnostics

运行审核诊断

asc review doctor --app "1234567890"
undefined
asc review doctor --app "1234567890"
undefined

Signing & Certificates

签名与证书

bash
undefined
bash
undefined

List certificates

列出证书

asc certificates list --output table
asc certificates list --output table

List provisioning profiles

列出配置描述文件

asc profiles list --output table
asc profiles list --output table

List bundle IDs

列出Bundle ID

asc bundle-ids list --output table
asc bundle-ids list --output table

Register new bundle ID

注册新的Bundle ID

asc bundle-ids create
--identifier "com.example.myapp"
--name "My App"
--platform "IOS"
undefined
asc bundle-ids create
--identifier "com.example.myapp"
--name "My App"
--platform "IOS"
undefined

Xcode Integration

Xcode 集成

bash
undefined
bash
undefined

Archive project

归档项目

asc xcode archive
--project MyApp.xcodeproj
--scheme "MyApp"
--archive-path ./build/MyApp.xcarchive
asc xcode archive
--project MyApp.xcodeproj
--scheme "MyApp"
--archive-path ./build/MyApp.xcarchive

Export IPA

导出IPA

asc xcode export
--archive-path ./build/MyApp.xcarchive
--export-options-plist ./ExportOptions.plist
--export-path ./build/output
undefined
asc xcode export
--archive-path ./build/MyApp.xcarchive
--export-options-plist ./ExportOptions.plist
--export-path ./build/output
undefined

Xcode Cloud

Xcode Cloud

bash
undefined
bash
undefined

List workflows

列出工作流

asc xcode-cloud workflows list --output table
asc xcode-cloud workflows list --output table

Trigger workflow from PR

从PR触发工作流

asc xcode-cloud run
--workflow-id "WORKFLOW_ID"
--pull-request-id "123"
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
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
undefined
asc xcode-cloud build-runs get --id "BUILD_RUN_ID" --output json
undefined

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
          }
        }
      ]
    }
  }
}
创建
.asc/workflow.json
来定义可复用工作流:
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
undefined
bash
undefined

Validate workflow

验证工作流

asc workflow validate
asc workflow validate

Dry run

试运行

asc workflow run --dry-run testflight_beta VERSION:1.2.3
asc workflow run --dry-run testflight_beta VERSION:1.2.3

Execute workflow

执行工作流

asc workflow run testflight_beta VERSION:1.2.3
asc workflow run testflight_beta VERSION:1.2.3

Execute App Store release

执行App Store发布

asc workflow run appstore_release VERSION:1.2.3
undefined
asc workflow run appstore_release VERSION:1.2.3
undefined

CI/CD Integration

CI/CD 集成

GitHub Actions

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"
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

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
    - asc publish testflight --app "$APP_ID" --ipa ./MyApp.ipa --group "Internal" --wait
  variables:
    ASC_BYPASS_KEYCHAIN: "1"
  only:
    - main
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
    - asc publish testflight --app "$APP_ID" --ipa ./MyApp.ipa --group "Internal" --wait
  variables:
    ASC_BYPASS_KEYCHAIN: "1"
  only:
    - main

CircleCI

CircleCI

yaml
version: 2.1

jobs:
  deploy:
    macos:
      xcode: 15.0.0
    steps:
      - checkout
      - run:
          name: Install asc
          command: brew install asc
      - run:
          name: Configure Auth
          command: |
            echo "$ASC_PRIVATE_KEY" > AuthKey.p8
            asc auth login \
              --bypass-keychain \
              --name "CircleCI" \
              --key-id "$ASC_KEY_ID" \
              --issuer-id "$ASC_ISSUER_ID" \
              --private-key ./AuthKey.p8
      - run:
          name: Deploy
          command: asc workflow run testflight_beta VERSION:${CIRCLE_TAG}
          environment:
            ASC_BYPASS_KEYCHAIN: "1"
yaml
version: 2.1

jobs:
  deploy:
    macos:
      xcode: 15.0.0
    steps:
      - checkout
      - run:
          name: Install asc
          command: brew install asc
      - run:
          name: Configure Auth
          command: |
            echo "$ASC_PRIVATE_KEY" > AuthKey.p8
            asc auth login \
              --bypass-keychain \
              --name "CircleCI" \
              --key-id "$ASC_KEY_ID" \
              --issuer-id "$ASC_ISSUER_ID" \
              --private-key ./AuthKey.p8
      - run:
          name: Deploy
          command: asc workflow run testflight_beta VERSION:${CIRCLE_TAG}
          environment:
            ASC_BYPASS_KEYCHAIN: "1"

Output Formats

输出格式

The CLI auto-detects output format based on context:
  • TTY (interactive):
    table
    format
  • Non-TTY (pipes/CI):
    json
    format
CLI会根据上下文自动检测输出格式:
  • TTY(交互式)
    table
    格式
  • 非TTY(管道/CI)
    json
    格式

Explicit Format Control

显式格式控制

bash
undefined
bash
undefined

Table output

表格输出

asc apps list --output table
asc apps list --output table

JSON output

JSON输出

asc apps list --output json
asc apps list --output json

Pretty JSON (human-readable)

格式化JSON(易读)

asc apps list --output json --pretty
asc apps list --output json --pretty

Markdown output

Markdown输出

asc apps list --output markdown
asc apps list --output markdown

Set default via environment

通过环境变量设置默认格式

export ASC_DEFAULT_OUTPUT=json
undefined
export ASC_DEFAULT_OUTPUT=json
undefined

Parsing JSON Output

解析JSON输出

bash
undefined
bash
undefined

Extract app IDs

提取应用ID

asc apps list --output json | jq -r '.data[].id'
asc apps list --output json | jq -r '.data[].id'

Filter by name

按名称过滤

asc apps list --output json | jq '.data[] | select(.attributes.name == "MyApp")'
asc apps list --output json | jq '.data[] | select(.attributes.name == "MyApp")'

Get build count

获取构建版本数量

asc builds list --app "1234567890" --output json | jq '.data | length'
asc builds list --app "1234567890" --output json | jq '.data | length'

Extract version strings

提取版本字符串

asc versions list --app "1234567890" --output json | jq -r '.data[].attributes.versionString'
undefined
asc versions list --app "1234567890" --output json | jq -r '.data[].attributes.versionString'
undefined

Common Patterns

常见模式

Complete Release Workflow

完整发布工作流

bash
#!/bin/bash
set -e

APP_ID="1234567890"
VERSION="1.2.3"
IPA_PATH="./build/output/MyApp.ipa"
bash
#!/bin/bash
set -e

APP_ID="1234567890"
VERSION="1.2.3"
IPA_PATH="./build/output/MyApp.ipa"

1. Get next build number

1. 获取下一个构建编号

BUILD_NUMBER=$(asc builds next-build-number --app "$APP_ID" --version "$VERSION" --output json | jq -r '.buildNumber') echo "Next build number: $BUILD_NUMBER"
BUILD_NUMBER=$(asc builds next-build-number --app "$APP_ID" --version "$VERSION" --output json | jq -r '.buildNumber') echo "Next build number: $BUILD_NUMBER"

2. Build (external Xcode process)

2. 构建(外部Xcode流程)

xcodebuild archive ...

xcodebuild archive ...

xcodebuild -exportArchive ...

xcodebuild -exportArchive ...

3. Upload and publish to TestFlight

3. 上传并发布到TestFlight

asc publish testflight
--app "$APP_ID"
--ipa "$IPA_PATH"
--group "Internal Testers"
--wait
asc publish testflight
--app "$APP_ID"
--ipa "$IPA_PATH"
--group "Internal Testers"
--wait

4. Wait for processing

4. 等待处理完成

sleep 60
sleep 60

5. Validate for App Store

5. 验证App Store发布就绪状态

asc validate --app "$APP_ID" --version "$VERSION"
asc validate --app "$APP_ID" --version "$VERSION"

6. Submit to App Store

6. 提交到App Store

asc publish appstore
--app "$APP_ID"
--version "$VERSION"
--build "BUILD_ID"
--submit
--confirm
asc publish appstore
--app "$APP_ID"
--version "$VERSION"
--build "BUILD_ID"
--submit
--confirm

7. Monitor status

7. 监控状态

asc status --app "$APP_ID" --watch
undefined
asc status --app "$APP_ID" --watch
undefined

Metadata Sync Between Versions

版本间元数据同步

bash
#!/bin/bash

APP_ID="1234567890"
FROM_VERSION="1.2.2"
TO_VERSION="1.2.3"
LOCALES=("en-US" "es-ES" "fr-FR" "de-DE")

for locale in "${LOCALES[@]}"; do
  echo "Syncing $locale..."
  asc metadata sync \
    --app "$APP_ID" \
    --from-version "$FROM_VERSION" \
    --to-version "$TO_VERSION" \
    --locale "$locale"
done
bash
#!/bin/bash

APP_ID="1234567890"
FROM_VERSION="1.2.2"
TO_VERSION="1.2.3"
LOCALES=("en-US" "es-ES" "fr-FR" "de-DE")

for locale in "${LOCALES[@]}"; do
  echo "Syncing $locale..."
  asc metadata sync \
    --app "$APP_ID" \
    --from-version "$FROM_VERSION" \
    --to-version "$TO_VERSION" \
    --locale "$locale"
done

Screenshot Upload Pipeline

截图上传流水线

bash
#!/bin/bash

APP_ID="1234567890"
VERSION_ID="VERSION_ID"
SCREENSHOTS_DIR="./screenshots"
bash
#!/bin/bash

APP_ID="1234567890"
VERSION_ID="VERSION_ID"
SCREENSHOTS_DIR="./screenshots"

Get version localizations

获取版本本地化信息

LOCALIZATIONS=$(asc localizations list
--version "$VERSION_ID"
--output json | jq -r '.data[] | "(.attributes.locale)|(.id)"')
while IFS='|' read -r locale loc_id; do echo "Uploading screenshots for $locale..."

Upload for each device type

for device in "IPHONE_65" "IPHONE_67" "IPAD_PRO_129"; do if [ -d "$SCREENSHOTS_DIR/$locale/$device" ]; then asc screenshots upload
--version-localization "$loc_id"
--path "$SCREENSHOTS_DIR/$locale/$device"
--device-type "$device"
--replace fi done done <<< "$LOCALIZATIONS"
undefined
LOCALIZATIONS=$(asc localizations list
--version "$VERSION_ID"
--output json | jq -r '.data[] | "(.attributes.locale)|(.id)"')
while IFS='|' read -r locale loc_id; do echo "Uploading screenshots for $locale..."

为每种设备类型上传

for device in "IPHONE_65" "IPHONE_67" "IPAD_PRO_129"; do if [ -d "$SCREENSHOTS_DIR/$locale/$device" ]; then asc screenshots upload
--version-localization "$loc_id"
--path "$SCREENSHOTS_DIR/$locale/$device"
--device-type "$device"
--replace fi done done <<< "$LOCALIZATIONS"
undefined

Crash Log Collection

崩溃日志收集

bash
#!/bin/bash

APP_ID="1234567890"
OUTPUT_DIR="./crash_logs"

mkdir -p "$OUTPUT_DIR"
bash
#!/bin/bash

APP_ID="1234567890"
OUTPUT_DIR="./crash_logs"

mkdir -p "$OUTPUT_DIR"

Get recent crashes

获取近期崩溃记录

CRASHES=$(asc testflight crashes list
--app "$APP_ID"
--sort -createdDate
--limit 20
--output json)
CRASHES=$(asc testflight crashes list
--app "$APP_ID"
--sort -createdDate
--limit 20
--output json)

Download logs for each crash

下载每个崩溃的日志

echo "$CRASHES" | jq -r '.data[].id' | while read -r submission_id; do echo "Downloading crash log: $submission_id" asc testflight crashes log
--submission-id "$submission_id" > "$OUTPUT_DIR/$submission_id.log" done
undefined
echo "$CRASHES" | jq -r '.data[].id' | while read -r submission_id; do echo "Downloading crash log: $submission_id" asc testflight crashes log
--submission-id "$submission_id" > "$OUTPUT_DIR/$submission_id.log" done
undefined

Automated TestFlight Feedback Reports

自动化TestFlight反馈报告

bash
#!/bin/bash

APP_ID="1234567890"
REPORT_FILE="testflight_feedback_$(date +%Y%m%d).json"
bash
#!/bin/bash

APP_ID="1234567890"
REPORT_FILE="testflight_feedback_$(date +%Y%m%d).json"

Collect all feedback

收集所有反馈

asc testflight feedback list
--app "$APP_ID"
--paginate
--output json > "$REPORT_FILE"
asc testflight feedback list
--app "$APP_ID"
--paginate
--output json > "$REPORT_FILE"

Generate summary

生成摘要

echo "Feedback Summary:" jq '.data | group_by(.attributes.rating) | map({rating: .[0].attributes.rating, count: length})' "$REPORT_FILE"
undefined
echo "Feedback Summary:" jq '.data | group_by(.attributes.rating) | map({rating: .[0].attributes.rating, count: length})' "$REPORT_FILE"
undefined

Environment Variables

环境变量

bash
undefined
bash
undefined

Authentication

身份验证

export ASC_KEY_ID="ABC123" export ASC_ISSUER_ID="DEF456" export ASC_PRIVATE_KEY_PATH="/path/to/AuthKey.p8"
export ASC_KEY_ID="ABC123" export ASC_ISSUER_ID="DEF456" export ASC_PRIVATE_KEY_PATH="/path/to/AuthKey.p8"

Bypass keychain (CI/CD)

绕过钥匙串(CI/CD)

export ASC_BYPASS_KEYCHAIN="1"
export ASC_BYPASS_KEYCHAIN="1"

Default output format

默认输出格式

export ASC_DEFAULT_OUTPUT="json"
export ASC_DEFAULT_OUTPUT="json"

API debugging

API调试

export ASC_DEBUG="api"
export ASC_DEBUG="api"

Config file location

配置文件位置

export ASC_CONFIG_PATH="/custom/path/config.json"
undefined
export ASC_CONFIG_PATH="/custom/path/config.json"
undefined

Troubleshooting

故障排除

Authentication Issues

身份验证问题

bash
undefined
bash
undefined

Check keychain access

检查钥匙串访问权限

asc auth doctor
asc auth doctor

Retry with bypass (if keychain blocked)

绕过钥匙串重试(如果钥匙串被阻止)

ASC_BYPASS_KEYCHAIN=1 asc auth status --validate
ASC_BYPASS_KEYCHAIN=1 asc auth status --validate

Validate active profile

验证活跃配置文件

asc auth status --validate
asc auth status --validate

Re-login with bypass

绕过钥匙串重新登录

asc auth login
--bypass-keychain
--name "Retry"
--key-id "$ASC_KEY_ID"
--issuer-id "$ASC_ISSUER_ID"
--private-key /path/to/AuthKey.p8
undefined
asc auth login
--bypass-keychain
--name "Retry"
--key-id "$ASC_KEY_ID"
--issuer-id "$ASC_ISSUER_ID"
--private-key /path/to/AuthKey.p8
undefined

API Debugging

API调试

bash
undefined
bash
undefined

Enable API debugging

启用API调试

ASC_DEBUG=api asc apps list
ASC_DEBUG=api asc apps list

Or use flag

或使用标志

asc --api-debug apps list
asc --api-debug apps list

Capture detailed logs

捕获详细日志

asc --api-debug apps list 2>&1 | tee debug.log
undefined
asc --api-debug apps list 2>&1 | tee debug.log
undefined

Build Upload Failures

构建版本上传失败

bash
undefined
bash
undefined

Verify IPA integrity

验证IPA完整性

unzip -t MyApp.ipa
unzip -t MyApp.ipa

Check app ID matches

检查应用ID是否匹配

asc apps list --output json | jq '.data[] | select(.id == "1234567890")'
asc apps list --output json | jq '.data[] | select(.id == "1234567890")'

Retry with explicit app ID

使用显式应用ID重试

asc builds upload --app "1234567890" --ipa ./MyApp.ipa --verbose
undefined
asc builds upload --app "1234567890" --ipa ./MyApp.ipa --verbose
undefined

Version Conflicts

版本冲突

bash
undefined
bash
undefined

List existing versions

列出已存在的版本

asc versions list --app "1234567890" --output table
asc versions list --app "1234567890" --output table

Check version state

检查版本状态

asc versions get --id "VERSION_ID" --output json | jq '.data.attributes.appStoreState'
asc versions get --id "VERSION_ID" --output json | jq '.data.attributes.appStoreState'

Delete draft version (if needed)

删除草稿版本(如需)

asc versions delete --id "VERSION_ID" --confirm
undefined
asc versions delete --id "VERSION_ID" --confirm
undefined

Screenshot Upload Issues

截图上传问题

bash
undefined
bash
undefined

Verify device type compatibility

验证设备类型兼容性

asc screenshots plan --app "1234567890" --version "1.2.3" --review-output-dir ./review
asc screenshots plan --app "1234567890" --version "1.2.3" --review-output-dir ./review

Check localization ID

检查本地化ID

asc localizations list --version "VERSION_ID" --output json
asc localizations list --version "VERSION_ID" --output json

Use correct device type codes:

使用正确的设备类型代码:

IPHONE_65, IPHONE_67, IPHONE_61, IPAD_PRO_129, IPAD_PRO_3GEN_129

IPHONE_65, IPHONE_67, IPHONE_61, IPAD_PRO_129, IPAD_PRO_3GEN_129

undefined
undefined

Best Practices

最佳实践

  1. Always validate before submission:
    bash
    asc validate --app "APP_ID" --version "VERSION"
  2. Use
    --dry-run
    for destructive operations
    :
    bash
    asc metadata apply --dry-run --app "APP_ID" --version "VERSION" --dir ./metadata
  3. Monitor submissions with
    --watch
    :
    bash
    asc status --app "APP_ID" --watch
  4. Store credentials securely in CI:
    • Use GitHub Secrets, GitLab Variables, etc.
    • Never commit
      .p8
      files
    • Use
      --bypass-keychain
      in CI
  5. Parse JSON programmatically:
    bash
    asc apps list --output json | jq -r '.data[].id'
  6. Use workflows for complex pipelines:
    • Define in
      .asc/workflow.json
    • Version control your workflows
    • Test with
      --dry-run
  7. Leverage
    --wait
    for synchronous operations
    :
    bash
    asc publish testflight --wait --app "APP_ID" --ipa ./app.ipa
  1. 提交前始终验证:
    bash
    asc validate --app "APP_ID" --version "VERSION"
  2. 对破坏性操作使用
    --dry-run
    :
    bash
    asc metadata apply --dry-run --app "APP_ID" --version "VERSION" --dir ./metadata
  3. 使用
    --watch
    监控提交状态
    :
    bash
    asc status --app "APP_ID" --watch
  4. 在CI中安全存储凭据:
    • 使用GitHub Secrets、GitLab变量等
    • 绝不提交
      .p8
      文件
    • 在CI中使用
      --bypass-keychain
  5. 以编程方式解析JSON:
    bash
    asc apps list --output json | jq -r '.data[].id'
  6. 对复杂流水线使用工作流:
    • .asc/workflow.json
      中定义
    • 对工作流进行版本控制
    • 使用
      --dry-run
      测试
  7. 对同步操作使用
    --wait
    :
    bash
    asc publish testflight --wait --app "APP_ID" --ipa ./app.ipa

Additional Resources

额外资源