增加构建通知
This commit is contained in:
parent
1a5786502a
commit
f6569fe020
@ -492,14 +492,20 @@ public class DeployServiceImpl implements IDeployService {
|
||||
|
||||
// 构建通知配置 - 使用MapStruct转换器
|
||||
TeamEnvironmentNotificationConfig notificationConfig = notificationConfigMap.get(configKey);
|
||||
UserTeamEnvironmentNotificationConfigDTO notificationConfigDTO =
|
||||
notificationConfigConverter.toUserDTO(notificationConfig, channelMap, templateMap);
|
||||
UserTeamEnvironmentNotificationConfigDTO notificationConfigDTO;
|
||||
if (notificationConfig != null) {
|
||||
notificationConfigDTO = notificationConfigConverter.toUserDTO(notificationConfig, channelMap, templateMap);
|
||||
} else {
|
||||
// 没有配置时返回默认值(开关字段为false)
|
||||
notificationConfigDTO = createDefaultNotificationConfigDTO();
|
||||
}
|
||||
dto.setNotificationConfig(notificationConfigDTO);
|
||||
} else {
|
||||
dto.setRequiresApproval(false);
|
||||
dto.setRequireCodeReview(false);
|
||||
dto.setApprovers(Collections.emptyList());
|
||||
dto.setNotificationConfig(null);
|
||||
// 没有配置时返回默认值(开关字段为false)
|
||||
dto.setNotificationConfig(createDefaultNotificationConfigDTO());
|
||||
}
|
||||
|
||||
// 构建应用列表
|
||||
@ -723,6 +729,17 @@ public class DeployServiceImpl implements IDeployService {
|
||||
|| status == DeployRecordStatusEnums.CREATED;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建默认的通知配置DTO(开关字段默认为false)
|
||||
*/
|
||||
private UserTeamEnvironmentNotificationConfigDTO createDefaultNotificationConfigDTO() {
|
||||
UserTeamEnvironmentNotificationConfigDTO dto = new UserTeamEnvironmentNotificationConfigDTO();
|
||||
dto.setPreApprovalNotificationEnabled(false);
|
||||
dto.setBuildNotificationEnabled(false);
|
||||
dto.setBuildFailureFileEnabled(false);
|
||||
return dto;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public DeployResultDTO executeDeploy(DeployExecuteRequest request) {
|
||||
|
||||
@ -16,8 +16,13 @@ import com.qqchen.deploy.backend.deploy.repository.*;
|
||||
import com.qqchen.deploy.backend.deploy.service.IJenkinsBuildService;
|
||||
import com.qqchen.deploy.backend.deploy.service.IJenkinsSyncHistoryService;
|
||||
import com.qqchen.deploy.backend.notification.entity.NotificationChannel;
|
||||
import com.qqchen.deploy.backend.notification.entity.NotificationTemplate;
|
||||
import com.qqchen.deploy.backend.notification.entity.config.WeworkTemplateConfig;
|
||||
import com.qqchen.deploy.backend.notification.repository.INotificationChannelRepository;
|
||||
import com.qqchen.deploy.backend.notification.repository.INotificationTemplateRepository;
|
||||
import com.qqchen.deploy.backend.notification.service.INotificationService;
|
||||
import com.qqchen.deploy.backend.notification.service.INotificationSendService;
|
||||
import com.qqchen.deploy.backend.notification.dto.SendNotificationRequest;
|
||||
import com.qqchen.deploy.backend.notification.dto.WeworkSendNotificationRequest;
|
||||
import com.qqchen.deploy.backend.notification.dto.EmailSendNotificationRequest;
|
||||
import com.qqchen.deploy.backend.notification.enums.WeworkMessageTypeEnum;
|
||||
@ -78,6 +83,12 @@ public class JenkinsBuildServiceImpl extends BaseServiceImpl<JenkinsBuild, Jenki
|
||||
@Resource
|
||||
private INotificationChannelRepository notificationChannelRepository;
|
||||
|
||||
@Resource
|
||||
private INotificationTemplateRepository notificationTemplateRepository;
|
||||
|
||||
@Resource
|
||||
private INotificationService notificationService;
|
||||
|
||||
@Resource
|
||||
private INotificationSendService notificationSendService;
|
||||
|
||||
@ -596,7 +607,7 @@ public class JenkinsBuildServiceImpl extends BaseServiceImpl<JenkinsBuild, Jenki
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送通知
|
||||
* 发送通知(使用模板)
|
||||
*/
|
||||
private void sendNotification(
|
||||
TeamEnvironmentNotificationConfig config,
|
||||
@ -607,88 +618,107 @@ public class JenkinsBuildServiceImpl extends BaseServiceImpl<JenkinsBuild, Jenki
|
||||
ExternalSystem externalSystem) {
|
||||
|
||||
try {
|
||||
// 构建通知内容
|
||||
StringBuilder content = new StringBuilder();
|
||||
content.append("### 构建通知\n");
|
||||
content.append(String.format("> 任务: %s\n", job.getJobName()));
|
||||
content.append(String.format("> 构建号: #%d\n", build.getBuildNumber()));
|
||||
// 1. 检查是否配置了构建通知模板
|
||||
if (config.getBuildNotificationTemplateId() == null) {
|
||||
log.warn("未配置构建通知模板,跳过通知: teamId={}, envId={}",
|
||||
config.getTeamId(), config.getEnvironmentId());
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 查询模板
|
||||
NotificationTemplate template = notificationTemplateRepository
|
||||
.findById(config.getBuildNotificationTemplateId())
|
||||
.orElse(null);
|
||||
if (template == null) {
|
||||
log.warn("构建通知模板不存在: templateId={}", config.getBuildNotificationTemplateId());
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 构建模板参数
|
||||
Map<String, Object> templateParams = new HashMap<>();
|
||||
templateParams.put("jobName", job.getJobName());
|
||||
templateParams.put("buildNumber", build.getBuildNumber());
|
||||
templateParams.put("buildUrl", build.getBuildUrl());
|
||||
templateParams.put("status", status);
|
||||
templateParams.put("startTime", build.getStarttime());
|
||||
|
||||
// 状态显示
|
||||
String statusDisplay;
|
||||
switch (status) {
|
||||
case "SUCCESS":
|
||||
statusDisplay = "✅ 成功";
|
||||
break;
|
||||
case "FAILURE":
|
||||
statusDisplay = "❌ 失败";
|
||||
break;
|
||||
case "BUILDING":
|
||||
statusDisplay = "🔄 构建中";
|
||||
break;
|
||||
default:
|
||||
statusDisplay = status;
|
||||
}
|
||||
content.append(String.format("> 状态: %s\n", statusDisplay));
|
||||
content.append(String.format("> 时间: %s\n", build.getStarttime()));
|
||||
String statusDisplay = switch (status) {
|
||||
case "SUCCESS" -> "✅ 成功";
|
||||
case "FAILURE" -> "❌ 失败";
|
||||
case "BUILDING" -> "🔄 构建中";
|
||||
default -> status;
|
||||
};
|
||||
templateParams.put("statusDisplay", statusDisplay);
|
||||
|
||||
// 耗时(仅结束状态)
|
||||
if (!"BUILDING".equals(status) && build.getDuration() != null) {
|
||||
// 耗时
|
||||
if (build.getDuration() != null) {
|
||||
long seconds = build.getDuration() / 1000;
|
||||
long minutes = seconds / 60;
|
||||
long secs = seconds % 60;
|
||||
content.append(String.format("> 耗时: %d分%d秒\n", minutes, secs));
|
||||
templateParams.put("duration", String.format("%d分%d秒", minutes, secs));
|
||||
templateParams.put("durationMs", build.getDuration());
|
||||
}
|
||||
|
||||
// 构建失败时,发送日志文件(如果开启)
|
||||
if ("FAILURE".equals(status) && config.getBuildFailureFileEnabled() != null && config.getBuildFailureFileEnabled()) {
|
||||
// 先发送文本通知
|
||||
sendNotificationByChannelType(channel, "Jenkins构建通知", content.toString());
|
||||
// 4. 构建 SendNotificationRequest
|
||||
SendNotificationRequest request = new SendNotificationRequest();
|
||||
request.setNotificationTemplateId(config.getBuildNotificationTemplateId());
|
||||
request.setTemplateParams(templateParams);
|
||||
request.setSendRequest(createSendRequestByChannel(channel, template));
|
||||
|
||||
// 然后发送日志文件
|
||||
// 5. 发送通知
|
||||
notificationService.send(request);
|
||||
|
||||
log.info("已发送构建通知: job={}, build={}, status={}, templateId={}",
|
||||
job.getJobName(), build.getBuildNumber(), status, config.getBuildNotificationTemplateId());
|
||||
|
||||
// 6. 构建失败时,发送日志文件(如果开启)
|
||||
if ("FAILURE".equals(status) && Boolean.TRUE.equals(config.getBuildFailureFileEnabled())) {
|
||||
sendBuildFailureLogFile(externalSystem, channel, job.getJobName(), build.getBuildNumber());
|
||||
return; // 已发送,直接返回
|
||||
}
|
||||
|
||||
// 发送通知
|
||||
sendNotificationByChannelType(channel, "Jenkins构建通知", content.toString());
|
||||
|
||||
log.info("已发送构建通知: job={}, build={}, status={}",
|
||||
job.getJobName(), build.getBuildNumber(), status);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("发送通知失败: job={}, build={}", job.getJobName(), build.getBuildNumber(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据渠道类型发送通知
|
||||
* 根据渠道类型创建对应的发送请求
|
||||
*/
|
||||
private void sendNotificationByChannelType(NotificationChannel channel, String title, String content) {
|
||||
try {
|
||||
private com.qqchen.deploy.backend.notification.dto.BaseSendNotificationRequest createSendRequestByChannel(
|
||||
NotificationChannel channel, NotificationTemplate template) {
|
||||
switch (channel.getChannelType()) {
|
||||
case WEWORK -> {
|
||||
case WEWORK:
|
||||
WeworkSendNotificationRequest weworkRequest = new WeworkSendNotificationRequest();
|
||||
weworkRequest.setChannelId(channel.getId());
|
||||
weworkRequest.setContent(title + "\n\n" + content);
|
||||
weworkRequest.setMessageType(WeworkMessageTypeEnum.MARKDOWN); // 使用Markdown格式
|
||||
notificationSendService.send(weworkRequest);
|
||||
}
|
||||
case EMAIL -> {
|
||||
weworkRequest.setMessageType(getWeworkMessageType(template));
|
||||
return weworkRequest;
|
||||
case EMAIL:
|
||||
EmailSendNotificationRequest emailRequest = new EmailSendNotificationRequest();
|
||||
emailRequest.setChannelId(channel.getId());
|
||||
emailRequest.setSubject(title);
|
||||
emailRequest.setContent(content);
|
||||
// 这里需要设置收件人,但Jenkins构建通知中没有提供
|
||||
// 实际应该从团队环境配置或其他地方获取
|
||||
emailRequest.setToReceivers(java.util.Arrays.asList("admin@company.com"));
|
||||
notificationSendService.send(emailRequest);
|
||||
emailRequest.setToReceivers(Arrays.asList("admin@company.com"));
|
||||
return emailRequest;
|
||||
default:
|
||||
throw new RuntimeException("不支持的渠道类型: " + channel.getChannelType());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从模板配置中获取企业微信消息类型
|
||||
*/
|
||||
private WeworkMessageTypeEnum getWeworkMessageType(NotificationTemplate template) {
|
||||
try {
|
||||
if (template.getTemplateConfig() != null) {
|
||||
WeworkTemplateConfig weworkConfig = JsonUtils.fromMap(
|
||||
template.getTemplateConfig(), WeworkTemplateConfig.class);
|
||||
if (weworkConfig != null && weworkConfig.getMessageType() != null) {
|
||||
return weworkConfig.getMessageType();
|
||||
}
|
||||
default -> throw new RuntimeException("不支持的渠道类型: " + channel.getChannelType());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("发送通知失败: channelId={}, type={}", channel.getId(), channel.getChannelType(), e);
|
||||
throw e;
|
||||
log.warn("解析企业微信模板配置失败,使用默认消息类型: {}", e.getMessage());
|
||||
}
|
||||
return WeworkMessageTypeEnum.TEXT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user