三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

企业通信工具审核gitlab合并请求

企业通信工具审核gitlab合并请求

1、国内主流企业即时通讯

  • 企业微信:腾讯出品,和微信互通;聊天、审批、打卡、会议、客户联系(客户朋友圈)、应用接入;支持私有化部署。适合绝大多数国内大中小微企业,客户运营场景优势明显。
  • 钉钉:阿里,强 OA 工作流:审批、考勤、钉盘、钉会议、宜搭低代码;功能重管理。制造业、传统企业、行政流程多的企业使用广泛。
  • 飞书:字节跳动,文档深度集成,会议、多维表格、知识库,适合知识型团队、互联网、研发团队。

本文主要讲解用户可以通过 REST API 或钉钉机器人消息触发 MR 的批准、拒绝、关闭以及创建 Tag 等操作。

2、流程图

  1. 研发人员提出合并请求url,将合并请求发给审核者。
  2. 审核者通过钉钉发送"同意合并url",即可合并程功。

3、实现代码

依赖

<dependency> <groupId>org.gitlab4j</groupId> <artifactId>gitlab4j-api</artifactId> <version>${gitlab4j-api.version}</version> </dependency> <dependency> <groupId>com.dingtalk.open</groupId> <artifactId>dingtalk-stream</artifactId> <version>${dingtalk-stream.version}</version> </dependency>

应用配置(application.yaml

audit: gitlab: base-url: http://127.0.0.1:8090 # GitLab 服务器地址 token: glpat-xxxxxxxxxxxx # GitLab Personal Access Token ding: talk: robot: client-id: dingxxxxxxxxxxxx # 钉钉机器人 ClientID client-secret: xxxxxxxxxxxxxxxx # 钉钉机器人 ClientSecret

钉钉监听核心代码

/** * 启动 Stream 客户端,监听机器人回调消息 */ @PostConstruct public void start() { if (!properties.isEnabled()) { log.info("钉钉机器人 Stream 监听已禁用 (dingtalk.robot.enabled=false)"); return; } streamThread = new Thread(this::doStartStreamClient, "dingtalk-robot-stream"); // 设置为守护线程,避免应用退出时 Stream 客户端未正常关闭 streamThread.setDaemon(true); streamThread.start(); log.info("钉钉机器人 Stream 客户端已启动, topic={}", properties.getTopic()); } /** * 启动 Stream 客户端,监听机器人回调消息 */ private void doStartStreamClient() { try { streamClient = OpenDingTalkStreamClientBuilder .custom() .credential(new AuthClientCredential(properties.getClientId(), properties.getClientSecret())) .registerCallbackListener(properties.getTopic(), (ChatbotMessage message) -> { //1、 处理消息,开发者根据自身业务需求,处理机器人回调 String result = handleMessage(message); //2、回复消息 reply(message, result); return new JSONObject(); }) .build(); // start() 为阻塞方法,需在独立线程中执行 streamClient.start(); } catch (Exception e) { log.error("钉钉机器人 Stream 客户端异常", e); } } /** * 处理消息 * * @param message 收到消息 * @methodName: handleMessage * @return: java.lang.String * @author: ybw * @date: 2026/7/28 **/ private String handleMessage(ChatbotMessage message) { //1、 获取钉钉消息内容 String content = message.getText().getContent(); //2、判断是否有"同意合并"关键字 if (!content.contains("同意合并")) { //2.1 不包含 return "没有同意合并关键字"; } //2.2 包含 //2.2.1 获取合并链接地址 String mergeRequestUrl = MyStrUtil.getMergeRequestUrl(content); log.info("合并请求地址:{}", mergeRequestUrl); if (StrUtil.isBlank(mergeRequestUrl)) { return "无合并请求链接地址"; } //2.2.2 发送合并请求 ApproveByUrlRequest request = new ApproveByUrlRequest(mergeRequestUrl); AuditResult auditResult = auditService.approveMrByUrl(request); return auditResult.getMessage(); } /** * 回复消息 * * @param message 收到消息 * @param result 处理结果 * @methodName: reply * @return: void * @author: ybw * @date: 2026/7/28 **/ private void reply(ChatbotMessage message, String result) { try { //1、 使用 sessionWebhook 回复消息 String sessionWebhook = message.getSessionWebhook(); if (StrUtil.isBlank(sessionWebhook)) { return; } //2、回复消息,使用 sessionWebhook 回复消息 BotReplier replier = new BotReplier(sessionWebhook); replier.replyText("处理结果:" + result); log.info("已通过 sessionWebhook 回复消息"); } catch (Exception e) { log.error("reply error", e); } } /** * 停止 Stream 客户端 */ @PreDestroy public void stop() { if (streamClient != null) { try { streamClient.stop(); log.info("钉钉机器人 Stream 客户端已关闭"); } catch (Exception e) { log.error("关闭 Stream 客户端失败", e); } } if (streamThread != null && streamThread.isAlive()) { streamThread.interrupt(); } }

审核核心代码

/** * 通过 MR 链接地址批准 MR */ public AuditResult approveMrByUrl(ApproveByUrlRequest request) { // 1. 解析 URL,提取项目路径和 MR IID GitLabApiClient.MrUrlInfo urlInfo = gitLabApiClient.parseMrUrl(request.getMrUrl()); log.info("解析 MR URL: projectPath={}, mrIid={}", urlInfo.projectPath(), urlInfo.mrIid()); // 2. 将项目路径解析为项目 ID Long projectId = gitLabApiClient.resolveProjectId(urlInfo.projectPath()); // 3. 委托给现有的 approveMr 逻辑 ApproveRequest approveRequest = new ApproveRequest(); approveRequest.setProjectId(projectId); approveRequest.setMrIid(urlInfo.mrIid()); return approveMr(approveRequest); }

4、使用

  • 钉钉用户发送:同意合并:http://172.168.0.2/test/git-audit/-/merge_requests/1
  • 钉钉返回消息:处理结果:MR 已批准并合并。

← 返回列表