Commit 6f96e84b authored by 黎博's avatar 黎博

jenkins pipline

parent b774d799
......@@ -136,6 +136,12 @@
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>com.offbytwo.jenkins</groupId>
<artifactId>jenkins-client</artifactId>
<version>0.3.8</version>
</dependency>
</dependencies>
<build>
......
package cn.qg.holmes.controller.gitlab;
import cn.qg.holmes.common.JsonResult;
import cn.qg.holmes.entity.gitlab.Pipeline;
import cn.qg.holmes.service.gitlab.PipelineService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.management.Query;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.util.List;
@Slf4j
@RestController
@CrossOrigin
@RequestMapping("/pipline")
public class PipelineController {
@Autowired
PipelineService pipelineService;
@PostMapping("/webhook")
public void piplineWebhook(HttpServletRequest request) {
StringBuilder piplineData = new StringBuilder();
try {
BufferedReader br = request.getReader();
String str = "";
while((str = br.readLine()) != null){
piplineData.append(str);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
log.info("收到gitlab推送来的数据:{}", piplineData);
pipelineService.buildPipelineJob(String.valueOf(piplineData));
}
@PostMapping("/add")
public JsonResult addPipeline(@RequestBody List<Pipeline> pipelineList) {
return JsonResult.buildSuccessResult(pipelineService.saveBatch(pipelineList));
}
@PostMapping("/modify")
public JsonResult modifyPipeline(@RequestBody List<Pipeline> pipelineList) {
try {
for (Pipeline pipeline: pipelineList) {
if (pipelineService.getById(pipeline.getId()) == null) {
pipelineService.save(pipeline);
} else {
pipelineService.updateById(pipeline);
}
}
return JsonResult.buildSuccessResult(true);
} catch (Exception e) {
e.printStackTrace();
return JsonResult.buildSuccessResult(false);
}
}
}
package cn.qg.holmes.controller.pipline;
import cn.qg.holmes.common.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
@Slf4j
@RestController
@CrossOrigin
@RequestMapping("/pipline")
public class PiplineController {
@PostMapping("/webhook")
public JsonResult piplineWebhook(HttpServletRequest request) {
StringBuilder piplineData = new StringBuilder();
try {
BufferedReader br = request.getReader();
String str = "";
while((str = br.readLine()) != null){
piplineData.append(str);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
log.info("发送过来的pipline数据为:{}", piplineData);
return JsonResult.buildSuccessResult(true);
}
}
package cn.qg.holmes.entity.gitlab;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
@Data
public class Pipeline {
@TableId(type = IdType.AUTO)
private Integer id;
private Integer dingRobotId;
private String serviceName;
private String serviceBranch;
private String serviceType;
private String namespace;
private Integer enable;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
package cn.qg.holmes.mapper.gitlab;
import cn.qg.holmes.entity.gitlab.Pipeline;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface PipelineMapper extends BaseMapper<Pipeline> {
}
package cn.qg.holmes.service.gitlab;
import cn.qg.holmes.entity.gitlab.Pipeline;
import com.baomidou.mybatisplus.extension.service.IService;
public interface PipelineService extends IService<Pipeline> {
void buildPipelineJob(String gitlabData);
}
package cn.qg.holmes.service.gitlab.impl;
import cn.qg.holmes.entity.gitlab.Pipeline;
import cn.qg.holmes.mapper.gitlab.PipelineMapper;
import cn.qg.holmes.service.gitlab.PipelineService;
import cn.qg.holmes.service.jira.DingRobotService;
import cn.qg.holmes.utils.DingdingUtils;
import cn.qg.holmes.utils.JenkinsService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jayway.jsonpath.JsonPath;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class PipelineServiceImpl extends ServiceImpl<PipelineMapper, Pipeline> implements PipelineService {
@Autowired
PipelineMapper pipelineMapper;
@Autowired
JenkinsService jenkinsService;
@Autowired
DingRobotService dingRobotService;
/**
* 构建pipeline
* @param gitlabData gitlab发送过来的推送事件
*/
@Override
public void buildPipelineJob(String gitlabData) {
String projectName = JsonPath.read(gitlabData, "$.project.name");
String branch = JsonPath.read(gitlabData, "$.project.default_branch");
String message = JsonPath.read(gitlabData, "$.commits[0].message");
String author = JsonPath.read(gitlabData, "$.user_username");
String commitDate = JsonPath.read(gitlabData, "$.commits[0].timestamp");
QueryWrapper<Pipeline> pipelineQueryWrapper = new QueryWrapper<>();
pipelineQueryWrapper.eq("service_name", projectName);
pipelineQueryWrapper.eq("service_branch", branch);
Pipeline pipeline = pipelineMapper.selectOne(pipelineQueryWrapper);
if (pipeline != null) {
if (pipeline.getEnable() == 1) {
log.info("pipeline中找到对应项目,且项目是启动状态,开始构建:{}", pipeline.toString());
jenkinsService.buildJenkinsJob(pipeline.getServiceType(), projectName, branch, pipeline.getNamespace());
String markdown = DingdingUtils.buildPipelineMarkdownMsg(projectName, branch, author, message, commitDate, pipeline.getNamespace());
DingdingUtils.sendToDingding(markdown, dingRobotService.getById(pipeline.getDingRobotId()).getDingUrl());
} else {
log.info("pipeline中找到项目,但是项目状态为不启用,因此不构建!");
}
} else {
log.info("pipeline中未找到该项目相关信息,不触发自动构建!");
}
}
}
......@@ -56,7 +56,7 @@ public class DingRobotServiceImpl extends ServiceImpl<DingRobotMapper, DingRobot
jiraBugPool.setDingUrl(robotUrl);
jiraBugPoolService.save(jiraBugPool);
if (robotUrl != null) {
String markdownMsg = DingdingUtils.buildMarkdownMsg(key, summary, creator, assignee, priority, module);
String markdownMsg = DingdingUtils.buildBugCommitMarkdownMsg(key, summary, creator, assignee, priority, module);
return DingdingUtils.sendToDingding(markdownMsg, robotUrl);
}
}
......
......@@ -8,9 +8,19 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 钉钉发送消息类
* @author libo
*/
@Slf4j
public class DingdingUtils {
/**
* 发送钉钉消息基本方法
* @param jsonString 发送的json字符串
* @param webhook 钉钉webhook
* @return 是否发送成功,true/false
*/
public static boolean sendToDingding(String jsonString, String webhook) {
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json; charset=utf-8");
......@@ -20,39 +30,58 @@ public class DingdingUtils {
return resultMap.get("errmsg").equals("ok");
}
public static String buildMarkdownMsg(String key, String summary, String creator, String assignee, String priority, String module) {
/**
* 构建markdown消息基础类
* @param title 标题
* @param content 内容
* @param atAll 是否at所有人
* @return markdown消息的json字符串
*/
public static String buildMarkdownMsg(String title, String content, boolean atAll) {
Map<String, Object> markdown = new HashMap<>();
Map<String, String> content = new HashMap<>();
Map<String, String> contentMap = new HashMap<>();
Map<String, Object> atMap = new HashMap<>();
atMap.put("isAtAll", atAll);
markdown.put("at", atMap);
markdown.put("msgtype", "markdown");
String title = creator + "提交了BUG:" + key;
contentMap.put("title", title);
contentMap.put("text", content);
markdown.put("markdown", contentMap);
return JSON.toJSONString(markdown);
}
/**
* 构建BUG刚提交时,发送给钉钉的markdown消息
* @param key jira issue key
* @param summary 标题
* @param creator 创建人
* @param assignee 经办人
* @param priority 优先级
* @param module 模块
* @return json字符串类型的markdown消息
*/
public static String buildBugCommitMarkdownMsg(String key, String summary, String creator, String assignee, String priority, String module) {
String title = "测试同学" + creator + "提交了BUG:" + key;
String issueUrl = "http://jira2.quantgroup.cn/browse/" + key;
content.put("title", title);
content.put("text", "#### " + title + "\n"
+ "#### 概要:[" + summary + "](" + issueUrl + ")"+ "\n"
String content = "#### 概要:[" + summary + "](" + issueUrl + ")"+ "\n"
+ "- 优先级:" + priority + "\n"
+ "- 模块:" + module + "\n"
+ "- 经办人:" + assignee);
markdown.put("markdown", content);
return JSON.toJSONString(markdown);
+ "- 经办人:" + assignee;
return buildMarkdownMsg(title, content, true);
}
/**
* for 数据工单
* 根据issueList构建未解决issueList的markdown格式
* @param issues Issue的迭代器
* @return
*/
public static String buildMarkdownMsgForUnsolvedIssueList(Iterable<Issue> issues) {
Map<String, Object> markdown = new HashMap<>();
Map<String, String> contentMap = new HashMap<>();
Map<String, Object> atMap = new HashMap<>();
atMap.put("isAtAll", true);
markdown.put("at", atMap);
List<Issue> issueList = new ArrayList<>();
for (Issue issue: issues) {
issueList.add(issue);
}
markdown.put("msgtype", "markdown");
contentMap.put("title", "今日剩余未解决BUG统计");
String title = "今日剩余未解决BUG统计";
String content = "#### 今日剩余未解决BUG数:" + issueList.size() + "\n";
int count = 0;
for (Issue issue: issueList) {
......@@ -63,25 +92,24 @@ public class DingdingUtils {
content = content + "- 状态:" + issue.getStatus().getName() + "\n";
content = content + "- 经办人:" + issue.getAssignee().getDisplayName() + "\n\n";
}
contentMap.put("text", content);
markdown.put("markdown", contentMap);
return JSON.toJSONString(markdown);
return buildMarkdownMsg(title, content, true);
}
/**
* 构建测试进度的markdown消息
* @param issues issue迭代器
* @param progress 测试进度
* @param risk 风险点
* @return 测试进度markdown消息的json字符串
*/
public static String buildTestScheduleMarkdownMsg(Iterable<Issue> issues, String progress, String risk) {
Map<String, Object> markdown = new HashMap<>();
Map<String, String> contentMap = new HashMap<>();
Map<String, Object> atMap = new HashMap<>();
atMap.put("isAtAll", true);
markdown.put("at", atMap);
List<Issue> issueList = new ArrayList<>();
for (Issue issue: issues) {
issueList.add(issue);
}
markdown.put("msgtype", "markdown");
Date date=new Date();
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
contentMap.put("title", format.format(date) + "今日测试进度汇报");
String title = format.format(date) + "今日测试进度汇报";
String content = format.format(date) + "\n\n";
content += "今日测试进度:" + progress + " \n\n";
content = content + "剩余未解决BUG列表:" + "\n\n";
......@@ -100,9 +128,7 @@ public class DingdingUtils {
if (risk != null && !risk.isEmpty()) {
content = content + "**风险:" + risk + "**\n";
}
contentMap.put("text", content);
markdown.put("markdown", contentMap);
return JSON.toJSONString(markdown);
return buildMarkdownMsg(title, content, true);
}
/**
......@@ -118,26 +144,41 @@ public class DingdingUtils {
if (elapsed >= 8) {
duration = (elapsed / 8) + "天";
}
Map<String, Object> markdown = new HashMap<>();
Map<String, String> contentMap = new HashMap<>();
Map<String, Object> atMap = new HashMap<>();
atMap.put("isAtAll", true);
markdown.put("at", atMap);
markdown.put("msgtype", "markdown");
contentMap.put("title", "BUG修复提醒");
String content = issue.getAssignee().getDisplayName() + "同学,你有一个BUG已经超过" + duration + "未解决,请多注意哦!\n\n";
String title = "BUG修复提醒";
String content = issue.getAssignee().getDisplayName() + "同学,你有一个BUG已经超过" + duration + "未解决,测试同学等得花儿都谢啦,麻烦赶紧修复哦!\n\n";
String bugUrl = "http://jira2.quantgroup.cn/browse/" + issue.getKey();
content += "BUG具体信息:\n\n";
content += "- 标题:[" + issue.getSummary().replace("\"", "") + "](" + bugUrl + ")\n";
content += "- 优先级:" + issue.getPriority().getName() + "\n";
content += "- 经办人:" + issue.getAssignee().getDisplayName() + "\n\n";
contentMap.put("text", content);
markdown.put("markdown", contentMap);
return JSON.toJSONString(markdown);
return buildMarkdownMsg(title, content, true);
}
/**
* 构建pipeline钉钉消息
* @param serviceName 服务名
* @param serviceBranch 分支
* @param creator 创建人
* @param commitMsg 提交信息
* @param date 日期
* @param namespace 环境
* @return
*/
public static String buildPipelineMarkdownMsg(String serviceName, String serviceBranch, String creator, String commitMsg, String date, String namespace) {
String title = "测试环境自动构建提醒";
String content = "> 项目名称:" + serviceName + "\n\n"
+ "> 分支名称:" + serviceBranch + "\n\n"
+ "> 部署空间:" + namespace + "\n\n"
+ "> 触发同学:" + creator + "\n\n"
+ "> 触发信息:" + commitMsg + "\n\n"
+ "> 触发时间:" + date + "\n\n"
+ "[查看详情](" + "" + ")";
return buildMarkdownMsg(title, content, false);
}
public static void main(String[] args) {
// String markdown = buildMarkdownMsg("YXM-1499", "【羊小咩v7.6.00】【VCC首次交易率提升专题】巴拉巴拉", "黎博", "于巧玲", "p1", "kddsp");
// sendToDingding(markdown, "https://oapi.dingtalk.com/robot/send?access_token=835663338d638e40daaf3ab358af741ef0680a826a962c91bedc53b149d85ee1");
String markdown = buildPipelineMarkdownMsg("holmes", "master", "bo.li", "测试", "2021-06-03 14:59:45", "fe");
sendToDingding(markdown, "https://oapi.dingtalk.com/robot/send?access_token=835663338d638e40daaf3ab358af741ef0680a826a962c91bedc53b149d85ee1");
}
}
package cn.qg.holmes.utils;
import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.client.JenkinsHttpClient;
import com.offbytwo.jenkins.model.Build;
import com.offbytwo.jenkins.model.Job;
import com.offbytwo.jenkins.model.JobWithDetails;
import com.offbytwo.jenkins.model.QueueReference;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Jenkins 相关操作工具类
* @author libo
*/
@Component
public class JenkinsService {
// Jenkins 对象
private JenkinsServer jenkinsServer;
// http 客户端对象
private JenkinsHttpClient jenkinsHttpClient;
// 连接 Jenkins 需要设置的信息
static final String JENKINS_URL = "http://172.29.1.15:8080/";
static final String JENKINS_USERNAME = "qahome";
static final String JENKINS_PASSWORD = "Quantgroup123";
/**
* 构造方法中调用连接 Jenkins 方法
*/
public JenkinsService() {
// 连接 Jenkins
try {
jenkinsServer = new JenkinsServer(new URI(JENKINS_URL), JENKINS_USERNAME, JENKINS_PASSWORD);
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
/**
* 构建jenkins job
* @param type 服务类型:java/node/ui
* @param project 项目名
* @param branch 分支名
* @param namespace 部署的环境
* @return
*/
public void buildJenkinsJob(String type, String project, String branch, String namespace) {
Map<String, String> buildParams = new HashMap<>();
buildParams.put("GIT_REPO", project);
buildParams.put("BRANCH_NAME", branch);
buildParams.put("DEPLOY", "true");
buildParams.put("NAMESPACE", namespace);
try {
QueueReference queueReference = jenkinsServer.getJob("tke-" + type).build(buildParams);
// Thread.sleep(5000);
Build build = jenkinsServer.getBuild(jenkinsServer.getQueueItem(queueReference));
System.out.println(build.getNumber());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根据job名称获取job信息
*/
public JobWithDetails getJobInfoByName(String jobName) {
try {
JobWithDetails job = jenkinsServer.getJob(jobName);
return job;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/**
* 获取job列表
* @return
*/
public List<Map<String, String>> getJobList() {
try {
Map<String, Job> jobs = jenkinsServer.getJobs();
List<Map<String, String>> jobList = new ArrayList<>();
for (Job job:jobs.values()){
Map<String, String> map = new HashMap<>();
map.put("value", job.getName());
map.put("label", job.getName());
jobList.add(map);
}
return jobList;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/**
* 获取Job Build列表
*/
public List<Build> getJobBuildList(String jobName, Integer num) {
try {
// 获取 Job 信息
JobWithDetails job = jenkinsServer.getJob(jobName);
// 获取全部 Build 信息
Build lastBuild = job.getLastBuild();
int lastBuildNumber = lastBuild.getNumber();
List<Build> buildList = new ArrayList<>();
for (int i = lastBuildNumber; i > lastBuildNumber - num; i--) {
Build tempBuild = job.getBuildByNumber(i);
if (tempBuild == null) {
return buildList;
} else {
buildList.add(job.getBuildByNumber(i));
}
}
return buildList;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/**
* 根据参数获取对应的build
*/
public List<Build> getJobBuildList(String jobName, Integer num, String project) {
try {
// 获取 Job 信息
JobWithDetails job = jenkinsServer.getJob(jobName);
int lastBuildNumber = job.getLastBuild().getNumber();
List<Build> buildList = new ArrayList<>();
int caculator = 0;
while (buildList.size() != num) {
Build build = job.getBuildByNumber(lastBuildNumber - caculator);
if (build == null) {
return buildList;
}
if (build.details().getParameters().get("GIT_REPO").equals(project)) {
buildList.add(build);
}
caculator += 1;
}
return buildList;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) throws IOException {
JenkinsService jenkinsApi = new JenkinsService();
// List<Build> buildList = jenkinsApi.getJobBuildList("tke-java", 1, "kdsp");
// List<String> userList = new ArrayList<>();
// for (Build build: buildList) {
// System.out.println(build.details().getParameters().get("BRANCH_NAME"));
// System.out.println(build.details().getParameters().get("NAMESPACE"));
// System.out.println(build.details().getCauses().get(0).getUserName());
// userList.add(build.details().getCauses().get(0).getUserName());
// BuildResult buildResult = build.details().getResult();
// System.out.println(buildResult);
// }
// System.out.println(userList.size());
jenkinsApi.buildJenkinsJob("java", "holmes", "pipline", "fe");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment