Skip to content

部署断链:合入 main 的改动不会到达线上 #384

Description

@johnnyzhang-eng

现象

合进 main 的改动到不了线上。

线上跑的是哪个提交,没有任何记录可查。

唯一的 Release 是 v0.1.0(08-17 09:57 UTC),之后没有再发过;而线上代码在这之后至少变过一次。08-18 16:40 有人重建了生产容器,线上 GET /api/openapi.json 从 25 条路径变成 30 条。这次部署没有对应的 Release、没有 tag、没有记录,事后只能靠比对接口形状反推它大概来自哪一版。

判据与实测:main 与那条集成分支的 quota 路由数分别是 4 与 5,且 action_preset.py 只在集成分支上。线上实测 quota 4 条、无 action-preset 端点,所以这次部署来自 main。这个结论是逐个端点比出来的,不是查出来的 —— 而部署本该是可查的。

原因

部署为手工执行,且源码不来自 main

服务器上只有一个源码目录 /root/windup-test,生产容器 windup-backend 与测试容器 windup-test-backend 都从它构建。该目录当前 HEAD 是 5998c27,属于一条集成分支而非 main。生产镜像的构建时间是 08-18 05:07。

/root 下有三十余个手写部署脚本(fe.sh fe2.sh fe3.sh final.sh final2.sh final3.sh final4.sh verify.sh verify2.sh vfy.sh 等),命名带序号,说明每次部署都是一次手工试错。

因此:合并到 main 不产生任何部署动作;除非有人手工进服务器 git pull 再重建,改动不会到达用户。

影响

已在生产库观测到的后果:

  • character_action 任务 completed 49 / failed 11 / running 3,其中 3 条自 08-13、08-14 起卡在 running,无终态无 error_message。用户界面表现为一直等待。
  • 11 条失败里 3 条是 缺少母版:reference_image_urls 为空 —— 提交时不拦、执行阶段才炸。该拦截的实现已完成但未提交。
  • 3 条 522/525 网关错误。fix(providers): 52x 重发按预算封顶 #297 已修重试判据,线上跑的是修复前的版本。

方案

#334 第四节「部署只认 Release」建立自动发布链:

阶段 触发 动作
发版 main 上 CI 全绿 按 Conventional Commits 计算下一版本号,打 Tag,生成 Release notes
部署 Release 发布 SSH 到服务器,从 Tag 检出到独立目录,构建并切换容器
校验 部署完成 拉线上 openapi.json 与该 Tag 的 openapi.json 比对,不一致则回滚

生产与测试的源码目录必须分开:生产只从 Tag 检出,测试可以继续跟集成分支。

不包含

验收

  • main 合入后无需人工介入即可产生新 Release
  • 线上 openapi.json 与最新 Release 的 openapi.json 逐字节一致
  • 生产源码目录的 HEAD 恒等于某个 Tag,不指向任何分支

补充(2026-08-18):自动化写过一次,因缺 Secrets 停摆

.github/workflows/deploy.yml 存在过,在分支 feat/workflow-run(提交 9ad72d5)上,触发模型是 PR 创建/更新 → 预览环境、PR 合并到 main → 正式环境。2026-08-10 跑过一次(run 31360873959)结论 failure,之后这个文件不在 main、也不在任何现存分支上。那次运行日志已过期,无法确认具体报错。

文件头部注明需要五个 Secrets:DEPLOY_HOSTDEPLOY_USERDEPLOY_SSH_KEYDEPLOY_PATHDEPLOY_PORT。仓库 Actions Secrets 里目前只有 CODECOV_TOKEN

所以缺口分两半:

一、五个 Secrets 需要有 admin 权限的人配置。 服务器凭证不在 Issue 里流转。

二、workflow 重新落到 main 时触发要换成消费 Release。 原版按 PR 合并触发,与本 Issue 第四节「部署只认 Release」冲突:PR 合并那一刻还没经过发版这道关。改成 release: [published] 后与 #387 接成一条链——main 过 CI → 发 Release → 部署该 Release 的 tag。第二步不需要 admin。

预览环境(原版的 deploy-preview)先不做:它要按 PR 号起多套环境,与正式部署是两件事。

Metadata

Metadata

Labels

No labels
No labels

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions