增加GIT检测节点

This commit is contained in:
dengqichen 2025-12-04 18:34:50 +08:00
parent 485bf949b2
commit f49c0915ec
4 changed files with 78 additions and 27 deletions

View File

@ -45,4 +45,31 @@ public class DateUtils {
long sec = seconds % 60L; long sec = seconds % 60L;
return String.format("%02d:%02d:%02d", hours, minutes, sec); return String.format("%02d:%02d:%02d", hours, minutes, sec);
} }
/**
* 格式化 LocalDateTime 为默认格式 (yyyy-MM-dd HH:mm:ss)
*
* @param dateTime 日期时间对象
* @return 格式化后的字符串如果为 null 则返回 "N/A"
*/
public static String format(LocalDateTime dateTime) {
if (dateTime == null) {
return "N/A";
}
return dateTime.format(DateTimeFormatter.ofPattern(DEFAULT_PATTERN));
}
/**
* 格式化 LocalDateTime 为指定格式
*
* @param dateTime 日期时间对象
* @param pattern 日期格式模板
* @return 格式化后的字符串如果为 null 则返回 "N/A"
*/
public static String format(LocalDateTime dateTime, String pattern) {
if (dateTime == null) {
return "N/A";
}
return dateTime.format(DateTimeFormatter.ofPattern(pattern));
}
} }

View File

