mcpField
A
alibabacloud-ecs-code-deploy

alibabacloud-ecs-code-deploy

github.com/aliyun云与 DevOps281273 次安装今天更新
代码仓库

关于 alibabacloud-ecs-code-deploy

此 Skill 指导 Agent 使用 `aliyun appmanager` 将本地目录或 Git URL 中的项目部署到 Alibaba Cloud ECS,并规定环境检查、项目准备和部署后的日志验证流程。

主要功能

  1. 01部署本地或 Git 项目
  2. 02检查 CLI、插件和凭据
  3. 03依据项目 README 运行说明
  4. 04通过日志验证部署

适用场景

  1. 01将当前目录项目部署到 ECS
  2. 02部署从 Git URL 获取的项目
  3. 03检查 ECS 部署后的日志

安装

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

$npx skills add https://github.com/aliyun/alibabacloud-aiops-skills --skill alibabacloud-ecs-code-deploy

安装后在 Claude Code 中输入/alibabacloud-ecs-code-deploy确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
deploy-output-and-management.md
init-and-credentials.md
lessons-learned.md
ram-policies.md
script-templates.md
skill-dir-resolution.md
tutorial-flask-app.md
scripts/
deploy_toolkit.py
requirements.txt

详细介绍

通过 aliyun appmanager 部署到 Alibaba Cloud ECS

概述

aliyun appmanager 是一款对 Agent 友好的 CLI 工具,可一键将应用(App)和 AI Agent 部署到 Alibaba Cloud ECS。它支持非交互模式(--non-interactive)、结构化 JSON 输出(--output json)和流式 NDJSON 响应。

默认行为:用户调用 /alibabacloud-ecs-code-deploy,但未指定项目路径或 URL 时,将当前工作目录中的项目部署到 Alibaba Cloud ECS。如果用户提供 Git URL,则先将其克隆到当前目录,再 cd 进入克隆后的目录并继续部署。

执行顺序:Agent 必须按照本文档底部的“完整部署工作流”部分执行,以确保顺序正确。下方的任务部分按主题组织,供参考;其中的编号不代表执行顺序。


必须:开始前创建待办清单

执行任何步骤之前,Agent 必须创建一份包含以下所有事项的待办清单。不得遗漏任何事项。创建待办清单之前不得开始部署。

Todo list (Deploy to Alibaba Cloud ECS):
  [ ] 0. Resolve $SKILL_DIR (cross-platform path — MUST run first; see "Step 0" below)
  [ ] 1. Environment pre-check (MUST run deploy_toolkit.py check; manual commands FORBIDDEN as replacement)
  [ ] 2. Obtain project (clone git URL here if needed; skip for local projects)
  ── Check whether .appmanager/config.yaml already exists (repeat-deploy shortcut) ──
  │  Exists + new ECS (no instanceId)      → skip 3-5, start from 5.5 (price check)
  │  Exists + existing ECS (has instanceId) → skip 3-5.5, jump to 6 (deploy)
  │  Does not exist                        → proceed normally from 3
  ───────────────────────────────────────────────────────────────────────────────
  [ ] 3. Read project (README.md -> quick-deploy method) + identify type (agent / app)
  [ ] 4. Ask user for deployment config (region + new ECS / existing ECS)
  [ ] 5. Init + generate scripts (appmanager init -> write start/stop scripts to config.yaml)
  [ ] 5.5. Pre-deploy price check + risk warning (MUST run deploy_toolkit.py price; confirm price / OSS billing / existing-ECS impact / group overwrite item by item)
  [ ] 6. Deploy (MUST run deploy_toolkit.py deploy; manual deploy command FORBIDDEN as replacement)
  [ ] 7. Verify (MUST run deploy_toolkit.py verify; manual status command FORBIDDEN as replacement)
  [ ] 8. Output final result (console link + cost reminder + management commands)

⛔ 脚本优先规则:步骤 1、5、6、7 均有专用工具包脚本 $SKILL_DIR/scripts/deploy_toolkit.py(其中 $SKILL_DIR 在下方步骤 0中解析,适用于 Qoder、Claude Code 和任何其他平台)。Agent 必须直接运行对应的子命令,作为该步骤的第一个且唯一的操作——绝不可在运行脚本之前或以脚本替代手动运行 CLI 命令(例如 aliyun version、版本检查、凭据检查)。脚本会在内部处理所有检查。仅当脚本文件本身不存在时,才允许将手动命令作为备用方案。

