14 KiB
14 KiB
name, description
| name | description |
|---|---|
| deploy-publish-check | 当 NianCode 发布部署角色检查学习者软件项目的构建准备、Docker 部署、项目 zip 打包、根目录 works-publish.json、部署与上传页面交接、发布步骤、回滚计划、作品广场提交准备和部署报告时使用。 |
部署发布检查
使用这个 skill,判断学习者项目是否已经准备好通过 Docker 发布。
给学生看的说话规则
必须使用 youth-plain-language。讲 Docker、zip、上传接口时,先说明它们在作品发布里分别做什么,再给具体下一步。
工作流程
- 确认发布目标,以及是否明确允许外部发布。
- 检查代码、Demo、素材、宣传文案和构建命令。
- 创建或维护
Dockerfile,确保项目可以构建为 Docker 镜像。 - 创建或维护
docker-compose.yml,确保项目可以通过 Docker Compose 启动。 - 检查
niancode.yml使用runtime: compose,并声明公开服务和8080端口;同时确认公开服务进程监听容器内0.0.0.0:8080。 - 在合适时运行 Docker Compose 配置检查、构建、启动或冒烟检查。
- 发布获准时,把当前项目打成
.zip包,并检查 zip 根目录包含niancode.yml、docker-compose.yml和 compose 构建引用到的 Dockerfile。 - 执行结构化机器检查:manifest、Compose services/public service/端口/build context、volume、禁止的运行时安装/构建、Dockerfile 构建阶段、Node/Python 锁文件、Vite
base: "./"、构建入口资源路径、浏览器存储降级、环境变量安全默认值、密钥/缓存/路径/大小/文件数量;游戏或画布项目额外检查根节点全屏和响应式画布布局。 - 如果本机有 Docker,运行
docker compose config、build --pull=false、up -d、动态端口检查、HTTP smoke、日志检查和清理;解压到全新目录后再重复一遍。如果本机没有 Docker,逐项写status: BLOCKED、execution: unavailable和原因,不要把未执行写成 PASS,也不要要求用户去服务器接管。 - 如果本机有浏览器,在不带
allow-same-origin的 sandbox iframe 中执行浏览器 smoke;任何白屏、未捕获SecurityError或启动失败都标为 BLOCKED。游戏或画布项目必须再执行桌面、移动和一次 resize/全屏变化 smoke,检查主画布是否达到最大等比尺寸。浏览器不可用时同样写execution: unavailable,不能伪造画布证据。 - 在项目根目录创建或更新
works-publish.json,写清作品信息、版本信息和 zip 路径。 - 在项目根目录创建
works-deploy-check.json,绑定当前 zip 的 SHA-256,并用PASS、SKIPPED、BLOCKED记录所有必填机器检查项;真实执行成功写 PASS,环境能力缺失写 SKIPPED,或在明确云端交接时写 BLOCKED +execution: unavailable,确定性失败写 BLOCKED;总状态按BLOCKED > SKIPPED > PASS聚合。 - 把
works-publish.json、works-deploy-check.json和 zip 路径交给“部署与上传”页面读取;如果“构建产品”已登记works-cloud-deploy.json,交给 Main 云端部署协调器,它会在静态复核通过和登录态有效时自动调用 Works Square 远端构建接口;如果没有登录态,记录下一步。 - 准备发布步骤和回滚步骤。
- 产出部署报告。
发布保护规则
- 在发布目标和权限明确前,不要判定为可发布。
- 必须使用 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必须占满 iframe,Phaser 使用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 路径。
必须输出
返回部署报告,包含:
- 发布目标
- 是否允许发布
- 准备情况
Dockerfile路径和关键内容说明docker-compose.yml路径、服务名和端口映射niancode.yml路径和runtime: compose/ 公开服务 /8080端口说明- Docker Compose 配置、构建、启动和检查命令结果
- Compose 包结构检查:zip 根目录、外层目录、build context、Dockerfile、排除项、大小和文件数量
- 项目根目录
works-publish.json路径和关键字段 - 程序包 zip 路径
works-cloud-deploy.json路径、当前状态、version_id/review_status(如已返回)和 Main 自动提交说明- 发布步骤
- 回滚步骤
- 作品广场提交清单(页面会读取的字段)
- 游戏/画布适用时的逻辑分辨率、桌面/移动 viewport、实际 canvas、最大等比预期和 resize 复测
- 阻塞项
纠偏清单
出现这些情况时纠偏:
- 发布目标不清楚,但要求发布。
- 缺少构建/测试状态。
- 宣传素材没有准备好。
- 可能暴露密钥、私有路径或不安全文件。
- 上传包缺少
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。
- 没有回滚或恢复说明。
没有明确许可和清晰目标时,不要对外发布。
交接
如果被阻塞,把准确缺失项交回负责角色。如果已准备好,提供最终发布说明和证据。