关于 solo-deploy
面向已完成构建阶段项目的部署技能。它读取技术栈模板和项目配置,检测可用的命令行工具,准备部署并验证项目是否上线。
主要功能
- 01读取技术栈模板和项目上下文
- 02检测已安装的部署命令行工具
- 03检查部署前提和项目类型
- 04准备数据库与环境变量
- 05部署并验证项目是否上线
适用场景
- 01部署已完成的 Web 应用
- 02将命令行工具或库发布到软件包注册表
- 03为标记为仅本地运行的项目跳过部署
MCP 相关
该技能可使用 MCP 工具搜索以往部署、检索项目代码模式,以及查询依赖或技术栈。若这些工具不可用,则改用文件搜索和读取。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ fortunto2/ solo-factory --skill solo-deploy安装后在 Claude Code 中输入/solo-deploy确认已加载。
附带文件references/platform-commands.md
详细介绍
/deploy
将项目部署到其托管平台。读取栈模板 YAML(templates/stacks/{stack}.yaml)以获取准确的部署配置(平台、CLI 工具、基础设施层级、CI/CD、监控),检测已安装的 CLI 工具,设置数据库和环境,推送代码,并验证部署已上线。
实时上下文
- 分支:!
git branch --show-current 2>/dev/null - 未提交文件:!
git status --short 2>/dev/null | wc -l | tr -d ' '个文件 - 上次提交:!
git log --oneline -1 2>/dev/null
参考资料
templates/principles/dev-principles.md— CI/CD、密钥、DNS、共享基础设施规则dev-principles-my.md(若存在)— 个人基础设施扩展(身份验证、隧道、监控)templates/stacks/*.yaml— 包含 deploy、infra、ci_cd、monitoring 字段的栈模板
路径相对于技能的插件根目录。如果未在预期位置找到这些文件,请使用 Glob 搜索。
适用时机
在 /build 完成所有任务后使用(构建阶段已完成)。这是部署引擎。
流水线:/build → /deploy → /review
MCP 工具(如果可用,请使用)
session_search(query)— 查找之前如何部署类似项目project_code_search(query, project)— 查找各项目中的部署模式codegraph_query(query)— 检查项目依赖和技术栈
如果 MCP 工具不可用,请改用 Glob + Grep + Read。
部署前检查
0. 检查是否需要部署
读取 docs/workflow.md(如果存在)。如果其中包含 "No deploy"、"no deploy stage" 或 "ship = commit":
- 输出:"Deploy skipped — workflow.md says no deploy stage (CLI/local project)."
- 立即输出
<solo:done/>。 - 不要继续执行任何部署步骤。
此外:如果项目没有部署基础设施(没有 Dockerfile、deploy.sh、wrangler.toml、vercel.json、sst.config.ts),且 workflow.md 存在:
- 同样跳过部署,输出 done。
1. 确认构建已完成(可选)
- 如果存在流水线状态跟踪(
.solo/states/目录),检查.solo/states/build。 - 如果
.solo/states/存在但缺少build标记:警告 "Build may not be complete. Consider running/buildfirst." - 如果
.solo/states/不存在:跳过此检查并继续部署。
2. 检测可用的 CLI 工具
并行运行 — 检测本地已安装的工具:
vercel --version 2>/dev/null && echo "VERCEL_CLI=yes" || echo "VERCEL_CLI=no"
wrangler --version 2>/dev/null && echo "WRANGLER_CLI=yes" || echo "WRANGLER_CLI=no"
npx supabase --version 2>/dev/null && echo "SUPABASE_CLI=yes" || echo "SUPABASE_CLI=no"
fly version 2>/dev/null && echo "FLY_CLI=yes" || echo "FLY_CLI=no"
sst version 2>/dev/null && echo "SST_CLI=yes" || echo "SST_CLI=no"
gh --version 2>/dev/null && echo "GH_CLI=yes" || echo "GH_CLI=no"
cargo --version 2>/dev/null && echo "CARGO_CLI=yes" || echo "CARGO_CLI=no"
记录哪些工具可用。发现工具后直接使用 — 如果 CLI 已全局安装,不要使用 npx。
3. 加载项目上下文(并行读取)
CLAUDE.md— 栈名称、架构、部署平台docs/prd.md— 产品需求、部署说明docs/workflow.md— CI/CD 策略(如果存在)package.json或pyproject.toml— 依赖项、脚本wrangler.toml、sst.config.ts、vercel.json— 平台配置(如果存在)docs/plan/*/plan.md— 当前计划(查找与部署相关的阶段/任务)
由计划驱动的部署: 如果当前计划包含部署阶段或任务(例如“将 Python 后端部署到 VPS”、“运行 deploy.sh”、“在服务器上设置 Docker”),请将这些内容视为主要部署指令。计划了解项目特定的部署目标,通用栈 YAML 可能未涵盖这些目标。除以下标准平台部署外(或代替它),还要执行计划中的部署任务。
3b. 检测项目类型
对项目进行分类,以选择合适的部署策略:
| 信号 | 项目类型 | 部署目标 |
|---|---|---|
package.json + next.config.* | Web(Next.js) | Vercel / CF Pages |
wrangler.toml | Web(Workers) | Cloudflare Workers |
Cargo.toml + [lib] only | 库(Rust crate) | crates.io |
Cargo.toml + [[bin]] only | CLI/TUI 工具 | crates.io + GitHub Releases |
Cargo.toml + [[bin]] + [lib] | 库 + CLI | crates.io + GitHub Releases |
pyproject.toml + [project.scripts] | CLI(Python) | PyPI |
pyproject.toml(无 scripts、无 Web) | 库(Python) | PyPI |
*.xcodeproj | iOS 应用 | App Store → /solo:ios-release |
build.gradle.kts + com.android.application | Android 应用 | Play → /solo:android-release |
**对于 CLI/TUI/库项目:**跳过 Web 部署步骤(Vercel、CF 等),直接进行包注册表部署(crates.io、PyPI、npm)。
3c. 交叉编译兼容性检查(Rust/原生项目)
**适用条件:**存在 Cargo.toml,且 CI/CD 将在不同架构上构建(例如,GitHub Actions 使用 x86_64,而本地使用 Apple Silicon)。
# Check for native/system dependencies that may fail cross-compile
grep -r 'links\s*=' Cargo.toml 2>/dev/null # C library bindings
grep -r 'build\s*=' Cargo.toml 2>/dev/null # build.rs (may compile C code)
grep -rn 'sys' Cargo.toml 2>/dev/null | grep -v '#' # *-sys crates (native bindings)
已知的交叉编译风险:
ort-sys/onnxruntime-sys— 并非所有目标平台都有预编译二进制文件,需要本地构建ffmpeg-sys/ffmpeg-next— 需要在 CI 运行器上安装 FFmpegopenssl-sys— 若要使用纯 Rust TLS,请改用rustls- 任何
*-syscrate — 检查是否存在适用于 CI 目标架构的预编译二进制文件
如果发现有风险的依赖:
- 检查 CI 矩阵是否包含所需目标(
.github/workflows/*.yml) - 建议在 CI 中添加交叉编译工具链,或
- 建议将原生依赖替换为纯 Rust 替代方案,或
- 将该依赖添加到 CI 安装步骤:
apt-get install/brew install - 在部署摘要中说明哪些依赖可能会阻碍 CI
4. 阅读技术栈模板 YAML
从 CLAUDE.md 中提取技术栈名称(查找 stack: 字段或技术栈部分)。
阅读技术栈模板,获取准确的部署配置:
搜索顺序(以第一个找到的为准):
templates/stacks/{stack}.yaml— 相对于此技能的插件根目录.solo/stacks/{stack}.yaml— 用户的本地覆盖项(来自/init)- 使用 Glob 在项目或父目录中搜索
**/stacks/{stack}.yaml
从 YAML 中提取以下字段:
deploy— 目标平台:vercel、cloudflare_workers、cloudflare_pages、docker、hetzner、app_store、play_store、localdeploy_cli— CLI 工具及其用途(例如vercel (local preview, env vars, promote))infra— 基础设施工具及层级(例如sst (sst.config.ts) — Tier 1)ci_cd— CI/CD 系统(例如github_actions)monitoring— 监控/分析工具(例如posthog)database/orm— 数据库和 ORM(如有,会影响迁移步骤)storage— 存储服务(如有,例如 R2、D1、KV 等)notes— 技术栈特定的部署说明
以下所有部署决策均以 YAML 中的值为准。YAML 配置优先于后备层级矩阵。
5. 检测平台(未找到 YAML 时的回退方案)
如果没有找到 stack YAML,请使用以下回退矩阵:
| Stack | 平台 | 层级 |
|---|---|---|
nextjs-supabase / nextjs-ai-agents | Vercel + Supabase | Tier 1 |
cloudflare-workers | Cloudflare Workers (wrangler) | Tier 1 |
astro-static / astro-hybrid | Cloudflare Pages (wrangler) | Tier 1 |
python-api | Cloudflare Workers(MVP)或 Pulumi + Hetzner(生产环境) | Tier 1/2 |
python-ml | 跳过(CLI 工具,无需托管) | — |
rust-native | crates.io(库/CLI crate)或二进制发布(GitHub Releases) | Tier 1 |
ios-swift | 移交给 /solo:ios-release(App Store / TestFlight) | — |
kotlin-android / kotlin-multiplatform | 移交给 /solo:android-release(Play Console) | — |
如果 $ARGUMENTS 指定了平台,请使用该平台,而不是自动检测或 YAML 中的平台。
自动部署平台(来自 YAML 的 deploy 字段或回退矩阵):
vercel/cloudflare_pages— 推送时自动部署。如果项目已关联,只需推送到 GitHub 即可。仅在初始设置时手动部署。cloudflare_workers— 需要运行wrangler deploy(Workers 不支持基于 git 的自动部署)。docker/hetzner— 通过 SSH 或 Pulumi 手动部署。
部署步骤
步骤 1. Git — 清理状态并推送
git status
git log --oneline -5
如果存在未提交的更改,请提交剩余更改:
git add -A
git commit -m "chore: pre-deploy cleanup"
确保远程仓库存在并推送:
git remote -v
git push origin main
如果没有远程仓库,请创建 GitHub 仓库:
gh repo create {project-name} --private --source=. --push
**对于支持自动部署的平台(Vercel、CF Pages):**推送到 main 会自动触发部署。如果项目已关联,请跳过手动部署命令。
步骤 2. 数据库设置
Supabase(如果检测到 supabase/ 目录或 Supabase 依赖项):
# If supabase CLI available:
supabase db push # apply migrations
supabase gen types --lang=typescript --local > db/types.ts # optional: regenerate types
如果没有 CLI:引导用户前往 Supabase 控制台执行迁移。
Drizzle ORM(如果存在 drizzle.config.ts):
npx drizzle-kit push # push schema to database
npx drizzle-kit generate # generate migration files (if needed)
D1(Cloudflare)(如果 wrangler.toml 中配置了 D1 绑定):
wrangler d1 migrations apply {db-name}
如果数据库尚未配置,请列出所需内容并继续,不要因此阻塞流程。
步骤 3. 环境变量
读取 .env.example 或 .env.local.example,确定所需变量。
生成特定平台的说明:
Vercel:
# If vercel CLI is available and project is linked:
vercel env ls # show current env vars
# Guide user:
echo "Set env vars: vercel env add VARIABLE_NAME"
echo "Or via dashboard: https://vercel.com/[team]/[project]/settings/environment-variables"
Cloudflare:
wrangler secret put VARIABLE_NAME # interactive prompt for value
# Or in wrangler.toml [vars] section for non-secret values
请勿创建或修改包含真实密钥的 .env 文件。
列出所需内容,让用户自行设置值。
步骤 4. 平台部署
请参阅 references/platform-commands.md,了解各平台完整的部署、环境变量和日志命令。
使用预检中检测到的平台:
- Vercel —
vercel link→vercel(预览)→vercel --prod - Cloudflare Workers —
wrangler deploy - Cloudflare Pages —
wrangler pages deploy ./out - SST —
sst deploy --stage prod
对于支持自动部署的平台(Vercel、CF Pages):如果已关联,运行 git push origin main 即可。
步骤 4b. Rust/Crates.io 部署
**检测条件:**项目根目录存在 Cargo.toml,且 cargo CLI 可用。
根据 Cargo.toml 确定部署目标:
- 如果存在
[lib]部分或 crate 是库 → 发布到 crates.io - 如果只有
[[bin]]→ 二进制发布(GitHub Releases) - 如果两者都有 → 两者都执行(发布 crate + 将二进制附加到 release)
发布前检查清单:
# 1. Verify tests + clippy pass
cargo test
cargo clippy --all-targets -- -D warnings
# 2. Check Cargo.toml has required fields for crates.io
grep -E '^(name|version|description|license|repository)' Cargo.toml
# 3. Dry run publish
cargo publish --dry-run
发布到 crates.io 所需的 Cargo.toml 字段(缺少时无法发布):
name、version、description、license(或license-file)、repository
如果缺少字段:请补上这些字段、提交更改,然后继续。
发布到 crates.io:
# Check if already published at this version
CRATE_NAME=$(grep '^name' Cargo.toml | head -1 | sed 's/.*= *"//' | sed 's/".*//')
CRATE_VER=$(grep '^version' Cargo.toml | head -1 | sed 's/.*= *"//' | sed 's/".*//')
# Publish (requires `cargo login` — if not authenticated, note in report and skip)
cargo publish
如果发布失败:
already uploaded→ 该版本已存在,请在 Cargo.toml 中提升版本号not logged in→ 在报告中注明:“使用 crates.io API token 运行cargo login”dependency not on crates.io→ 检查 path/git 依赖,并替换为 crates.io 上的版本
二进制发布(可选,适用于 CLI 工具):
# Build release binary
cargo build --release
# Create GitHub release with binary attached
BINARY_NAME=$(grep '^name' Cargo.toml | head -1 | sed 's/.*= *"//' | sed 's/".*//')
gh release create "v${CRATE_VER}" --title "v${CRATE_VER}" --generate-notes \
"target/release/${BINARY_NAME}#${BINARY_NAME}-$(uname -s)-$(uname -m)"
验证 crates.io 上的 crate:
# Wait a few seconds for index to update, then check
curl -s "https://crates.io/api/v1/crates/${CRATE_NAME}/${CRATE_VER}" | head -100
第 5 步:验证部署
部署后,验证部署确实有效:
STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://{deployment-url})
BODY=$(curl -s https://{deployment-url} | head -200)
**如果 HTTP 状态码不是 200:**检查环境变量,修复问题后重新部署。有关特定平台的环境变量和错误解决命令,请参阅 references/platform-commands.md。
**在在线 URL 返回 HTTP 200 且页面无错误地加载之前,切勿输出 <solo:done/>。**如果无法修复问题,请输出 <solo:redo/>,返回构建阶段。仅当 .solo/states/ 目录存在时,才输出流水线信号。
第 6 步:部署后日志监控
确认 HTTP 200 后,持续查看生产环境日志,以发现运行时错误。有关特定平台的日志命令和需要留意的内容,请参阅 references/platform-commands.md。
日志出现错误时的处理方式:
- 缺少环境变量 → 使用平台 CLI 修复(参见第 3 步),然后重新部署
- 数据库连接错误 → 检查连接字符串和 IP 允许列表
- 运行时崩溃/未处理的错误 → 如果
.solo/states/存在,则输出<solo:redo/>,返回构建阶段并修复;否则,修复问题后重新部署 - 30 行日志中没有错误 → 继续生成报告
如果日志显示流量为零(刚部署),请发送几次测试请求:
curl -s https://{deployment-url}/ # homepage
curl -s https://{deployment-url}/api/health # API health (if exists)
然后重新检查日志,查看这些请求是否触发了任何错误。
第 7 步:部署后报告
Deployment: {project-name}
Platform: {platform}
URL: {deployment-url}
Branch: main
Commit: {sha}
Done:
- [x] Code pushed to GitHub
- [x] Deployed to {platform}
- [x] Database migrations applied (or N/A)
Manual steps remaining:
- [ ] Set environment variables (listed above)
- [ ] Custom domain (optional)
- [ ] PostHog / analytics setup (optional)
Next: /review — final quality gate
完成
发出完成信号
如果 .solo/states/ 目录存在,请输出以下精确标签,且仅输出一次——流水线会检测首次出现:
<solo:done/>
请勿在响应的其他位置重复该信号标签。只能出现一次。
如果 .solo/states/ 目录不存在,则跳过该信号标签。
错误处理
找不到 CLI
**原因:**未安装平台 CLI。
**解决方法:**安装相应的 CLI:npm i -g vercel、npm i -g wrangler、brew install supabase/tap/supabase。
部署失败 — 构建错误
**原因:**本地构建正常,但在平台上失败(Node 版本不同、缺少环境变量)。
**解决方法:**检查平台构建日志。确保 package.json 中的 engines 与平台要求一致。设置缺失的环境变量。
数据库连接失败
**原因:**未设置 DATABASE_URL,或网络规则阻止了连接。 **解决方法:**检查连接字符串、平台的数据库控制面板和 IP 允许列表。
Git 推送被拒绝
**原因:**远程分支已发生分歧。
**解决方法:**运行 git pull --rebase origin main,解决冲突后再次推送。
验证关卡
在报告“部署成功”之前:
- 运行
curl -s -o /dev/null -w "%{http_code}",对部署 URL 执行请求。 - 确认 HTTP 状态码为 200(而非 404、500 或重定向循环)。
- 检查实际页面内容是否符合预期(不是空白页面或错误页面)。
- 只有完成以上检查后,才能报告部署成功。
不要说“部署应该已经上线”——请验证它确实已上线。
流水线/自主模式
在流水线中运行时(--print,无人监看):
- 绝不调用 AskUserQuestion——不同迭代之间的响应会丢失,导致无限重试循环(曾观察到:OpenWok 部署浪费了 5 次迭代)
- 自主决定部署方式:
- 未安装部署 CLI → 如果可行,通过 brew/npm 安装;否则创建 Dockerfile + .dockerignore,推送代码,并标记为“Ready for manual deploy”
- 没有身份验证/凭据 → 创建所有部署配置,推送到 GitHub,写入包含身份验证说明的状态文件,并发出完成信号
- 有多个平台可选 → 按以下规则选择:堆栈 YAML > Next.js/React → Vercel,Python → Cloudflare Workers(MVP)或 Hetzner(生产环境),静态网站 → Cloudflare Pages
- 跳过阻塞项——浏览器登录、人工审批、缺少 API 密钥 → 在报告中注明并继续
- 始终发出完成信号——部分完成部署(已创建配置 + 已推送代码)也好过无限重试。即使实际部署需要手动完成身份验证步骤,也要输出
<solo:done/>。
关键规则
- 使用已安装的 CLI — 回退到
npx之前,先检测vercel、wrangler、supabase、fly和sst。 - 注意自动部署 — 如果平台会在推送代码时自动部署,只需推送即可。不要不必要地运行手动部署命令。
- 绝不提交机密 — 不要提交包含真实值的 .env 文件,也不要在代码中放入 API 密钥。
- 先预览,再部署到生产环境 — 先部署预览版本并进行验证,然后再推广到生产环境。
- 先在本地检查构建 — 部署前运行
pnpm build/uv build(或同等命令)。 - 检查生产环境日志 — 部署后始终跟踪日志,在宣布成功前捕获运行时错误。
- 报告所有 URL — 部署 URL 和平台控制面板链接。
- 将基础设施配置保存在代码仓库中 — 优先使用
sst.config.ts或wrangler.toml,而不是手动配置控制面板。 - 验证后再宣称完成 — 确认线上 URL 返回 HTTP 200 且日志无错误,不能只凭“部署命令成功”。