Skip to content

Latest commit

 

History

History
404 lines (288 loc) · 14.3 KB

File metadata and controls

404 lines (288 loc) · 14.3 KB

LearnSite 团队开发协作规范

1. 目标与适用范围

本文档用于统一 LearnSite 仓库的日常开发、提测、合并、发布与文档更新方式。

适用范围:

  • 仓库内的页面开发、后端逻辑、数据库升级、前端资源、测试与发布脚本
  • 团队成员的日常开发分支、提交记录、代码评审和版本发布

原则:

  • 小步提交,避免一次性混入多类改动
  • 先验证再合并,避免把问题带入 devmain
  • 文档与代码一起维护,确保变更可以被追溯
  • 优先兼容现有部署方式,尤其是数据库升级、静态资源、本地化部署和离线场景

2. 分支约定

推荐使用以下分支策略:

  • main:稳定发布分支,只接受已验证完成、可发布的改动
  • dev:日常集成分支,功能开发先合入此分支
  • feature/<name>:新功能分支,例如 feature/ai-exam-summary
  • fix/<name>:普通问题修复分支,例如 fix/survey-null-check
  • hotfix/<name>:线上紧急修复分支,例如 hotfix/login-error
  • release/<name>:大版本发布整理分支,按需使用,例如 release/2026-04

分支流转建议:

  • 日常开发:feature/*fix/* 基于 dev 创建,完成后合回 dev
  • 发版准备:从 dev 整理后合入 main
  • 紧急修复:hotfix/* 基于 main 创建,修复后同时回合 maindev

限制:

  • 非紧急情况不要直接向 main 提交代码
  • 一个分支只解决一类问题,不要同时处理功能、重构和样式清理
  • 长周期分支要定期同步基线,减少一次性大冲突

3. Git 提交约定

3.1 提交格式

统一使用如下格式:

type(scope): 简要说明

说明:

  • type 使用英文小写
  • scope 可选,表示影响范围,如 teacherstudentdbupgradedocs
  • 简要说明 建议使用中文,直接写清“本次改动解决了什么问题”

示例:

feat(teacher): 新增问卷设置中心入口和保存逻辑
fix(upgrade): 修复空库初始化时数据库握手失败问题
refactor(db): 抽取数据库初始化公共帮助类
docs(changelog): 补充 2026-04-07 更新日志
test(student): 为测验评估流程补充单元测试
chore(ci): 调整 dev 分支自动测试流程

3.2 type 类型

推荐使用以下类型:

  • feat:新功能
  • fix:缺陷修复
  • refactor:重构,不改变对外行为
  • perf:性能优化
  • docs:文档修改
  • test:测试新增或调整
  • build:构建、打包、发布脚本调整
  • ci:CI 工作流调整
  • chore:杂项维护,不属于以上分类
  • revert:回滚某次提交

3.3 提交内容要求

  • 一次提交只做一件事,保持原子性
  • 提交前先自查,避免把临时代码、调试输出、无关格式化混入提交
  • 不要把无关文件一起提交,例如本次只改 teacher 页面,却顺手带上大量其他目录格式化修改
  • 涉及数据库结构、升级页、配置文件、发布脚本时,提交说明必须明确写清风险点
  • 修改后文件需要保证编码格式为 UTF-8,避免中文乱码

不推荐的提交示例:

update
修改一下
fix bug
最终版

3.4 Issue 链接绑定

当改动是为了修复或解决某个具体 issue 时,必须在提交信息中包含 issue 链接,以建立代码变更与问题追踪的关联。

格式要求

  • 在提交说明末尾添加 (#issue编号) 或完整的 issue URL
  • 如果修复的是多个 issue,可添加多个链接

推荐示例

fix(student): 修复 ScoreConfig 命名空间歧义引用问题 (#IJE25T)
fix(student): 修复 ScoreConfig 命名空间歧义引用问题 (https://gitee.com/nylon26/openlearnsite/issues/IJE25T)
feat(teacher): 新增测验 AI 评估摘要展示 (#IJE123, #IJE456)

绑定作用

  • 自动关联 issue,方便团队追踪问题解决进度
  • 在 Gitee 上会自动显示提交与 issue 的关联关系
  • 便于后续追溯问题修复历史

4. Pull Request 与合并约定

PR 标题建议与最终 squash commit 保持一致,例如:

feat(student): 新增测验 AI 评估摘要展示

PR 描述至少包含以下内容:

  • 背景:为什么要改
  • 范围:改了哪些模块或页面
  • 风险:是否影响数据库、配置、升级流程、静态资源、本地部署
  • 验证:本地执行了哪些测试或人工验证
  • 截图:涉及 UI 变更时提供前后截图

合并前检查:

  • 已解决 review 意见
  • 已同步目标分支最新代码并处理冲突
  • 已更新必要文档,包括 CHANGELOG.md
  • 已完成最低限度验证

建议:

  • 默认使用 squash merge,保持主干提交历史清晰
  • 大功能如果需要保留开发过程,可使用 merge commit,但要提前说明

5. CHANGELOG 写法约定

仓库根目录已存在 CHANGELOG.md,后续沿用当前格式,不改写风格。

5.1 更新时间点

以下情况必须更新 CHANGELOG.md

  • 用户可感知的新功能
  • 实际缺陷修复
  • 升级流程、数据库迁移、部署方式变化
  • 明显影响维护成本、性能、安全性的改动

以下情况通常不单独写入:

  • 纯注释修改
  • 不影响行为的小范围格式整理
  • 临时调试代码

5.2 结构格式

按日期追加,格式如下:

## YYYY-MM-DD

### 新功能
- **标题**:具体说明

### 问题修复
- **标题**:具体说明

### 升级增强
- **标题**:具体说明

### 涉及文件
- 模块分组:`文件1``文件2`

约定:

  • 日期使用 YYYY-MM-DD
  • 分类顺序固定为:新功能问题修复升级增强涉及文件
  • 没有内容的分类可以省略,不要硬凑
  • 每条内容先写一个加粗短标题,再写具体变化和价值
  • 优先写“为什么值得记录”,不要只写“改了某个文件”

5.3 写作要求

  • 面向团队和发布阅读者,避免只有作者自己能看懂的简称
  • 说明业务影响、兼容性变化、风险降低点或维护价值
  • 同类改动尽量合并描述,不要拆成很多碎条目
  • 涉及文件 用模块归类,不要求把每个小文件都列全,但要能帮助快速定位

推荐示例:

### 问题修复
- **课程删除流程空值保护**:补齐课程菜单删除时的空值判断,避免教师端在异常数据下出现未处理异常

不推荐示例:

### 问题修复
- 改了 teacher/courseshow.aspx.cs

6. Release Notes 写法约定

对外发布或阶段性版本整理时,新增单独发布说明文件:docs/releases/RELEASE_NOTES_YYYY-MM-DD.md

建议结构:

# 版本发布说明 - YYYY-MM-DD

## 概要
- 2 到 4 条本次最重要变化

## 重点更新
### 模块 A
- 说明

## 修复项
- 说明

## 重点变更区域
- 模块:`文件或目录`

适用场景:

  • 生成发布包
  • 发布 GitHub Release
  • 需要给测试、实施或学校管理员说明本次升级内容

要求:

  • CHANGELOG.md 偏内部持续记录
  • docs/releases/RELEASE_NOTES_*.md 偏一次发布的摘要说明
  • 两者内容可以相互提炼,但不要简单复制粘贴

7. 测试与验收约定

仓库当前已有统一脚本:run_tests.sh

常用命令:

./run_tests.sh
./run_tests.sh --no-e2e
./run_tests.sh --only-unit
./build_release.sh

本地验证最低要求:

  • 普通后端或前端改动:至少执行 ./run_tests.sh --no-e2e
  • 涉及页面交互、接口联调、升级流程或部署流程:应执行 ./run_tests.sh
  • 涉及发布内容:应额外执行 ./build_release.sh

手工验证建议:

  • 教师端页面改动:验证教师主流程是否正常
  • 学生端页面改动:验证移动端和桌面端基础布局
  • 数据库相关改动:验证新库初始化、旧库升级、空库场景
  • 静态资源改动:验证离线可用性和本地资源引用

如果暂时无法完成某项验证,必须在 PR 描述中明确说明未验证部分和原因。

8. 数据库与升级相关约定

以下改动属于高风险改动:

  • sql/ 下的结构脚本
  • upgrade.aspxmanager/dbupgrade.aspx 及其后台代码
  • App_Code/Utility/DbMigration.cs 与迁移链
  • 连接字符串、部署配置、初始化逻辑

处理要求:

  • 数据库结构改动必须考虑新装、空库和老库升级三种场景
  • 如引入新表、新字段或初始化数据,优先走明确的迁移路径
  • 不允许只在页面逻辑里假设“表一定存在”或“字段一定已有”
  • 升级说明要同步写入 CHANGELOG.md;必要时补充单独发布说明

9. 前端资源与页面改动约定

  • 优先复用仓库中的本地静态资源,减少对外部 CDN 的依赖
  • 页面改动要兼顾现有皮肤、母版页和旧页面兼容性
  • 不要在一次提交里同时做业务改动和大规模样式重写,除非该提交明确就是界面重构
  • 涉及学生端、教师端、管理端共用资源时,要验证是否产生全局回归

10. 代码风格与实现约定

  • 优先做最小正确修改,避免无必要的大重构
  • 没有明确收益时,不新增抽象层、不提前封装
  • 保留现有项目可运行方式,不随意替换技术栈或部署路径
  • 新增代码要可读,复杂逻辑可加简短注释说明意图
  • 不提交真实密钥、口令、数据库账号或学校敏感数据

11. 发布流程约定

当前对外发布仓库统一使用 https://gitee.com/nylon26/openlearnsiterelease.log 是系统当前版本号的唯一权威来源:服务端页面展示版本、 教师端/管理端在线更新检测、发布包内版本文件都以它为准。 仓库根目录的 update.json 是在线更新元数据契约,至少维护以下字段:

  • version:必须与 release.log 完全一致,继续使用单行 v1.6.1 这类格式
  • downloadUrl:优先填写稳定下载直链;如暂时没有稳定直链,必须明确回退到 release 页面,不能留空
  • htmlUrl:发布页地址,至少指向 https://gitee.com/nylon26/openlearnsite/releases
  • notes:更新说明摘要,可以为空字符串,但不能省略或写成占位提示
  • publishedAt:本次版本发布时间,建议使用 ISO 8601 UTC 字符串

结合当前仓库脚本与 CI,建议发布顺序如下:

  1. 功能分支合入 dev
  2. dev 完成集成测试与问题修复。
  3. 更新 CHANGELOG.md 与本次发布需要的说明文档。
  4. dev 合入 main
  5. 先同步维护仓库根目录的 release.logupdate.json
    • update.json.version 改成与本次版本完全一致;
    • update.json.downloadUrl 更新为稳定下载地址,若没有稳定直链则明确回退到 releases 页面;
    • update.json.htmlUrlnotespublishedAt 更新为本次发布内容。
  6. 执行 scripts/build_release.sh <版本号>RELEASE_VERSION=<版本号> scripts/build_release.sh。脚本会在打包前 强制写入 release.log,并校验 update.json.versionrelease.log 一致,避免远端版本、页面版本和下载入口再次漂移。
  7. 构建完成后,检查发布产物中的 release.logupdate.json 都非空, 且 update.json.versionrelease.log、本次发布版本完全一致。
  8. 访问教师端或管理端,确认页面显示版本来自 release.log,并验证在线 更新检测只读取以下 raw 文件:
    • https://gitee.com/nylon26/openlearnsite/raw/master/release.log
    • https://gitee.com/nylon26/openlearnsite/raw/master/update.json 同时确认远端版本更高时展示下载入口,字段缺失或网络失败时页面主流程不受影响。
  9. 生成对应 docs/releases/RELEASE_NOTES_YYYY-MM-DD.md
  10. 发布完成后,确认仓库中的 release.logupdate.json、发布页说明与 下载入口保持一致,不再依赖 Gitee release API 返回结构做页面解析。

补充说明:

  • dev 分支已有自动测试工作流,可作为日常集成检查基线。
  • main/master 关联发布构建与多环境验证,进入前要确保变更已稳定。
  • 不再使用旧仓库地址 aymwoo/openlearnsite,也不要保留“按需更新版本 文件”这类模糊流程说明。

11.1 如何判断当前实例是否是较新的 dev 分支版本

当你需要判断“当前运行的站点是不是本地 dev 分支上更近的源码版本”时, 先记住两条契约:

  • release.log 仍然是版本号唯一真值。
  • Git 分支与提交号只是附加元数据,只用于帮助区分“同版本号但来源不同”的实例。

具体判断方式如下:

  1. 如果站点运行在保留 .git 的源码工作区中,教师端和管理端版本区会额外显示 当前分支名与短提交号,例如 dev @ a1b2c3d
  2. 如果页面同时提示“当前为开发分支构建,远端比较仅代表发布线版本”,说明当前 实例来自 devfeature/*fix/* 等非发布分支;这时在线更新结果只能说明 master 发布线是否有更新,不能反推出你的本地 dev 一定更旧。
  3. 如果页面只显示 release.log 版本号,没有分支或提交信息,通常表示当前实例是 发布包、部署包,或运行目录里没有 .git。这种场景下不能仅凭页面反推出它是否 来自 dev。

静默降级要求:

  • .git 缺失、HEAD 异常、ref 文件不存在、packed-refs 读取失败时,页面必须继续 正常显示,只回退为仅展示 release.log 版本。
  • 不要把版本真值改回页面文案解析、远端 release API 或其他非 release.log 来源。

12. 建议的评审清单

代码评审时优先看以下问题:

  • 是否引入行为回归
  • 是否覆盖边界条件与空值场景
  • 是否影响数据库兼容性和升级路径
  • 是否修改了全局资源或公共母版页
  • 是否缺少测试、截图或升级说明
  • 是否需要更新 CHANGELOG.mddocs/releases/RELEASE_NOTES_*.md

13. 文档维护约定

  • 本文档位于仓库根目录:CONTRIBUTING.md
  • 当协作流程、测试方式、发布脚本、CI 或版本策略变化时,应同步更新本文档
  • 如团队后续需要,可继续拆分为:docs/release-process.mddocs/code-review-checklist.mddocs/db-migration-guide.md

推荐执行口径:

  • 日常开发看 CONTRIBUTING.md
  • 持续变更记录看 CHANGELOG.md
  • 单次发版说明看 docs/releases/RELEASE_NOTES_YYYY-MM-DD.md