大声道撒旦
This commit is contained in:
parent
a23e7237a2
commit
ec79cfa018
@ -66,7 +66,6 @@ public class JenkinsBaseBuildVariables {
|
||||
private String jobId;
|
||||
|
||||
|
||||
|
||||
@SchemaProperty(
|
||||
title = "Pipeline script",
|
||||
description = "流水线脚本",
|
||||
@ -84,8 +83,59 @@ public class JenkinsBaseBuildVariables {
|
||||
autoComplete = true,
|
||||
folding = true
|
||||
),
|
||||
order = 6
|
||||
order = 5
|
||||
)
|
||||
private String script;
|
||||
//
|
||||
// @SchemaProperty(
|
||||
// title = "绑定三方Git系统",
|
||||
// description = "请选择三方Git系统",
|
||||
// required = true,
|
||||
// dataSource = @SchemaPropertyDataSource(
|
||||
// type = "api",
|
||||
// url = "/api/v1/external-system/list?type=GIT",
|
||||
// valueField = "id",
|
||||
// labelField = "name"
|
||||
// ),
|
||||
// order = 6
|
||||
// )
|
||||
// private String gitExternalSystemId;
|
||||
//
|
||||
// @SchemaProperty(
|
||||
// title = "绑定Git项目",
|
||||
// description = "绑定Git项目",
|
||||
// required = true,
|
||||
// dataSource = @SchemaPropertyDataSource(
|
||||
// type = "api",
|
||||
// url = "/api/v1/repository-project/list",
|
||||
// valueField = "repoProjectId",
|
||||
// labelField = "name",
|
||||
// dependsOn = {"gitExternalSystemId"},
|
||||
// params = {
|
||||
// @SchemaPropertyDataSourceParam(name = "externalSystemId", value = "${gitExternalSystemId}")
|
||||
// }
|
||||
// ),
|
||||
// order = 7
|
||||
// )
|
||||
// private String repoProjectId;
|
||||
//
|
||||
// @SchemaProperty(
|
||||
// title = "绑定代码分支",
|
||||
// description = "请选择代码分支",
|
||||
// required = true,
|
||||
// dataSource = @SchemaPropertyDataSource(
|
||||
// type = "api",
|
||||
// url = "/api/v1/repository-branch/list",
|
||||
// valueField = "name",
|
||||
// labelField = "name",
|
||||
// dependsOn = {"gitExternalSystemId", "repoProjectId"},
|
||||
// params = {
|
||||
// @SchemaPropertyDataSourceParam(name = "externalSystemId", value = "${gitExternalSystemId}"),
|
||||
// @SchemaPropertyDataSourceParam(name = "repoProjectId", value = "${repoProjectId}")
|
||||
// }
|
||||
// ),
|
||||
// order = 8
|
||||
// )
|
||||
// private String branch;
|
||||
|
||||
}
|
||||
@ -21,8 +21,8 @@ import org.hibernate.annotations.Type;
|
||||
@Table(name = "deploy_app_config")
|
||||
public class DeployAppConfig extends Entity<Long> {
|
||||
|
||||
@Column(name = "branch", nullable = false)
|
||||
private String branch;
|
||||
// @Column(name = "branch", nullable = false)
|
||||
// private String branch;
|
||||
|
||||
@Column(name = "build_type", nullable = false)
|
||||
@Enumerated(EnumType.STRING)
|
||||
|
||||
@ -28,6 +28,19 @@ import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
@ -103,10 +116,6 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration
|
||||
return new HttpEntity<>(headers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExternalSystemTypeEnum getSystemType() {
|
||||
return ExternalSystemTypeEnum.JENKINS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JenkinsCrumbIssuerResponse getJenkinsCrumbIssue() {
|
||||
@ -120,6 +129,11 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration
|
||||
@Override
|
||||
public String buildWithParameters(ExternalSystem externalSystem, String jobName, Map<String, String> parameters) {
|
||||
try {
|
||||
// 如果参数中包含PIPELINE_SCRIPT,确保Job配置中有该参数
|
||||
if (parameters.containsKey("PIPELINE_SCRIPT")) {
|
||||
ensurePipelineScriptParameter(externalSystem, jobName);
|
||||
}
|
||||
|
||||
// 1. 获取Crumb
|
||||
JenkinsCrumbIssuerResponse jenkinsCrumbIssue = getJenkinsCrumbIssue();
|
||||
|
||||
@ -162,6 +176,177 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保Jenkins Job配置中包含PIPELINE_SCRIPT参数
|
||||
*/
|
||||
private void ensurePipelineScriptParameter(ExternalSystem externalSystem, String jobName) {
|
||||
try {
|
||||
// 获取 Crumb
|
||||
JenkinsCrumbIssuerResponse jenkinsCrumbIssue = getJenkinsCrumbIssue();
|
||||
|
||||
// 获取Job配置
|
||||
String configUrl = String.format("%s/job/%s/config.xml", externalSystem.getUrl(), jobName);
|
||||
HttpHeaders headers = createHeaders(externalSystem);
|
||||
headers.set(HttpHeaders.ACCEPT_CHARSET, "UTF-8");
|
||||
headers.set("Jenkins-Crumb", jenkinsCrumbIssue.getCrumb());
|
||||
headers.set("Cookie", jenkinsCrumbIssue.getCookie());
|
||||
HttpEntity<String> entity = new HttpEntity<>(headers);
|
||||
ResponseEntity<String> response = restTemplate.exchange(
|
||||
configUrl,
|
||||
HttpMethod.GET,
|
||||
entity,
|
||||
String.class
|
||||
);
|
||||
|
||||
if (response.getBody() == null) {
|
||||
throw new RuntimeException("无法获取Jenkins Job配置");
|
||||
}
|
||||
|
||||
// 解析XML
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
||||
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||||
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
|
||||
// 使用UTF-8编码解析XML
|
||||
InputSource is = new InputSource(new StringReader(response.getBody()));
|
||||
is.setEncoding("UTF-8");
|
||||
Document doc = builder.parse(is);
|
||||
|
||||
// 检查是否已存在PIPELINE_SCRIPT参数
|
||||
NodeList parameterDefinitions = doc.getElementsByTagName("parameterDefinitions");
|
||||
if (parameterDefinitions.getLength() > 0) {
|
||||
NodeList parameters = parameterDefinitions.item(0).getChildNodes();
|
||||
for (int i = 0; i < parameters.getLength(); i++) {
|
||||
Node parameter = parameters.item(i);
|
||||
if (parameter.getNodeType() == Node.ELEMENT_NODE) {
|
||||
NodeList parameterChildren = parameter.getChildNodes();
|
||||
for (int j = 0; j < parameterChildren.getLength(); j++) {
|
||||
Node child = parameterChildren.item(j);
|
||||
if ("name".equals(child.getNodeName()) && "PIPELINE_SCRIPT".equals(child.getTextContent())) {
|
||||
// 参数已存在,无需添加
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 需要添加PIPELINE_SCRIPT参数
|
||||
Element root = doc.getDocumentElement();
|
||||
|
||||
// 获取或创建properties元素
|
||||
NodeList propertiesList = doc.getElementsByTagName("properties");
|
||||
Element properties;
|
||||
if (propertiesList.getLength() == 0) {
|
||||
properties = doc.createElement("properties");
|
||||
root.appendChild(properties);
|
||||
} else {
|
||||
properties = (Element) propertiesList.item(0);
|
||||
}
|
||||
|
||||
// 获取或创建ParametersDefinitionProperty元素
|
||||
NodeList paramDefProps = properties.getElementsByTagName("hudson.model.ParametersDefinitionProperty");
|
||||
Element paramDefProp;
|
||||
if (paramDefProps.getLength() == 0) {
|
||||
paramDefProp = doc.createElement("hudson.model.ParametersDefinitionProperty");
|
||||
properties.appendChild(paramDefProp);
|
||||
} else {
|
||||
paramDefProp = (Element) paramDefProps.item(0);
|
||||
}
|
||||
|
||||
// 获取或创建parameterDefinitions元素
|
||||
NodeList paramDefs = paramDefProp.getElementsByTagName("parameterDefinitions");
|
||||
Element parameterDefs;
|
||||
if (paramDefs.getLength() == 0) {
|
||||
parameterDefs = doc.createElement("parameterDefinitions");
|
||||
paramDefProp.appendChild(parameterDefs);
|
||||
} else {
|
||||
parameterDefs = (Element) paramDefs.item(0);
|
||||
}
|
||||
|
||||
// 创建PIPELINE_SCRIPT参数定义
|
||||
Element stringParam = doc.createElement("hudson.model.StringParameterDefinition");
|
||||
|
||||
Element name = doc.createElement("name");
|
||||
name.setTextContent("PIPELINE_SCRIPT");
|
||||
stringParam.appendChild(name);
|
||||
|
||||
Element description = doc.createElement("description");
|
||||
description.setTextContent("Pipeline脚本内容");
|
||||
stringParam.appendChild(description);
|
||||
|
||||
Element defaultValue = doc.createElement("defaultValue");
|
||||
defaultValue.setTextContent("");
|
||||
stringParam.appendChild(defaultValue);
|
||||
|
||||
Element trim = doc.createElement("trim");
|
||||
trim.setTextContent("false");
|
||||
stringParam.appendChild(trim);
|
||||
|
||||
parameterDefs.appendChild(stringParam);
|
||||
|
||||
// 更新Job配置时设置正确的编码
|
||||
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||
Transformer transformer = transformerFactory.newTransformer();
|
||||
transformer.setOutputProperty(javax.xml.transform.OutputKeys.ENCODING, "UTF-8");
|
||||
transformer.setOutputProperty(javax.xml.transform.OutputKeys.VERSION, "1.1");
|
||||
transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "yes");
|
||||
transformer.setOutputProperty(javax.xml.transform.OutputKeys.STANDALONE, "no");
|
||||
StringWriter writer = new StringWriter();
|
||||
transformer.transform(new DOMSource(doc), new StreamResult(writer));
|
||||
String updatedConfig = writer.toString();
|
||||
|
||||
// 更新Job配置
|
||||
HttpHeaders updateHeaders = createHeaders(externalSystem);
|
||||
updateHeaders.setContentType(MediaType.APPLICATION_XML);
|
||||
updateHeaders.set(HttpHeaders.ACCEPT_CHARSET, "UTF-8");
|
||||
updateHeaders.set("Content-Type", "application/xml; charset=utf-8");
|
||||
updateHeaders.set("Jenkins-Crumb", jenkinsCrumbIssue.getCrumb());
|
||||
updateHeaders.set("Cookie", jenkinsCrumbIssue.getCookie());
|
||||
HttpEntity<String> updateEntity = new HttpEntity<>(updatedConfig, updateHeaders);
|
||||
restTemplate.exchange(
|
||||
configUrl,
|
||||
HttpMethod.POST,
|
||||
updateEntity,
|
||||
String.class
|
||||
);
|
||||
|
||||
log.info("Successfully added PIPELINE_SCRIPT parameter to Jenkins job: {}", jobName);
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to ensure PIPELINE_SCRIPT parameter for Jenkins job: {}, error: {}", jobName, e.getMessage(), e);
|
||||
throw new RuntimeException("确保Jenkins Job PIPELINE_SCRIPT参数失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理XML内容,移除无效字符
|
||||
*/
|
||||
private String cleanXmlContent(String xml) {
|
||||
if (xml == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// 移除XML中的无效字符
|
||||
StringBuilder cleanXml = new StringBuilder();
|
||||
for (int i = 0; i < xml.length(); i++) {
|
||||
char c = xml.charAt(i);
|
||||
// XML 1.1规范允许的字符范围(比1.0更宽松)
|
||||
if ((c == 0x9) ||
|
||||
(c == 0xA) ||
|
||||
(c == 0xD) ||
|
||||
((c >= 0x20) && (c <= 0xD7FF)) ||
|
||||
((c >= 0xE000) && (c <= 0xFFFD)) ||
|
||||
((c >= 0x10000) && (c <= 0x10FFFF)) ||
|
||||
// 允许一些常见的控制字符
|
||||
(c >= 0x1) && (c <= 0x1F)) {
|
||||
cleanXml.append(c);
|
||||
}
|
||||
}
|
||||
return cleanXml.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JenkinsQueueBuildInfoResponse getQueuedBuildInfo(String queueId) {
|
||||
ExternalSystem externalSystem = systemRepository.findById(1L).orElseThrow(() -> new RuntimeException("没有找到三方系统"));
|
||||
|
||||
@ -16,12 +16,6 @@ public class RepositoryBranchQuery extends BaseQuery {
|
||||
@QueryField(field = "name", type = QueryType.LIKE)
|
||||
private String name;
|
||||
|
||||
@QueryField(field = "project_id")
|
||||
private Long projectId;
|
||||
|
||||
@QueryField(field = "external_system_id")
|
||||
private Long externalSystemId;
|
||||
|
||||
@QueryField(field = "is_default_branch")
|
||||
private Boolean isDefaultBranch;
|
||||
|
||||
@ -30,4 +24,13 @@ public class RepositoryBranchQuery extends BaseQuery {
|
||||
|
||||
@QueryField(field = "commit_author", type = QueryType.LIKE)
|
||||
private String commitAuthor;
|
||||
|
||||
@QueryField(field = "externalSystemId", type = QueryType.EQUAL)
|
||||
private Long externalSystemId;
|
||||
|
||||
@QueryField(field = "projectId", type = QueryType.EQUAL)
|
||||
private Long projectId;
|
||||
|
||||
@QueryField(field = "repoProjectId", type = QueryType.EQUAL)
|
||||
private Long repoProjectId;
|
||||
}
|
||||
@ -22,15 +22,15 @@ public class RepositoryProjectQuery extends BaseQuery {
|
||||
@QueryField(field = "visibility")
|
||||
private String visibility;
|
||||
|
||||
@QueryField(field = "externalSystemId")
|
||||
@QueryField(field = "externalSystemId", type = QueryType.EQUAL)
|
||||
private Long externalSystemId;
|
||||
|
||||
@QueryField(field = "projectId")
|
||||
@QueryField(field = "projectId", type = QueryType.EQUAL)
|
||||
private Long projectId;
|
||||
|
||||
@QueryField(field = "repoGroupId")
|
||||
@QueryField(field = "repoGroupId", type = QueryType.EQUAL)
|
||||
private Long repoGroupId;
|
||||
|
||||
@QueryField(field = "repoProjectId")
|
||||
@QueryField(field = "repoProjectId", type = QueryType.EQUAL)
|
||||
private Long repoProjectId;
|
||||
}
|
||||
@ -62,6 +62,7 @@ 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!!!"));
|
||||
// Pipeline脚本模板
|
||||
Map<String, String> parameters = new HashMap<>();
|
||||
parameters.put("PIPELINE_SCRIPT", localVariables.getScript());
|
||||
String queueId = jenkinsServiceIntegration.buildWithParameters(externalSystem, jenkinsJob.getJobName(), parameters);
|
||||
|
||||
@ -652,7 +652,6 @@ CREATE TABLE deploy_app_config
|
||||
form_variables_schema TEXT NULL,
|
||||
language_type VARCHAR(50) NOT NULL,
|
||||
workflow_definition_id BIGINT NOT NULL,
|
||||
branch VARCHAR(50) NOT NULL,
|
||||
|
||||
environment_id BIGINT NOT NULL,
|
||||
application_id BIGINT NOT NULL,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user