Files
ai-proj-helper/skills-dev/dev-deploy-plugin/skills/references/details.md
T
johnQ 237631147a chore(skill): 清理全部 23 条历史校验警告
- 11 个超 20KB 的 SKILL.md 拆分,大章节移入 references/details.md
- 7 处非标准字段(arguments/user_invocable)移入 metadata
- 修 req-dev 4 条相对链接;validate 跳过行内代码避免 ![](...) 误报
- validate-skills.py: 23 warns -> 0 warns,0 errors
2026-10-31 22:21:07 +08:00

4.9 KiB
Raw Blame History

skills 详细内容

回滚策略

iOS TestFlight 回滚

TestFlight 无法真正回滚已安装的版本,但有以下应急手段:

手段 说明 API
停止分发 将 build 从测试中移除,用户不再收到更新 PATCH /v1/builds/{id} 设置 expired: true
过期 build 强制过期有问题的 build 同上
紧急热修 构建新版本覆盖上线 常规部署流程
# 通过 ASC API 停止分发某个 build
curl -X PATCH "https://api.appstoreconnect.apple.com/v1/builds/$BUILD_ID" \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"data":{"type":"builds","id":"'$BUILD_ID'","attributes":{"expired":true}}}'

Docker 回滚

Docker 回滚相对简单,拉取上一个正常版本的镜像重新部署即可:

# 1. 确定上一个正常的 tag
PREVIOUS_TAG=<previous-good-tag>
REGISTRY=crpi-q4nnuivosic0zc98.cn-beijing.personal.cr.aliyuncs.com

# 2. 在服务器上回滚
ssh -i ~/.ssh/xiaoqu.pem root@39.104.87.246 "
  cd /opt/xiaoqu/production   # 或 /opt/xiaoqu/staging
  export IMAGE_TAG=$PREVIOUS_TAG
  docker compose pull
  docker compose up -d
"

# 3. 验证回滚成功
curl -sf http://39.104.87.246/health && echo 'Rollback OK'

数据库回滚注意事项

场景 策略
可逆 migration(加列、加表) 部署回滚后数据库无需回滚,旧代码忽略新列
不可逆 migration(删列、改类型) 必须先回滚 migration 再回滚代码,否则旧代码报错
数据 migration 评估是否需要补偿脚本,建议 migration 前做备份快照
# 数据库 migration 回滚示例(如果使用 golang-migrate)
ssh -i ~/.ssh/xiaoqu.pem root@39.104.87.246 "
  docker compose exec gateway migrate -path /migrations -database \$DATABASE_URL down 1
"

部署监控

Post-deploy 健康检查模式

# 通用部署后验证函数
post_deploy_verify() {
  local url=$1
  local max_retries=${2:-5}
  local interval=${3:-10}

  echo "Verifying deployment at $url ..."
  for i in $(seq 1 $max_retries); do
    local status
    status=$(curl -sf -o /dev/null -w "%{http_code}" "$url" 2>/dev/null || echo "000")
    if [ "$status" = "200" ]; then
      echo "Health check passed (attempt $i/$max_retries)"
      return 0
    fi
    echo "Attempt $i/$max_retries: status=$status, retrying in ${interval}s..."
    sleep $interval
  done
  echo "Health check FAILED after $max_retries attempts"
  return 1
}

# 使用示例
post_deploy_verify "http://39.104.87.246/health" 5 10

飞书通知模板

部署完成后通过飞书 Webhook 发送通知:

# 部署成功通知
send_feishu_deploy_notification() {
  local env=$1       # staging / production
  local version=$2   # 版本号或 tag
  local status=$3    # success / failure
  local detail=$4    # 额外说明

  local WEBHOOK_URL="<飞书群 Webhook 地址>"

  if [ "$status" = "success" ]; then
    local color="green"
    local emoji="✅"
  else
    local color="red"
    local emoji="❌"
  fi

  curl -s -X POST "$WEBHOOK_URL" \
    -H "Content-Type: application/json" \
    -d '{
      "msg_type": "interactive",
      "card": {
        "header": {
          "title": {"tag": "plain_text", "content": "'"$emoji"' 部署通知 - '"$env"'"},
          "template": "'"$color"'"
        },
        "elements": [
          {"tag": "div", "text": {"tag": "lark_md", "content": "**环境**: '"$env"'\n**版本**: '"$version"'\n**状态**: '"$status"'\n**时间**: '"$(date '+%Y-%m-%d %H:%M:%S')"'\n**详情**: '"$detail"'"}}
        ]
      }
    }'
}

# 使用示例
send_feishu_deploy_notification "production" "v1.2.3" "success" "Gateway + Web 部署完成"
send_feishu_deploy_notification "staging" "abc12345" "failure" "Health check 超时"

iOS TestFlight 构建状态监控

通过 ASC API 持续监控 build 处理状态:

# 监控 TestFlight build 处理状态
monitor_testflight_build() {
  local build_id=$1
  local jwt_token=$2
  local max_wait=600  # 最长等待 10 分钟
  local elapsed=0

  while [ $elapsed -lt $max_wait ]; do
    local response
    response=$(curl -s "https://api.appstoreconnect.apple.com/v1/builds/$build_id" \
      -H "Authorization: Bearer $jwt_token")

    local state
    state=$(echo "$response" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['attributes']['processingState'])" 2>/dev/null)

    echo "[$(date '+%H:%M:%S')] Build $build_id: $state"

    case "$state" in
      VALID)
        echo "Build 处理完成,可用于测试"
        return 0
        ;;
      FAILED|INVALID)
        echo "Build 处理失败: $state"
        return 1
        ;;
      PROCESSING)
        sleep 30
        ((elapsed+=30))
        ;;
      *)
        sleep 15
        ((elapsed+=15))
        ;;
    esac
  done

  echo "Build 处理超时(${max_wait}s)"
  return 1
}