❌ 错误(步骤 1):运行 aliyun version → 检查版本 → 运行 ~/.aliyun/appmanager-venv/bin/python ... → 检查版本 → 然后运行 deploy_toolkit.py check ✅ 正确(步骤 1):运行 python3 "$SKILL_DIR/scripts/deploy_toolkit.py" check → 如果退出码为 1,则修复其报告的问题 → 如果脚本文件缺失,此时才改用手动检查

第 6 项绝对不可妥协。如果 Agent 跳过日志验证,直接输出“部署成功”,则表示未正确完成此技能。如果 deploy_toolkit.py verify 以 1(失败)退出,Agent 必须修复问题并重新部署,然后才能继续执行第 7 项。


步骤 0(必须):解析 $SKILL_DIR — 跨平台路径

工具包脚本位于 <skill-root>/scripts/deploy_toolkit.py。不同平台会将技能安装到不同位置(Qoder/Claude Code/Qwen/...)。Agent 必须在会话开始时解析出技能根目录的绝对路径,并在下文所有 $SKILL_DIR 出现的位置重复使用。严禁硬编码任何特定平台的路径。

有关完整的 10 个候选路径检测算法、export + test -f 验证代码片段,以及 Pattern A / Pattern B / ⛔ Anti-pattern 的使用规则,请参阅 references/skill-dir-resolution.md。

快速回顾(详情请阅读参考文档):

  • ✅ Pattern A(持久 Shell):先运行 export SKILL_DIR="/abs/path",之后再运行 python3 "$SKILL_DIR/scripts/deploy_toolkit.py" <sub>
  • ✅ Pattern B(每次调用都使用新的 Shell):直接填入绝对路径 — python3 "/abs/path/scripts/deploy_toolkit.py" <sub>
  • ⛔ 反模式:SKILL_DIR=/path python3 "$SKILL_DIR/..." — 外层 Shell 会在前缀赋值之前展开 $SKILL_DIR,导致路径变为 /scripts/deploy_toolkit.py 并出现 ENOENT。如果看到 python3: can't open file '/scripts/deploy_toolkit.py',请改用 Pattern A 或 B。

任务 1:安装 Alibaba Cloud CLI

主要操作:运行 python3 "$SKILL_DIR/scripts/deploy_toolkit.py" check——该命令会一次性检查 CLI 版本、appmanager-cli 版本和凭证。只有在脚本文件缺失时,才使用 references/init-and-credentials.md 中的备用方案。

必须 — 处理未满足的环境前置条件:当 check 因 aliyun CLI 缺失或版本低于 3.3.19(或 appmanager-cli 缺失或版本过旧)而以状态码 1 退出时,Agent 不得默默停止工作流。必须按以下流程处理:

  1. 未安装 CLI → 直接自动安装,无需询问用户——执行安装命令(见下方代码片段,或查看 references/init-and-credentials.md 以确定适用的架构),然后重新运行 deploy_toolkit.py check 进行确认。
  2. 已安装 CLI → 先询问用户——显示检测到的版本、所需版本和升级命令,并征求用户明确同意(例如:“已安装 aliyun CLI 3.3.4,但低于 appmanager 所需的 >= 3.3.19;是否批准升级(覆盖安装到 /usr/local/bin,需要 sudo)?”)。绝不能默认用户同意;绝不能粘贴凭证。
    • 用户同意后——执行安装/升级命令,然后重新运行 deploy_toolkit.py check 进行确认。
    • 用户拒绝后——以用户拒绝为由停止。不要继续使用旧版本(部署无论如何都会失败)。

工具包的 check 输出已针对每个可修复问题包含 → AGENT: DO NOT stop. ASK user ... 行——请原样遵循(“未安装”情况除外,该情况会自动处理)。

必须 — 升级方法优先级:由 brew 管理 → 使用 brew upgrade(不要再次覆盖 /usr/local/bin/);有 sudo → 覆盖 /usr/local/bin/;没有 sudo → 使用 ~/bin/ 并持久化设置 PATH(Unix)。Scoop/Choco → 使用 %USERPROFILE%\bin 并设置用户 PATH(Windows)。完整优先级规则 → references/init-and-credentials.md §“CLI Install/Upgrade Method Priority”。安装/升级后,始终重新运行 deploy_toolkit.py check 进行确认;如果 which -a aliyun 仍显示旧二进制文件排在首位,请修正 PATH 顺序——不要重复执行相同的覆盖操作。