@ -6,6 +6,7 @@ import com.qqchen.deploy.backend.deploy.integration.response.GitCommitResponse;
import com.qqchen.deploy.backend.deploy.repository.IExternalSystemRepository; import com.qqchen.deploy.backend.deploy.repository.IExternalSystemRepository;
import com.qqchen.deploy.backend.framework.enums.ResponseCode; import com.qqchen.deploy.backend.framework.enums.ResponseCode;
import com.qqchen.deploy.backend.framework.exception.BusinessException; import com.qqchen.deploy.backend.framework.exception.BusinessException;
import com.qqchen.deploy.backend.framework.utils.DateUtils;
import com.qqchen.deploy.backend.workflow.dto.CommitDifferenceInfo; import com.qqchen.deploy.backend.workflow.dto.CommitDifferenceInfo;
import com.qqchen.deploy.backend.workflow.dto.inputmapping.GitSyncCheckInputMapping; import com.qqchen.deploy.backend.workflow.dto.inputmapping.GitSyncCheckInputMapping;
import com.qqchen.deploy.backend.workflow.dto.outputs.GitSyncCheckOutputs; import com.qqchen.deploy.backend.workflow.dto.outputs.GitSyncCheckOutputs;
@ -35,18 +36,19 @@ public class GitSyncCheckDelegate extends BaseNodeDelegate<GitSyncCheckInputMapp
private IExternalSystemRepository externalSystemRepository; private IExternalSystemRepository externalSystemRepository;
/** /**
* 获取commits的数量限制 * 获取commits的数量限制用于检测
*/ */
private static final int COMMITS_LIMIT = 10; private static final int COMMITS_LIMIT = 50;
/**
* 通知中显示的commit数量限制防止内容过长
*/
private static final int DISPLAY_COMMITS_LIMIT = 5;
@Override @Override
protected void executeInternal(DelegateExecution execution, protected void executeInternal(DelegateExecution execution, Map<String, Object> configs, GitSyncCheckInputMapping input) {
Map<String, Object> configs,
GitSyncCheckInputMapping input) {
log.info("开始Git同步检测 - 源分支: {}/{}/{}, 目标分支: {}/{}/{}", log.info("开始Git同步检测 - 源分支: {}/{}/{}, 目标分支: {}/{}/{}", input.getSourceGitSystemId(), input.getSourceGitProjectId(), input.getSourceBranch(), input.getTargetGitSystemId(), input.getTargetGitProjectId(), input.getTargetBranch());
input.getSourceGitSystemId(), input.getSourceGitProjectId(), input.getSourceBranch(),
input.getTargetGitSystemId(), input.getTargetGitProjectId(), input.getTargetBranch());
try { try {
// 0. 检查是否配置了目标Git信息非强制如果未配置则跳过检测 // 0. 检查是否配置了目标Git信息非强制如果未配置则跳过检测
@ -56,7 +58,7 @@ public class GitSyncCheckDelegate extends BaseNodeDelegate<GitSyncCheckInputMapp
input.getTargetBranch().trim().isEmpty()) { input.getTargetBranch().trim().isEmpty()) {
String skipReason = "目标Git系统未配置跳过Git同步检测团队可能未启用同步模式"; String skipReason = "目标Git系统未配置跳过Git同步检测团队可能未启用同步模式";
log.info("⏭️ {}", skipReason); log.info("{}", skipReason);
output.setStatus(NodeExecutionStatusEnum.SUCCESS); output.setStatus(NodeExecutionStatusEnum.SUCCESS);
output.setMessage(skipReason); output.setMessage(skipReason);
output.setCheckDetail(skipReason); output.setCheckDetail(skipReason);
@ -129,9 +131,11 @@ public class GitSyncCheckDelegate extends BaseNodeDelegate<GitSyncCheckInputMapp
if (!compareResult.hasDifference) { if (!compareResult.hasDifference) {
// 合规目标分支的所有commits都在源分支中 // 合规目标分支的所有commits都在源分支中
String detail = String.format( String detail = String.format(
"✅ Git同步检测通过目标分支 [%s] 的所有代码已回归到源分支 [%s]", "[%s] %s 与 [%s] %s 代码已同步",
input.getTargetBranch(), sourceSystem.getName(),
input.getSourceBranch() input.getSourceBranch(),
targetSystem.getName(),
input.getTargetBranch()
); );
output.setStatus(NodeExecutionStatusEnum.SUCCESS); output.setStatus(NodeExecutionStatusEnum.SUCCESS);
output.setMessage(detail); output.setMessage(detail);
@ -141,28 +145,48 @@ public class GitSyncCheckDelegate extends BaseNodeDelegate<GitSyncCheckInputMapp
} else { } else {
// 不合规目标分支有源分支没有的commits // 不合规目标分支有源分支没有的commits
StringBuilder detailBuilder = new StringBuilder(); StringBuilder detailBuilder = new StringBuilder();
// 添加Git系统和分支信息
detailBuilder.append(String.format( detailBuilder.append(String.format(
"❌ Git同步检测不合规目标分支 [%s] 存在 %d 个未回归到源分支 [%s] 的提交\n\n", "[%s] %s 存在 %d 个未回归到 [%s] %s 的提交\n\n",
targetSystem.getName(),
input.getTargetBranch(), input.getTargetBranch(),
compareResult.commitsBehind, compareResult.commitsBehind,
sourceSystem.getName(),
input.getSourceBranch() input.getSourceBranch()
)); ));
// 详细列出不合规的commits // 只显示前N个commits避免内容过长
detailBuilder.append("不合规提交列表:\n"); int displayCount = Math.min(DISPLAY_COMMITS_LIMIT, compareResult.differenceCommits.size());
for (int i = 0; i < compareResult.differenceCommits.size(); i++) { detailBuilder.append(String.format("最近%d个提交\n", displayCount));
for (int i = 0; i < displayCount; i++) {
CommitDifferenceInfo commit = compareResult.differenceCommits.get(i); CommitDifferenceInfo commit = compareResult.differenceCommits.get(i);
detailBuilder.append(String.format( detailBuilder.append(String.format(
"%d. [%s] %s\n 作者: %s <%s>\n 时间: %s\n", "%d. [%s] %s (%s %s)\n",
i + 1, i + 1,
commit.getCommitId().substring(0, 8), commit.getCommitId().substring(0, 8),
commit.getShortMessage(), commit.getShortMessage(),
commit.getAuthor(), commit.getAuthor(),
commit.getAuthorEmail(), DateUtils.format(commit.getCommittedDate())
commit.getCommittedDate()
)); ));
} }
// 如果还有更多未显示的提交
if (compareResult.commitsBehind > displayCount) {
detailBuilder.append(String.format(
"\n...还有 %d 个未显示的提交\n",
compareResult.commitsBehind - displayCount
));
}
// 简化操作指引
detailBuilder.append(String.format(
"\n请将上述提交回归到 [%s] %s 或确认为客户定制化代码",
sourceSystem.getName(),
input.getSourceBranch()
));
String detail = detailBuilder.toString(); String detail = detailBuilder.toString();
output.setStatus(NodeExecutionStatusEnum.FAILURE); output.setStatus(NodeExecutionStatusEnum.FAILURE);
output.setCheckDetail(detail); output.setCheckDetail(detail);
@ -172,7 +196,7 @@ public class GitSyncCheckDelegate extends BaseNodeDelegate<GitSyncCheckInputMapp
)); ));
logWarn(detail); logWarn(detail);
// 正常返回基类会根据 output.status + continueOnFailure 决定是否抛 BpmnError // 正常返回基类会根据 output.status + continueOnFailure 决定是否抛 BpmnError
} }
} catch (BusinessException e) { } catch (BusinessException e) {
@ -225,7 +249,7 @@ public class GitSyncCheckDelegate extends BaseNodeDelegate<GitSyncCheckInputMapp
result.commitsBehind = 0; result.commitsBehind = 0;
result.differenceCommits = Collections.emptyList(); result.differenceCommits = Collections.emptyList();
log.info("Git同步检测通过 - 目标分支的所有提交都已回归到源分支"); log.info("Git同步检测通过 - 目标分支的所有提交都已回归到源分支");
return result; return result;
} }
@ -235,7 +259,7 @@ public class GitSyncCheckDelegate extends BaseNodeDelegate<GitSyncCheckInputMapp
result.commitsBehind = nonCompliantCommits.size(); // 目标分支独有的commit数量 result.commitsBehind = nonCompliantCommits.size(); // 目标分支独有的commit数量
result.differenceCommits = buildDifferenceList(nonCompliantCommits, "target"); result.differenceCommits = buildDifferenceList(nonCompliantCommits, "target");
log.warn("⚠️ Git同步检测不合规 - 目标分支存在{}个未回归到源分支的提交", log.warn("Git同步检测不合规 - 目标分支存在{}个未回归到源分支的提交",
nonCompliantCommits.size()); nonCompliantCommits.size());
// 打印不合规的commits用于调试 // 打印不合规的commits用于调试
@ -273,12 +297,12 @@ public class GitSyncCheckDelegate extends BaseNodeDelegate<GitSyncCheckInputMapp
*/ */
private String truncateMessage(String message, int maxLength) { private String truncateMessage(String message, int maxLength) {
if (message == null) { if (message == null) {
return null; return "N/A";
} }
if (message.length() <= maxLength) { if (message.length() <= maxLength) {
return message; return message;
} }
return message.substring(0, maxLength) + "..."; return message.substring(0, maxLength - 3) + "...";
} }
/** /**

View File

@ -33,9 +33,7 @@ public class HttpRequestNodeDelegate extends BaseNodeDelegate<HttpRequestInputMa
private ObjectMapper objectMapper; private ObjectMapper objectMapper;
@Override @Override
protected void executeInternal(DelegateExecution execution, protected void executeInternal(DelegateExecution execution, Map<String, Object> configs, HttpRequestInputMapping input) {
Map<String, Object> configs,
HttpRequestInputMapping input) {
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
try { try {

View File

@ -431,6 +431,8 @@ public class BpmnConverter {
return "${deployDelegate}"; return "${deployDelegate}";
case "HTTP_REQUEST": case "HTTP_REQUEST":
return "${httpRequestDelegate}"; return "${httpRequestDelegate}";
case "GIT_SYNC_CHECK":
return "${gitSyncCheckDelegate}";
default: default:
log.warn("未知的节点类型: {}, 将不设置 delegateExpression", nodeCode); log.warn("未知的节点类型: {}, 将不设置 delegateExpression", nodeCode);
return null; return null;