GitLab的Webhook配置和开发

您所在的位置:网站首页 webhook怎么用 GitLab的Webhook配置和开发

GitLab的Webhook配置和开发

#GitLab的Webhook配置和开发| 来源: 网络整理| 查看: 265

文章目录 前提准备企业微信消息发送接口gitlab(账号,用户组,项目)gitlab开放API文档 webhook配置和开发配置webhookgitlab的webhook原理 项目实战总结

本文主要介绍如何使用gitlab的webhook来打通企业微信消息提醒。

前提准备 企业微信消息发送接口

根据企业微信开发者文档得到一个消息发送的接口url,参照:企业微信群机器人配置说明;

gitlab(账号,用户组,项目)

生成gitlab账号token 在这里插入图片描述 在这里插入图片描述

获取项目的project_id 参考gitlab如何查询项目ID

获取用户组的group_id 方法类似于上面project_id的获取

gitlab开放API文档

开放API文档 在这里插入图片描述

webhook配置和开发 配置webhook

在这里插入图片描述

Secret Token和Enable SSL verification配置项可以先不配置。

在这里配置wenhook,我这里先配置两个触发事件,Tag push events(tag新增/删除事件)和Merge request events(MR新增/删除事件)。

gitlab的webhook原理

上面的配置中有一个URL配置项还没有配置。 想知道这里应该配什么,首先应该了解gitlab的webhook工作原理。

这里还是以发送通知到企业微信为例。

在这里插入图片描述

项目代码变动往gitlab上推送相应的事件,例如代码push,新建tag,创建merge request等等;gitlab收到相应事件,触发对应的webhook,设置HTTP请求的header以及request body,然后发送HTTP请求到配置的webhook的URL;HTTP请求到达对应的处理服务器以后,对request body和header进行解析,包装通知内容;将通知的内容通过企业微信的消息发送接口发送到企业微信; 具体参考webhook使用指南 在这里插入图片描述 接下来所有的重点就是这个URL是什么?他应该是一个接口,用来处理gitlab的事件。 项目实战

前提准备做好之后,就可以开发处理事件的服务端了(基于SpringBoot项目)。 以下是一些核心代码。 GitLabApiUtils.java

/** * 获取所有项目master成员 * @param projectId * @return */ public static List getAllProjectMembers(Integer projectId) { getProjectMembersUrl = getProjectMembersUrl.replace("$",""+projectId); getGroupMembersUrl = getGroupMembersUrl.replace("$","800"); List projectMasterMembers = getGitLabMasterMembers(getProjectMembersUrl); List groupMasterMembers = getGitLabMasterMembers(getGroupMembersUrl); return Stream.of(projectMasterMembers,groupMasterMembers).flatMap(Collection::stream).distinct().collect(Collectors.toList()); } /** * 获取master成员 * @param url * @return */ private static List getGitLabMasterMembers(String url) { List result = new ArrayList(); OkHttpClient okHttpClient = new OkHttpClient(); Request request = new Request.Builder().url(url).header("PRIVATE-TOKEN",token).build(); Response response = null; try { response = okHttpClient.newCall(request).execute(); String body = response.body().string(); JSONArray jsonArray = JSONArray.parseArray(body); for (int i = 0;i result.add(jsonObject.getString("name")); } } } catch (IOException e) { log.error("调用GitLab API失败!",e); } finally { if (response != null) { response.close(); } } return result; }

这个例子中只做了Tag Push Event和Merge Request Event的处理,主要是根据不同的事件构建不同的企业微信消息内容。其他的可以自己扩展。 MessageStrategy.java

/** * 构建消息内容 */ public interface MessageStrategy { String produceMsg(JSONObject jsonObject); }

TagMessageStrategy.java