可观测性(强制):注入 User-Agent

⛔ 每次 aliyun CLI 调用都必须携带此技能的 User-Agent,以便在云端日志中追踪所有 API 请求。Agent 必须在会话开始时(紧接着 Step 0 之后),在调用任何 aliyun / deploy_toolkit.py 之前,将 UA 环境变量导出一次。

完整 UA 模板:

AlibabaCloud-Agent-Skills/alibabacloud-ecs-code-deploy/{session-id}

session-id 统一规则:

  • 每个 Agent 会话只生成一次:SESSION_ID=$(uuidgen | tr '[:upper:]' '[:lower:]')——小写 UUID(任何长度不少于 16 个字符的小写十六进制随机令牌也可)。
  • 在会话中的所有 CLI 调用中重复使用同一个 session-id——绝不要为每条命令重新生成,否则一次部署会散落成无法追踪的片段。
  • 按照 Step 0 规则统一持久化:模式 A 使用 export SESSION_ID=...(持久 shell),或在每次调用使用全新 shell 时内联字面值。

注入方法(现代方式——环境变量):

export ALIBABA_CLOUD_USER_AGENT="AlibabaCloud-Agent-Skills/alibabacloud-ecs-code-deploy/${SESSION_ID}"

⛔ 旧版 aliyun configure ai-mode enable / set-user-agent 机制已弃用——请勿使用。不要将 ALIBABA_CLOUD_USER_AGENT 与 ai-mode 或针对每条命令设置的环境变量前缀结合起来用于同一个技能令牌:CLI 会叠加这些来源并生成重复的 UA。每个会话只设置一次环境变量,然后保持不变。

任务 2:配置凭据

deploy_toolkit.py check 已会验证凭据。只有在凭据缺失或无效时,才参考 references/init-and-credentials.md,了解默认凭据链的补救流程。

⛔ 优先选择 OAuth,而非 AK:OAuth 更安全、更方便(无需长期存储密钥)。Agent 必须将 OAuth 作为首选方案。用户同意后,Agent 直接运行登录命令——但必须先提醒用户,该命令会打开浏览器授权页面,且会一直等待,直到用户在浏览器中完成授权——然后执行 aliyun configure --mode OAuth --profile oauth,并通过 aliyun sts get-caller-identity --profile oauth 验证。

⛔ SA-2.12 — 不要在聊天中收集 AK/SK:如果用户更倾向于使用 AK 认证,请提供一条可直接运行的命令模板,其中包含占位符——aliyun configure set --profile default --mode AK --access-key-id <your-access-key-id> --access-key-secret <your-access-key-secret> --region cn-hangzhou——并请用户填写自己的 AK/SK,然后在自己的终端中运行。Agent 绝不要求用户将 AccessKey/Secret/STS-Token 值粘贴到聊天中,绝不将原始 AK/SK 放入工具调用参数或脚本中,也绝不回显凭据值。也支持默认凭据链(ECS RAM Role / 环境变量 / 已有的 ~/.aliyun/config.json)。完整补救流程 → references/init-and-credentials.md。

严格禁止:绝不运行独立的 appmanager 或 aliyun appmanager login。


任务 3:初始化项目

步骤 1(必须):首先阅读 README.md

严格的顺序规则:扫描任何项目文件之前,Agent 必须先阅读项目根目录中的 README.md(或 README)。这始终是任务 3 的第一项操作。

从 README 中提取的信息:

  • 快速入门 / 部署命令(例如 pip install -r requirements.txt && python main.py、npm install && npm start)
  • 官方构建 / 运行命令、Docker 部署方式、端口号、必需的环境变量
必须:向用户介绍 README 中的方法,并按决策流程执行

步骤 A:向用户列出 README 提供的信息。

步骤 B:按优先级选择方法:

优先级方法类型操作
1(最高)原生 CLI / 包管理器安装(npm install -g、pip install、go install)直接使用
2原生构建并运行(pip install && python main.py、npm install && npm start)使用该方法,并安装运行时
3基于脚本的部署(bash deploy.sh)必须确认其为非交互式
4(最低)Docker / docker-compose仅在没有更高优先级的方法时使用;检查中国地区的可访问性

