# webhook-server **Repository Path**: duxvfeng/webhook-server ## Basic Information - **Project Name**: webhook-server - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-03 - **Last Updated**: 2026-07-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Webhook Server [English](README.md) 基于 Spring Boot 的 GitLab Push 事件 Webhook 服务,用于接收代码推送、触发通知,并自动生成/更新禅道周报任务中的日报描述。 ## 功能特性 - **接收 GitLab Push Webhook** - 校验 `X-Gitlab-Token` 密钥 - 按分支白名单过滤(默认允许 `main`、`master`、`release/*`) - 解析提交信息并持久化到本地 H2 数据库 - **通知分发** - 钉钉机器人 Markdown 通知(可选) - 禅道 `api-webhook` 通知(可选) - **周报与日报自动化** - 定时为每位已映射用户创建禅道周报任务 - 定时将本周内的 Push 事件汇总为日报描述,追加到对应周报任务 - 支持提交信息中的工时解析,自动汇总每日工时 - 提交信息润色:通过 Claude API 对 commit message 进行批处理,生成更干净的日报描述 - **管理后台** - 基于 Spring Security + Thymeleaf 的 Web 管理界面 - 维护 GitLab 用户名与禅道用户名的映射关系 - 路径:`/admin` ## 技术栈 | 技术 | 版本/说明 | |------|-----------| | Java | 17 | | Spring Boot | 3.2.5 | | Spring Security | 表单登录 + 角色控制 | | Thymeleaf | 管理后台页面 | | MyBatis | 数据持久层 | | H2 | 本地文件数据库(`./data/webhook-server`) | | Maven | 构建工具 | | Docker | 容器化部署(可选) | ## 项目结构 ```text src/main/java/com/example/webhookserver/ ├── WebhookServerApplication.java # 启动类 ├── config/ # 配置类与配置属性 ├── controller/ # Webhook API ├── filter/ # Secret Token / 分支过滤 ├── model/ # PushEvent、CommitInfo 等模型 ├── notifier/ # 钉钉、禅道通知器 ├── parser/ # GitLab Payload 解析器 ├── service/ # 核心业务逻辑 ├── storage/ # PushEvent 存储与 HTML 生成 ├── report/ # 日报/周报描述生成 ├── weekly/ # 周报任务调度与禅道交互 ├── admin/ # 管理后台 ├── zentao/ # 禅道 Token / 任务客户端 └── polish/ # Claude API 提交信息润色 ``` ## 快速开始 ### 1. 环境要求 - JDK 17+ - Maven 3.8+ - (可选)Docker 20.10+ ### 2. 本地运行 ```bash # 克隆项目 git clone cd webhook-server # 编译并测试 ./mvnw test # 启动应用(默认端口 15200) ./mvnw spring-boot:run ``` ### 3. 配置环境变量 生产环境**必须**覆盖以下默认值: ```bash export GITLAB_SECRET_TOKEN=your-secret-token export ADMIN_PASSWORD='$2a$10$...' # bcrypt 加密后的密码,默认 admin 仅供本地测试 export ZENTAO_BASE_URL=https://zentao.example.com export ZENTAO_USERNAME=your-zentao-username export ZENTAO_PASSWORD=your-zentao-password ``` ## 配置说明 所有配置集中在 `src/main/resources/application.yml`,可通过环境变量覆盖。 ### 服务与管理后台 | 配置项 | 环境变量 | 默认值 | 说明 | |--------|----------|--------|------| | `server.port` | `SERVER_PORT` | `15200` | HTTP 服务端口 | | `spring.security.user.name` | `ADMIN_USERNAME` | `admin` | 管理后台用户名 | | `spring.security.user.password` | `ADMIN_PASSWORD` | `admin`(bcrypt) | 管理后台密码 | | `spring.security.user.roles` | `ADMIN_ROLES` | `ADMIN` | 角色 | ### GitLab Webhook | 配置项 | 环境变量 | 默认值 | 说明 | |--------|----------|--------|------| | `webhook.gitlab.secret-token` | `GITLAB_SECRET_TOKEN` | `dxsm` | GitLab 推送时携带的 `X-Gitlab-Token` | | `webhook.gitlab.allowed-branches` | - | `main`、`master`、`release/*` | 允许处理的分支,支持通配符 `*` | ### 通知配置 #### 钉钉 | 配置项 | 环境变量 | 默认值 | 说明 | |--------|----------|--------|------| | `notification.dingtalk.enabled` | - | `false` | 是否启用 | | `notification.dingtalk.webhook-url` | `DINGTALK_WEBHOOK_URL` | - | 钉钉机器人 Webhook | | `notification.dingtalk.secret` | `DINGTALK_SECRET` | - | 加签密钥 | #### 禅道 | 配置项 | 环境变量 | 默认值 | 说明 | |--------|----------|--------|------| | `notification.zentao.enabled` | - | `true` | 是否启用 | | `notification.zentao.base-url` | `ZENTAO_BASE_URL` | `http://192.168.10.115:8099/` | 禅道站点根地址 | | `notification.zentao.username` | `ZENTAO_USERNAME` | `dxf` | 禅道账号 | | `notification.zentao.password` | `ZENTAO_PASSWORD` | - | 禅道密码 | ### 周报/日报配置 | 配置项 | 环境变量 | 默认值 | 说明 | |--------|----------|--------|------| | `report.weekly.enabled` | `WEEKLY_REPORT_ENABLED` | `true` | 是否启用周报任务 | | `report.weekly.create-cron` | - | `0 27 16 * * ?` | 创建周报任务的 Cron | | `report.weekly.update-cron` | - | `0 */3 * * * ?` | 追加日报描述的 Cron | | `report.weekly.project-id` | `WEEKLY_REPORT_PROJECT_ID` | `2` | 禅道项目 ID | | `report.weekly.execution-id` | `WEEKLY_REPORT_EXECUTION_ID` | `3` | 禅道执行/迭代 ID | | `report.weekly.title-prefix` | - | `周报` | 周报任务标题前缀 | | `report.weekly.assigned-to` | `WEEKLY_REPORT_ASSIGNED_TO` | `dxf` | 周报任务指派给 | | `report.weekly.day-emoji` | `WEEKLY_REPORT_DAY_EMOJI` | `⏰` | 日报日期符号(HTML 实体,3 字节安全) | > **注意**:禅道默认使用 `utf8` 字符集,无法存储 4 字节 Emoji(如 `📅`)。请使用 3 字节符号或 HTML 实体,例如 `⏰`(⏰)。 ### 提交润色配置 | 配置项 | 环境变量 | 默认值 | 说明 | |--------|----------|--------|------| | `report.polishing.enabled` | `REPORT_POLISHING_ENABLED` | `true` | 是否启用 Claude 润色 | | `report.polishing.filter-noise` | `REPORT_POLISHING_FILTER_NOISE` | `true` | 是否过滤无意义提交 | | `report.polishing.max-commits-per-group` | `REPORT_POLISHING_MAX_COMMITS` | `20` | 每组最大提交数 | | `report.polishing.batch-cron` | - | `0 */2 * * * ?` | 润色任务定时 | | `report.polishing.batch-size` | - | `5` | 每批处理数量 | | `report.polishing.claude.api-key` | `ANTHROPIC_AUTH_TOKEN` | - | Claude API Key | | `report.polishing.claude.base-url` | `CLAUDE_BASE_URL` | `http://10.101.2.252:3000/` | Claude API 基础地址 | | `report.polishing.claude.model` | `CLAUDE_MODEL` | `kimi-for-coding` | 模型名称 | | `report.polishing.claude.max-tokens` | `CLAUDE_MAX_TOKENS` | `1024` | 最大 token | | `report.polishing.claude.timeout-seconds` | `CLAUDE_TIMEOUT_SECONDS` | `30` | 请求超时 | | `report.polishing.claude.retry-count` | `CLAUDE_RETRY_COUNT` | `2` | 重试次数 | ### 数据保留 | 配置项 | 默认值 | 说明 | |--------|--------|------| | `report.retention.days` | `30` | PushEvent 保留天数 | | `report.retention.cleanup-cron` | `0 0 3 * * ?` | 每日凌晨 3 点清理 | ## API 说明 ### 接收 GitLab Push 事件 ```http POST /api/v1/webhooks/gitlab Content-Type: application/json X-Gitlab-Token: {GITLAB_SECRET_TOKEN} ``` 请求体:标准 [GitLab Push Hook Payload](https://docs.gitlab.com/ee/user/project/integrations/webhooks.html#push-events)。 响应示例: ```json { "code": 200, "message": "processed" } ``` ## 管理后台 启动后访问:http://localhost:15200/admin 默认登录信息(**生产环境务必修改**): - 用户名:`admin` - 密码:`admin` 后台功能: - 仪表盘 - GitLab ↔ 禅道 用户映射管理 - 推送事件管理 - 表格支持长文本省略显示,鼠标悬停查看完整内容 - 使用 Bootstrap 主色作为表头,视觉层次清晰 - 所有单元格带边框,易于阅读 ## 数据模型 核心表: - `push_events`:接收到的 Push 事件,包含仓库、分支、提交信息、润色内容等 - `gitlab_zentao_user_mapping`:GitLab 用户名与禅道用户名的映射 - `zentao_weekly_task_binding`:禅道周报任务与用户的绑定关系 建表脚本:`src/main/resources/schema.sql` ## Docker 部署 > **提示**:当前 `Dockerfile` 与 `docker-compose.yml` 默认暴露端口为 `8080`,但应用默认监听 `15200`。使用 Docker 部署时建议通过环境变量 `SERVER_PORT=8080` 统一端口。 ### 使用 Docker Compose ```bash # 创建 .env export GITLAB_SECRET_TOKEN=your-secret-token export SERVER_PORT=8080 # 构建并启动 docker-compose up -d --build ``` ### 单独构建镜像 ```bash docker build -t webhook-server . docker run -d \ -p 8080:8080 \ -e SERVER_PORT=8080 \ -e GITLAB_SECRET_TOKEN=your-secret-token \ -v $(pwd)/data:/app/data \ webhook-server ``` 详细说明参见 [DOCKER.md](./DOCKER.md)。 ## 测试 ```bash # 运行全部单元测试与集成测试 ./mvnw test ``` ## 提交信息格式 日报生成器会解析 commit message 中的工时信息,例如: ```text fix(login): 修复登录态过期问题 本次修复了 token 刷新逻辑,耗时 2.5h。 ``` 支持识别 `2.5h`、`2.5小时`、`2.5 h` 等格式。未标注工时的提交默认不计算工时。 ## 注意事项 1. **生产安全**:`application.yml` 中的默认密钥、密码仅为本地开发使用,部署前必须通过环境变量覆盖。 2. **禅道字符集**:发往禅道的描述内容避免使用 4 字节 Emoji,否则可能显示为 `????`。 3. **H2 数据库**:数据文件位于 `./data/webhook-server.*`,建议定期备份。 4. **Docker 端口**:注意 `SERVER_PORT` 与容器暴露端口保持一致。 ## 许可证 [LICENSE](./LICENSE)