@Override public String produceMsg(JSONObject jsonObject) { String operateType = OPERATE_TYPE_ADD; if ("0000000000000000000000000000000000000000".equals(jsonObject.getString("after"))) { operateType = OPERATE_TYPE_DELETE; } Integer projectId = jsonObject.getInteger("project_id"); JSONObject prObject = jsonObject.getJSONObject("project"); String repo = prObject.getString("name"); String operator = jsonObject.getString("user_name"); String tag = jsonObject.getString("ref"); String[] tagArr = tag.split("/"); tag = tagArr[tagArr.length-1]; String detailUrl = prObject.getString("web_url")+"/tags/"+tag; String commitInfo = ""; if (OPERATE_TYPE_ADD.equals(operateType)) { String newTagMsg = jsonObject.getString("message"); JSONObject latestCommit = jsonObject.getJSONArray("commits").getJSONObject(0); String latestCommitMsg = latestCommit.getString("message").replaceAll("\r\n"," "); String latestCommitUser = latestCommit.getJSONObject("author").getString("name"); commitInfo = "\n>Tag描述:"+newTagMsg +"\n>最近一次提交信息:"+latestCommitMsg +"\n>最近一次提交人:"+latestCommitUser; } List members = GitLabApiUtils.getAllProjectMembers(projectId); String alertUsers = members.stream().map(s -> "@"+s+" ").collect(Collectors.joining()); String alertContent = alertUsers+"【"+repo+"】"+operator+""+operateType+"了一个Tag!" +"\n>Tag名称:"+tag +commitInfo +"\n>[查看详情]("+detailUrl+")"; return alertContent; }

MRMessageStrategy.java

@Override public String produceMsg(JSONObject jsonObject) { String operator = jsonObject.getJSONObject("user").getString("name"); JSONObject objectAttributes = jsonObject.getJSONObject("object_attributes"); String operateType = "变更"; String state = objectAttributes.getString("state"); if ("closed".equals(state)) { operateType = "关闭"; } else if ("opened".equals(state)) { operateType = "新增"; } else if ("merged".equals(state)) { operateType = "审核通过"; } String source = objectAttributes.getString("source_branch"); String target = objectAttributes.getString("target_branch"); Integer projectId = objectAttributes.getInteger("target_project_id"); String title = objectAttributes.getString("title"); String description = objectAttributes.getString("description"); JSONObject lastCommit = objectAttributes.getJSONObject("last_commit"); String lastCommitMsg = lastCommit.getString("message").replaceAll("\n",""); String lastCommitUser = lastCommit.getJSONObject("author").getString("name"); String repo = objectAttributes.getJSONObject("target").getString("name"); String url = objectAttributes.getString("url"); List members = GitLabApiUtils.getAllProjectMembers(projectId); String alertUsers = members.stream().map(s -> "@"+s+" ").collect(Collectors.joining()); String alertContent = alertUsers+"【"+repo+"】"+operator+""+operateType+"了一个Merge Request!" +"\n>标题:"+title +"\n>描述:"+description +"\n>Source Branch:"+source +"\n>Target Branch:"+target +"\n>最近一次提交信息:"+lastCommitMsg +"\n>最近一次提交人:"+lastCommitUser +"\n>[查看详情]("+url+")"; return alertContent; }

AlertController.java

@PostMapping("/alert") public String alert(@RequestBody JSONObject jsonObject, HttpServletRequest request) { String bodyContext = "发送成功"; String objectKind = jsonObject.getString("object_kind"); MessageStrategy messageStrategy = null; if("tag_push".equals(objectKind)) { messageStrategy = new TagMessageStrategy(); } else if("merge_request".equals(objectKind)) { messageStrategy = new MRMessageStrategy(); } MessageStrategyContext messageStrategyContext = new MessageStrategyContext(messageStrategy); String alertContent = messageStrategyContext.buildMessage(jsonObject); log.info("消息内容:"+alertContent); String[] cmds={"curl",weChatSendUrl,"-H" ,"Content-Type: application/json","-d","{\"msgtype\": \"markdown\",\"markdown\": {\"content\": \""+alertContent+"\"}}"}; ProcessBuilder process = new ProcessBuilder(cmds); try { process.start(); } catch (Exception e) { bodyContext = "发送失败"; } return bodyContext; }

完整代码请查看gitlab-to-企业微信

经过开发之后webhook配置项里的URL自然也就有了,那就是http://{服务ip}:{服务端口}/alert

总结

其实hook这种设计在很多地方都有,且不说一些开源中间件,JDK本身就提供了ShutdownHook,最重要的还是了解hook的工作原理,才能更好的使用hook,感受它带来的扩展和便捷。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3