步骤 C:根据场景执行:

  • README 中有原生方法(优先级 1/2) → 直接将其作为启动脚本的核心。绝不忽略 README 并从头构建。
  • README 中只有 Docker 方法 → 检查镜像可访问性(参见 references/script-templates.md 中的“Docker 镜像可访问性检查”)。提醒用户中国镜像源可能带来的风险。
  • README 中没有部署信息 / README 不存在 → Agent 独立扫描项目文件(仅允许在此情况下操作)。

为什么要先读 README? 大多数项目都会记录准确的构建 / 运行命令。仅根据文件自动检测容易出错。


步骤 2:确定项目类型
条件类型
项目依赖 agentscopeagent
其他所有情况(langchain、mcp、autogen、Web 服务、工具等)app
确定 --name

使用项目目录名称(转为小写,并使用连字符)。告知用户:Default app name uses the directory name <name>。

确定 --region 和 ECS 目标(必须询问用户)

Agent 必须在同一条消息中同时询问以下两个问题:

1. 你想部署到哪个区域?

  • 上海 (cn-shanghai) / 杭州 (cn-hangzhou) / 北京 (cn-beijing) / 深圳 (cn-shenzhen) / 广州 (cn-guangzhou) / 成都 (cn-chengdu) / 南京 (cn-nanjing) / 香港 (cn-hongkong)

2. 使用新建 ECS 还是已有 ECS?

  • 新建 ECS(自动创建实例,按量付费)
  • 已有 ECS(从下方列表中选择,或手动提供实例 ID)

绝不能使用“华东 1”“华北 2”等基于可用区的标签。绝不能添加描述。仅使用城市名称。

已有 ECS — 列出所选区域中用户最近创建的 10 个实例(必须执行)

当用户选择已有 ECS时,Agent 必须先查询账号在所选区域中最近创建的 10 个实例(插件模式:aliyun ecs describe-instances),并将它们列成编号列表供用户选择——不得要求用户凭记忆提供实例 ID。始终也要允许用户手动输入实例 ID(例如 i-bp1xxxxxxxx)作为备用选项。查询时必须传入与部署相同的 --profile(同一账号),否则可能返回零个实例或错误的实例。完整命令(jq 管道、无 jq 时的回退方案、零实例处理)→ references/init-and-credentials.md §“列出现有 ECS 实例”。选定或输入的 ID 将传入 appmanager init --ecs existing --instance-id <ID>。

⚠️ 区域传递检查(必须执行):所选区域必须原样传入 appmanager init --region,写入 config.yaml 中的 common.deployment.regionId,并作为 --region <REGION_ID> 附加到后续每一次 deploy_toolkit.py {price,deploy,verify} 调用中。区域不匹配或遗漏会导致 OOS API 返回 InvalidParameter: DeployRegionId is invalid。

确定 --port(仅 App 类型,可选)

仅当项目实际监听 HTTP 时才指定。后台服务(机器人、工作进程、CLI 工具)无需指定。如确有需要但端口未知,默认使用 8080。Agent 类型不使用 --port。

非交互式初始化

所有初始化标志组合请参阅 references/init-and-credentials.md。

这会创建 .appmanager/config.yaml。不支持 --overwrite——如果 .appmanager/ 已存在,请先将其删除。


任务 4:生成部署脚本

对于所有项目类型,Agent 必须生成部署脚本并将其写入 .appmanager/config.yaml。

工作流
  1. 首先阅读 README.md——遵循任务 3 的决策树
  2. 如果 README 没有部署信息——扫描项目结构(见下方“语言检测”)
  3. 检查 Docker 可访问性——如果选择 Docker 路径(见 references/script-templates.md)
  4. 生成启动和停止脚本——遵循下方规则。启动脚本必须始终包含 zip 解压步骤。
  5. 写入 config.yaml——写入 common.scripts.start 和 common.scripts.stop 下(绝不能写入顶层 scripts)
语言检测、要读取的文件和入口点

语言检测规则(指示文件)、各语言必须读取的文件以及入口点检测顺序 → references/script-templates.md §“项目分析”。

