大声道撒旦
This commit is contained in:
parent
a2ccd9012c
commit
851a560afd
@ -6,6 +6,7 @@ import com.qqchen.deploy.backend.deploy.integration.response.*;
|
|||||||
import com.qqchen.deploy.backend.system.enums.ExternalSystemTypeEnum;
|
import com.qqchen.deploy.backend.system.enums.ExternalSystemTypeEnum;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Jenkins集成服务接口
|
* Jenkins集成服务接口
|
||||||
@ -32,7 +33,7 @@ public interface IJenkinsServiceIntegration extends IExternalSystemIntegration {
|
|||||||
*
|
*
|
||||||
* @return 构建队列ID
|
* @return 构建队列ID
|
||||||
*/
|
*/
|
||||||
String buildWithParameters(ExternalSystem externalSystem, String jobName);
|
String buildWithParameters(ExternalSystem externalSystem, String jobName, Map<String, String> parameters);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取队列中的构建信息
|
* 获取队列中的构建信息
|
||||||
|
|||||||
@ -20,8 +20,11 @@ import org.springframework.http.HttpEntity;
|
|||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Service;
|
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.client.RestTemplate;
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@ -31,6 +34,7 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@ -116,20 +120,48 @@ public class JenkinsServiceIntegration implements IJenkinsServiceIntegration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String buildWithParameters(ExternalSystem externalSystem, String jobName) {
|
public String buildWithParameters(ExternalSystem externalSystem, String jobName, Map<String, String> parameters) {
|
||||||
JenkinsCrumbIssuerResponse jenkinsCrumbIssue = getJenkinsCrumbIssue();
|
try {
|
||||||
HttpHeaders headers = createHeaders(externalSystem);
|
// 1. 获取Crumb
|
||||||
headers.set("Jenkins-Crumb", jenkinsCrumbIssue.getCrumb());
|
JenkinsCrumbIssuerResponse jenkinsCrumbIssue = getJenkinsCrumbIssue();
|
||||||
headers.set("Cookie", jenkinsCrumbIssue.getCookie());
|
|
||||||
HttpEntity<String> entity = new HttpEntity<>(headers);
|
// 2. 构建URL
|
||||||
String url = externalSystem.getUrl() + String.format("/job/%s/buildWithParameters", jobName);
|
String url = UriComponentsBuilder.fromHttpUrl(externalSystem.getUrl())
|
||||||
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
|
.path("/job/")
|
||||||
// 2. 从Location头获取队列ID
|
.path(jobName)
|
||||||
String location = response.getHeaders().getFirst("Location");
|
.path("/buildWithParameters")
|
||||||
if (location == null) {
|
.build()
|
||||||
throw new RuntimeException("未获取到构建队列信息");
|
.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
|
@Override
|
||||||
@ -223,18 +255,18 @@ public class JenkinsServiceIntegration implements IJenkinsServiceIntegration {
|
|||||||
* 通用的Jenkins API调用方法
|
* 通用的Jenkins API调用方法
|
||||||
*
|
*
|
||||||
* @param externalSystem Jenkins系统配置
|
* @param externalSystem Jenkins系统配置
|
||||||
* @param path API路径
|
* @param path API路径
|
||||||
* @param treeQuery tree查询参数
|
* @param treeQuery tree查询参数
|
||||||
* @param jsonArrayKey JSON数组的key
|
* @param jsonArrayKey JSON数组的key
|
||||||
* @param responseType 响应类型的Class对象,用于类型安全
|
* @param responseType 响应类型的Class对象,用于类型安全
|
||||||
* @param <T> 响应类型泛型
|
* @param <T> 响应类型泛型
|
||||||
* @return API响应结果
|
* @return API响应结果
|
||||||
*/
|
*/
|
||||||
private <T> List<T> callJenkinsApi(ExternalSystem externalSystem,
|
private <T> List<T> callJenkinsApi(ExternalSystem externalSystem,
|
||||||
String path,
|
String path,
|
||||||
String treeQuery,
|
String treeQuery,
|
||||||
String jsonArrayKey,
|
String jsonArrayKey,
|
||||||
Class<T> responseType) {
|
Class<T> responseType) {
|
||||||
try {
|
try {
|
||||||
String url = UriComponentsBuilder.fromHttpUrl(externalSystem.getUrl())
|
String url = UriComponentsBuilder.fromHttpUrl(externalSystem.getUrl())
|
||||||
.path(path)
|
.path(path)
|
||||||
@ -302,7 +334,7 @@ public class JenkinsServiceIntegration implements IJenkinsServiceIntegration {
|
|||||||
* 查询视图下的所有任务
|
* 查询视图下的所有任务
|
||||||
*
|
*
|
||||||
* @param externalSystem Jenkins系统配置
|
* @param externalSystem Jenkins系统配置
|
||||||
* @param viewName 视图名称
|
* @param viewName 视图名称
|
||||||
* @return 任务列表
|
* @return 任务列表
|
||||||
*/
|
*/
|
||||||
public List<JenkinsJobResponse> listJobs(ExternalSystem externalSystem, String viewName) {
|
public List<JenkinsJobResponse> listJobs(ExternalSystem externalSystem, String viewName) {
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import org.flowable.engine.delegate.DelegateExecution;
|
|||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
@ -61,7 +62,9 @@ public class DeployNodeDelegate extends BaseNodeDelegate<DeployNodePanelVariable
|
|||||||
protected void executeInternal(DelegateExecution execution, DeployNodePanelVariables panelVariables, DeployNodeLocalVariables localVariables) {
|
protected void executeInternal(DelegateExecution execution, DeployNodePanelVariables panelVariables, DeployNodeLocalVariables localVariables) {
|
||||||
ExternalSystem externalSystem = externalSystemRepository.findById(localVariables.getExternalSystemId()).orElseThrow(() -> new RuntimeException("ExternalSystem not found!!!"));
|
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!!!"));
|
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);
|
JenkinsQueueBuildInfoResponse buildInfo = waitForBuildToStart(queueId);
|
||||||
// 3. 轮询构建状态
|
// 3. 轮询构建状态
|
||||||
pollBuildStatus(externalSystem, jenkinsJob.getJobName(), buildInfo.getBuildNumber());
|
pollBuildStatus(externalSystem, jenkinsJob.getJobName(), buildInfo.getBuildNumber());
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables;
|
package com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.qqchen.deploy.backend.workflow.annotation.CodeEditorConfig;
|
||||||
import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty;
|
import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@ -36,5 +37,26 @@ public class DeployNodeLocalVariables extends BaseNodeLocalVariables {
|
|||||||
)
|
)
|
||||||
private Long jobId;
|
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;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user