Appearance
源码交付与版本控制
本文定义 OARS 面向客户源码交付时的版本控制、客户二开、升级合并、交付验收和回滚闭环。源码插件只是扩展边界之一,客户拿到完整项目源码并自行二开时,也必须按本文执行。
总体原则
源码交付的核心目标是让每一次客户交付都能回答四个问题:
- 客户当前运行版本来自哪个 OARS 产品基线。
- 客户自己或项目组改过哪些代码。
- 厂商发布新版本后如何合并到客户版本。
- 出现问题时如何定位、回退源码和处理数据库。
因此不能只给客户一份源码压缩包。正式交付必须同时包含 Git 历史、版本标签、迁移脚本、构建产物、变更说明和升级策略。
仓库模型
源码交付建议使用“双远端”或“私有 fork”模型。
text
厂商产品仓库 upstream/oars
├── main
├── release/1.4
└── tag: oars-v1.4.0
客户交付仓库 customer/acme-oars
├── main
├── customer/acme/dev
├── customer/acme/release
└── tag: acme-oars-v1.0.0角色边界:
| 仓库 | 维护方 | 用途 |
|---|---|---|
| 产品仓库 | OARS 产品团队 | 标准产品开发、产品 release、通用缺陷修复 |
| 客户交付仓库 | 交付团队或客户联合维护 | 客户源码、客户配置、二开功能、交付 tag |
| 客户现场仓库 | 客户自管时可选 | 客户内部二开、现场补丁、部署审计 |
客户需要自行二开时,优先给客户私有 fork,不建议让客户直接提交到产品仓库。产品仓库通过 release tag 向客户仓库提供升级基线,客户仓库通过补丁或 PR 向产品仓库回传可复用改动。
分支与标签
推荐分支:
| 层级 | 版本对象 | 管理方式 |
|---|---|---|
| 产品基线 | OARS 标准产品源码、数据库迁移、前端构建 | 使用产品 release 分支和 Git tag 标记,例如 oars-v1.4.0 |
| 客户交付 | 客户项目源码、配置、初始化数据、交付包 | 使用客户分支、私有 fork 或交付仓库管理,例如 customer/acme/main |
| 客户开发 | 客户或项目组正在二开的代码 | 使用 customer/<code>/dev 或 feature 分支管理 |
| 客户发布 | 已验收待部署代码 | 使用 customer/<code>/release 和客户 tag 管理 |
产品主线只承载标准产品能力。客户特性优先放在扩展边界内;确需修改产品核心时,应形成补丁记录,并评估是否合入产品主线。
推荐流转:
text
main
|
+-- release/1.4
|
+-- tag: oars-v1.4.0
|
+-- customer/acme/main
|
+-- tag: customer-acme-v1.0.0规则:
main面向产品持续开发。release/x.y只接受稳定修复和明确纳入版本的变更。customer/<code>/main保存客户源码交付状态。customer/<code>/dev承载客户二开和现场联调。customer/<code>/release承载已验收的待交付版本。- 每次正式交付必须打客户 tag,tag 对应源码、SQL、构建产物和交付说明。
- 不允许用未提交工作区作为客户交付依据。
客户 tag 建议格式:
text
<customer>-oars-v<major>.<minor>.<patch>示例:acme-oars-v1.0.0、acme-oars-v1.1.0-hotfix.1。
二开边界
客户二开分为三类,管理要求不同:
| 类型 | 推荐位置 | 升级影响 | 管理要求 |
|---|---|---|---|
| 配置类二开 | 数据字典、系统配置、菜单、流程模板、表单模板 | 低 | 导出配置快照,随交付说明归档 |
| 扩展类二开 | oars-plugins/、com.oars.plugins.*、src/plugins/* | 中 | 独立插件、独立 SQL、独立版本 |
| 核心改动 | oars-java、oars-web 标准模块原文件 | 高 | 必须登记补丁,优先回合产品主线 |
客户可以二开,但必须遵守以下规则:
- 不直接修改已发布 tag。
- 不在产品 release 分支上直接开发客户功能。
- 客户核心改动必须有 issue、commit、说明和验收记录。
- 可复用修复以 PR 形式回传产品仓库;客户专属逻辑留在客户仓库。
- 客户自行修改核心代码后,后续升级冲突由客户分支合并流程处理,不能覆盖产品新版本。
客户二开闭环
客户二开按以下流程跑通:
text
产品 release tag
-> 创建/更新客户分支
-> 客户二开 feature 分支
-> 代码评审和自动化检查
-> 合并到 customer/<code>/dev
-> 客户验收
-> 合并到 customer/<code>/release
-> 打客户 tag
-> 构建交付包
-> 部署和回归每个客户二开需求至少保留:
- 需求编号或变更单。
- 涉及模块和文件范围。
- 数据库脚本。
- 配置变更。
- 测试记录。
- 是否可回合产品主线。
- 对后续产品升级的影响判断。
厂商向客户升级交付
产品发布新版本后,客户升级不是重新覆盖源码,而是合并产品基线:
bash
git remote add upstream <oars-product-repo>
git fetch upstream --tags
git checkout customer/acme/dev
git merge oars-v1.5.0合并后按以下顺序处理:
- 解决客户二开与产品新版本的冲突。
- 检查核心补丁是否已被产品主线吸收。
- 重跑后端、前端、数据库迁移和关键业务测试。
- 追加客户升级 SQL,不修改已执行脚本。
- 客户验收后合并到
customer/<code>/release。 - 打客户升级 tag,例如
acme-oars-v1.1.0。
禁止直接把产品新版本源码覆盖到客户仓库。覆盖会丢失客户二开历史,也无法解释冲突来源。
升级操作模板
客户仓库已经配置产品仓库为 upstream 时,升级操作按以下顺序执行:
bash
git fetch upstream --tags
git checkout customer/acme/dev
git merge oars-v1.5.0冲突解决后提交升级合并:
bash
git status
git add <resolved-files>
git commit验收通过后进入客户发布分支并打 tag:
bash
git checkout customer/acme/release
git merge customer/acme/dev
git tag acme-oars-v1.1.0交付归档至少记录:
git rev-parse HEADgit diff oars-v1.5.0..HEAD --stat- 数据库脚本清单
- 客户二开补丁清单
- 自动化检查结果
- 客户验收记录
客户向厂商回传改动
客户二开中可复用的缺陷修复或通用能力,应从客户仓库提取为独立补丁:
text
customer/acme/dev
-> cherry-pick 或 format-patch
-> 产品仓库 feature/fix-xxx
-> 产品评审
-> 合入 main/release回传前需要剥离:
- 客户名称、客户数据、专属流程。
- 客户环境地址、账号、密钥。
- 只适用于客户现场的临时兼容逻辑。
回传后,客户分支后续升级时优先使用产品主线版本,减少长期 patch。
交付包内容
每次客户源码交付至少包含:
| 内容 | 说明 |
|---|---|
| Git tag | 客户交付 tag |
| 源码仓库 | 包含完整提交历史或可审计镜像 |
| 构建产物 | 后端包、前端 dist、镜像或部署包 |
| 数据库脚本 | 产品 Flyway、客户 SQL、插件 SQL |
| 配置模板 | application-*.yml 模板、环境变量清单 |
| 发布说明 | 产品基线、客户变更、已知限制、升级步骤 |
| 回滚方案 | 源码回退 tag、数据库备份恢复或前向修复策略 |
| 验收记录 | 自动化检查、关键业务流程、客户确认 |
源码压缩包只能作为辅助交付物,不能替代 Git tag 和客户仓库。
源码插件交付边界
源码插件模式的标准目录如下:
text
oars-plugins/<pluginKey>/
├── delivery/
│ └── <module>.delivery.json
├── modules/
│ └── <module>.json
└── sql/
├── <module>.install.sql
├── <module>.uninstall.sql
└── upgrade/
└── README.md
oars-java/oars-app/src/main/java/com/oars/plugins/<pluginKey>/
oars-web/apps/web-antd/src/plugins/<pluginKey>/源码插件内的业务代码、SQL、manifest 和 delivery descriptor 都必须提交到 Git。交付时不只交付生成后的 Java/Vue 文件,还要保留 ModuleSpec、manifest、交付描述文件和 SQL。
交付描述文件
源码插件生成器会生成两个交付元数据文件:
| 文件 | 作用 |
|---|---|
oars-plugins/<pluginKey>/modules/<module>.json | 插件模块清单,记录模块、插件、菜单、表、文件和发布信息 |
oars-plugins/<pluginKey>/delivery/<module>.delivery.json | 客户交付描述,记录产品基线、Git commit、生成器版本、Spec 哈希、SQL 和源码边界 |
交付描述文件中的关键字段:
| 字段 | 说明 |
|---|---|
base.gitCommit | 生成时的 OARS 源码 commit |
base.oarsVersion | 产品基线版本或 release tag |
plugin.version | 插件版本 |
module.version | 模块版本 |
spec.sourceSpecHash | ModuleSpec 的 SHA-256 哈希 |
sql.install | 安装 SQL |
sql.uninstall | 停用 SQL |
sql.upgradeDirectory | 后续升级 SQL 目录 |
正式交付前,交付负责人需要确认 base.gitDirty=false,或在交付说明中列明未提交变更原因。标准交付不应使用脏工作区。
生成命令
源码插件生成时可以传入交付版本信息:
bash
node oars-tools/src/cli/index.js create:module \
--spec ./expense.module.json \
--source-mode plugin \
--plugin-key acme-expense \
--plugin-version 1.0.0 \
--module-version 1.0.0 \
--base-oars-version oars-v1.4.0 \
--customer-code acme生成后执行交付检查:
bash
node oars-tools/src/cli/index.js plugin:delivery-check \
--manifest oars-plugins/acme-expense/modules/expense.json检查项包括:
- manifest 类型、版本、插件版本、模块版本完整;
- delivery descriptor 存在且 Spec 哈希一致;
- manifest 声明的生成文件仍存在于仓库内;
- 产品基线、Git commit、生成器版本可追溯。
数据库升级规则
产品核心数据库变更仍使用 oars-java/oars-migration/src/main/resources/db/migration 下的 Flyway 脚本。
客户二开数据库变更按以下规则处理:
- 产品通用表结构变化进入产品 Flyway。
- 客户专属表结构变化进入客户分支 SQL 目录或源码插件
sql/upgrade/。 - 源码插件初次交付使用
<module>.install.sql。 - 源码插件停用入口使用
<module>.uninstall.sql,默认不删除业务数据表。 - 已在客户环境执行的 SQL 不允许修改,只能追加前向升级脚本。
- 客户私有数据修复脚本应与产品通用升级脚本分开。
生产回滚不依赖修改已执行 SQL。数据库回滚通过备份恢复或前向修复脚本处理。
交付验收清单
正式交付前完成以下检查:
- 产品基线 tag 或 commit 已确认。
- 客户分支已提交所有源码、SQL、配置模板和文档。
- 客户二开补丁清单已归档,核心改动已标记是否回合产品主线。
- 如包含源码插件,
plugin:delivery-check通过。 - 数据库安装和升级 SQL 已在空库或基线库验证。
- 后端、前端、移动端和关键业务流程已验证。
- 菜单、按钮权限、移动端入口和流程绑定已验收。
- 客户 tag、构建产物、数据库脚本、发布说明和回滚方案已归档。
升级流程
客户项目升级时按以下顺序执行:
- 将产品新 release 合并到客户分支。
- 解决客户补丁和插件代码冲突。
- 判断客户核心补丁是否已被产品主线吸收。
- 对源码插件执行必要的
ModuleSpec升版或手工二开。 - 追加客户升级 SQL,不修改已执行脚本。
- 运行后端、前端、移动端和关键业务检查;如包含源码插件,运行
plugin:delivery-check。 - 生成客户升级 tag 和升级说明。
回滚边界
源码回滚可以回退到上一客户 tag 后重新部署。数据库回滚不能直接删除 Flyway、客户 SQL 或插件已执行记录;生产环境应优先使用备份恢复,或补前向修复脚本。
plugin:remove 只删除生成文件或停用运行时入口,不等同于业务数据回滚,也不删除客户业务表。