通用脚本规则
规则要求
⛔ 必须解压 zip启动脚本必须:查找 zip → mkdir -p → unzip -o → cd。否则,ECS 上的项目目录不存在
安装运行时必须先安装语言运行时(ECS 是裸机环境)
安装 unzipcommand -v unzip &>/dev/null || $PKG_MGR install -y unzip
幂等可安全地多次运行
⛔ 日志文件路径固定必须使用 /root/app.log 和 /root/app.pid。验证脚本是否将这些路径写死
追加日志始终使用 >>(绝不使用 >)
PID 文件在 nohup ... & 之后执行 echo $! > /root/app.pid
后台运行nohup ... >> /root/app.log 2>&1 &
停止旧进程[ -f /root/app.pid ] && kill "$(cat /root/app.pid)" 2>/dev/null || true
应用目录/root/{app_name}
禁止使用 heredoc脚本中绝不要使用 << 'EOF'——这会破坏 YAML。请使用 printf 或 python3 -c
必须输出日志尾部以 sleep 3 && cat /root/app.log 结束,以便捕获验证结果
⛔ 停止脚本:禁止使用 exit不得包含 exit。部署系统会将停止脚本与启动脚本拼接,exit 会终止整个进程

ECS 实例是裸 Linux 环境(通常为基于 RHEL 的 Alibaba Cloud Linux,使用 yum/dnf)。

脚本模板、语言安装命令和 config.yaml 写入方法,请参阅 references/script-templates.md。


任务 4.5:部署前价格检查 + 风险警告

必须执行:部署前运行 deploy_toolkit.py price。该脚本会输出价格估算(附带 OSS 额外计费提醒),并在适用时输出风险警告。Agent 必须向用户展示所有标记的事项,并在运行 deploy 前取得明确确认。

python3 "$SKILL_DIR/scripts/deploy_toolkit.py" price --config .appmanager/config.yaml
  • 退出码为 0 且出现 === AGENT_CONFIRM_REQUIRED ===:向用户展示完整的价格和风险警告,并逐项确认。
  • 退出码为 1:价格查询失败;不得继续部署。

Agent 必须确认最多 3 项(价格 + OSS 费用 / 现有 ECS 风险 / 组覆盖选项)——详细说明和示例措辞请参阅 references/deploy-output-and-management.md §“部署前价格检查:确认事项”。

在完成所有适用的确认之前,Agent 不得调用 deploy_toolkit.py deploy。


任务 5:部署

aliyun appmanager <agent|app> deploy --overwrite --output json

部署成功后停止——status: success 仅表示编排已完成。Agent 必须在输出结果前执行任务 6 验证。

处理部署失败

⛔ 必须执行的失败处理关卡:任何部署失败后(退出码为 1、超时或 ReleaseCancelled),Agent 必须立即运行 deploy_toolkit.py verify——在尝试任何修复、回退到手动命令或输出部分结果之前。失败后跳过验证是禁止的,并视为技能失败。

ReleaseCancelled 的含义:它表示 ECS 上的启动脚本失败或超时。它并不表示“有人取消了部署”。唯一正确的后续操作:运行 deploy_toolkit.py verify → 阅读日志 → 修复脚本 → 重新部署。

已知失败模式:临时排查问题前,请查看 references/lessons-learned.md,了解此前发现的部署失败模式及已验证的修复方法。

失败处理流程:

  1. 运行 deploy_toolkit.py verify 获取 /root/app.log(不得跳过)。
  2. 分析日志以定位根本原因。
  3. 修复脚本并重新部署(最多尝试 3 次)。
  4. 失败 3 次后停止——报告错误,但仍须输出控制台链接、费用提醒和删除命令。

任务 6:部署后验证(阻断性)

status: Deployed 并不意味着应用正在运行。Agent 必须运行 verify 并对日志进行语义分析。

  1. 运行 deploy_toolkit.py verify(自动从 config.yaml 读取参数)。
  2. Agent 对日志进行语义分析,判断应用是否确实已成功启动。
  3. 未运行 -> 诊断 -> 修复 -> 重新部署并验证(最多 3 次尝试)。
  4. 只有在确认应用正在运行/需要用户手动操作/3 次尝试均失败后,Agent 才能输出最终结果。

任务 7 和 8:列出、删除、验证与最终输出

