Files
Telegram-Panel/docs/developer/release-process.md
2026-08-13 15:07:19 +08:00

153 lines
7.6 KiB
Markdown
Raw Permalink 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.
# 开发发布流程
本文档定义 Telegram Panel 从功能开发到主分支发布的唯一流程。目标是让 `dev` 成为可部署、可验收的集成环境,让 `main` 只接收已经完成云端验证的代码。
## 分支职责
- `main`:稳定主分支,生产镜像和正式文档从这里发布。
- `dev`:集成和云端测试分支,推送后构建 `ghcr.io/moeacgx/telegram-panel:dev-latest`
- `codex/<purpose>`:临时功能分支。完成合并后删除本地分支、远端分支和对应临时 worktree。
不使用历史版本分支、临时 merge 分支或长期个人分支承载发布状态。
## 标准流程
### 1. 开发与文档
开始前记录当前分支和工作区状态。重要改动必须同步开发文档,具体门禁见 [文档维护](documentation.md) 和根目录 `AGENTS.md`
提交前至少确认:
- 功能行为、API、配置和部署方式已经在对应文档中说明
- 文档写明前置条件、验证步骤、失败排查和回滚方式;
- 测试覆盖新增行为和关键回归场景;
- `mkdocs.yml` 已包含新增文档页面。
### 2. 合并到 `dev`
功能分支完成本地验证后,推送到远端并通过 PR 合并到 `dev`。没有云端验收结果时,不得合并到 `main`
当前仓库的 Docker 工作流 `.github/workflows/docker.yml``dev` 推送后会构建并推送:
```text
ghcr.io/moeacgx/telegram-panel:dev-latest
```
`dev` 默认只构建 `linux/amd64`,便于更快完成集成验证;正式 `main` 和 tag 构建多架构镜像。
### 3. 部署云端测试环境
在 GitHub Actions 手动运行 `Deploy Telegram Panel`,选择 `dev` 分支,镜像使用对应 `dev-latest` 或带 SHA 的不可变标签,并在 `update_mode` 中选择 `auto``image``binary`。工作流会:
1. 在云端 `/home/docker/Telegram-Panel` 拉取 `dev`
2. 备份 `docker-data` 中的 SQLite 数据文件;
3. 拉取镜像并保留 `docker-compose.warp.yml` 等 override
4. 重建 `telegram-panel` 容器;
5. 检查容器状态、最近日志、`/ui/dashboard``/api/panel/auth/me`
部署脚本会把选择的更新模式写入 `/data/update-mode.txt`,并比较镜像 `/app/version.txt``/api/panel/auth/me` 的实际运行版本;两者不一致时部署失败,避免工作流表面成功但容器仍运行旧的持久化程序。
入口脚本会比较镜像内的 `version.txt` 与持久化自更新目录 `/data/app-current/version.txt`
- 镜像版本更高时,优先启动镜像版本,并将旧的持久化程序目录归档为 `/data/app-obsolete-*`
- 持久化自更新版本更高时,继续优先使用已确认启动成功的自更新版本;
- 该比较同时适用于新版确认标记和旧版 `.telegram-panel-self-update` 标记,避免历史自更新目录永久遮住新镜像;
- 镜像包含 `version.txt` 但旧持久化包没有该文件时,将旧包视为未知旧版本并归档,使用镜像目录,避免 v1.31.37 及更早更新包永久遮住新镜像;
- 镜像也没有 `version.txt` 时保持旧兼容行为,仍按启动确认标记选择目录。
可通过 `.env``TP_UPDATE_MODE` 明确选择 `auto``image``binary`。该策略同时注入入口脚本和应用配置,避免 UI 显示的更新方式与容器实际启动目录不一致。
因此,升级 Docker 镜像后如果页面仍显示旧版本,应先查看容器日志中的版本选择记录和 `/data/app-obsolete-*`,确认是否存在旧自更新目录残留。
部署完成不等于验收完成。验收时还要实际操作本次改动涉及的页面、API、后台任务或代理链路并记录
- `dev` 提交 SHA 和实际镜像标签;
- 容器状态、启动日志和关键错误日志检查结果;
- 页面/API 的成功结果及关键响应;
- 数据持久化、重启恢复和权限边界检查结果;
- 失败时使用的回滚镜像或上一个可用提交。
若改动涉及 WARP 或其他代理管理能力,还要验证协议、容器网络、端口、账号绑定和重启后的状态恢复;不能只以 HTTP 健康检查作为通过依据。
### 4. 合并到 `main`
只有以下条件全部满足时,才创建或合并 `dev -> main` 的 PR
- 本地构建和测试通过;
- 文档门禁通过;
- Docker 镜像工作流成功;
- 云端部署成功;
- 本次功能验收有明确通过证据;
- 没有未处理的回滚、数据迁移或安全风险。
Docker PR 工作流必须覆盖会改变镜像内容或运行版本的路径;至少包括 `frontend/**`
`src/**``docker/**``Directory.Build.props`。如果相关 PR 没有出现 Docker 检查,
应先修复路径门禁并等待构建通过,不得把“未触发”视为“已通过”。
`main` 合并后会构建 `latest` 和多架构镜像;若需要正式版本,再按现有 Release 工作流创建 tag。正式发布不得反向替代 `dev` 验收。
创建正式 tag 前,必须先把 `Directory.Build.props` 中的 `Version``AssemblyVersion`
`FileVersion``InformationalVersion` 更新为目标版本。Docker tag 构建和 Release 工作流
都会校验 `vX.Y.Z` 与项目 `Version` 完全一致;不一致时应停止发布,禁止生成“文件名是新
版本、包内二进制仍显示旧版本”的资产。成功判据是 Release ZIP 内 `version.txt`、运行时
`/api/panel/auth/me` 和 tag 三者一致。回滚时删除尚未发布的错误 tag已经公开的错误版本
不得覆盖重发,应递增补丁版本重新发布。
Release 正文由 `.github/workflows/release.yml``Generate Chinese release notes` 步骤生成,不再直接使用 GitHub 默认的英文 `What's Changed`。生成规则:
- 正文顶部固定为 `## 本次版本主要更新`;变更列表在部署说明之前;
- 如果 release/squash 提交正文中包含 `## 本次版本主要更新` 小节,工作流会优先提取该小节内容,直到下一个二级标题为止,并为 `### 新增功能``### 修复问题``### 文档更新` 等已知分类标题补齐 emoji
- 如果提交正文没有该小节,工作流才回退到 commit 标题分类生成;
- conventional commit 类型会映射到带 emoji 的中文分类,如 `feat``✨ 新增功能``fix``🐛 修复问题``release``🚀 版本发布`
- 回退生成的列表项会去掉 `fix:``feat:` 等英文前缀,只保留中文或可读标题与短 SHA
- 底部保留 GitHub compare 链接,标题为 `🔗 完整变更记录`
发布 PR 的 squash 正文必须包含面向用户的 `## 本次版本主要更新` 小节,示例:
```markdown
## 本次版本主要更新
### ✨ 新增功能
- 账号导入时可以直接选择分类。
- 新增存储桶在线备份配置和立即备份入口。
## 验证
- Docker Build & Publish 通过。
- 云端部署验收通过。
```
提交信息仍建议写中文摘要,例如 `fix: 修复导入分类选择不生效`。如果提交标题是英文,工作流只能去掉类型前缀,不能可靠翻译业务含义;发布前应在 PR squash 标题或提交标题中改成中文。
### 5. 清理分支
合并确认后执行清理:
```powershell
git fetch --prune origin
git branch --merged dev
git branch --merged main
git push origin --delete <已合并的功能分支>
git branch -d <已合并的功能分支>
```
删除前逐个检查 worktree 和未推送提交。`main``dev`、当前正在使用的分支和包含唯一未合并提交的分支不得删除。临时 worktree 只能在确认没有用户改动后移除。
## 发布证据模板
```text
功能:
文档:
dev 提交:
镜像:
部署工作流:
容器状态:
健康检查:
功能验收:
回滚点:
main 合并:
分支清理:
```