大声道撒旦

This commit is contained in:
dengqichen 2025-01-07 16:14:24 +08:00
parent a2ccd9012c
commit 851a560afd
4 changed files with 88 additions and 30 deletions

View File

@ -6,6 +6,7 @@ import com.qqchen.deploy.backend.deploy.integration.response.*;
import com.qqchen.deploy.backend.system.enums.ExternalSystemTypeEnum;
import java.util.List;
import java.util.Map;
/**
* Jenkins集成服务接口
@ -32,7 +33,7 @@ public interface IJenkinsServiceIntegration extends IExternalSystemIntegration {
*
* @return 构建队列ID
*/
String buildWithParameters(ExternalSystem externalSystem, String jobName);
String buildWithParameters(ExternalSystem externalSystem, String jobName, Map<String, String> parameters);
/**
* 获取队列中的构建信息

View File

@ -20,8 +20,11 @@ import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import org.apache.commons.lang3.StringUtils;
@ -31,6 +34,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.stream.Collectors;
@Slf4j
@Service
@ -116,20 +120,48 @@ public class JenkinsServiceIntegration implements IJenkinsServiceIntegration {
}
@Override
public String buildWithParameters(ExternalSystem externalSystem, String jobName) {
JenkinsCrumbIssuerResponse jenkinsCrumbIssue = getJenkinsCrumbIssue();
HttpHeaders headers = createHeaders(externalSystem);
headers.set("Jenkins-Crumb", jenkinsCrumbIssue.getCrumb());
headers.set("Cookie", jenkinsCrumbIssue.getCookie());
HttpEntity<String> entity = new HttpEntity<>(headers);
String url = externalSystem.getUrl() + String.format("/job/%s/buildWithParameters", jobName);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
// 2. 从Location头获取队列ID
String location = response.getHeaders().getFirst("Location");
if (location == null) {
throw new RuntimeException("未获取到构建队列信息");
public String buildWithParameters(ExternalSystem externalSystem, String jobName, Map<String, String> parameters) {
try {
// 1. 获取Crumb
JenkinsCrumbIssuerResponse jenkinsCrumbIssue = getJenkinsCrumbIssue();
// 2. 构建URL
String url = UriComponentsBuilder.fromHttpUrl(externalSystem.getUrl())
.path("/job/")
.path(jobName)
.path("/buildWithParameters")
.build()
.toUriString();
// 3. 构建请求头
HttpHeaders headers = createHeaders(externalSystem);
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("Jenkins-Crumb", jenkinsCrumbIssue.getCrumb());
headers.set("Cookie", jenkinsCrumbIssue.getCookie());
// 4. 构建请求体
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
parameters.forEach(formData::add);
// 5. 发送请求
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(formData, headers);
ResponseEntity<String> response = restTemplate.exchange(
url,
HttpMethod.POST,
entity,
String.class
);
// 6. 获取队列ID
String location = response.getHeaders().getFirst("Location");
if (location == null) {
throw new RuntimeException("未获取到构建队列信息");
}
return extractQueueId(location);
} catch (Exception e) {
log.error("Failed to trigger Jenkins build: job={}, error={}", jobName, e.getMessage(), e);
throw new RuntimeException("触发Jenkins构建失败: " + jobName, e);
}
return extractQueueId(location);
}
@Override
@ -223,18 +255,18 @@ public class JenkinsServiceIntegration implements IJenkinsServiceIntegration {
* 通用的Jenkins API调用方法
*
* @param externalSystem Jenkins系统配置
* @param path API路径
* @param treeQuery tree查询参数
* @param jsonArrayKey JSON数组的key
* @param responseType 响应类型的Class对象用于类型安全
* @param <T> 响应类型泛型
* @param path API路径
* @param treeQuery tree查询参数
* @param jsonArrayKey JSON数组的key
* @param responseType 响应类型的Class对象用于类型安全
* @param <T> 响应类型泛型
* @return API响应结果
*/
private <T> List<T> callJenkinsApi(ExternalSystem externalSystem,
String path,
String treeQuery,
String jsonArrayKey,
Class<T> responseType) {
String path,
String treeQuery,
String jsonArrayKey,
Class<T> responseType) {
try {
String url = UriComponentsBuilder.fromHttpUrl(externalSystem.getUrl())
.path(path)
@ -302,7 +334,7 @@ public class JenkinsServiceIntegration implements IJenkinsServiceIntegration {
* 查询视图下的所有任务
*
* @param externalSystem Jenkins系统配置
* @param viewName 视图名称
* @param viewName 视图名称
* @return 任务列表
*/
public List<JenkinsJobResponse> listJobs(ExternalSystem externalSystem, String viewName) {

View File

@ -18,6 +18,7 @@ import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -61,7 +62,9 @@ public class DeployNodeDelegate extends BaseNodeDelegate<DeployNodePanelVariable
protected void executeInternal(DelegateExecution execution, DeployNodePanelVariables panelVariables, DeployNodeLocalVariables localVariables) {
ExternalSystem externalSystem = externalSystemRepository.findById(localVariables.getExternalSystemId()).orElseThrow(() -> new RuntimeException("ExternalSystem not found!!!"));
JenkinsJob jenkinsJob = jenkinsJobRepository.findById(localVariables.getJobId()).orElseThrow(() -> new RuntimeException("Jenkins job not found!!!"));
String queueId = jenkinsServiceIntegration.buildWithParameters(externalSystem, jenkinsJob.getJobName());
Map<String, String> parameters = new HashMap<>();
parameters.put("PIPELINE_SCRIPT", localVariables.getScript());
String queueId = jenkinsServiceIntegration.buildWithParameters(externalSystem, jenkinsJob.getJobName(), parameters);
JenkinsQueueBuildInfoResponse buildInfo = waitForBuildToStart(queueId);
// 3. 轮询构建状态
pollBuildStatus(externalSystem, jenkinsJob.getJobName(), buildInfo.getBuildNumber());

View File

@ -1,6 +1,7 @@
package com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.qqchen.deploy.backend.workflow.annotation.CodeEditorConfig;
import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -36,5 +37,26 @@ public class DeployNodeLocalVariables extends BaseNodeLocalVariables {
)
private Long jobId;
@SchemaProperty(
title = "Pipeline script",
description = "流水线脚本",
required = true,
format = "monaco-editor", // 使用 Monaco Editor
defaultValue = "#!/bin/bash\n\necho \"Hello World\"",
codeEditor = @CodeEditorConfig(
language = "shell",
theme = "vs-dark",
minimap = false,
lineNumbers = true,
wordWrap = true,
fontSize = 14,
tabSize = 2,
autoComplete = true,
folding = true
),
order = 6
)
private String script;
}