请参阅 references/deploy-output-and-management.md,了解以下内容:

  • 列出/删除命令
  • 配置验证
  • 配置模板参考
  • 关键注意事项和易错点
  • 部署后必须遵循的输出格式(控制台链接、费用提醒、使用指南)
输出前关卡——自检(⛔ 阻断性)

输出结果前,Agent 必须准确打印 Deployment self-check report 模板(见工作流步骤 7.5)。跳过报告 = 技能失败(报告不是可选的摘要)。如果任何项目为 ❌,必须在输出步骤 8 之前修复。

📘 包含具体输入/输出及边缘情况的实操指南(Python Flask 示例):请参阅 references/tutorial-flask-app.md。

完整部署工作流

⛔ 强制执行规则:Agent 必须严格按照此顺序执行。对于指定脚本的步骤(步骤 1、5、6),Agent 必须运行脚本,绝不能用单独的命令手动复现脚本逻辑。上面的任务章节仅供参考(用于了解脚本的内部工作方式,或在脚本缺失时作为后备方案)。

# 0. Resolve $SKILL_DIR (MANDATORY — see "Step 0" section above for full algorithm)
# → Detect the absolute directory containing THIS SKILL.md (most accurate)
# → Or fall back to platform-specific candidates: ~/.qoder/skills/..., ~/.claude/skills/..., ~/.qwen/skills/..., $SKILLS_HOME/..., etc.
# → Pattern A (persistent shell): export SKILL_DIR=<abs_path> ; verify $SKILL_DIR/scripts/deploy_toolkit.py exists ; reuse $SKILL_DIR everywhere
# → Pattern B (fresh shell per command): inline the absolute path — `python3 "/abs/path/scripts/deploy_toolkit.py" ...`
# → ⛔ NEVER use `SKILL_DIR=/path python3 "$SKILL_DIR/..."` — outer shell expands $SKILL_DIR
#    BEFORE the prefix assignment, producing `/scripts/deploy_toolkit.py` and ENOENT.

# 1. Environment check (MUST use deploy_toolkit.py check — DO NOT run manual commands)
python3 "$SKILL_DIR/scripts/deploy_toolkit.py" check
# ⛔ FORBIDDEN: running `aliyun version`, `~/.aliyun/appmanager-venv/bin/python -c "..."`,
#    credential checks, or ANY manual version-check commands before or instead of this script.
#    The script checks ALL of: CLI version + appmanager-cli version + credentials in one run.
#    Just run the script. Period.
# → If exit 0: all checks passed, proceed to step 2
# → If exit 1, address the issue printed by the script:
#    ⚠️ DO NOT stop silently. For every fixable ❌ line the script prints,
#       Agent MUST follow the flow below:
#       - aliyun CLI NOT installed: AUTO-INSTALL directly (no need to ask user)
#       - aliyun CLI already installed but outdated: ASK user to approve upgrade
#         (covers to /usr/local/bin, needs sudo), then run the install command
#         printed by the script (see Task 1).
#       - appmanager-cli < 1.1.1 or BROKEN venv: ASK user to approve
#         `rm -rf ~/.aliyun/appmanager-venv` (auto-recreates on next aliyun
#         appmanager run).
#         ⚠️ This path is fixed at ~/.aliyun/appmanager-venv (the venv is self-managed
#            by the aliyun CLI). After deletion, the next `aliyun appmanager` run
#            auto-recreates it. The Agent MUST use this exact literal path —
#            NEVER replace it with a variable or build it via concatenation,
#            to avoid accidentally wiping user data.
#       - credentials missing/invalid: present OAuth-first remediation
#         to the user (OAuth / RAM Role / env vars / `aliyun configure` interactive) — NEVER
#         collect AK/SK in chat. See Task 2 + references/init-and-credentials.md.
# → If user refuses any fix: stop with that refusal as the reason — DO NOT
#   continue with a broken environment (deployment will fail anyway).
# → If script file not found: ONLY THEN fall back to manual checks (Task 1 + Task 2)

# 2. Obtain project source (if needed)
# → If git URL provided: clone to CURRENT WORKING DIRECTORY, cd into cloned dir
#    git clone <URL> && cd <cloned_dir>
# → If local path / current directory: skip this step, use directly

