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