修复后端构建提交号注入
This commit is contained in:
@@ -4,16 +4,16 @@
|
|||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 最近更新 | 2026-07-21 |
|
| 最近更新 | 2026-07-21 |
|
||||||
| 当前分支 | `feature/huangting` |
|
| 当前分支 | `feature/huangting` |
|
||||||
| 当前阶段 | M002 V4 入站、多卡模型、持久化基线、入站写入、查询接口、卡片确认、复核解阻、目录校验、订单详情 V4 总览、DB 目录、Lookup API、前端 lookup 接入、目录管理后台 CP1 前后端、订单列表 V4 继续处理入口 / open count 收口、V4 业务审计查询、停止旧任务双写、Debug EML V4 profile 对齐、Room Information 后端展示模型与前端业务化展示、V4 任务详情 smoke 修复、Rooming List 确认自动 DEF 后端联动、Room Information 复核 pointer 与任务详情安全边界修复、Room Information 复核 pointer 运行时规则收口、复核 pointer 部署证明与运行时 trace、Account + booking type 过滤 Rate Code 文档口径、Payment 附件预览文档口径、Rooming List 事项确认卡文档口径,以及 V4 复核态卡片交互和字段白名单文档口径 |
|
| 当前阶段 | M002 V4 入站、多卡模型、持久化基线、入站写入、查询接口、卡片确认、复核解阻、目录校验、订单详情 V4 总览、DB 目录、Lookup API、前端 lookup 接入、目录管理后台 CP1 前后端、订单列表 V4 继续处理入口 / open count 收口、V4 业务审计查询、停止旧任务双写、Debug EML V4 profile 对齐、Room Information 后端展示模型与前端业务化展示、V4 任务详情 smoke 修复、Rooming List 确认自动 DEF 后端联动、Room Information 复核 pointer 与任务详情安全边界修复、Room Information 复核 pointer 运行时规则收口、复核 pointer 部署证明与运行时 trace、部署包 build commit 注入收口、Account + booking type 过滤 Rate Code 文档口径、Payment 附件预览文档口径、Rooming List 事项确认卡文档口径,以及 V4 复核态卡片交互和字段白名单文档口径 |
|
||||||
| 当前重点 | M002 V4 已停止普通业务入站双写旧 `workflow_reservation_task`,V4 后新业务主线只写 V4 order task / cards / source notification;Debug EML V4 smoke 默认复用实时 AgentBus V4 Open API subject,避免误走历史 Debug V2/V3 profile。开发阶段不维护 V2/V3 旧任务兼容,测试数据可重建,生产迁移策略后续上线前单独设计。`GET /api/reservation/orders` 可返回 V4 下一步订单任务、卡片、动作类型、动作状态、V4 open 数和统一展示字段 `open_work_item_count`;旧 `open_task_count` / `next_processable_task_id` 仅作历史诊断兼容。Room Information 已完成后端稳定展示模型和前端业务化展示:`GET /api/reservation/order-tasks/{orderTaskId}` 在 `display_payload.room_information` 返回 New / Update / Cancel 的 `current_values`、`proposed_values`、`final_values`、`change_summary[]`,前端只消费该展示模型和 `fields[]`,不再从 Agent raw payload、`business_fields` 或 `target_order` 自行推导;如果卡片 payload 已经是稳定 `room_information.final_values` 结构,后端会按稳定模型归一化查询和复核;Nights、Breakfast 和 Group Booking Status 均以后端派生值为准;确认和复核写入稳定 `confirmed_payload_json.room_information.final_values`,不回写 Agent 原始 `target_order`、Adult、邮件正文或附件 URL;接口对前端暴露的 `fields[].write_target` 使用 `confirmed_payload` / `review_resolution.field_overrides` 这类安全语义,不暴露内部列名;查询侧 `fields[].editable` 和命令侧 `review-resolution` 复核 pointer 校验已共用同一套 Room Information 字段策略。测试机部署证明已补齐:`GET /api/health` 返回 `runtime_marker`、`build_commit`、`build_time`、`build_version`,启动日志也输出同一组非敏感字段;复核 pointer 拒绝前会记录 `review_pointer_policy=m002_v4_review_pointer_runtime_trace_v1`,包含 order task、card、incoming pointer、query-side editable pointers、command-side allowed pointers 和 reject reason,但不记录 payload、邮件正文或附件 URL。V4 任务详情 smoke 修复已完成:页面顺序固定为 Basic Information、业务卡、SourceMessage Display;来源邮件卡位于页面底部,只通过 SourceMessage conversation 接口定位当前触发邮件并默认折叠正文;Basic Information 和普通业务卡的展示 / 确认 payload 不再返回 Agent `target_order`,普通业务卡还会移除邮件 HTML、raw evidence、附件原始 URL 和 PMS 原始响应等敏感字段。Rooming List 卡确认时已实现 Group 自动置 `DEF`:如同订单存在可更新的已确认 Room Information 快照,后端会覆盖其 `group_booking_status=DEF` 并写 `V4_ROOMING_LIST_AUTO_DEF` 审计;刷新任务详情时 `display_payload` 和 `confirmed_payload` 均以 DEF 后的确认快照为准;当前订单详情 `order_overview` 不返回 Group Booking Status 字段;如没有可更新投影,Rooming List 确认仍成功,只写安全审计提示,不临时创建不完整 Room Information。已确认 Rate Code 下一阶段按 Reservation Account + `booking_type`(GROUP / FIT)过滤和校验,不按全酒店 Rate Code 全量展示;已确认 Payment 卡展示付款凭证附件时,`attachment_ids[]` 第一版只读,前端只展示并确认卡片,不增删或替换附件集合,图片在卡片内显示缩略图并点击大图预览,非图片统一文件列表 + 下载,附件外链仍走 SourceMessage 原文权限链路;已确认 Rooming List 任务卡第一版只做事项确认,不做名单解析、附件预览、Excel 生成或 PMS 导入,用户点击“确认卡片”表示已人工处理该 Rooming List 事项;已确认 `REVIEW_REQUIRED` 仍是原业务卡复核态,页面按钮统一叫“确认卡片”,复核态允许编辑当前卡 `fields[]` 白名单内业务字段,问题字段红字提示。后续可继续做测试机 V4 smoke 复测、Rooming List 前端轻量卡展示、Payment 附件预览、Account 范围 Rate Code lookup、真实 PMS / OPERA / OHIP 同步或 SuperAgent 目录供给方案。 |
|
| 当前重点 | M002 V4 已停止普通业务入站双写旧 `workflow_reservation_task`,V4 后新业务主线只写 V4 order task / cards / source notification;Debug EML V4 smoke 默认复用实时 AgentBus V4 Open API subject,避免误走历史 Debug V2/V3 profile。开发阶段不维护 V2/V3 旧任务兼容,测试数据可重建,生产迁移策略后续上线前单独设计。`GET /api/reservation/orders` 可返回 V4 下一步订单任务、卡片、动作类型、动作状态、V4 open 数和统一展示字段 `open_work_item_count`;旧 `open_task_count` / `next_processable_task_id` 仅作历史诊断兼容。Room Information 已完成后端稳定展示模型和前端业务化展示:`GET /api/reservation/order-tasks/{orderTaskId}` 在 `display_payload.room_information` 返回 New / Update / Cancel 的 `current_values`、`proposed_values`、`final_values`、`change_summary[]`,前端只消费该展示模型和 `fields[]`,不再从 Agent raw payload、`business_fields` 或 `target_order` 自行推导;如果卡片 payload 已经是稳定 `room_information.final_values` 结构,后端会按稳定模型归一化查询和复核;Nights、Breakfast 和 Group Booking Status 均以后端派生值为准;确认和复核写入稳定 `confirmed_payload_json.room_information.final_values`,不回写 Agent 原始 `target_order`、Adult、邮件正文或附件 URL;接口对前端暴露的 `fields[].write_target` 使用 `confirmed_payload` / `review_resolution.field_overrides` 这类安全语义,不暴露内部列名;查询侧 `fields[].editable` 和命令侧 `review-resolution` 复核 pointer 校验已共用同一套 Room Information 字段策略。测试机部署证明已补齐:`GET /api/health` 返回 `runtime_marker`、`build_commit`、`build_time`、`build_version`,启动日志也输出同一组非敏感字段;复核 pointer 拒绝前会记录 `review_pointer_policy=m002_v4_review_pointer_runtime_trace_v1`,包含 order task、card、incoming pointer、query-side editable pointers、command-side allowed pointers 和 reject reason,但不记录 payload、邮件正文或附件 URL。V4 任务详情 smoke 修复已完成:页面顺序固定为 Basic Information、业务卡、SourceMessage Display;来源邮件卡位于页面底部,只通过 SourceMessage conversation 接口定位当前触发邮件并默认折叠正文;Basic Information 和普通业务卡的展示 / 确认 payload 不再返回 Agent `target_order`,普通业务卡还会移除邮件 HTML、raw evidence、附件原始 URL 和 PMS 原始响应等敏感字段。Rooming List 卡确认时已实现 Group 自动置 `DEF`:如同订单存在可更新的已确认 Room Information 快照,后端会覆盖其 `group_booking_status=DEF` 并写 `V4_ROOMING_LIST_AUTO_DEF` 审计;刷新任务详情时 `display_payload` 和 `confirmed_payload` 均以 DEF 后的确认快照为准;当前订单详情 `order_overview` 不返回 Group Booking Status 字段;如没有可更新投影,Rooming List 确认仍成功,只写安全审计提示,不临时创建不完整 Room Information。已确认 Rate Code 下一阶段按 Reservation Account + `booking_type`(GROUP / FIT)过滤和校验,不按全酒店 Rate Code 全量展示;已确认 Payment 卡展示付款凭证附件时,`attachment_ids[]` 第一版只读,前端只展示并确认卡片,不增删或替换附件集合,图片在卡片内显示缩略图并点击大图预览,非图片统一文件列表 + 下载,附件外链仍走 SourceMessage 原文权限链路;已确认 Rooming List 任务卡第一版只做事项确认,不做名单解析、附件预览、Excel 生成或 PMS 导入,用户点击“确认卡片”表示已人工处理该 Rooming List 事项;已确认 `REVIEW_REQUIRED` 仍是原业务卡复核态,页面按钮统一叫“确认卡片”,复核态允许编辑当前卡 `fields[]` 白名单内业务字段,问题字段红字提示。后续可继续做测试机 V4 smoke 复测、Rooming List 前端轻量卡展示、Payment 附件预览、Account 范围 Rate Code lookup、真实 PMS / OPERA / OHIP 同步或 SuperAgent 目录供给方案。 |
|
||||||
|
|
||||||
## 1. 当前 Checkpoint
|
## 1. 当前 Checkpoint
|
||||||
|
|
||||||
- 名称:`M002-V4-review-pointer-deployment-proof-and-runtime-trace`
|
- 名称:`M002-V4-build-commit-injection-fix`
|
||||||
- 状态:Backend Done,已补齐部署证明字段和复核 pointer 拒绝前安全 trace。
|
- 状态:In Progress,正在收口部署包 build commit 注入和 package fail-fast。
|
||||||
- 目标:先通过 `/api/health` 和启动日志证明测试机运行包版本,再在确实进入新代码路径但仍拒绝时,用安全日志对比 query-side editable pointers 与 command-side allowed pointers。
|
- 目标:让测试机 / UAT / 生产 Jar 必须从干净 Git 工作区打包,且 Jar 内嵌 build-info 中的 `build.commit` 必须是真实 Git commit;`GET /api/health` 的 `build_commit=UNKNOWN` 不能再作为可部署包产物出现。
|
||||||
- 边界:本 checkpoint 不做 Payment 附件预览、不做 Rate Code lookup、不做 PMS / OPERA / OHIP、不推进 M011。
|
- 边界:本 checkpoint 不做 Payment 附件预览、不做 Rate Code lookup、不做 PMS / OPERA / OHIP、不推进 M011。
|
||||||
- 联调备注:Source conversation 接口仍是带 `SOURCE_MESSAGE_ORIGINAL_READ` 的原文权限接口,可返回 `html_body` 和 `html_body_sanitized`;V4 task detail 本身不得返回 raw HTML。若测试机仍出现 `V4_REVIEW_POINTER_NOT_ALLOWED`,先访问 `/api/health` 确认 `build_commit` 是否为预期提交;`build_commit` 优先来自 Jar 内嵌 build-info,不能仅靠运行时环境变量证明代码包已更新;本次修复必须先提交后再用新 HEAD 打包,不能把未提交工作区代码标记为旧提交;再检索日志 `review_pointer_policy=m002_v4_review_pointer_runtime_trace_v1`。没有 health build 字段或没有该 marker,优先按部署包未更新 / 未进入新代码路径处理,不继续改业务逻辑。
|
- 联调备注:Source conversation 接口仍是带 `SOURCE_MESSAGE_ORIGINAL_READ` 的原文权限接口,可返回 `html_body` 和 `html_body_sanitized`;V4 task detail 本身不得返回 raw HTML。若测试机仍出现 `V4_REVIEW_POINTER_NOT_ALLOWED`,先访问 `/api/health` 确认 `build_commit` 是否为预期提交;`build_commit` 优先来自 Jar 内嵌 build-info,不能仅靠运行时环境变量证明代码包已更新;本次修复必须先提交后再用新 HEAD 打包,推荐使用 `scripts/package-server-with-build-info.sh`,不能把未提交工作区代码标记为旧提交;再检索日志 `review_pointer_policy=m002_v4_review_pointer_runtime_trace_v1`。没有 health build 字段、`build_commit=UNKNOWN` 或没有该 marker,优先按部署包未更新 / 未进入新代码路径处理,不继续改业务逻辑。
|
||||||
|
|
||||||
## 2. 当前优先级
|
## 2. 当前优先级
|
||||||
|
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -41,16 +41,24 @@ docs/
|
|||||||
```bash
|
```bash
|
||||||
cd server
|
cd server
|
||||||
./mvnw test
|
./mvnw test
|
||||||
./mvnw verify
|
TH_HOTEL_BUILD_COMMIT=$(git rev-parse --short HEAD) ./mvnw verify
|
||||||
./mvnw spring-boot:run
|
./mvnw spring-boot:run
|
||||||
```
|
```
|
||||||
|
|
||||||
中文说明:
|
中文说明:
|
||||||
|
|
||||||
- `./mvnw test`:运行后端单元测试和 Spring 集成测试。
|
- `./mvnw test`:运行后端单元测试和 Spring 集成测试。
|
||||||
- `./mvnw verify`:运行 Maven verify 阶段,用于提交前完整检查。
|
- `TH_HOTEL_BUILD_COMMIT=$(git rev-parse --short HEAD) ./mvnw verify`:运行 Maven verify 阶段,用于部署级完整检查;该命令会要求当前 Git 提交真实存在且工作区干净。
|
||||||
- `./mvnw spring-boot:run`:本地启动后端服务,默认端口为 `8080`。
|
- `./mvnw spring-boot:run`:本地启动后端服务,默认端口为 `8080`。
|
||||||
|
|
||||||
|
后端部署包必须写入真实 Git commit,不能生成 `build_commit=UNKNOWN` 的 Jar。测试机 / UAT / 生产打包统一使用:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
scripts/package-server-with-build-info.sh -DskipTests
|
||||||
|
```
|
||||||
|
|
||||||
|
中文说明:该脚本会要求 Git 工作区干净,从当前 `HEAD` 解析 commit,设置 `TH_HOTEL_BUILD_COMMIT` 后执行 `server` 打包,并检查 `target/classes/META-INF/build-info.properties` 中的 `build.commit`。直接执行 `cd server && ./mvnw package` / `./mvnw verify` 时,如果没有提供真实 commit 或工作区不干净,也会在 `prepare-package` 阶段失败,避免部署包在 `/api/health` 中返回 `build_commit=UNKNOWN`。
|
||||||
|
|
||||||
## 前端命令
|
## 前端命令
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -130,6 +138,8 @@ GET /api/health
|
|||||||
|
|
||||||
返回后端最小健康状态,用于本地开发、部署探活和前端连通性验证。
|
返回后端最小健康状态,用于本地开发、部署探活和前端连通性验证。
|
||||||
|
|
||||||
|
部署验证时必须检查 `build_commit` 是否为本次部署 commit,`UNKNOWN` 只表示本地测试或未生成 build-info,不能作为测试机 / UAT 已部署证明。
|
||||||
|
|
||||||
## M001 SourceMessage Inbox
|
## M001 SourceMessage Inbox
|
||||||
|
|
||||||
当前实现 checkpoint 聚焦:
|
当前实现 checkpoint 聚焦:
|
||||||
|
|||||||
@@ -334,9 +334,11 @@ INTERNAL_ONLY
|
|||||||
```bash
|
```bash
|
||||||
cd server
|
cd server
|
||||||
./mvnw test
|
./mvnw test
|
||||||
./mvnw verify
|
TH_HOTEL_BUILD_COMMIT=$(git rev-parse --short HEAD) ./mvnw verify
|
||||||
```
|
```
|
||||||
|
|
||||||
|
中文说明:`./mvnw test` 用于日常开发和普通回归;`verify` 会进入部署包生命周期,必须提供真实 `TH_HOTEL_BUILD_COMMIT` 且 Git 工作区干净,否则会在 `prepare-package` 阶段失败。测试机 / UAT / 生产打包优先使用仓库根目录的 `scripts/package-server-with-build-info.sh`。
|
||||||
|
|
||||||
聚焦开发时可先运行相关测试:
|
聚焦开发时可先运行相关测试:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -377,4 +379,4 @@ cd server
|
|||||||
- [ ] 是否没有提交真实 Secret 或客户数据?
|
- [ ] 是否没有提交真实 Secret 或客户数据?
|
||||||
- [ ] 是否没有把 Provider 输出直接当业务事实?
|
- [ ] 是否没有把 Provider 输出直接当业务事实?
|
||||||
- [ ] 是否运行了 `./mvnw test` 或说明了无法运行原因?
|
- [ ] 是否运行了 `./mvnw test` 或说明了无法运行原因?
|
||||||
- [ ] 是否运行了 `./mvnw verify` 或说明了无法运行原因?
|
- [ ] 是否在干净工作区运行了带 `TH_HOTEL_BUILD_COMMIT` 的 `./mvnw verify`,或说明了无法运行原因?
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
上线前至少确认以下事项:
|
上线前至少确认以下事项:
|
||||||
|
|
||||||
- 当前分支、提交和部署包来源清楚,不能混入本地临时文件、真实 Secret、真实客户邮件样本或构建产物;测试机 / UAT 构建包必须在本次代码提交后再打包,且能通过 `GET /api/health` 的 `build_commit` 证明当前运行提交。
|
- 当前分支、提交和部署包来源清楚,不能混入本地临时文件、真实 Secret、真实客户邮件样本或构建产物;测试机 / UAT 构建包必须在本次代码提交后再打包,且能通过 `GET /api/health` 的 `build_commit` 证明当前运行提交。
|
||||||
- `server` 后端通过完整检查:`cd server && ./mvnw verify`。
|
- `server` 后端通过完整检查:在干净 Git 工作区执行 `cd server && TH_HOTEL_BUILD_COMMIT=$(git rev-parse --short HEAD) ./mvnw verify`,或使用仓库根目录 `scripts/package-server-with-build-info.sh` 生成部署包。
|
||||||
- 生产或 UAT 数据库已经备份,并确认 Flyway migration 只新增不修改历史脚本。
|
- 生产或 UAT 数据库已经备份,并确认 Flyway migration 只新增不修改历史脚本。
|
||||||
- 所有 Secret 都通过环境变量、部署平台 Secret 或密钥管理系统注入,不写入仓库、镜像、前端环境变量或普通配置文件。
|
- 所有 Secret 都通过环境变量、部署平台 Secret 或密钥管理系统注入,不写入仓库、镜像、前端环境变量或普通配置文件。
|
||||||
- 生产默认不保存 AgentBus raw frame 样本。
|
- 生产默认不保存 AgentBus raw frame 样本。
|
||||||
@@ -63,12 +63,13 @@
|
|||||||
|
|
||||||
| 变量 | 是否 Secret | 上线注意事项 |
|
| 变量 | 是否 Secret | 上线注意事项 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `TH_HOTEL_BUILD_COMMIT` | 否 | 构建包时设置为已提交后的当前 Git commit,例如 `TH_HOTEL_BUILD_COMMIT=$(git rev-parse --short HEAD) ./mvnw clean package`;该值会写入 Jar 内嵌 build-info,`/api/health` 返回内嵌值;未设置时 `/api/health` 返回 `build_commit=UNKNOWN`,不能作为“已部署指定提交”的证明。不要用未提交工作区代码打包后仍标记旧 HEAD,否则 build commit 只能证明旧提交,不能证明本次修复。 |
|
| `TH_HOTEL_BUILD_COMMIT` | 否 | 构建包时必须设置为已提交后的当前 Git commit;推荐在仓库根目录执行 `scripts/package-server-with-build-info.sh -DskipTests`,由脚本自动从干净工作区的 `HEAD` 注入。该值会写入 Jar 内嵌 build-info,`/api/health` 返回内嵌值;未设置或不是有效 Git commit 时,`server` 的 `package` / `verify` 会在打包前失败,不允许继续产出 `build_commit=UNKNOWN` 的部署包。不要用未提交工作区代码打包后仍标记旧 HEAD,否则 build commit 只能证明旧提交,不能证明本次修复。 |
|
||||||
|
|
||||||
说明:
|
说明:
|
||||||
|
|
||||||
- `GET /api/health` 会返回 `runtime_marker`、`build_commit`、`build_time`、`build_version`,这些字段不包含 Secret,只用于部署排查;`build_commit` 应以构建阶段写入 Jar 的 build-info 为准,不把运行时临时环境变量或未提交工作区状态当作已部署代码证明。
|
- `GET /api/health` 会返回 `runtime_marker`、`build_commit`、`build_time`、`build_version`,这些字段不包含 Secret,只用于部署排查;`build_commit` 应以构建阶段写入 Jar 的 build-info 为准,不把运行时临时环境变量或未提交工作区状态当作已部署代码证明。
|
||||||
- 应用启动日志也会输出同一组 build info;如果测试机接口不可访问,可先看启动日志确认运行包。
|
- 应用启动日志也会输出同一组 build info;如果测试机接口不可访问,可先看启动日志确认运行包。
|
||||||
|
- 测试机 / UAT / 生产 Jar 必须从干净 Git 工作区打包;当前 POM 会在 `prepare-package` 阶段校验 `TH_HOTEL_BUILD_COMMIT` 是否是有效 Git commit,并校验工作区是否干净。工作区 dirty、CI 没有 Git 提交信息或人工忘记注入 commit 时,打包应直接失败并重新走标准打包流程。
|
||||||
- 如果 `build_commit` 不是预期提交,先修部署或重新打包,不要继续改业务逻辑。
|
- 如果 `build_commit` 不是预期提交,先修部署或重新打包,不要继续改业务逻辑。
|
||||||
|
|
||||||
### 3.1 数据库
|
### 3.1 数据库
|
||||||
|
|||||||
30
scripts/package-server-with-build-info.sh
Executable file
30
scripts/package-server-with-build-info.sh
Executable file
@@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
cd "$repo_root"
|
||||||
|
|
||||||
|
git update-index -q --refresh
|
||||||
|
if [[ -n "$(git status --porcelain)" ]]; then
|
||||||
|
echo "ERROR: Git worktree is not clean. Commit or stash changes before packaging a deployment-proof Jar." >&2
|
||||||
|
git status --short >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
build_commit="$(git rev-parse --short HEAD 2>/dev/null || true)"
|
||||||
|
if [[ -z "$build_commit" || "$build_commit" == "UNKNOWN" ]]; then
|
||||||
|
echo "ERROR: Cannot resolve current Git commit for TH_HOTEL_BUILD_COMMIT." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Packaging TH Hotel backend with TH_HOTEL_BUILD_COMMIT=$build_commit"
|
||||||
|
cd "$repo_root/server"
|
||||||
|
TH_HOTEL_BUILD_COMMIT="$build_commit" ./mvnw clean package "$@"
|
||||||
|
|
||||||
|
build_info_file="$repo_root/server/target/classes/META-INF/build-info.properties"
|
||||||
|
if ! grep -q "^build.commit=$build_commit$" "$build_info_file"; then
|
||||||
|
echo "ERROR: build-info verification failed. Expected build.commit=$build_commit in $build_info_file." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Build proof OK: build.commit=$build_commit"
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
<angus-mail.version>2.0.3</angus-mail.version>
|
<angus-mail.version>2.0.3</angus-mail.version>
|
||||||
<aliyun-oss.version>3.18.3</aliyun-oss.version>
|
<aliyun-oss.version>3.18.3</aliyun-oss.version>
|
||||||
<apache-poi.version>5.4.1</apache-poi.version>
|
<apache-poi.version>5.4.1</apache-poi.version>
|
||||||
|
<maven-antrun-plugin.version>1.8</maven-antrun-plugin.version>
|
||||||
<th.hotel.build.commit>UNKNOWN</th.hotel.build.commit>
|
<th.hotel.build.commit>UNKNOWN</th.hotel.build.commit>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
@@ -125,6 +126,51 @@
|
|||||||
<parameters>${maven.compiler.parameters}</parameters>
|
<parameters>${maven.compiler.parameters}</parameters>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
|
<version>${maven-antrun-plugin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>verify-build-commit-before-package</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>run</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<target name="verify-build-commit-before-package">
|
||||||
|
<condition property="th.hotel.build.commit.unknown">
|
||||||
|
<equals arg1="${th.hotel.build.commit}" arg2="UNKNOWN"/>
|
||||||
|
</condition>
|
||||||
|
<fail if="th.hotel.build.commit.unknown"
|
||||||
|
message="TH_HOTEL_BUILD_COMMIT is required before packaging. Commit changes first, then use scripts/package-server-with-build-info.sh or set TH_HOTEL_BUILD_COMMIT to the current Git commit."/>
|
||||||
|
<exec executable="git" failonerror="true">
|
||||||
|
<arg value="rev-parse"/>
|
||||||
|
<arg value="--verify"/>
|
||||||
|
<arg value="--quiet"/>
|
||||||
|
<arg value="${th.hotel.build.commit}^{commit}"/>
|
||||||
|
</exec>
|
||||||
|
<exec executable="git" failonerror="true">
|
||||||
|
<arg value="update-index"/>
|
||||||
|
<arg value="-q"/>
|
||||||
|
<arg value="--refresh"/>
|
||||||
|
</exec>
|
||||||
|
<exec executable="git" failonerror="true" outputproperty="th.hotel.git.status">
|
||||||
|
<arg value="status"/>
|
||||||
|
<arg value="--porcelain"/>
|
||||||
|
</exec>
|
||||||
|
<condition property="th.hotel.git.dirty">
|
||||||
|
<not>
|
||||||
|
<equals arg1="${th.hotel.git.status}" arg2=""/>
|
||||||
|
</not>
|
||||||
|
</condition>
|
||||||
|
<fail if="th.hotel.git.dirty"
|
||||||
|
message="Git worktree must be clean before packaging a deployment-proof Jar. Commit or stash changes first. Dirty entries: ${th.hotel.git.status}"/>
|
||||||
|
</target>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user