# 🔀 REPEAT DEPLOYMENT SHORTCUT — check BEFORE step 3
# → Check if .appmanager/config.yaml already exists in the project directory
# → If YES (config.yaml exists):
#    Read the file and check for common.deployment.instanceId:
#      - instanceId ABSENT (new ECS): skip steps 3-5, jump to step 5.5 (price check)
#      - instanceId PRESENT (existing ECS): skip steps 3-5.5, jump to step 6 (deploy)
#    In both cases, inform user: "Existing .appmanager/config.yaml detected; will reuse the existing config and deploy directly."
# → If NO (config.yaml does NOT exist): proceed normally from step 3

# 3. Read project + identify type (agent or app)
# → READ README.md FIRST — highest priority source for deployment method:
#    - Agent MUST list README's methods to user and select by priority:
#      Native CLI install > Native build+run > Script deploy > Docker
#    - ❌ NEVER ignore README methods and scan project files instead
#    - ❌ NEVER prefer Docker when native methods are available
#    - Docker: ONLY when no native method exists, MUST warn user about China mirror risks
#    - Only if README absent/empty/no deploy info → Agent scans project files independently
# → Only classify as "agent" if project depends on `agentscope`; everything else is "app"
# → Determine --name from directory name, --port from project config/README
# → For Docker: check image accessibility from China (see references/script-templates.md)

# 4. Ask user for deployment region + ECS target (MANDATORY — ask together in one question)
# → Question 1: "Which region do you want to deploy to? Shanghai(cn-shanghai)/Hangzhou(cn-hangzhou)/Beijing(cn-beijing)/Shenzhen(cn-shenzhen)/Guangzhou(cn-guangzhou)..."
# → Question 2: "New ECS or existing ECS?" — if existing, FIRST query the account's 10 most-recently-created
#   ECS instances in the chosen region and present them as a numbered list for selection:
#     aliyun ecs describe-instances --biz-region-id <REGION> --region <REGION> --page-size 100 | jq -r '.Instances.Instance | sort_by(.CreationTime) | reverse | .[:10] | .[] | "..."'  (plugin mode; no `--output json`; JSON is the default)
#   Also always support manual instance ID entry (e.g. i-bp1xxxxxxxx). See Task 3 "Existing ECS" section.
# → NEVER use zone-based labels like "East China 1" / "North China 2" — always use city names
# → NEVER skip the ECS choice and default to creating new
# → ⚠️ Region MUST be propagated verbatim to: appmanager init --region, config.yaml common.deployment.regionId, AND every deploy_toolkit.py --region. Mismatch → InvalidParameter: DeployRegionId from OOS API.

# 5. Init + generate scripts (appmanager init → write start/stop to config.yaml)
# → If .appmanager/ already exists in the CURRENT project directory, ask user before removing.
#   ⚠️ DESTRUCTIVE: `rm -rf .appmanager` deletes the existing deployment config.
#      Required guard before deletion:
#        a. Confirm CWD matches the intended project directory (`pwd` shows expected path)
#        b. Confirm target is the relative path `.appmanager` (NEVER absolute, NEVER with variables)
#        c. Inform the user "About to delete the existing deployment config under ./.appmanager/. This is irreversible." and obtain consent
#      Recommended safer alternative: back up first
#        mv .appmanager .appmanager.bak.$(date +%Y%m%d%H%M%S)
#      Only after explicit user consent: rm -rf ./.appmanager
# → Run: aliyun appmanager init --non-interactive --name <DIR_NAME> --type <app|agent> --region <REGION> [--port <PORT>] [--ecs existing --instance-id <ID>] [--model qwen3.6-plus --api-key "$API_KEY"]
#   (See references/init-and-credentials.md for full flag combinations by type)
# → Then generate start/stop scripts and write to config.yaml:
#   - MUST write to common.scripts.start and common.scripts.stop (NEVER top-level scripts key)
#   - Use python3 yaml library: config['common']['scripts'] = {'start': ..., 'stop': ...}
#   - PRIORITY: README deployment commands → use directly; only auto-generate when README has none
#   - ⛔ MANDATORY: Start script MUST ALWAYS include zip extraction (mkdir + unzip + cd) BEFORE
#     any build/run commands. appmanager uploads zip but does NOT extract it.

