mcpField
A
asc-shots-pipeline

asc-shots-pipeline

github.com/rorkai营销与增长1.1k7.0k 次安装2 天前更新
代码仓库

关于 asc-shots-pipeline

此技能介绍使用 Xcode 命令行工具、AXe 和 `asc` 的 Agent 驱动型 App Store 截图流程,涵盖构建、截图、加框、审核及单语言或多语言上传。

主要功能

  1. 01在模拟器中构建并运行应用
  2. 02使用计划和 AXe 捕获界面
  3. 03通过固定版本的 Koubou 添加边框
  4. 04审核并批准截图集
  5. 05规划并应用多语言上传
  6. 06重新排列已上传截图

适用场景

  1. 01从模拟器捕获应用界面
  2. 02为商店页面准备带边框的图片
  3. 03上传前审核截图
  4. 04捕获并上传多种语言的截图

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/rorkai/app-store-connect-cli-skills --skill asc-shots-pipeline

安装后在 Claude Code 中输入/asc-shots-pipeline确认已加载。

详细介绍

asc 截图流水线(xcodebuild -> AXe -> frame -> asc)

适用于由 Agent 驱动的截图工作流:使用 Xcode CLI 工具构建并启动应用,通过 AXe 驱动 UI,并使用 asc 上传截图。

当前范围

  • 目前已实现:构建/运行、AXe 计划捕获、画框合成和上传。
  • 可通过 asc screenshots list-frame-devices 内置发现设备。
  • asc CLI 中的本地截图自动化命令仍处于实验阶段。
  • 画框固定使用 Koubou 0.20.0,以确保输出具有确定性。
  • 反馈/问题:https://github.com/rorkai/App-Store-Connect-CLI/issues/new/choose

默认值

  • 设置文件:.asc/shots.settings.json
  • 捕获计划:.asc/screenshots.json
  • 原始截图目录:./screenshots/raw
  • 加框截图目录:./screenshots/framed
  • 默认画框设备:iphone-air

1) 首先创建设置 JSON

创建或更新 .asc/shots.settings.json:

{
  "version": 1,
  "app": {
    "bundle_id": "com.example.app",
    "project": "MyApp.xcodeproj",
    "scheme": "MyApp",
    "simulator_udid": "booted"
  },
  "paths": {
    "plan": ".asc/screenshots.json",
    "raw_dir": "./screenshots/raw",
    "framed_dir": "./screenshots/framed"
  },
  "pipeline": {
    "frame_enabled": true,
    "upload_enabled": false
  },
  "upload": {
    "version_localization_id": "",
    "device_type": "IPHONE_65",
    "source_dir": "./screenshots/framed"
  }
}

如果有意跳过画框,请设置:

  • "frame_enabled": false
  • "upload.source_dir": "./screenshots/raw"

2) 在模拟器上构建并运行应用

使用 Xcode CLI 进行构建/安装/启动:

xcrun simctl boot "$UDID" || true

xcodebuild \
  -project "MyApp.xcodeproj" \
  -scheme "MyApp" \
  -configuration Debug \
  -destination "platform=iOS Simulator,id=$UDID" \
  -derivedDataPath ".build/DerivedData" \
  build

xcrun simctl install "$UDID" ".build/DerivedData/Build/Products/Debug-iphonesimulator/MyApp.app"
xcrun simctl launch "$UDID" "com.example.app"

如果应用包路径与默认位置不同,请使用 xcodebuild -showBuildSettings。

3) 使用 AXe(或 asc screenshots run)捕获截图

优先使用计划驱动的捕获方式:

asc screenshots run --plan ".asc/screenshots.json" --udid "$UDID" --output json

编写计划时可用的 AXe 基本操作:

axe describe-ui --udid "$UDID"
axe tap --id "search_field" --udid "$UDID"
axe type "wwdc" --udid "$UDID"
axe screenshot --output "./screenshots/raw/home.png" --udid "$UDID"

最简 .asc/screenshots.json 示例:

{
  "version": 1,
  "app": {
    "bundle_id": "com.example.app",
    "udid": "booted",
    "output_dir": "./screenshots/raw"
  },
  "steps": [
    { "action": "launch" },
    { "action": "wait", "duration_ms": 800 },
    { "action": "screenshot", "name": "home" }
  ]
}

4) 使用 asc screenshots frame 为截图加框

asc CLI 固定使用 Koubou 0.20.0 进行画框。 运行画框步骤前,请先安装并验证:

pip install koubou==0.20.0
kou --version  # expect 0.20.0
# After upgrading from 0.18.x, or if Koubou reports missing device frames,
# run once with network access:
kou setup-frames

先列出支持的画框设备值:

asc screenshots list-frame-devices --output json

为一张截图加框(默认为 iphone-air):

asc screenshots frame \
  --input "./screenshots/raw/home.png" \
  --output-dir "./screenshots/framed" \
  --device "iphone-air" \
  --output json

