大声道撒旦

This commit is contained in:
dengqichen 2025-01-09 16:38:58 +08:00
parent 914ad0d1a1
commit 5598468fab
6 changed files with 189 additions and 42 deletions

View File

@ -31,6 +31,12 @@ public class RepositoryBranch extends Entity<Long> {
@Column(name = "commit_date")
private LocalDateTime commitDate;
@Column(name = "last_update_time")
private LocalDateTime lastUpdateTime;
@Column(name = "last_commit_time")
private LocalDateTime lastCommitTime;
@Column(name = "is_protected")
private Boolean isProtected = false;
@ -54,5 +60,4 @@ public class RepositoryBranch extends Entity<Long> {
@Column(name = "external_system_id")
private Long externalSystemId;
}

View File

@ -6,6 +6,7 @@ import com.qqchen.deploy.backend.deploy.integration.response.GitGroupResponse;
import com.qqchen.deploy.backend.deploy.integration.response.GitProjectResponse;
import com.qqchen.deploy.backend.system.enums.ExternalSystemTypeEnum;
import java.time.LocalDateTime;
import java.util.List;
/**

View File

@ -11,10 +11,15 @@ import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Git服务集成实现
@ -25,6 +30,7 @@ import java.util.List;
public class GitServiceIntegrationImpl implements IGitServiceIntegration {
private final RestTemplate restTemplate = new RestTemplate();
private static final DateTimeFormatter GITLAB_DATE_FORMATTER = DateTimeFormatter.ISO_DATE_TIME;
@Override
public boolean testConnection(ExternalSystem system) {
@ -117,6 +123,16 @@ public class GitServiceIntegrationImpl implements IGitServiceIntegration {
HttpHeaders headers = createHeaders(system);
HttpEntity<String> entity = new HttpEntity<>(headers);
// 先获取原始响应以便调试
ResponseEntity<String> rawResponse = restTemplate.exchange(
url,
HttpMethod.GET,
entity,
String.class
);
log.info("GitLab API raw response for project {}: {}", projectId, rawResponse.getBody());
// 然后解析为对象
ResponseEntity<List<GitBranchResponse>> response = restTemplate.exchange(
url,
HttpMethod.GET,
@ -124,7 +140,12 @@ public class GitServiceIntegrationImpl implements IGitServiceIntegration {
new ParameterizedTypeReference<>() {}
);
return response.getBody() != null ? response.getBody() : Collections.emptyList();
List<GitBranchResponse> branches = response.getBody();
if (branches != null && !branches.isEmpty()) {
log.info("First branch details: {}", branches.get(0));
}
return branches != null ? branches : Collections.emptyList();
} catch (Exception e) {
log.error("Failed to fetch git branches for system: {} and project: {}", system.getName(), projectId, e);
return Collections.emptyList();
@ -160,4 +181,90 @@ public class GitServiceIntegrationImpl implements IGitServiceIntegration {
return headers;
}
}
/**
* GitLab事件响应对象
*/
class GitlabEvent {
private String action;
private String targetType;
private String targetBranch;
private LocalDateTime createdAt;
// Getters and setters
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getTargetType() {
return targetType;
}
public void setTargetType(String targetType) {
this.targetType = targetType;
}
public String getTargetBranch() {
return targetBranch;
}
public void setTargetBranch(String targetBranch) {
this.targetBranch = targetBranch;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
}
/**
* GitLab仓库事件响应对象
*/
class GitlabRepositoryEvent {
private String actionName;
private String refType;
private String ref;
private LocalDateTime createdAt;
// Getters and setters
public String getActionName() {
return actionName;
}
public void setActionName(String actionName) {
this.actionName = actionName;
}
public String getRefType() {
return refType;
}
public void setRefType(String refType) {
this.refType = refType;
}
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
}

View File

@ -1,8 +1,11 @@
package com.qqchen.deploy.backend.deploy.integration.response;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
/**
* Git分支响应对象
@ -12,23 +15,62 @@ public class GitBranchResponse {
private String name;
@JsonProperty("default")
private Boolean isDefaultBranch;
private Boolean isProtected;
@JsonProperty("can_push")
private Boolean canPush;
@JsonProperty("developers_can_push")
private Boolean developersCanPush;
@JsonProperty("developers_can_merge")
private Boolean developersCanMerge;
private String commitId;
private String commitMessage;
private String commitAuthor;
private LocalDateTime commitDate;
@JsonProperty("commit")
private GitCommitResponse commit;
@JsonProperty("web_url")
private String webUrl;
}
@Data
public static class GitCommitResponse {
private String id;
private String message;
private String author_name;
@JsonProperty("authored_date")
private OffsetDateTime authoredDate;
@JsonProperty("committed_date")
private OffsetDateTime committedDate;
}
public String getCommitId() {
return commit != null ? commit.id : null;
}
public String getCommitMessage() {
return commit != null ? commit.message : null;
}
public String getCommitAuthor() {
return commit != null ? commit.author_name : null;
}
public LocalDateTime getCommitDate() {
return commit != null && commit.authoredDate != null ?
commit.authoredDate.atZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime() : null;
}
public LocalDateTime getLastUpdateTime() {
return commit != null && commit.committedDate != null ?
commit.committedDate.atZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime() : null;
}
public LocalDateTime getLastCommitTime() {
return getLastUpdateTime();
}
}

View File

@ -38,6 +38,8 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.time.LocalDateTime;
/**
* Git仓库分支服务实现
*/
@ -117,54 +119,41 @@ public class RepositoryBranchServiceImpl extends BaseServiceImpl<RepositoryBranc
return 0;
}
// 4. 获取上次成功同步的历史记录
RepositorySyncHistory lastSuccessSync = repositorySyncHistoryRepository
.findTopByExternalSystemIdAndSyncTypeAndStatusOrderByStartTimeDesc(
externalSystemId, RepositorySyncType.BRANCH, ExternalSystemSyncStatus.SUCCESS);
// 5. 筛选需要同步的项目
List<RepositoryProject> projectsToSync = projects;
if (lastSuccessSync != null) {
projectsToSync = projects.stream()
.filter(project -> project.getLastActivityAt() == null ||
project.getLastActivityAt().isAfter(lastSuccessSync.getEndTime()))
.collect(Collectors.toList());
}
if (projectsToSync.isEmpty()) {
log.info("No projects need to be synchronized for external system: {}", externalSystem.getName());
repositorySyncHistoryService.updateSyncHistory(syncHistory.getId(), ExternalSystemSyncStatus.SUCCESS, null);
return 0;
}
AtomicInteger totalSyncedBranches = new AtomicInteger(0);
List<CompletableFuture<Void>> futures = new ArrayList<>();
List<RepositoryBranch> branchesToSave = Collections.synchronizedList(new ArrayList<>());
// 6. 异步同步每个项目的分支
for (RepositoryProject project : projectsToSync) {
// 4. 异步处理每个项目
for (RepositoryProject project : projects) {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
try {
// 6.1 获取远程分支信息
// 4.1 获取当前项目在GitLab上的所有分支
List<GitBranchResponse> remoteBranches = gitServiceIntegration.branches(externalSystem, project.getProjectId());
if (remoteBranches.isEmpty()) {
log.info("No branches found for project: {}", project.getName());
return;
}
Set<String> remoteBranchNames = remoteBranches.stream()
.map(GitBranchResponse::getName)
.collect(Collectors.toSet());
// 6.2 获取本地已存在的分支
// 4.2 获取数据库中的所有分支
Map<String, RepositoryBranch> existingBranchMap = repositoryBranchRepository
.findByExternalSystemIdAndProjectIdAndDeletedFalse(externalSystemId, project.getId())
.stream()
.collect(Collectors.toMap(RepositoryBranch::getName, Function.identity()));
// 6.3 更新或创建分支
// 4.3 处理所有远程分支新增或更新
for (GitBranchResponse remoteBranch : remoteBranches) {
RepositoryBranch branch = updateOrCreateBranch(externalSystemId, project.getId(), remoteBranch, existingBranchMap);
branchesToSave.add(branch);
totalSyncedBranches.incrementAndGet();
existingBranchMap.remove(remoteBranch.getName());
}
// 4.4 处理已删除的分支
existingBranchMap.forEach((branchName, branch) -> {
branch.setDeleted(true);
branchesToSave.add(branch);
totalSyncedBranches.incrementAndGet();
});
log.info("Processed {} branches for project: {}", remoteBranches.size(), project.getName());
} catch (Exception e) {
log.error("Failed to sync branches for project: {}", project.getName(), e);
@ -188,16 +177,15 @@ public class RepositoryBranchServiceImpl extends BaseServiceImpl<RepositoryBranc
}
}
// 7. 更新同步历史为成功
// 5. 更新同步历史为成功
repositorySyncHistoryService.updateSyncHistory(syncHistory.getId(), ExternalSystemSyncStatus.SUCCESS, null);
log.info("Successfully synchronized total {} branches for external system: {}",
totalSyncedBranches.get(), externalSystem.getName());
return totalSyncedBranches.get();
} catch (Exception e) {
// 8. 更新同步历史为失败
// 6. 更新同步历史为失败
repositorySyncHistoryService.updateSyncHistory(syncHistory.getId(), ExternalSystemSyncStatus.FAILED, e.getMessage());
log.error("Failed to sync branches for external system: {}", externalSystemId, e);
throw new BusinessException(ResponseCode.REPOSITORY_BRANCH_SYNC_FAILED);
}
}
@ -224,6 +212,8 @@ public class RepositoryBranchServiceImpl extends BaseServiceImpl<RepositoryBranc
branch.setCommitAuthor(remoteBranch.getCommitAuthor());
branch.setCommitDate(remoteBranch.getCommitDate());
branch.setWebUrl(remoteBranch.getWebUrl());
branch.setLastUpdateTime(remoteBranch.getLastUpdateTime());
branch.setLastCommitTime(remoteBranch.getLastCommitTime());
return branch;
}

View File

@ -359,6 +359,8 @@ CREATE TABLE deploy_repo_branch
commit_message TEXT NULL COMMENT '最新提交信息',
commit_author VARCHAR(100) NULL COMMENT '最新提交作者',
commit_date DATETIME(6) NULL COMMENT '最新提交时间',
last_update_time DATETIME(6) NULL COMMENT '分支最后更新时间',
last_commit_time DATETIME(6) NULL COMMENT '分支最后提交时间',
web_url VARCHAR(255) NULL COMMENT '网页URL'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='代码仓库分支表';