Files
makelore/.opencode/skills/deploy-publish-check/SKILL.md
2026-07-29 17:22:35 +08:00

136 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: deploy-publish-check
description: 当 NianCode 发布部署角色检查学习者软件项目的构建准备、Docker 部署、项目 zip 打包、根目录 works-publish.json、部署与上传页面交接、发布步骤、回滚计划、作品广场提交准备和部署报告时使用。
---
# 部署发布检查
使用这个 skill判断学习者项目是否已经准备好通过 Docker 发布。
## 给学生看的说话规则
必须使用 `youth-plain-language`。讲 Docker、zip、上传接口时先说明它们在作品发布里分别做什么再给具体下一步。
## 工作流程
1. 确认发布目标,以及是否明确允许外部发布。
2. 检查代码、Demo、素材、宣传文案和构建命令。
3. 创建或维护 `Dockerfile`,确保项目可以构建为 Docker 镜像。
4. 创建或维护 `docker-compose.yml`,确保项目可以通过 Docker Compose 启动。
5. 检查 `niancode.yml` 使用 `runtime: compose`,并声明公开服务和 `8080` 端口;同时确认公开服务进程监听容器内 `0.0.0.0:8080`
6. 在合适时运行 Docker Compose 配置检查、构建、启动或冒烟检查。
7. 发布获准时,把当前项目打成 `.zip` 包,并检查 zip 根目录包含 `niancode.yml``docker-compose.yml` 和 compose 构建引用到的 Dockerfile。
8. 执行结构化机器检查manifest、Compose services/public service/端口/build context、volume、禁止的运行时安装/构建、Dockerfile 构建阶段、Node/Python 锁文件、Vite `base: "./"`、构建入口资源路径、浏览器存储降级、环境变量安全默认值、密钥/缓存/路径/大小/文件数量;游戏或画布项目额外检查根节点全屏和响应式画布布局。
9. 如果本机有 Docker运行 `docker compose config``build --pull=false``up -d`、动态端口检查、HTTP smoke、日志检查和清理解压到全新目录后再重复一遍。如果本机没有 Docker逐项写 `status: BLOCKED``execution: unavailable` 和原因,不要把未执行写成 PASS也不要要求用户去服务器接管。
10. 如果本机有浏览器,在不带 `allow-same-origin` 的 sandbox iframe 中执行浏览器 smoke任何白屏、未捕获 `SecurityError` 或启动失败都标为 BLOCKED。游戏或画布项目必须再执行桌面、移动和一次 resize/全屏变化 smoke检查主画布是否达到最大等比尺寸。浏览器不可用时同样写 `execution: unavailable`,不能伪造画布证据。
11. 在项目根目录创建或更新 `works-publish.json`,写清作品信息、版本信息和 zip 路径。
12. 在项目根目录创建 `works-deploy-check.json`,绑定当前 zip 的 SHA-256并用 `PASS``SKIPPED``BLOCKED` 记录所有必填机器检查项;真实执行成功写 PASS环境能力缺失写 SKIPPED或在明确云端交接时写 BLOCKED + `execution: unavailable`,确定性失败写 BLOCKED总状态按 `BLOCKED > SKIPPED > PASS` 聚合。
13.`works-publish.json``works-deploy-check.json` 和 zip 路径交给“部署与上传”页面读取;如果“构建产品”已登记 `works-cloud-deploy.json`,交给 Main 云端部署协调器,它会在静态复核通过和登录态有效时自动调用 Works Square 远端构建接口;如果没有登录态,记录下一步。
14. 准备发布步骤和回滚步骤。
15. 产出部署报告。
## 发布保护规则
- 在发布目标和权限明确前,不要判定为可发布。
- 必须使用 Docker 部署。不能把本地开发服务器、直接打开 HTML 文件或手工命令当作最终部署方式。
- 使用最新构建、冒烟检查、预览或文件检查作为证据。
- 记录准确命令和观察结果。
- 检查密钥、私有路径、个人数据或未完成占位内容。
- 缺少 `Dockerfile``docker-compose.yml` 时,不能判定为可发布;应先创建或要求补齐这两个文件。
- 交给 Main 的云端部署协调器提交时,`.zip` 包必须在根目录包含 `niancode.yml``docker-compose.yml`,并包含 compose 构建引用到的 `Dockerfile` 或其它 Dockerfile。
- zip 根目录必须直接包含 `niancode.yml``docker-compose.yml`,不能是 `project/niancode.yml` 或其它外层目录套壳。
- 最小 `niancode.yml` 必须声明 `runtime: compose``compose.file: docker-compose.yml``compose.public_service``compose.public_port: 8080`
- `docker-compose.yml` 的公开服务必须发布容器端口 `8080`,服务进程必须监听 `0.0.0.0:8080`,并使用 `127.0.0.1::8080` 动态宿主机端口;固定宿主机端口和非 loopback 发布都不能判定为可发布。
- 不能只准备 `Dockerfile`。作品广场 builder 和 runner 会按 Docker Compose 路径构建、启动和清理项目。
- 所有服务禁止 bind mount、Docker socket、`privileged`、host network、host pid、host ipc 和固定宿主机端口;只允许顶层声明的命名卷保存运行数据。
- Compose `command` / `entrypoint` 不得安装依赖、同步依赖或构建项目;这些动作必须写在 Dockerfile 的 build 阶段。
- Compose 只能使用非敏感环境变量或 `${NAME:-safe-default}` 安全默认值;不得依赖宿主机未明确注入的业务变量,不得使用 `env_file: .env`。真实 `.env*` 文件全部排除,`.env.example` 只允许无敏感示例。
- 如果项目是游戏或画布项目,`html``body``#app`/`#game-container` 必须占满 iframePhaser 使用 `FIT`/`CENTER_BOTH` 或等价缩放,其他引擎必须在 viewport/全屏变化后重新布局;桌面或移动任一实际 canvas 尺寸比最大等比预期小超过 5% 就是 BLOCKED。
- 实际成功才写 `PASS`;仅因当前环境没有 Docker、Playwright、Puppeteer 或浏览器自动化而未执行时写 `SKIPPED`,或在明确云端交接时写 `BLOCKED` + `execution: unavailable`,保留原命令和缺失能力;命令执行失败或项目检查发现问题写 `BLOCKED``SKIPPED` 允许上传但必须提示未验证风险;云端模式只能把明确 unavailable 的动态检查交给 Works Square 远端复核。
- 上传文件名必须以 `.zip` 结尾zip 原始大小最大 `50MB`,解压后总大小最大 `200MB`,文件数量最大 `2000`
- 打包时默认排除 `.git/``node_modules/``.venv/``venv/``.next/cache/``.pytest_cache/`、真实 `.env`、证书、私钥和无关本地构建产物。
- 缺少项目根目录 `works-publish.json`、缺少必填字段或 `zip_file_path` 不是 `.zip` 时,不能判定为可发布。
- 缺少 zip 包路径或项目根目录 `works-publish.json` 时,不能判定为可交接;应先打包并写好交接文件。
- 缺少 `works-deploy-check.json`、schema 不支持、zip SHA-256 不匹配、静态检查失败或任一确定性必填 check 为 `BLOCKED`,不能判定为可交接;仅环境能力缺失的 `SKIPPED` 或明确 unavailable 可交接但必须提示风险并交给云端复核。
- Works Square 远端提交失败、缺少访问令牌或缺少登录态时,不要宣称发布完成;保留交接文件,记录 `waiting_for_login`/`failed` 和原因Main 会在登录态恢复后继续。
- 发布部署角色负责准备 zip 包、`works-publish.json``works-deploy-check.json`“部署与上传”页面的“构建产品”负责明确授权一次云端提交Main 负责正式提交不要要求用户手动填写字段、SSH 或服务器。
- 标记为可发布前,必须包含回滚或恢复步骤。
## 云端部署与交接规则
- “部署与上传”页面的“构建产品”按钮会登记一次 `works-cloud-deploy.json` 云端部署意图页面只展示状态Main 负责正式提交。
- “远程上传”在本项目中特指 Works Square 后端 HTTP 上传接口,不是 SSH、SFTP、rsync 或自备服务器部署。
- Main 会通过受控边界先确保项目元数据存在,再调用上游接口:`POST /api/projects/{appId}/versions/upload`
- Agent 不接触 `accessToken`,不能在 shell、聊天或报告中打印令牌。
- `works-cloud-deploy.json``submitted` 只表示远端已接受并返回 `version_id``queued``building``reviewing` 都不等于已公开。
- 不要询问 SSH 主机、用户名、端口或目标路径。
- 如果没有云端部署意图,完成文件后说明需要从“部署与上传”页面点击“构建产品”授权一次提交;如果暂时没有登录态,保留交接文件并等待 Main 自动重试,不要让用户去服务器接管。
## 根目录发布信息文件
- 打包完成后,必须在项目根目录创建或更新 `works-publish.json`
- 文件必须是 JSON 对象,字段包括:`app_id``title``summary``category``age_band``difficulty``version_name``change_log``zip_file_path`
- `zip_file_path` 必须指向已经生成的 `.zip` 包。
- Main 云端部署协调器读取 `works-publish.json`;页面仍可展示文件内容和历史版本,但不再让用户手动填写这些字段。
- `works-publish.json` 是桌面页面交接文件,不是服务端校验 zip 的必填项,也不替代 zip 根目录的 `niancode.yml``docker-compose.yml`
- 不要要求用户手动填写这些字段;部署工程师要根据项目事实和交付物写入文件。
- 缺少 `works-publish.json`、缺少必填字段或 `zip_file_path` 不是 `.zip` 时,不能云端交接。
## zip 包结构和安全检查
- 创建 zip 时,让项目根目录内容直接进入 zip 根目录;不要把整个项目目录再包一层,不能是 `project/niancode.yml`
- 重新打开 zip检查根目录是否直接存在 `niancode.yml``docker-compose.yml`
- 检查 zip 是否包含 Compose build context 实际需要的源码、资源、锁文件和 Dockerfile。
- 检查 zip 是否排除了真实密钥、本地依赖目录、缓存目录、符号链接、绝对路径、`..` 路径和不安全 volume / build 路径。
## 必须输出
返回部署报告,包含:
1. 发布目标
2. 是否允许发布
3. 准备情况
4. `Dockerfile` 路径和关键内容说明
5. `docker-compose.yml` 路径、服务名和端口映射
6. `niancode.yml` 路径和 `runtime: compose` / 公开服务 / `8080` 端口说明
7. Docker Compose 配置、构建、启动和检查命令结果
8. Compose 包结构检查zip 根目录、外层目录、build context、Dockerfile、排除项、大小和文件数量
9. 项目根目录 `works-publish.json` 路径和关键字段
10. 程序包 zip 路径
11. `works-cloud-deploy.json` 路径、当前状态、version_id/review_status如已返回和 Main 自动提交说明
12. 发布步骤
13. 回滚步骤
14. 作品广场提交清单(页面会读取的字段)
15. 游戏/画布适用时的逻辑分辨率、桌面/移动 viewport、实际 canvas、最大等比预期和 resize 复测
16. 阻塞项
## 纠偏清单
出现这些情况时纠偏:
- 发布目标不清楚,但要求发布。
- 缺少构建/测试状态。
- 宣传素材没有准备好。
- 可能暴露密钥、私有路径或不安全文件。
- 上传包缺少 `niancode.yml``docker-compose.yml`、compose 构建引用到的 Dockerfile 或清晰 zip 路径。
- zip 根目录没有直接包含 `niancode.yml``docker-compose.yml`,或者把项目套成 `project/niancode.yml` 时,不能判定为可发布。
- `works-deploy-check.json` 必须把 `compose_config``compose_build``compose_up``container_port``http_smoke``fresh_directory_smoke``sandbox_browser_smoke` 逐项写清楚;每项要有 `status``detail``command`,动态项还要有 `execution: executed``execution: unavailable`。本机环境不可用时写 BLOCKED + unavailable不得伪造 PASS存在云端部署意图时由 Main cloud 模式继续提交前复核。
- 游戏或画布项目必须额外写 `game_canvas_smoke`;只有浏览器真实执行成功才提供 `canvas_evidence.logical_resolution``desktop_viewport``mobile_viewport``desktop_canvas``mobile_canvas``expected_max_canvas``resize_verified`。浏览器不可用时写 BLOCKED + `execution: unavailable`,普通网站不需要伪造此项。
- 缺少 `Dockerfile``docker-compose.yml` 时,不能判定为可发布。
- `niancode.yml` 仍使用 `runtime: docker` 或没有声明 `compose.public_service` / `compose.public_port: 8080` 时,不能判定为可发布。
- `docker-compose.yml` 没有公开服务、没有发布容器端口 `8080`、写死宿主机端口,或不是 `127.0.0.1::8080` 这类 loopback 动态映射时,不能判定为可发布。
- 容器内服务没有监听 `0.0.0.0:8080`,或 Compose 依赖未明确注入的宿主机环境变量、真实 `.env*``env_file: .env` 时,不能判定为可发布;`${NAME:-safe-default}` 才是允许的安全默认形式。
- 游戏或画布项目根节点没有占满 iframe、主画布固定在逻辑分辨率、缺少响应式缩放/resize 重新布局、桌面或移动 canvas 比最大等比预期小超过 5%,或缺少 `game_canvas_smoke` 真实证据时,不能判定为可发布。
- 缺少项目根目录 `works-publish.json`、缺少必填字段或 `zip_file_path` 不合法时,不能判定为可发布。
- 缺少 zip 包路径或项目根目录 `works-publish.json` 时,不能判定为可交接。
- 没有说明 Main 如何读取交接文件并自动提交,或远端提交失败但报告里没有失败原因。
- zip 包超过大小/文件数量限制或者包含真实密钥、本地依赖目录、缓存目录、不安全路径、符号链接、Docker socket、host network / privileged 配置时,不能判定为可发布。
- 没有 Docker 构建、Docker Compose 启动或等价检查证据时,必须明确写 unavailable/阻塞原因;不能把缺少证据说成 PASS。
- 没有回滚或恢复说明。
没有明确许可和清晰目标时,不要对外发布。
## 交接
如果被阻塞,把准确缺失项交回负责角色。如果已准备好,提供最终发布说明和证据。