# 5.5. Pre-deploy price check + risk warning (MUST run deploy_toolkit.py price — Agent handles user confirmation)
python3 "$SKILL_DIR/scripts/deploy_toolkit.py" price --config .appmanager/config.yaml
# → Script output structure:
#    [Price table] estimate from `appmanager price` (order-billed resources: ECS/EIP/bandwidth) + the trailing 📦 OSS extra-billing reminder
#    [Risk warning] only when detected: [Existing-ECS deployment risk] / [Group overwrite risk] / [Failure-leftover group]
# → Script does NOT ask user for confirmation — that's the Agent's job
# → If exit 0: Agent MUST read the output, present the COMPLETE breakdown to user — including:
#    1) Price estimate + OSS extra-billing reminder (OSS storage ~CNY 0.12/GB/month, public outbound ~CNY 0.50/GB only when cross-region, requests billed per 10k)
#    2) If output contains [Existing-ECS deployment risk] -> ask whether to deploy onto that existing ECS (may impact other apps on it)
#    3) If output contains [Group overwrite risk] -> ask user to choose A (overwrite) or B (new group)
#    Example: "Estimated cost: compute resources CNY X.XXX/hour (~CNY XXX.XX/month); public traffic billed by usage at CNY 0.80/GB;
#             the deployment also incurs minor OSS storage and request fees (intra-region pull is free of public outbound charges).
#             Confirm to continue?"
# → After ALL items confirmed by user: run the matching deploy command per item 3's choice (default overwrite / --force-new-group for new group)
# → If ANY item refused: STOP deployment
# → If exit 1: price query failed, show error to user, do NOT proceed

# 6. Deploy (MUST use deploy_toolkit.py deploy — DO NOT run deploy manually)
python3 "$SKILL_DIR/scripts/deploy_toolkit.py" deploy \
  --type <agent|app> --name <APP_NAME> --group <GROUP_NAME> --region <REGION_ID>
# ⛔ FORBIDDEN: running `aliyun appmanager deploy` directly without this script
# → Handles: group status check → conflict auto-resolve → deploy
# → Exit 0: deploy submitted, proceed to step 7
# → Exit 1: ⛔ MUST run step 7 (verify) IMMEDIATELY to fetch /root/app.log;
#           skipping to step 8, outputting partial results, or running manual
#           commands instead is FORBIDDEN. Then fix script per log and redeploy
#           (max 3 attempts).

# 7. Verify (MUST use deploy_toolkit.py verify — DO NOT check status manually)
python3 "$SKILL_DIR/scripts/deploy_toolkit.py" verify \
  --type <agent|app> --name <APP_NAME> --group <GROUP_NAME> --region <REGION_ID>
# ⛔ FORBIDDEN: running `aliyun appmanager status` + manual log analysis instead of this script
# → Optional: --wait <seconds> for slow-starting apps (default 3s, Java/heavy use 15-30)
# → Dual-path: Cloud Assistant cat /root/app.log (preferred) → deployCommandOutput (fallback)
# → Exit 0: app running, proceed to step 8
# → Exit 1: app failed — fix start script, re-deploy (back to step 6)
# → Exit 2: inconclusive — retry with longer --wait or suggest SSH check

# 7.5. Self-check summary (⛔ BLOCKING — skill fails if omitted)
# MUST print the exact template below to the user — this is a completion criterion, NOT optional.
#
# ---
# ✅ Deployment self-check report:
#   0. Path resolution — SKILL_DIR=___ (script exists ✅)
#   1. Environment pre-check — CLI v___ / appmanager-cli v___ / credentials valid ✅
#   2. Project obtained — (local / cloned) ✅
#   3. Project identified — type: ___ / deploy method source: README.md ✅
#   4. Deployment region — user choice: ___ ✅
#   5. Init + scripts — config.yaml generated; start script: ___ (key command summary) ✅
#   5.5. Pre-deploy price check — user confirmed price (CNY ___/hour, ~CNY ___/month) ✅
#   6. Deploy executed — deploy_toolkit.py deploy exit 0 ✅
#   7. Run verification — deploy_toolkit.py verify exit 0 / log keywords: ___ ✅
# ---
#
# If any item is ❌, fix it BEFORE step 8 — this is for the USER to see, proving the work is properly done.

# 8. Output results (MANDATORY: console link + cost reminder + management commands)
# → See references/deploy-output-and-management.md for full output format

评论

支持 Markdown