支持的 --device 值:

  • iPhone:iphone-air(默认)、iphone-17-pro、iphone-17-pro-max、iphone-16e、iphone-17
  • iPad:ipad-pro-13、ipad-pro-11、ipad-air-13、ipad-air-11、ipad-mini
  • 其他:mac、watch-series-11、watch-ultra-3、apple-tv

5) 使用 asc 上传截图

上传前生成并检查文件:

asc screenshots review-generate --framed-dir "./screenshots/framed" --output-dir "./screenshots/review"
asc screenshots review-open --output-dir "./screenshots/review"
asc screenshots review-approve --all-ready --output-dir "./screenshots/review"

对于经过审核的多语言区域截图集,优先使用 plan/apply 流程,以便在上传前计入现有远程截图数量:

asc screenshots plan --app "APP_ID" --version "1.2.3" --review-output-dir "./screenshots/review" --output json
asc screenshots apply --app "APP_ID" --version "1.2.3" --review-output-dir "./screenshots/review" --confirm --output json

从配置的源目录上传(启用画框时,默认为 ./screenshots/framed):

asc screenshots upload \
  --version-localization "LOC_ID" \
  --path "./screenshots/framed" \
  --device-type "IPHONE_65" \
  --output json

必要时,在上传前列出或验证:

asc screenshots sizes --output table
asc screenshots list --version-localization "LOC_ID" --output table

更改已上传截图集的顺序,无需重新上传。--ids 必须恰好列出该截图集中的每张截图一次,并按新顺序排列。如果命令读取截图集后又添加了截图,App Store Connect 会拒绝此次更新并保留更新前的顺序;请重新列出截图集并再次运行。其他人所做的仅调整顺序不会被检测到,并会被覆盖。

asc localizations screenshot-sets list --localization-id "LOC_ID" --include appScreenshots
asc screenshots list --set-id "SET_ID" --output table
asc screenshots reorder --set-id "SET_ID" --ids "THIRD_ID,FIRST_ID,SECOND_ID"

Agent 行为

  • 运行命令前,始终使用 --help 确认准确的标志。
  • 由于截图命令变化很快,请使用 asc screenshots --help 重新检查命令路径。
  • 保持输出确定:机器处理步骤默认使用 JSON。
  • 选择画框设备前,优先运行 asc screenshots list-frame-devices --output json。
  • 上传前确保截图文件存在。
  • 使用 asc screenshots reorder 重新排列已上传截图集;切勿为了更改顺序而删除并重新上传截图。
  • 使用明确的长标志(--app、--output、--version-localization 等)。
  • 将截图本地自动化视为实验性功能,并在面向用户的交接说明中明确指出。
  • 需要针对现有远程截图使用追加数量限制防护时,对经过审核的批次使用 asc screenshots plan / asc screenshots apply。
  • 如果画框因版本错误而失败,请重新安装固定版本的 Koubou:pip install koubou==0.20.0。
  • 如果画框因缺少设备边框而失败,请在可访问网络时运行一次 kou setup-frames。

6)多语言环境截图(可选)

不要使用 xcrun simctl launch ... -e AppleLanguages 进行本地化设置。 -e 是环境变量模式,无法可靠地切换应用语言。

对于此流水线,请为每个 UDID 设置模拟器级区域默认值。这适用于 asc screenshots capture,该命令会在内部重新启动应用。

# Map each locale to a dedicated simulator UDID.
# (Create these simulators once with `xcrun simctl create`.)
declare -A LOCALE_UDID=(
  ["en-US"]="UDID_EN_US"
  ["de-DE"]="UDID_DE_DE"
  ["fr-FR"]="UDID_FR_FR"
  ["ja-JP"]="UDID_JA_JP"
)

set_simulator_locale() {
  local UDID="$1"
  local LOCALE="$2"            # e.g. de-DE
  local LANG="${LOCALE%%-*}"   # de
  local APPLE_LOCALE="${LOCALE/-/_}" # de_DE

  xcrun simctl boot "$UDID" || true
  xcrun simctl spawn "$UDID" defaults write NSGlobalDomain AppleLanguages -array "$LANG"
  xcrun simctl spawn "$UDID" defaults write NSGlobalDomain AppleLocale -string "$APPLE_LOCALE"
}

for LOCALE in "${!LOCALE_UDID[@]}"; do
  UDID="${LOCALE_UDID[$LOCALE]}"
  echo "Capturing $LOCALE on $UDID..."
  set_simulator_locale "$UDID" "$LOCALE"

  xcrun simctl terminate "$UDID" "com.example.app" || true
  asc screenshots capture \
    --bundle-id "com.example.app" \
    --name "home" \
    --udid "$UDID" \
    --output-dir "./screenshots/raw/$LOCALE" \
    --output json
done

如果手动启动(不使用 asc screenshots capture),请使用应用启动参数:

xcrun simctl launch "$UDID" "com.example.app" -AppleLanguages "(de)" -AppleLocale "de_DE"

7)并行执行以加快速度

为每个模拟器 UDID 并行运行一种语言环境:

#!/bin/bash
# parallel-capture.sh

declare -A LOCALE_UDID=(
  ["en-US"]="UDID_EN_US"
  ["de-DE"]="UDID_DE_DE"
  ["fr-FR"]="UDID_FR_FR"
  ["ja-JP"]="UDID_JA_JP"
)

capture_locale() {
  local LOCALE="$1"
  local UDID="$2"
  local LANG="${LOCALE%%-*}"
  local APPLE_LOCALE="${LOCALE/-/_}"

  echo "Starting $LOCALE on $UDID"
  xcrun simctl boot "$UDID" || true
  xcrun simctl spawn "$UDID" defaults write NSGlobalDomain AppleLanguages -array "$LANG"
  xcrun simctl spawn "$UDID" defaults write NSGlobalDomain AppleLocale -string "$APPLE_LOCALE"
  xcrun simctl terminate "$UDID" "com.example.app" || true

  asc screenshots capture \
    --bundle-id "com.example.app" \
    --name "home" \
    --udid "$UDID" \
    --output-dir "./screenshots/raw/$LOCALE" \
    --output json

  echo "Completed $LOCALE"
}

for LOCALE in "${!LOCALE_UDID[@]}"; do
  capture_locale "$LOCALE" "${LOCALE_UDID[$LOCALE]}" &
done

wait
echo "All captures done. Now framing..."

或者使用包含 locale:udid 配对的 xargs:

printf "%s\n" \
  "en-US:UDID_EN_US" \
  "de-DE:UDID_DE_DE" \
  "fr-FR:UDID_FR_FR" \
  "ja-JP:UDID_JA_JP" | xargs -P 4 -I {} bash -c '
    PAIR="{}"
    LOCALE="${PAIR%%:*}"
    UDID="${PAIR##*:}"
    LANG="${LOCALE%%-*}"
    APPLE_LOCALE="${LOCALE/-/_}"
    xcrun simctl boot "$UDID" || true
    xcrun simctl spawn "$UDID" defaults write NSGlobalDomain AppleLanguages -array "$LANG"
    xcrun simctl spawn "$UDID" defaults write NSGlobalDomain AppleLocale -string "$APPLE_LOCALE"
    xcrun simctl terminate "$UDID" "com.example.app" || true
    asc screenshots capture --bundle-id "com.example.app" --name "home" --udid "$UDID" --output-dir "./screenshots/raw/$LOCALE" --output json
  '

8)多语言环境流水线完整示例

#!/bin/bash
# full-pipeline-multi-locale.sh

declare -A LOCALE_UDID=(
  ["en-US"]="UDID_EN_US"
  ["de-DE"]="UDID_DE_DE"
  ["fr-FR"]="UDID_FR_FR"
  ["es-ES"]="UDID_ES_ES"
  ["ja-JP"]="UDID_JA_JP"
)

DEVICE="iphone-air"
RAW_DIR="./screenshots/raw"
FRAMED_DIR="./screenshots/framed"

# Step 1: Parallel capture with per-simulator locale defaults
for LOCALE in "${!LOCALE_UDID[@]}"; do
  (
    UDID="${LOCALE_UDID[$LOCALE]}"
    LANG="${LOCALE%%-*}"
    APPLE_LOCALE="${LOCALE/-/_}"

    xcrun simctl boot "$UDID" || true
    xcrun simctl spawn "$UDID" defaults write NSGlobalDomain AppleLanguages -array "$LANG"
    xcrun simctl spawn "$UDID" defaults write NSGlobalDomain AppleLocale -string "$APPLE_LOCALE"
    xcrun simctl terminate "$UDID" "com.example.app" || true

    asc screenshots capture \
      --bundle-id "com.example.app" \
      --name "home" \
      --udid "$UDID" \
      --output-dir "$RAW_DIR/$LOCALE" \
      --output json
    echo "Captured $LOCALE"
  ) &
done
wait

# Step 2: Parallel framing
for LOCALE in "${!LOCALE_UDID[@]}"; do
  (
    asc screenshots frame \
      --input "$RAW_DIR/$LOCALE/home.png" \
      --output-dir "$FRAMED_DIR/$LOCALE" \
      --device "$DEVICE" \
      --output json
    echo "Framed $LOCALE"
  ) &
done
wait

# Step 3: Generate review (single run, aggregates all locales)
asc screenshots review-generate \
  --framed-dir "$FRAMED_DIR" \
  --output-dir "./screenshots/review"

# Step 4: Upload (run per locale if needed)
for LOCALE in "${!LOCALE_UDID[@]}"; do
  asc screenshots upload \
    --version-localization "LOC_ID_FOR_$LOCALE" \
    --path "$FRAMED_DIR/$LOCALE" \
    --device-type "IPHONE_65" \
    --output json
done

评论

支持 Markdown