v4 提交新的模型,但是模型不能运行,如果要运行,把ci-process卸载pom
This commit is contained in:
parent
a9820840f4
commit
42759b8f40
52
.idea/CopilotChatHistory.xml
generated
52
.idea/CopilotChatHistory.xml
generated
File diff suppressed because one or more lines are too long
2
.idea/compiler.xml
generated
2
.idea/compiler.xml
generated
@ -14,8 +14,8 @@
|
|||||||
<entry name="$MAVEN_REPOSITORY$/org/mapstruct/mapstruct/1.6.2/mapstruct-1.6.2.jar" />
|
<entry name="$MAVEN_REPOSITORY$/org/mapstruct/mapstruct/1.6.2/mapstruct-1.6.2.jar" />
|
||||||
</processorPath>
|
</processorPath>
|
||||||
<module name="ci-scm-repository" />
|
<module name="ci-scm-repository" />
|
||||||
<module name="spring-boot-starter-protection" />
|
|
||||||
<module name="pipeline-ci-process-api" />
|
<module name="pipeline-ci-process-api" />
|
||||||
|
<module name="spring-boot-starter-protection" />
|
||||||
<module name="spring-boot-starter-monitor" />
|
<module name="spring-boot-starter-monitor" />
|
||||||
<module name="module-system-biz" />
|
<module name="module-system-biz" />
|
||||||
<module name="ci-quality" />
|
<module name="ci-quality" />
|
||||||
|
@ -19,12 +19,12 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON 工具类
|
* JSON 工具类 ,经量用hutool的
|
||||||
*
|
*
|
||||||
* @author mianbin
|
* @author mianbin
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class JsonUtils {
|
public class JsonUtils extends JSONUtil {
|
||||||
|
|
||||||
private static ObjectMapper objectMapper = new ObjectMapper();
|
private static ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
@ -25,7 +25,14 @@ public interface IModelTemplate {
|
|||||||
@Schema(title = "变量", required = true)
|
@Schema(title = "变量", required = true)
|
||||||
Map<String, String> getVariables();
|
Map<String, String> getVariables();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判读是否来自于模板
|
||||||
|
*
|
||||||
|
* @return true 是来自于模板|false 不是来自于模板
|
||||||
|
*/
|
||||||
default boolean fromTemplate() {
|
default boolean fromTemplate() {
|
||||||
return getTemplate() != null && !getTemplate().isEmpty();
|
String template = getTemplate();
|
||||||
|
return template != null && !template.isEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cd.casic.ci.common.pipeline.container;
|
package cd.casic.ci.common.pipeline.container;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.type.agent.AgentType;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
package cd.casic.ci.common.pipeline.container;
|
package cd.casic.ci.common.pipeline.container;
|
||||||
|
|
||||||
import cd.casic.ci.common.pipeline.IModelTemplate;
|
import cd.casic.ci.common.pipeline.IModelTemplate;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
||||||
import cd.casic.ci.common.pipeline.pojo.time.BuildRecordTimeCost;
|
import cd.casic.ci.common.pipeline.pojo.time.BuildRecordTimeCost;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.Getter;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -20,8 +24,8 @@ import java.util.Map;
|
|||||||
* @Filename:Container
|
* @Filename:Container
|
||||||
* @description:Todo
|
* @description:Todo
|
||||||
*/
|
*/
|
||||||
|
@Data
|
||||||
|
@SuperBuilder
|
||||||
@Schema(title = "流水线模型-多态基类")
|
@Schema(title = "流水线模型-多态基类")
|
||||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type")
|
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type")
|
||||||
@JsonSubTypes({
|
@JsonSubTypes({
|
||||||
@ -29,50 +33,65 @@ import java.util.Map;
|
|||||||
@JsonSubTypes.Type(value = NormalContainer.class, name = NormalContainer.classType),
|
@JsonSubTypes.Type(value = NormalContainer.class, name = NormalContainer.classType),
|
||||||
@JsonSubTypes.Type(value = VMBuildContainer.class, name = VMBuildContainer.classType)
|
@JsonSubTypes.Type(value = VMBuildContainer.class, name = VMBuildContainer.classType)
|
||||||
})
|
})
|
||||||
public interface Container extends IModelTemplate {
|
@Getter
|
||||||
String getId();
|
@AllArgsConstructor
|
||||||
void setId(String id);
|
public abstract class Container implements IModelTemplate {
|
||||||
String getName();
|
private String id;
|
||||||
void setName(String name);
|
private String name;
|
||||||
List<Element> getElements();
|
private List<Element> elements;
|
||||||
void setElements(List<Element> elements);
|
private String status;
|
||||||
String getStatus();
|
@Deprecated
|
||||||
void setStatus(String status);
|
private Long startEpoch;
|
||||||
Long getStartEpoch();
|
@Deprecated
|
||||||
void setStartEpoch(Long startEpoch);
|
private Long systemElapsed;
|
||||||
Long getSystemElapsed();
|
@Deprecated
|
||||||
void setSystemElapsed(Long systemElapsed);
|
private Long elementElapsed;
|
||||||
Long getElementElapsed();
|
private Boolean canRetry;
|
||||||
void setElementElapsed(Long elementElapsed);
|
private String containerId;
|
||||||
Boolean getCanRetry();
|
private String containerHashId;
|
||||||
void setCanRetry(Boolean canRetry);
|
private String startVMStatus;
|
||||||
String getContainerId();
|
private Integer executeCount;
|
||||||
void setContainerId(String containerId);
|
private String jobId;
|
||||||
String getContainerHashId();
|
private Boolean containPostTaskFlag;
|
||||||
void setContainerHashId(String containerHashId);
|
private Boolean matrixGroupFlag;
|
||||||
String getStartVMStatus();
|
private BuildRecordTimeCost timeCost;
|
||||||
void setStartVMStatus(String startVMStatus);
|
private Integer startVMTaskSeq;
|
||||||
Integer getExecuteCount();
|
|
||||||
void setExecuteCount(Integer executeCount);
|
|
||||||
String getJobId();
|
|
||||||
void setJobId(String jobId);
|
|
||||||
Boolean getContainPostTaskFlag();
|
|
||||||
void setContainPostTaskFlag(Boolean containPostTaskFlag);
|
|
||||||
Boolean getMatrixGroupFlag();
|
|
||||||
void setMatrixGroupFlag(Boolean matrixGroupFlag);
|
|
||||||
BuildRecordTimeCost getTimeCost();
|
|
||||||
void setTimeCost(BuildRecordTimeCost timeCost);
|
|
||||||
Integer getStartVMTaskSeq();
|
|
||||||
void setStartVMTaskSeq(Integer startVMTaskSeq);
|
|
||||||
|
|
||||||
void resetBuildOption(int executeCount);
|
public void resetBuildOption(int executeCount) {
|
||||||
void transformCompatibility();
|
this.status = null;
|
||||||
Map<String, Object> genTaskParams();
|
this.timeCost = null;
|
||||||
String getClassType();
|
this.startEpoch = null;
|
||||||
Container getContainerById(String vmSeqId);
|
this.elementElapsed = null;
|
||||||
void retryFreshMatrixOption();
|
this.systemElapsed = null;
|
||||||
List<Container> fetchGroupContainers();
|
this.startVMStatus = null;
|
||||||
Map<String, String> fetchMatrixContext();
|
this.executeCount = executeCount;
|
||||||
Boolean containerEnabled();
|
}
|
||||||
void setContainerEnable(Boolean enable);
|
|
||||||
|
public void transformCompatibility() {
|
||||||
|
if (elements != null) {
|
||||||
|
elements.forEach(Element::transformCompatibility);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> genTaskParams() {
|
||||||
|
Map<String, Object> configParams = JSONUtil.parseObj(this).toBean(Map.class);
|
||||||
|
if (elements != null && !elements.isEmpty()) {
|
||||||
|
configParams.put("elements", List.of());
|
||||||
|
}
|
||||||
|
return configParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract String getClassType();
|
||||||
|
|
||||||
|
public abstract Container getContainerById(String vmSeqId);
|
||||||
|
|
||||||
|
public abstract void retryFreshMatrixOption();
|
||||||
|
|
||||||
|
public abstract List<Container> fetchGroupContainers();
|
||||||
|
|
||||||
|
public abstract Map<String, String> fetchMatrixContext();
|
||||||
|
|
||||||
|
public abstract boolean containerEnabled();
|
||||||
|
|
||||||
|
public abstract void setContainerEnable(boolean enable);
|
||||||
}
|
}
|
@ -1,5 +1,10 @@
|
|||||||
package cd.casic.ci.common.pipeline.container;
|
package cd.casic.ci.common.pipeline.container;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.NameAndValue;
|
||||||
|
import cd.casic.ci.common.pipeline.option.JobControlOption;
|
||||||
|
import cd.casic.ci.common.pipeline.option.MatrixControlOption;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.time.BuildRecordTimeCost;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@ -130,6 +135,11 @@ public class NormalContainer implements Container {
|
|||||||
jobControlOption = jobControlOption != null ? jobControlOption.copy(enable) : new JobControlOption(enable);
|
jobControlOption = jobControlOption != null ? jobControlOption.copy(enable) : new JobControlOption(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetBuildOption(int executeCount) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void transformCompatibility() {
|
public void transformCompatibility() {
|
||||||
if (jobControlOption != null && jobControlOption.getTimeoutVar() == null || jobControlOption.getTimeoutVar().isBlank()) {
|
if (jobControlOption != null && jobControlOption.getTimeoutVar() == null || jobControlOption.getTimeoutVar().isBlank()) {
|
||||||
@ -139,4 +149,24 @@ public class NormalContainer implements Container {
|
|||||||
mutexGroup.setTimeoutVar(String.valueOf(mutexGroup.getTimeout()));
|
mutexGroup.setTimeoutVar(String.valueOf(mutexGroup.getTimeout()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> genTaskParams() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTemplate() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRef() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getVariables() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package cd.casic.ci.common.pipeline.container;
|
package cd.casic.ci.common.pipeline.container;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.IModelTemplate;
|
||||||
|
import cd.casic.ci.common.pipeline.option.StageControlOption;
|
||||||
import cd.casic.ci.common.pipeline.pojo.StagePauseCheck;
|
import cd.casic.ci.common.pipeline.pojo.StagePauseCheck;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.time.BuildRecordTimeCost;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@ -17,11 +20,10 @@ import java.util.Map;
|
|||||||
* @Filename:Stage
|
* @Filename:Stage
|
||||||
* @description:Todo
|
* @description:Todo
|
||||||
*/
|
*/
|
||||||
public class Stage {
|
@Data
|
||||||
@Data
|
@NoArgsConstructor
|
||||||
@NoArgsConstructor
|
@Schema(title = "流水线模型-阶段")
|
||||||
@Schema(title = "流水线模型-阶段")
|
public class Stage implements IModelTemplate {
|
||||||
public class Stage implements IModelTemplate {
|
|
||||||
@Schema(title = "容器集合", required = true)
|
@Schema(title = "容器集合", required = true)
|
||||||
private List<Container> containers;
|
private List<Container> containers;
|
||||||
@Schema(title = "阶段ID (系统标识,用户不可编辑)", required = false)
|
@Schema(title = "阶段ID (系统标识,用户不可编辑)", required = false)
|
||||||
@ -45,7 +47,7 @@ public class Stage {
|
|||||||
@Schema(title = "是否启用容器失败快速终止阶段", required = false)
|
@Schema(title = "是否启用容器失败快速终止阶段", required = false)
|
||||||
private Boolean fastKill;
|
private Boolean fastKill;
|
||||||
@Schema(title = "标识是否为FinallyStage,每个Model只能包含一个FinallyStage,并且处于最后位置", required = false)
|
@Schema(title = "标识是否为FinallyStage,每个Model只能包含一个FinallyStage,并且处于最后位置", required = false)
|
||||||
private Boolean finally;
|
private Boolean finallyStage;
|
||||||
@Schema(title = "当前Stage是否能重试", required = false)
|
@Schema(title = "当前Stage是否能重试", required = false)
|
||||||
private Boolean canRetry;
|
private Boolean canRetry;
|
||||||
@Schema(title = "流程控制选项", required = true)
|
@Schema(title = "流程控制选项", required = true)
|
||||||
@ -74,7 +76,7 @@ public class Stage {
|
|||||||
if (stageControlOption != null && stageControlOption.getManualTrigger() && checkIn == null) {
|
if (stageControlOption != null && stageControlOption.getManualTrigger() && checkIn == null) {
|
||||||
checkIn = StagePauseCheck.convertControlOption(stageControlOption);
|
checkIn = StagePauseCheck.convertControlOption(stageControlOption);
|
||||||
}
|
}
|
||||||
if (finally !=null && finally){
|
if (finallyStage !=null && finallyStage){
|
||||||
canRetry = false;
|
canRetry = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,4 +104,19 @@ public class Stage {
|
|||||||
public Boolean stageEnabled() {
|
public Boolean stageEnabled() {
|
||||||
return stageControlOption != null ? stageControlOption.getEnable() : true;
|
return stageControlOption != null ? stageControlOption.getEnable() : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTemplate() {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRef() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getVariables() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
package cd.casic.ci.common.pipeline.container;
|
package cd.casic.ci.common.pipeline.container;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.NameAndValue;
|
||||||
|
import cd.casic.ci.common.pipeline.enums.VMBaseOS;
|
||||||
|
import cd.casic.ci.common.pipeline.option.JobControlOption;
|
||||||
|
import cd.casic.ci.common.pipeline.option.MatrixControlOption;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.time.BuildRecordTimeCost;
|
||||||
|
import cd.casic.ci.common.pipeline.type.DispatchType;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@ -154,7 +161,7 @@ public class VMBuildContainer implements Container {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setContainerEnable(Boolean enable) {
|
public void setContainerEnable(Boolean enable) {
|
||||||
jobControlOption = jobControlOption != null ? jobControlOption.copy(enable) : new JobControlOption(enable);
|
jobControlOption = jobControlOption != null ? jobControlOption.setEnable(enable) : new JobControlOption(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.dialect;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.dialect
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:ClassicPipelineDialect
|
||||||
|
* @Date:2025/03/27 10:36
|
||||||
|
* @Filename:ClassicPipelineDialect
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class ClassicPipelineDialect implements IPipelineDialect {
|
||||||
|
@Override
|
||||||
|
public String getPipelineDialectType() {
|
||||||
|
return PipelineDialectType.CLASSIC.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportUseExpression() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportChineseVarName() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.dialect;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.dialect
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:ConstrainedPipelineDialect
|
||||||
|
* @Date:2025/03/27 10:36
|
||||||
|
* @Filename:ConstrainedPipelineDialect
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class ConstrainedPipelineDialect implements IPipelineDialect {
|
||||||
|
@Override
|
||||||
|
public String getPipelineDialectType() {
|
||||||
|
return PipelineDialectType.CONSTRAINED.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportUseExpression() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportChineseVarName() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.dialect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.dialect
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:IPipelineDialect
|
||||||
|
* @Date:2025/03/27 10:35
|
||||||
|
* @Filename:IPipelineDialect
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
public interface IPipelineDialect {
|
||||||
|
String getPipelineDialectType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. 仅支持双花括号,避免出现 bash 脚本变量在执行前被系统赋值的问题
|
||||||
|
* 2. 流程控制选项、插件入参、Job设置等流水线配置中均可使用函数
|
||||||
|
*/
|
||||||
|
boolean supportUseExpression();
|
||||||
|
/**
|
||||||
|
* 是否支持中文变量名
|
||||||
|
*/
|
||||||
|
boolean supportChineseVarName();
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.dialect;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.dialect
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:PipelineDialectType
|
||||||
|
* @Date:2025/03/27 10:36
|
||||||
|
* @Filename:PipelineDialectType
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum PipelineDialectType {
|
||||||
|
CLASSIC(new ClassicPipelineDialect()),
|
||||||
|
CONSTRAINED(new ConstrainedPipelineDialect());
|
||||||
|
|
||||||
|
private final IPipelineDialect dialect;
|
||||||
|
|
||||||
|
PipelineDialectType(IPipelineDialect dialect) {
|
||||||
|
this.dialect = dialect;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.dialect;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.enums.ChannelCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.dialect
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:PipelineDialectUtil
|
||||||
|
* @Date:2025/03/27 10:36
|
||||||
|
* @Filename:PipelineDialectUtil
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class PipelineDialectUtil {
|
||||||
|
public static IPipelineDialect getPipelineDialect(String pipelineDialectType) {
|
||||||
|
return pipelineDialectType != null ? PipelineDialectType.valueOf(pipelineDialectType).getDialect() : PipelineDialectType.CLASSIC.getDialect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IPipelineDialect getPipelineDialect(Boolean inheritedDialect, String projectDialect, String pipelineDialect) {
|
||||||
|
return getPipelineDialectType(inheritedDialect, projectDialect, pipelineDialect).getDialect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PipelineDialectType getPipelineDialectType(Boolean inheritedDialect, String projectDialect, String pipelineDialect) {
|
||||||
|
if (inheritedDialect == null || inheritedDialect) {
|
||||||
|
if (projectDialect != null) {
|
||||||
|
return PipelineDialectType.valueOf(projectDialect);
|
||||||
|
}
|
||||||
|
} else if (pipelineDialect != null) {
|
||||||
|
return PipelineDialectType.valueOf(pipelineDialect);
|
||||||
|
}
|
||||||
|
return PipelineDialectType.CLASSIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package cd.casic.ci.common.pipeline.enums;
|
package cd.casic.ci.common.pipeline.enums;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.trigger.*;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -0,0 +1,83 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.extend;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.Model;
|
||||||
|
import cd.casic.ci.common.pipeline.container.Container;
|
||||||
|
import cd.casic.ci.common.pipeline.dialect.IPipelineDialect;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.atom.BeforeDeleteParam;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.setting.PipelineSetting;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.extend
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:ModelCheckPlugin
|
||||||
|
* @Date:2025/03/27 10:39
|
||||||
|
* @Filename:ModelCheckPlugin
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
public interface ModelCheckPlugin {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查[model]编排的完整性,并返回[JobSize + ElementSize = MetaSize]所有元素数量
|
||||||
|
*
|
||||||
|
* @param userId 操作人
|
||||||
|
* @param oauthUser 当前流水线权限代持人
|
||||||
|
* @param pipelineDialect 流水线方言,只有新增/编辑流水线或模版时才需要传入
|
||||||
|
* @throws ErrorCodeException 检查失败或异常
|
||||||
|
*/
|
||||||
|
int checkModelIntegrity(
|
||||||
|
Model model,
|
||||||
|
String projectId,
|
||||||
|
String userId,
|
||||||
|
boolean isTemplate,
|
||||||
|
String oauthUser,
|
||||||
|
IPipelineDialect pipelineDialect,
|
||||||
|
String pipelineId
|
||||||
|
) throws ErrorCodeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查[setting]配置的完整性
|
||||||
|
*
|
||||||
|
* @throws ErrorCodeException 检查失败或异常
|
||||||
|
*/
|
||||||
|
void checkSettingIntegrity(PipelineSetting setting, String projectId) throws ErrorCodeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理Model--不删除里面的Element内的逻辑
|
||||||
|
*/
|
||||||
|
void clearUpModel(Model model);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在删除element前做的一些处理
|
||||||
|
* 对比sourceModel,并清理model中与之不同的Element
|
||||||
|
*
|
||||||
|
* @param existModel 目标Model(要清理的Model)
|
||||||
|
* @param sourceModel 源要比较的Model
|
||||||
|
*/
|
||||||
|
void beforeDeleteElementInExistsModel(
|
||||||
|
Model existModel,
|
||||||
|
Model sourceModel,
|
||||||
|
BeforeDeleteParam param
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查[container]下的[element]插件的超时配置是否合法。
|
||||||
|
* 如果使用了变量,则从变量表[contextMap]进行替换,如果值不符合,则抛出异常[ErrorCodeException]
|
||||||
|
*/
|
||||||
|
void checkElementTimeoutVar(Container container, Element element, Map<String, String> contextMap) throws ErrorCodeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查[container]下互斥组配置是否合法,
|
||||||
|
* 如果使用了变量,则从变量表[contextMap]进行替换,如果值不符合,则抛出异常[ErrorCodeException]
|
||||||
|
*/
|
||||||
|
void checkMutexGroup(Container container, Map<String, String> contextMap) throws ErrorCodeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否是[finallyStage]Stage的Job[container]下[JobControlOption]配置是否合法。
|
||||||
|
* 如果使用了变量,则从变量表[contextMap]进行替换,如果值不符合,则抛出异常[ErrorCodeException]
|
||||||
|
*/
|
||||||
|
void checkJobCondition(Container container, boolean finallyStage, Map<String, String> contextMap) throws ErrorCodeException;
|
||||||
|
}
|
@ -1,6 +1,16 @@
|
|||||||
package cd.casic.ci.common.pipeline.pojo;
|
package cd.casic.ci.common.pipeline.pojo;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.EnvReplacementParser;
|
||||||
|
import cd.casic.ci.common.pipeline.dialect.IPipelineDialect;
|
||||||
|
import cd.casic.ci.common.pipeline.enums.BuildStatus;
|
||||||
|
import cd.casic.ci.common.pipeline.enums.ManualReviewAction;
|
||||||
|
import cd.casic.ci.common.pipeline.option.StageControlOption;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.atom.ManualReviewParam;
|
||||||
|
import cn.hutool.captcha.generator.RandomGenerator;
|
||||||
|
import cn.hutool.core.lang.UUID;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
@ -20,6 +30,7 @@ import java.util.stream.Collectors;
|
|||||||
* @description:Todo
|
* @description:Todo
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
@Builder
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@Schema(title = "stage准入准出配置模型")
|
@Schema(title = "stage准入准出配置模型")
|
||||||
public class StagePauseCheck {
|
public class StagePauseCheck {
|
||||||
@ -192,11 +203,12 @@ public class StagePauseCheck {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static StagePauseCheck convertControlOption(StageControlOption stageControlOption) {
|
public static StagePauseCheck convertControlOption(StageControlOption stageControlOption) {
|
||||||
|
|
||||||
return new StagePauseCheck()
|
return new StagePauseCheck()
|
||||||
.setManualTrigger(stageControlOption.getManualTrigger())
|
.setManualTrigger(stageControlOption.getManualTrigger())
|
||||||
.setStatus(stageControlOption.getTriggered() ? BuildStatus.REVIEW_PROCESSED.name() : null)
|
.setStatus(stageControlOption.getTriggered() ? BuildStatus.REVIEW_PROCESSED.name() : null)
|
||||||
.setReviewGroups(List.of(new StageReviewGroup()
|
.setReviewGroups(List.of(new StageReviewGroup()
|
||||||
.setId(UUIDUtil.generate())
|
.setId(IdUtil.fastUUID())
|
||||||
.setReviewers(stageControlOption.getTriggerUsers())
|
.setReviewers(stageControlOption.getTriggerUsers())
|
||||||
.setStatus(stageControlOption.getTriggered() ? ManualReviewAction.PROCESS.name() : null)
|
.setStatus(stageControlOption.getTriggered() ? ManualReviewAction.PROCESS.name() : null)
|
||||||
.setParams(stageControlOption.getReviewParams())))
|
.setParams(stageControlOption.getReviewParams())))
|
||||||
|
@ -4,9 +4,19 @@ import cd.casic.ci.common.pipeline.IModelTemplate;
|
|||||||
import cd.casic.ci.common.pipeline.NameAndValue;
|
import cd.casic.ci.common.pipeline.NameAndValue;
|
||||||
import cd.casic.ci.common.pipeline.enums.BuildStatus;
|
import cd.casic.ci.common.pipeline.enums.BuildStatus;
|
||||||
import cd.casic.ci.common.pipeline.enums.StartType;
|
import cd.casic.ci.common.pipeline.enums.StartType;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.agent.*;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.market.MarketBuildAtomElement;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.market.MarketBuildLessAtomElement;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.market.MarketCheckImageElement;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.matrix.MatrixStatusElement;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.quality.QualityGateInElement;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.quality.QualityGateOutElement;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.trigger.*;
|
||||||
import cd.casic.ci.common.pipeline.pojo.time.BuildRecordTimeCost;
|
import cd.casic.ci.common.pipeline.pojo.time.BuildRecordTimeCost;
|
||||||
import cd.casic.ci.common.pipeline.pojo.transfer.PreStep;
|
import cd.casic.ci.common.pipeline.pojo.transfer.PreStep;
|
||||||
import cd.casic.ci.common.pipeline.utils.ElementUtils;
|
import cd.casic.ci.common.pipeline.utils.ElementUtils;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
@ -121,7 +131,7 @@ public abstract class Element implements IModelTemplate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> genTaskParams() {
|
public Map<String, Object> genTaskParams() {
|
||||||
return JsonUtil.toMutableMap(this);
|
return JSONUtil.parseObj(this).toBean(Map.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanUp() {
|
public void cleanUp() {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cd.casic.ci.common.pipeline.pojo.element;
|
package cd.casic.ci.common.pipeline.pojo.element;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -13,6 +14,7 @@ import lombok.Data;
|
|||||||
* @description:Todo
|
* @description:Todo
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
@Schema(title = "插件属性")
|
@Schema(title = "插件属性")
|
||||||
public class ElementProp {
|
public class ElementProp {
|
||||||
private String name;
|
private String name;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package cd.casic.ci.common.pipeline.pojo.market;
|
package cd.casic.ci.common.pipeline.pojo.element.market;
|
||||||
|
|
||||||
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
@ -1,4 +1,4 @@
|
|||||||
package cd.casic.ci.common.pipeline.pojo.market;
|
package cd.casic.ci.common.pipeline.pojo.element.market;
|
||||||
|
|
||||||
import cd.casic.ci.common.pipeline.NameAndValue;
|
import cd.casic.ci.common.pipeline.NameAndValue;
|
||||||
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
@ -1,4 +1,4 @@
|
|||||||
package cd.casic.ci.common.pipeline.pojo.market;
|
package cd.casic.ci.common.pipeline.pojo.element.market;
|
||||||
|
|
||||||
import cd.casic.ci.common.pipeline.NameAndValue;
|
import cd.casic.ci.common.pipeline.NameAndValue;
|
||||||
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
@ -1,4 +1,4 @@
|
|||||||
package cd.casic.ci.common.pipeline.pojo.market;
|
package cd.casic.ci.common.pipeline.pojo.element.market;
|
||||||
|
|
||||||
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
@ -1,4 +1,4 @@
|
|||||||
package cd.casic.ci.common.pipeline.pojo.matrix;
|
package cd.casic.ci.common.pipeline.pojo.element.matrix;
|
||||||
|
|
||||||
import cd.casic.ci.common.pipeline.NameAndValue;
|
import cd.casic.ci.common.pipeline.NameAndValue;
|
||||||
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
@ -1,4 +1,4 @@
|
|||||||
package cd.casic.ci.common.pipeline.pojo.quality;
|
package cd.casic.ci.common.pipeline.pojo.element.quality;
|
||||||
|
|
||||||
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
@ -1,4 +1,4 @@
|
|||||||
package cd.casic.ci.common.pipeline.pojo.quality;
|
package cd.casic.ci.common.pipeline.pojo.element.quality;
|
||||||
|
|
||||||
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
@ -0,0 +1,225 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.pojo.element.trigger;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.api.enums.TriggerRepositoryType;
|
||||||
|
import cd.casic.ci.common.pipeline.enums.StartType;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.ElementProp;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.trigger.enums.CodeEventType;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.trigger.enums.PathFilterType;
|
||||||
|
import cd.casic.ci.common.pipeline.utils.TriggerElementPropUtils;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.pojo.element.trigger
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:CodeGitWebHookTriggerElement
|
||||||
|
* @Date:2025/03/27 10:20
|
||||||
|
* @Filename:CodeGitWebHookTriggerElement
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@Schema(title = "Git事件触发", description = CodeGitWebHookTriggerElement.classType)
|
||||||
|
public class CodeGitWebHookTriggerElement extends WebHookTriggerElement {
|
||||||
|
public static final String classType = "codeGitWebHookTrigger";
|
||||||
|
public static final String MERGE_ACTION_OPEN = "open";
|
||||||
|
public static final String MERGE_ACTION_CLOSE = "close";
|
||||||
|
public static final String MERGE_ACTION_REOPEN = "reopen";
|
||||||
|
public static final String MERGE_ACTION_PUSH_UPDATE = "push-update";
|
||||||
|
public static final String MERGE_ACTION_MERGE = "merge";
|
||||||
|
public static final String PUSH_ACTION_CREATE_BRANCH = "new-branch";
|
||||||
|
public static final String PUSH_ACTION_PUSH_FILE = "push-file";
|
||||||
|
|
||||||
|
@Schema(title = "任务名称", required = true)
|
||||||
|
private String name = "Git事件触发";
|
||||||
|
|
||||||
|
@Schema(title = "id", required = false)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(title = "状态", required = false)
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(title = "仓库ID", required = true)
|
||||||
|
private String repositoryHashId;
|
||||||
|
|
||||||
|
@Schema(title = "分支名称", required = false)
|
||||||
|
private String branchName;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的分支名", required = false)
|
||||||
|
private String excludeBranchName;
|
||||||
|
|
||||||
|
@Schema(title = "路径过滤类型", required = true)
|
||||||
|
private PathFilterType pathFilterType = PathFilterType.NamePrefixFilter;
|
||||||
|
|
||||||
|
@Schema(title = "用于包含的路径", required = false)
|
||||||
|
private String includePaths;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的路径", required = false)
|
||||||
|
private String excludePaths;
|
||||||
|
|
||||||
|
@Schema(title = "用户白名单", required = false)
|
||||||
|
private List<String> includeUsers;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的user id", required = false)
|
||||||
|
private List<String> excludeUsers;
|
||||||
|
|
||||||
|
@Schema(title = "事件类型", required = false)
|
||||||
|
private CodeEventType eventType;
|
||||||
|
|
||||||
|
@Schema(title = "是否为block", required = false)
|
||||||
|
private Boolean block;
|
||||||
|
|
||||||
|
@Schema(title = "新版的git原子的类型")
|
||||||
|
private TriggerRepositoryType repositoryType;
|
||||||
|
|
||||||
|
@Schema(title = "新版的git代码库名")
|
||||||
|
private String repositoryName;
|
||||||
|
|
||||||
|
@Schema(title = "tag名称", required = false)
|
||||||
|
private String tagName;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的tag名称", required = false)
|
||||||
|
private String excludeTagName;
|
||||||
|
|
||||||
|
@Schema(title = "tag从哪条分支创建", required = false)
|
||||||
|
private String fromBranches;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的源分支名称", required = false)
|
||||||
|
private String excludeSourceBranchName;
|
||||||
|
|
||||||
|
@Schema(title = "用于包含的源分支名称", required = false)
|
||||||
|
private String includeSourceBranchName;
|
||||||
|
|
||||||
|
@Schema(title = "webhook队列", required = false)
|
||||||
|
private Boolean webhookQueue = false;
|
||||||
|
|
||||||
|
@Schema(title = "code review 状态", required = false)
|
||||||
|
private List<String> includeCrState;
|
||||||
|
|
||||||
|
@Schema(title = "code review 类型", required = false)
|
||||||
|
private List<String> includeCrTypes;
|
||||||
|
|
||||||
|
@Schema(title = "code note comment", required = false)
|
||||||
|
private String includeNoteComment;
|
||||||
|
|
||||||
|
@Schema(title = "code note 类型", required = false)
|
||||||
|
private List<String> includeNoteTypes;
|
||||||
|
|
||||||
|
@Schema(title = "是否启用回写")
|
||||||
|
private Boolean enableCheck = true;
|
||||||
|
|
||||||
|
@Schema(title = "issue事件action")
|
||||||
|
private List<String> includeIssueAction;
|
||||||
|
|
||||||
|
@Schema(title = "mr事件action")
|
||||||
|
private List<String> includeMrAction;
|
||||||
|
|
||||||
|
@Schema(title = "push事件action")
|
||||||
|
private List<String> includePushAction;
|
||||||
|
|
||||||
|
@Schema(title = "是否启用第三方过滤")
|
||||||
|
private Boolean enableThirdFilter = false;
|
||||||
|
|
||||||
|
@Schema(title = "第三方应用地址")
|
||||||
|
private String thirdUrl;
|
||||||
|
|
||||||
|
@Schema(title = "第三方应用鉴权token")
|
||||||
|
private String thirdSecretToken;
|
||||||
|
|
||||||
|
@Schema(title = "跳过WIP")
|
||||||
|
private Boolean skipWip = false;
|
||||||
|
|
||||||
|
public CodeGitWebHookTriggerElement(String name, String id, String status) {
|
||||||
|
super(name, id, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getClassType() {
|
||||||
|
return classType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String findFirstTaskIdByStartType(StartType startType) {
|
||||||
|
return StartType.WEB_HOOK.name().equals(startType.name()) ? this.id : super.findFirstTaskIdByStartType(startType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ElementProp> triggerCondition() {
|
||||||
|
List<ElementProp> props;
|
||||||
|
switch (eventType) {
|
||||||
|
case PUSH:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.vuexInput("action", joinToString(includePushAction)),
|
||||||
|
TriggerElementPropUtils.vuexInput("branchName", branchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludeBranchName", excludeBranchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("includePaths", includePaths),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludePaths", excludePaths),
|
||||||
|
TriggerElementPropUtils.staffInput("includeUsers", includeUsers),
|
||||||
|
TriggerElementPropUtils.staffInput("excludeUsers", excludeUsers)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case MERGE_REQUEST:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.vuexInput("action", joinToString(includeMrAction)),
|
||||||
|
TriggerElementPropUtils.selector("skip-wip", List.of((skipWip != null ? skipWip.toString() : "false"))),
|
||||||
|
TriggerElementPropUtils.vuexInput("branchName", branchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludeBranchName", excludeBranchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("includeSourceBranchName", includeSourceBranchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("includeSourceBranchName", includeSourceBranchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("includePaths", includePaths),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludePaths", excludePaths),
|
||||||
|
TriggerElementPropUtils.staffInput("includeUsers", includeUsers),
|
||||||
|
TriggerElementPropUtils.staffInput("excludeUsers", excludeUsers)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case MERGE_REQUEST_ACCEPT:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.vuexInput("action", "merge"),
|
||||||
|
TriggerElementPropUtils.vuexInput("branchName", branchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludeBranchName", excludeBranchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("includeSourceBranchName", includeSourceBranchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("includeSourceBranchName", includeSourceBranchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("includePaths", includePaths),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludePaths", excludePaths),
|
||||||
|
TriggerElementPropUtils.staffInput("includeUsers", includeUsers),
|
||||||
|
TriggerElementPropUtils.staffInput("excludeUsers", excludeUsers)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case TAG_PUSH:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.vuexInput("tagName", tagName),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludeTagName", excludeTagName),
|
||||||
|
TriggerElementPropUtils.vuexInput("fromBranches", fromBranches),
|
||||||
|
TriggerElementPropUtils.staffInput("includeUsers", includeUsers),
|
||||||
|
TriggerElementPropUtils.staffInput("excludeUsers", excludeUsers)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case REVIEW:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.selector("includeCrState", includeCrState),
|
||||||
|
TriggerElementPropUtils.selector("includeCrTypes", includeCrTypes)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case ISSUES:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.selector("includeIssueAction", includeIssueAction)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case NOTE:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.selector("includeNoteTypes", includeNoteTypes),
|
||||||
|
TriggerElementPropUtils.vuexInput("includeNoteComment", includeNoteComment)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
props = List.of();
|
||||||
|
}
|
||||||
|
return props.stream().filter(java.util.Objects::nonNull).toList();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,134 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.pojo.element.trigger;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.api.enums.TriggerRepositoryType;
|
||||||
|
import cd.casic.ci.common.pipeline.enums.StartType;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.ElementProp;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.trigger.enums.CodeEventType;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.trigger.enums.PathFilterType;
|
||||||
|
import cd.casic.ci.common.pipeline.utils.TriggerElementPropUtils;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.pojo.element.trigger
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:CodeGithubWebHookTriggerElement
|
||||||
|
* @Date:2025/03/27 9:42
|
||||||
|
* @Filename:CodeGithubWebHookTriggerElement
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@Schema(title = "Github事件触发", description = CodeGithubWebHookTriggerElement.classType)
|
||||||
|
public class CodeGithubWebHookTriggerElement extends WebHookTriggerElement {
|
||||||
|
public static final String classType = "codeGithubWebHookTrigger";
|
||||||
|
public static final String MERGE_ACTION_OPEN = "open";
|
||||||
|
public static final String MERGE_ACTION_CLOSE = "close";
|
||||||
|
public static final String MERGE_ACTION_REOPEN = "reopen";
|
||||||
|
public static final String MERGE_ACTION_PUSH_UPDATE = "push-update";
|
||||||
|
public static final String MERGE_ACTION_MERGE = "merge";
|
||||||
|
|
||||||
|
@Schema(title = "任务名称", required = true)
|
||||||
|
private String name = "GitHub事件触发";
|
||||||
|
|
||||||
|
@Schema(title = "id", required = false)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(title = "状态", required = false)
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(title = "仓库ID", required = true)
|
||||||
|
private String repositoryHashId;
|
||||||
|
|
||||||
|
@Schema(title = "分支名称", required = false)
|
||||||
|
private String branchName;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的分支名称", required = false)
|
||||||
|
private String excludeBranchName;
|
||||||
|
|
||||||
|
@Schema(title = "路径过滤类型", required = true)
|
||||||
|
private PathFilterType pathFilterType = PathFilterType.NamePrefixFilter;
|
||||||
|
|
||||||
|
@Schema(title = "用于包含的路径", required = false)
|
||||||
|
private String includePaths;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的路径", required = false)
|
||||||
|
private String excludePaths;
|
||||||
|
|
||||||
|
@Schema(title = "用户白名单", required = false)
|
||||||
|
private List<String> includeUsers;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的user id", required = false)
|
||||||
|
private String excludeUsers;
|
||||||
|
|
||||||
|
@Schema(title = "tag名称", required = false)
|
||||||
|
private String tagName;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的tag名称", required = false)
|
||||||
|
private String excludeTagName;
|
||||||
|
|
||||||
|
@Schema(title = "tag从哪条分支创建", required = false)
|
||||||
|
private String fromBranches;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的源分支名称", required = false)
|
||||||
|
private String excludeSourceBranchName;
|
||||||
|
|
||||||
|
@Schema(title = "用于包含的源分支名称", required = false)
|
||||||
|
private String includeSourceBranchName;
|
||||||
|
|
||||||
|
@Schema(title = "webhook队列", required = false)
|
||||||
|
private Boolean webhookQueue = false;
|
||||||
|
|
||||||
|
@Schema(title = "code review 类型", required = false)
|
||||||
|
private List<String> includeCrTypes;
|
||||||
|
|
||||||
|
@Schema(title = "是否启用回写")
|
||||||
|
private Boolean enableCheck = true;
|
||||||
|
|
||||||
|
@Schema(title = "push事件action")
|
||||||
|
private List<String> includePushAction;
|
||||||
|
|
||||||
|
@Schema(title = "是否启用第三方过滤")
|
||||||
|
private Boolean enableThirdFilter = false;
|
||||||
|
|
||||||
|
@Schema(title = "事件类型", required = false)
|
||||||
|
private CodeEventType eventType;
|
||||||
|
|
||||||
|
@Schema(title = "新版的github原子的类型")
|
||||||
|
private TriggerRepositoryType repositoryType;
|
||||||
|
|
||||||
|
@Schema(title = "新版的github代码库名")
|
||||||
|
private String repositoryName;
|
||||||
|
|
||||||
|
@Schema(title = "code review 状态", required = false)
|
||||||
|
private List<String> includeCrState;
|
||||||
|
|
||||||
|
@Schema(title = "code note comment", required = false)
|
||||||
|
private String includeNoteComment;
|
||||||
|
|
||||||
|
@Schema(title = "code note 类型", required = false)
|
||||||
|
private List<String> includeNoteTypes;
|
||||||
|
|
||||||
|
@Schema(title = "issue事件action")
|
||||||
|
private List<String> includeIssueAction;
|
||||||
|
|
||||||
|
@Schema(title = "pull request事件action")
|
||||||
|
private List<String> includeMrAction = List.of(MERGE_ACTION_OPEN, MERGE_ACTION_REOPEN, MERGE_ACTION_PUSH_UPDATE);
|
||||||
|
|
||||||
|
public CodeGithubWebHookTriggerElement(String name, String id, String status) {
|
||||||
|
super(name, id, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getClassType() {
|
||||||
|
return classType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String findFirstTaskIdByStartType(StartType startType) {
|
||||||
|
return StartType.WEB_HOOK.name().equals(startType.name()) ? this.id : super.findFirstTaskIdByStartType(startType);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,164 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.pojo.element.trigger;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.api.enums.TriggerRepositoryType;
|
||||||
|
import cd.casic.ci.common.pipeline.enums.StartType;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.ElementProp;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.trigger.enums.CodeEventType;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.trigger.enums.PathFilterType;
|
||||||
|
import cd.casic.ci.common.pipeline.utils.TriggerElementPropUtils;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.pojo.element.trigger
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:CodeGitlabWebHookTriggerElement
|
||||||
|
* @Date:2025/03/27 10:22
|
||||||
|
* @Filename:CodeGitlabWebHookTriggerElement
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@Schema(title = "GitLab仓库代码提交触发", description = CodeGitlabWebHookTriggerElement.classType)
|
||||||
|
public class CodeGitlabWebHookTriggerElement extends WebHookTriggerElement {
|
||||||
|
public static final String classType = "codeGitlabWebHookTrigger";
|
||||||
|
|
||||||
|
@Schema(title = "任务名称", required = true)
|
||||||
|
private String name = "Gitlab变更触发";
|
||||||
|
|
||||||
|
@Schema(title = "id", required = false)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(title = "状态", required = false)
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(title = "仓库ID", required = true)
|
||||||
|
private String repositoryHashId;
|
||||||
|
|
||||||
|
@Schema(title = "分支名称", required = false)
|
||||||
|
private String branchName;
|
||||||
|
|
||||||
|
@Schema(title = "新版的gitlab原子的类型")
|
||||||
|
private TriggerRepositoryType repositoryType;
|
||||||
|
|
||||||
|
@Schema(title = "新版的gitlab代码库名")
|
||||||
|
private String repositoryName;
|
||||||
|
|
||||||
|
@Schema(title = "事件类型", required = false)
|
||||||
|
private CodeEventType eventType = CodeEventType.PUSH;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的分支名", required = false)
|
||||||
|
private String excludeBranchName;
|
||||||
|
|
||||||
|
@Schema(title = "路径过滤类型", required = true)
|
||||||
|
private PathFilterType pathFilterType = PathFilterType.NamePrefixFilter;
|
||||||
|
|
||||||
|
@Schema(title = "用于包含的路径", required = false)
|
||||||
|
private String includePaths;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的路径", required = false)
|
||||||
|
private String excludePaths;
|
||||||
|
|
||||||
|
@Schema(title = "用于包含的user id", required = false)
|
||||||
|
private List<String> includeUsers;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的user id", required = false)
|
||||||
|
private List<String> excludeUsers;
|
||||||
|
|
||||||
|
@Schema(title = "是否为block", required = false)
|
||||||
|
private Boolean block;
|
||||||
|
|
||||||
|
@Schema(title = "tag名称", required = false)
|
||||||
|
private String tagName;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的tag名称", required = false)
|
||||||
|
private String excludeTagName;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的源分支名称", required = false)
|
||||||
|
private String excludeSourceBranchName;
|
||||||
|
|
||||||
|
@Schema(title = "用于包含的源分支名称", required = false)
|
||||||
|
private String includeSourceBranchName;
|
||||||
|
|
||||||
|
@Schema(title = "用于包含的提交信息", required = false)
|
||||||
|
private String includeCommitMsg;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的提交信息", required = false)
|
||||||
|
private String excludeCommitMsg;
|
||||||
|
|
||||||
|
@Schema(title = "push事件action")
|
||||||
|
private List<String> includePushAction;
|
||||||
|
|
||||||
|
@Schema(title = "mr事件action")
|
||||||
|
private List<String> includeMrAction;
|
||||||
|
|
||||||
|
public CodeGitlabWebHookTriggerElement(String name, String id, String status) {
|
||||||
|
super(name, id, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getClassType() {
|
||||||
|
return classType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String findFirstTaskIdByStartType(StartType startType) {
|
||||||
|
return StartType.WEB_HOOK.name().equals(startType.name()) ? this.id : super.findFirstTaskIdByStartType(startType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ElementProp> triggerCondition() {
|
||||||
|
List<ElementProp> props;
|
||||||
|
switch (eventType) {
|
||||||
|
case PUSH:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.vuexInput("action", joinToString(includePushAction)),
|
||||||
|
TriggerElementPropUtils.vuexInput("branchName", branchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludeBranchName", excludeBranchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("includePaths", includePaths),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludePaths", excludePaths),
|
||||||
|
TriggerElementPropUtils.staffInput("includeUsers", includeUsers),
|
||||||
|
TriggerElementPropUtils.staffInput("excludeUsers", excludeUsers)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case MERGE_REQUEST:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.vuexInput("action", joinToString(includeMrAction)),
|
||||||
|
TriggerElementPropUtils.vuexInput("branchName", branchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludeBranchName", excludeBranchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("includeSourceBranchName", includeSourceBranchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("includeSourceBranchName", includeSourceBranchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("includePaths", includePaths),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludePaths", excludePaths),
|
||||||
|
TriggerElementPropUtils.staffInput("includeUsers", includeUsers),
|
||||||
|
TriggerElementPropUtils.staffInput("excludeUsers", excludeUsers)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case MERGE_REQUEST_ACCEPT:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.vuexInput("action", "merge"),
|
||||||
|
TriggerElementPropUtils.vuexInput("branchName", branchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludeBranchName", excludeBranchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("includeSourceBranchName", includeSourceBranchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("includeSourceBranchName", includeSourceBranchName),
|
||||||
|
TriggerElementPropUtils.vuexInput("includePaths", includePaths),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludePaths", excludePaths),
|
||||||
|
TriggerElementPropUtils.staffInput("includeUsers", includeUsers),
|
||||||
|
TriggerElementPropUtils.staffInput("excludeUsers", excludeUsers)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case TAG_PUSH:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.vuexInput("tagName", tagName),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludeTagName", excludeTagName)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
props = List.of();
|
||||||
|
}
|
||||||
|
return props.stream().filter(java.util.Objects::nonNull).toList();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,100 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.pojo.element.trigger;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.api.enums.TriggerRepositoryType;
|
||||||
|
import cd.casic.ci.common.pipeline.enums.StartType;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.ElementProp;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.trigger.enums.CodeEventType;
|
||||||
|
import cd.casic.ci.common.pipeline.utils.TriggerElementPropUtils;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.pojo.element.trigger
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:CodeP4WebHookTriggerElement
|
||||||
|
* @Date:2025/03/27 10:20
|
||||||
|
* @Filename:CodeP4WebHookTriggerElement
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@Schema(title = "p4事件触发", description = CodeP4WebHookTriggerElement.classType)
|
||||||
|
public class CodeP4WebHookTriggerElement extends WebHookTriggerElement {
|
||||||
|
public static final String classType = "codeP4WebHookTrigger";
|
||||||
|
|
||||||
|
@Schema(title = "任务名称", required = true)
|
||||||
|
private String name = "P4事件触发";
|
||||||
|
|
||||||
|
@Schema(title = "id", required = false)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(title = "状态", required = false)
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(title = "数据", required = true)
|
||||||
|
private CodeP4WebHookTriggerData data;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getClassType() {
|
||||||
|
return classType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String findFirstTaskIdByStartType(StartType startType) {
|
||||||
|
return StartType.WEB_HOOK.name().equals(startType.name()) ? this.id : super.findFirstTaskIdByStartType(startType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ElementProp> triggerCondition() {
|
||||||
|
CodeP4WebHookTriggerInput input = data.getInput();
|
||||||
|
List<ElementProp> props;
|
||||||
|
switch (input.getEventType()) {
|
||||||
|
case CHANGE_COMMIT:
|
||||||
|
case CHANGE_SUBMIT:
|
||||||
|
case CHANGE_CONTENT:
|
||||||
|
case SHELVE_COMMIT:
|
||||||
|
case SHELVE_SUBMIT:
|
||||||
|
case SHELVE_DELETE:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.vuexInput("includePaths", input.getIncludePaths()),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludePaths", input.getExcludePaths())
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
props = List.of();
|
||||||
|
}
|
||||||
|
return props.stream().filter(java.util.Objects::nonNull).toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
class CodeP4WebHookTriggerData {
|
||||||
|
private CodeP4WebHookTriggerInput input;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
class CodeP4WebHookTriggerInput {
|
||||||
|
@Schema(title = "仓库ID", required = true)
|
||||||
|
private String repositoryHashId;
|
||||||
|
|
||||||
|
@Schema(title = "新版的git原子的类型")
|
||||||
|
private TriggerRepositoryType repositoryType;
|
||||||
|
|
||||||
|
@Schema(title = "新版的git代码库名")
|
||||||
|
private String repositoryName;
|
||||||
|
|
||||||
|
@Schema(title = "用于包含的路径", required = false)
|
||||||
|
private String includePaths;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的路径", required = false)
|
||||||
|
private String excludePaths;
|
||||||
|
|
||||||
|
@Schema(title = "事件类型", required = false)
|
||||||
|
private CodeEventType eventType;
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.pojo.element.trigger;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.api.enums.TriggerRepositoryType;
|
||||||
|
import cd.casic.ci.common.pipeline.enums.StartType;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.ElementProp;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.trigger.enums.PathFilterType;
|
||||||
|
import cd.casic.ci.common.pipeline.utils.TriggerElementPropUtils;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.pojo.element.trigger
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:CodeSVNWebHookTriggerElement
|
||||||
|
* @Date:2025/03/27 10:09
|
||||||
|
* @Filename:CodeSVNWebHookTriggerElement
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@Schema(title = "SVN仓库代码提交触发", description = CodeSVNWebHookTriggerElement.classType)
|
||||||
|
public class CodeSVNWebHookTriggerElement extends WebHookTriggerElement {
|
||||||
|
public static final String classType = "codeSVNWebHookTrigger";
|
||||||
|
|
||||||
|
@Schema(title = "任务名称", required = true)
|
||||||
|
private String name = "SVN事件触发";
|
||||||
|
|
||||||
|
@Schema(title = "id", required = false)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(title = "状态", required = false)
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(title = "仓库ID", required = true)
|
||||||
|
private String repositoryHashId;
|
||||||
|
|
||||||
|
@Schema(title = "路径过滤类型", required = true)
|
||||||
|
private PathFilterType pathFilterType = PathFilterType.NamePrefixFilter;
|
||||||
|
|
||||||
|
@Schema(title = "相对路径", required = true)
|
||||||
|
private String relativePath;
|
||||||
|
|
||||||
|
@Schema(title = "排除的路径", required = false)
|
||||||
|
private String excludePaths;
|
||||||
|
|
||||||
|
@Schema(title = "用户黑名单", required = false)
|
||||||
|
private List<String> excludeUsers;
|
||||||
|
|
||||||
|
@Schema(title = "用户白名单", required = false)
|
||||||
|
private List<String> includeUsers;
|
||||||
|
|
||||||
|
@Schema(title = "新版的svn原子的类型")
|
||||||
|
private TriggerRepositoryType repositoryType;
|
||||||
|
|
||||||
|
@Schema(title = "新版的svn代码库名")
|
||||||
|
private String repositoryName;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getClassType() {
|
||||||
|
return classType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String findFirstTaskIdByStartType(StartType startType) {
|
||||||
|
return StartType.WEB_HOOK.name().equals(startType.name()) ? this.id : super.findFirstTaskIdByStartType(startType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ElementProp> triggerCondition() {
|
||||||
|
return List.of(
|
||||||
|
TriggerElementPropUtils.vuexInput("relativePath", relativePath),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludePaths", excludePaths),
|
||||||
|
TriggerElementPropUtils.staffInput("includeUsers", includeUsers),
|
||||||
|
TriggerElementPropUtils.staffInput("excludeUsers", excludeUsers)
|
||||||
|
).stream().filter(java.util.Objects::nonNull).toList();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,222 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.pojo.element.trigger;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.api.enums.TriggerRepositoryType;
|
||||||
|
import cd.casic.ci.common.pipeline.enums.StartType;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.ElementProp;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.trigger.enums.CodeEventType;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.trigger.enums.PathFilterType;
|
||||||
|
import cd.casic.ci.common.pipeline.utils.TriggerElementPropUtils;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.pojo.element.trigger
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:CodeTGitWebHookTriggerElement
|
||||||
|
* @Date:2025/03/27 10:05
|
||||||
|
* @Filename:CodeTGitWebHookTriggerElement
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@Schema(title = "TGit事件触发", description = CodeTGitWebHookTriggerElement.classType)
|
||||||
|
public class CodeTGitWebHookTriggerElement extends WebHookTriggerElement {
|
||||||
|
public static final String classType = "codeTGitWebHookTrigger";
|
||||||
|
|
||||||
|
@Schema(title = "任务名称", required = true)
|
||||||
|
private String name = "TGit事件触发";
|
||||||
|
|
||||||
|
@Schema(title = "id", required = false)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(title = "状态", required = false)
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(title = "数据", required = true)
|
||||||
|
private CodeTGitWebHookTriggerData data;
|
||||||
|
|
||||||
|
public CodeTGitWebHookTriggerElement(String name, String id, String status) {
|
||||||
|
super(name, id, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getClassType() {
|
||||||
|
return classType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String findFirstTaskIdByStartType(StartType startType) {
|
||||||
|
return StartType.WEB_HOOK.name().equals(startType.name()) ? this.id : super.findFirstTaskIdByStartType(startType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ElementProp> triggerCondition() {
|
||||||
|
CodeTGitWebHookTriggerInput input = data.getInput();
|
||||||
|
List<ElementProp> props;
|
||||||
|
switch (input.getEventType()) {
|
||||||
|
case PUSH:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.vuexInput("action", joinToString(input.getIncludePushAction())),
|
||||||
|
TriggerElementPropUtils.vuexInput("branchName", input.getBranchName()),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludeBranchName", input.getExcludeBranchName()),
|
||||||
|
TriggerElementPropUtils.vuexInput("includePaths", input.getIncludePaths()),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludePaths", input.getExcludePaths()),
|
||||||
|
TriggerElementPropUtils.staffInput("includeUsers", input.getIncludeUsers()),
|
||||||
|
TriggerElementPropUtils.staffInput("excludeUsers", input.getExcludeUsers())
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case MERGE_REQUEST:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.vuexInput("action", joinToString(input.getIncludeMrAction())),
|
||||||
|
TriggerElementPropUtils.selector("skip-wip", List.of((input.getSkipWip() != null ? input.getSkipWip().toString() : "false"))),
|
||||||
|
TriggerElementPropUtils.vuexInput("branchName", input.getBranchName()),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludeBranchName", input.getExcludeBranchName()),
|
||||||
|
TriggerElementPropUtils.vuexInput("includeSourceBranchName", input.getIncludeSourceBranchName()),
|
||||||
|
TriggerElementPropUtils.vuexInput("includeSourceBranchName", input.getIncludeSourceBranchName()),
|
||||||
|
TriggerElementPropUtils.vuexInput("includePaths", input.getIncludePaths()),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludePaths", input.getExcludePaths()),
|
||||||
|
TriggerElementPropUtils.staffInput("includeUsers", input.getIncludeUsers()),
|
||||||
|
TriggerElementPropUtils.staffInput("excludeUsers", input.getExcludeUsers())
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case MERGE_REQUEST_ACCEPT:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.vuexInput("action", "merge"),
|
||||||
|
TriggerElementPropUtils.vuexInput("branchName", input.getBranchName()),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludeBranchName", input.getExcludeBranchName()),
|
||||||
|
TriggerElementPropUtils.vuexInput("includeSourceBranchName", input.getIncludeSourceBranchName()),
|
||||||
|
TriggerElementPropUtils.vuexInput("includeSourceBranchName", input.getIncludeSourceBranchName()),
|
||||||
|
TriggerElementPropUtils.vuexInput("includePaths", input.getIncludePaths()),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludePaths", input.getExcludePaths()),
|
||||||
|
TriggerElementPropUtils.staffInput("includeUsers", input.getIncludeUsers()),
|
||||||
|
TriggerElementPropUtils.staffInput("excludeUsers", input.getExcludeUsers())
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case TAG_PUSH:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.vuexInput("tagName", input.getTagName()),
|
||||||
|
TriggerElementPropUtils.vuexInput("excludeTagName", input.getExcludeTagName()),
|
||||||
|
TriggerElementPropUtils.vuexInput("fromBranches", input.getFromBranches()),
|
||||||
|
TriggerElementPropUtils.staffInput("includeUsers", input.getIncludeUsers()),
|
||||||
|
TriggerElementPropUtils.staffInput("excludeUsers", input.getExcludeUsers())
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case REVIEW:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.selector("includeCrState", input.getIncludeCrState())
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case ISSUES:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.selector("includeIssueAction", input.getIncludeIssueAction())
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case NOTE:
|
||||||
|
props = List.of(
|
||||||
|
TriggerElementPropUtils.selector("includeNoteTypes", input.getIncludeNoteTypes()),
|
||||||
|
TriggerElementPropUtils.vuexInput("includeNoteComment", input.getIncludeNoteComment())
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
props = List.of();
|
||||||
|
}
|
||||||
|
return props.stream().filter(java.util.Objects::nonNull).toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
class CodeTGitWebHookTriggerData {
|
||||||
|
private CodeTGitWebHookTriggerInput input;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
class CodeTGitWebHookTriggerInput {
|
||||||
|
@Schema(title = "仓库ID", required = true)
|
||||||
|
private String repositoryHashId;
|
||||||
|
|
||||||
|
@Schema(title = "分支名称", required = false)
|
||||||
|
private String branchName;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的分支名", required = false)
|
||||||
|
private String excludeBranchName;
|
||||||
|
|
||||||
|
@Schema(title = "路径过滤类型", required = true)
|
||||||
|
private PathFilterType pathFilterType = PathFilterType.NamePrefixFilter;
|
||||||
|
|
||||||
|
@Schema(title = "用于包含的路径", required = false)
|
||||||
|
private String includePaths;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的路径", required = false)
|
||||||
|
private String excludePaths;
|
||||||
|
|
||||||
|
@Schema(title = "用户白名单", required = false)
|
||||||
|
private List<String> includeUsers;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的user id", required = false)
|
||||||
|
private List<String> excludeUsers;
|
||||||
|
|
||||||
|
@Schema(title = "事件类型", required = false)
|
||||||
|
private CodeEventType eventType;
|
||||||
|
|
||||||
|
@Schema(title = "是否为block", required = false)
|
||||||
|
private Boolean block;
|
||||||
|
|
||||||
|
@Schema(title = "新版的git原子的类型")
|
||||||
|
private TriggerRepositoryType repositoryType;
|
||||||
|
|
||||||
|
@Schema(title = "新版的git代码库名")
|
||||||
|
private String repositoryName;
|
||||||
|
|
||||||
|
@Schema(title = "tag名称", required = false)
|
||||||
|
private String tagName;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的tag名称", required = false)
|
||||||
|
private String excludeTagName;
|
||||||
|
|
||||||
|
@Schema(title = "tag从哪条分支创建", required = false)
|
||||||
|
private String fromBranches;
|
||||||
|
|
||||||
|
@Schema(title = "用于排除的源分支名称", required = false)
|
||||||
|
private String excludeSourceBranchName;
|
||||||
|
|
||||||
|
@Schema(title = "用于包含的源分支名称", required = false)
|
||||||
|
private String includeSourceBranchName;
|
||||||
|
|
||||||
|
@Schema(title = "webhook队列", required = false)
|
||||||
|
private Boolean webhookQueue = false;
|
||||||
|
|
||||||
|
@Schema(title = "code review 状态", required = false)
|
||||||
|
private List<String> includeCrState;
|
||||||
|
|
||||||
|
@Schema(title = "code review 类型", required = false)
|
||||||
|
private List<String> includeCrTypes;
|
||||||
|
|
||||||
|
@Schema(title = "code note comment", required = false)
|
||||||
|
private String includeNoteComment;
|
||||||
|
|
||||||
|
@Schema(title = "code note 类型", required = false)
|
||||||
|
private List<String> includeNoteTypes;
|
||||||
|
|
||||||
|
@Schema(title = "是否启用回写")
|
||||||
|
private Boolean enableCheck = true;
|
||||||
|
|
||||||
|
@Schema(title = "issue事件action")
|
||||||
|
private List<String> includeIssueAction;
|
||||||
|
|
||||||
|
@Schema(title = "mr事件action")
|
||||||
|
private List<String> includeMrAction;
|
||||||
|
|
||||||
|
@Schema(title = "push事件action")
|
||||||
|
private List<String> includePushAction;
|
||||||
|
|
||||||
|
@Schema(title = "是否启用第三方过滤")
|
||||||
|
private Boolean enableThirdFilter = false;
|
||||||
|
|
||||||
|
@Schema(title = "跳过WIP")
|
||||||
|
private Boolean skipWip = false;
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.pojo.element.trigger;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.enums.StartType;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.pojo.element.trigger
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:ManualTriggerElement
|
||||||
|
* @Date:2025/03/27 10:04
|
||||||
|
* @Filename:ManualTriggerElement
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@Schema(title = "手动触发")
|
||||||
|
public class ManualTriggerElement extends Element {
|
||||||
|
public static final String classType = "manualTrigger";
|
||||||
|
|
||||||
|
@Schema(title = "任务名称", required = true)
|
||||||
|
private String name = "手动触发";
|
||||||
|
|
||||||
|
@Schema(title = "id", required = false)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(title = "状态", required = false)
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(title = "是否可跳过插件", required = false)
|
||||||
|
private Boolean canElementSkip;
|
||||||
|
|
||||||
|
@Schema(title = "是否使用最近一次的参数进行构建", required = false)
|
||||||
|
private Boolean useLatestParameters;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getClassType() {
|
||||||
|
return classType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> startTypeSet = Set.of(StartType.MANUAL.name(), StartType.SERVICE.name(), StartType.PIPELINE.name());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String findFirstTaskIdByStartType(StartType startType) {
|
||||||
|
return startTypeSet.contains(startType.name()) ? this.id : super.findFirstTaskIdByStartType(startType);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.pojo.element.trigger;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.pojo.element.trigger
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:RemoteTriggerElement
|
||||||
|
* @Date:2025/03/27 10:01
|
||||||
|
* @Filename:RemoteTriggerElement
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@Schema(title = "远程触发触发")
|
||||||
|
public class RemoteTriggerElement extends Element {
|
||||||
|
|
||||||
|
public static final String classType = "remoteTrigger";
|
||||||
|
|
||||||
|
@Schema(title = "任务名称", required = true)
|
||||||
|
private String name = "远程触发";
|
||||||
|
|
||||||
|
@Schema(title = "id", required = false)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(title = "状态", required = false)
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(title = "是否可跳过插件", required = false)
|
||||||
|
private Boolean canElementSkip;
|
||||||
|
|
||||||
|
@Schema(title = "远程触发token", required = true)
|
||||||
|
private String remoteToken;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getClassType() {
|
||||||
|
return classType;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.pojo.element.trigger;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.api.enums.TriggerRepositoryType;
|
||||||
|
import cd.casic.ci.common.pipeline.enums.StartType;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.pojo.element.trigger
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:TimerTriggerElement
|
||||||
|
* @Date:2025/03/27 10:00
|
||||||
|
* @Filename:TimerTriggerElement
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@Schema(title = "定时触发")
|
||||||
|
public class TimerTriggerElement extends Element {
|
||||||
|
public static final String classType = "timerTrigger";
|
||||||
|
|
||||||
|
@Schema(title = "任务名称", required = true)
|
||||||
|
private String name = "定时触发";
|
||||||
|
|
||||||
|
@Schema(title = "id", required = false)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(title = "状态", required = false)
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(title = "定时表达式", required = false)
|
||||||
|
@Deprecated
|
||||||
|
private String expression;
|
||||||
|
|
||||||
|
@Schema(title = "改进后的表达式", required = false)
|
||||||
|
private List<String> newExpression;
|
||||||
|
|
||||||
|
@Schema(title = "高级定时表达式", required = false)
|
||||||
|
private List<String> advanceExpression;
|
||||||
|
|
||||||
|
@Schema(title = "源代码未更新则不触发构建", required = false)
|
||||||
|
private Boolean noScm;
|
||||||
|
|
||||||
|
@Schema(title = "指定代码库分支", required = false)
|
||||||
|
private List<String> branches;
|
||||||
|
|
||||||
|
@Schema(title = "代码库类型", required = false)
|
||||||
|
private TriggerRepositoryType repositoryType;
|
||||||
|
|
||||||
|
@Schema(title = "代码库HashId", required = false)
|
||||||
|
private String repoHashId;
|
||||||
|
|
||||||
|
@Schema(title = "指定代码库别名", required = false)
|
||||||
|
private String repoName;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getClassType() {
|
||||||
|
return classType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isOldExpress() {
|
||||||
|
return (newExpression == null || newExpression.isEmpty()) &&
|
||||||
|
(advanceExpression == null || advanceExpression.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String checkAndSetSecond(String expression) {
|
||||||
|
String trimmedExpression = expression.trim();
|
||||||
|
String[] expressionParts = trimmedExpression.split(" ");
|
||||||
|
if (!"0".equals(expressionParts[0])) {
|
||||||
|
List<String> newExpressionParts = Arrays.asList(expressionParts);
|
||||||
|
newExpressionParts.set(0, "0");
|
||||||
|
return String.join(" ", newExpressionParts);
|
||||||
|
}
|
||||||
|
return trimmedExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String findFirstTaskIdByStartType(StartType startType) {
|
||||||
|
return StartType.TIME_TRIGGER.name().equals(startType.name()) ? this.id : super.findFirstTaskIdByStartType(startType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean enableRepoConfig() {
|
||||||
|
return TriggerRepositoryType.SELF.equals(repositoryType) ||
|
||||||
|
(TriggerRepositoryType.ID.equals(repositoryType) && repoHashId != null && !repoHashId.isBlank()) ||
|
||||||
|
(TriggerRepositoryType.NAME.equals(repositoryType) && repoName != null && !repoName.isBlank());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.pojo.element.trigger;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.ElementProp;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.pojo.element.trigger
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:WebHookTriggerElement
|
||||||
|
* @Date:2025/03/27 9:59
|
||||||
|
* @Filename:WebHookTriggerElement
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@Schema(title = "Webhook基础类")
|
||||||
|
public abstract class WebHookTriggerElement extends Element {
|
||||||
|
public WebHookTriggerElement(String name, String id, String status) {
|
||||||
|
super(name, id, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ElementProp> triggerCondition() {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String joinToString(List<String> list) {
|
||||||
|
return list == null || list.isEmpty() ? "" : String.join(",", list);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.pojo.element.trigger.enums;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.api.enums.ScmType;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.pojo.element.trigger.enums
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:CodeEventType
|
||||||
|
* @Date:2025/03/27 10:26
|
||||||
|
* @Filename:CodeEventType
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
public enum CodeEventType {
|
||||||
|
// Git events
|
||||||
|
PUSH,
|
||||||
|
TAG_PUSH,
|
||||||
|
MERGE_REQUEST,
|
||||||
|
MERGE_REQUEST_ACCEPT,
|
||||||
|
ISSUES,
|
||||||
|
NOTE,
|
||||||
|
REVIEW,
|
||||||
|
// GitHub events
|
||||||
|
CREATE,
|
||||||
|
PULL_REQUEST,
|
||||||
|
// SVN events
|
||||||
|
POST_COMMIT,
|
||||||
|
LOCK_COMMIT,
|
||||||
|
PRE_COMMIT,
|
||||||
|
// Perforce (P4) events
|
||||||
|
CHANGE_COMMIT,
|
||||||
|
PUSH_SUBMIT,
|
||||||
|
CHANGE_CONTENT,
|
||||||
|
CHANGE_SUBMIT,
|
||||||
|
PUSH_CONTENT,
|
||||||
|
PUSH_COMMIT,
|
||||||
|
FIX_ADD,
|
||||||
|
FIX_DELETE,
|
||||||
|
FORM_COMMIT,
|
||||||
|
SHELVE_COMMIT,
|
||||||
|
SHELVE_DELETE,
|
||||||
|
SHELVE_SUBMIT,
|
||||||
|
|
||||||
|
// Sub-pipeline
|
||||||
|
PARENT_PIPELINE;
|
||||||
|
|
||||||
|
public static final String MESSAGE_CODE_PREFIX = "EVENT_TYPE";
|
||||||
|
|
||||||
|
// Git events
|
||||||
|
public static final List<CodeEventType> CODE_GIT_EVENTS = List.of(
|
||||||
|
PUSH, MERGE_REQUEST, MERGE_REQUEST_ACCEPT, TAG_PUSH, NOTE, REVIEW, ISSUES
|
||||||
|
);
|
||||||
|
|
||||||
|
// GitHub events
|
||||||
|
public static final List<CodeEventType> CODE_GITHUB_EVENTS = List.of(
|
||||||
|
PUSH, PULL_REQUEST, CREATE, REVIEW, ISSUES, NOTE
|
||||||
|
);
|
||||||
|
|
||||||
|
// Perforce (P4) events
|
||||||
|
public static final List<CodeEventType> CODE_P4_EVENTS = List.of(
|
||||||
|
CHANGE_COMMIT, CHANGE_SUBMIT, CHANGE_CONTENT, SHELVE_COMMIT, SHELVE_SUBMIT
|
||||||
|
);
|
||||||
|
|
||||||
|
// GitLab events
|
||||||
|
public static final List<CodeEventType> CODE_GITLAB_EVENTS = List.of(
|
||||||
|
PUSH, MERGE_REQUEST, MERGE_REQUEST_ACCEPT, TAG_PUSH
|
||||||
|
);
|
||||||
|
|
||||||
|
// Tencent Git (TGit) events
|
||||||
|
public static final List<CodeEventType> CODE_TGIT_EVENTS = List.of(
|
||||||
|
PUSH, MERGE_REQUEST, MERGE_REQUEST_ACCEPT, TAG_PUSH, NOTE, ISSUES
|
||||||
|
);
|
||||||
|
|
||||||
|
// SVN events
|
||||||
|
public static final List<CodeEventType> CODE_SVN_EVENTS = List.of(
|
||||||
|
POST_COMMIT, PRE_COMMIT, LOCK_COMMIT
|
||||||
|
);
|
||||||
|
|
||||||
|
public static List<CodeEventType> getEventsByScmType(ScmType scmType) {
|
||||||
|
if (scmType == null) {
|
||||||
|
return List.of(values());
|
||||||
|
}
|
||||||
|
switch (scmType) {
|
||||||
|
case CODE_GIT:
|
||||||
|
return new ArrayList<>(CODE_GIT_EVENTS);
|
||||||
|
case CODE_TGIT:
|
||||||
|
return new ArrayList<>(CODE_TGIT_EVENTS);
|
||||||
|
case GITHUB:
|
||||||
|
return new ArrayList<>(CODE_GITHUB_EVENTS);
|
||||||
|
case CODE_GITLAB:
|
||||||
|
return new ArrayList<>(CODE_GITLAB_EVENTS);
|
||||||
|
case CODE_SVN:
|
||||||
|
return new ArrayList<>(CODE_SVN_EVENTS);
|
||||||
|
case CODE_P4:
|
||||||
|
return new ArrayList<>(CODE_P4_EVENTS);
|
||||||
|
default:
|
||||||
|
return List.of(values());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.pojo.element.trigger.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.pojo.element.trigger.enums
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:CodeType
|
||||||
|
* @Date:2025/03/27 10:28
|
||||||
|
* @Filename:CodeType
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
public enum CodeType {
|
||||||
|
SVN,
|
||||||
|
GIT,
|
||||||
|
GITLAB,
|
||||||
|
GITHUB,
|
||||||
|
TGIT,
|
||||||
|
P4
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.pojo.element.trigger.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.pojo.element.trigger.enums
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:PathFilterType
|
||||||
|
* @Date:2025/03/27 10:28
|
||||||
|
* @Filename:PathFilterType
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
public enum PathFilterType {
|
||||||
|
NamePrefixFilter,
|
||||||
|
RegexBasedFilter
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.pojo.git;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.enums.GitPullModeType;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.pojo.git
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:GitPullMode
|
||||||
|
* @Date:2025/03/27 10:24
|
||||||
|
* @Filename:GitPullMode
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class GitPullMode {
|
||||||
|
private GitPullModeType type;
|
||||||
|
private String value;
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.type;
|
||||||
|
|
||||||
|
import cn.hutool.http.useragent.OS;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.type
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:BuildType
|
||||||
|
* @Date:2025/03/27 10:45
|
||||||
|
* @Filename:BuildType
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum BuildType {
|
||||||
|
ESXI("蓝盾公共构建资源", List.of(OS.MACOS), false, false, false),
|
||||||
|
MACOS("云托管: MacOS on DevCloud", List.of(OS.MACOS), false, false, false),
|
||||||
|
WINDOWS("云托管:Windows on DevCloud", List.of(OS.WINDOWS), false, false, false),
|
||||||
|
KUBERNETES("Kubernetes构建资源", List.of(OS.LINUX), false, false, false),
|
||||||
|
PUBLIC_DEVCLOUD("公共:Docker on DevCloud", List.of(OS.LINUX), true, false, false),
|
||||||
|
PUBLIC_BCS("公共:Docker on Bcs", List.of(OS.LINUX), false, false, false),
|
||||||
|
THIRD_PARTY_AGENT_ID("私有:单构建机", List.of(OS.MACOS, OS.LINUX, OS.WINDOWS), false, true, true),
|
||||||
|
THIRD_PARTY_AGENT_ENV("私有:构建集群", List.of(OS.MACOS, OS.LINUX, OS.WINDOWS), false, true, true),
|
||||||
|
THIRD_PARTY_PCG("PCG公共构建资源", List.of(OS.LINUX), false, false, false),
|
||||||
|
THIRD_PARTY_DEVCLOUD("腾讯自研云(云devnet资源)", List.of(OS.LINUX), false, false, false),
|
||||||
|
GIT_CI("工蜂CI", List.of(OS.LINUX), false, false, false),
|
||||||
|
DOCKER("Docker公共构建机", List.of(OS.LINUX), true, true, true),
|
||||||
|
STREAM("stream", List.of(OS.LINUX), false, false, false),
|
||||||
|
AGENT_LESS("无编译环境", List.of(OS.LINUX), false, false, false);
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
private final List<OS> osList;
|
||||||
|
private final boolean enableApp;
|
||||||
|
private final boolean clickable;
|
||||||
|
private final boolean visible;
|
||||||
|
|
||||||
|
public String getI18n(String language) {
|
||||||
|
return MessageUtil.getMessageByLocale("buildType." + this.name(), language);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.type;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.type
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:DispatchRouteKeySuffix
|
||||||
|
* @Date:2025/03/27 10:45
|
||||||
|
* @Filename:DispatchRouteKeySuffix
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum DispatchRouteKeySuffix {
|
||||||
|
DOCKER_VM(".docker.vm"),
|
||||||
|
DOCKER_VM_DEMOTE(".docker.vm.demote"),
|
||||||
|
KUBERNETES(".kubernetes"),
|
||||||
|
KUBERNETES_DEMOTE(".kubernetes.demote"),
|
||||||
|
PCG(".pcg.sumeru"),
|
||||||
|
DEVCLOUD(".devcloud.public"),
|
||||||
|
BCS(".bcs.public"),
|
||||||
|
IDC(".idc.public"),
|
||||||
|
GITCI(".gitci.public"),
|
||||||
|
STREAM(".stream.docker"),
|
||||||
|
STREAM_DEMOTE(".stream.docker.demote"),
|
||||||
|
CODECC(".codecc.scan"),
|
||||||
|
MACOS(".macos"),
|
||||||
|
WINDOWS(".windows");
|
||||||
|
|
||||||
|
private final String routeKeySuffix;
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.type;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.type.agent.ThirdPartyAgentEnvDispatchType;
|
||||||
|
import cd.casic.ci.common.pipeline.type.agent.ThirdPartyAgentIDDispatchType;
|
||||||
|
import cd.casic.ci.common.pipeline.utils.EnvUtils;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.type
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:DispatchType
|
||||||
|
* @Date:2025/03/27 10:45
|
||||||
|
* @Filename:DispatchType
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
|
||||||
|
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "buildType", visible = false)
|
||||||
|
@JsonSubTypes({
|
||||||
|
@JsonSubTypes.Type(value = DockerDispatchType.class, name = "DOCKER"),
|
||||||
|
@JsonSubTypes.Type(value = KubernetesDispatchType.class, name = "KUBERNETES"),
|
||||||
|
@JsonSubTypes.Type(value = ThirdPartyAgentIDDispatchType.class, name = "THIRD_PARTY_AGENT_ID"),
|
||||||
|
@JsonSubTypes.Type(value = ThirdPartyAgentEnvDispatchType.class, name = "THIRD_PARTY_AGENT_ENV"),
|
||||||
|
@JsonSubTypes.Type(value = ThirdPartyDevCloudDispatchType.class, name = "THIRD_PARTY_DEVCLOUD")
|
||||||
|
})
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public abstract class DispatchType {
|
||||||
|
private String value;
|
||||||
|
private DispatchRouteKeySuffix routeKeySuffix;
|
||||||
|
|
||||||
|
public void replaceVariable(Map<String, String> variables) {
|
||||||
|
this.value = EnvUtils.parseEnv(value, variables);
|
||||||
|
replaceField(variables);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract BuildType buildType();
|
||||||
|
|
||||||
|
protected abstract void replaceField(Map<String, String> variables);
|
||||||
|
|
||||||
|
public abstract void cleanDataBeforeSave();
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.type;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.type
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:StoreDispatchType
|
||||||
|
* @Date:2025/03/27 10:45
|
||||||
|
* @Filename:StoreDispatchType
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public abstract class StoreDispatchType extends DispatchType {
|
||||||
|
@Schema(title = "docker构建版本", required = false)
|
||||||
|
private String dockerBuildVersion;
|
||||||
|
|
||||||
|
@Schema(title = "镜像类型", required = false)
|
||||||
|
private ImageType imageType = ImageType.BKDEVOPS;
|
||||||
|
|
||||||
|
@Schema(title = "凭证id", required = false)
|
||||||
|
private String credentialId = "";
|
||||||
|
|
||||||
|
@Schema(title = "凭证项目id", required = false)
|
||||||
|
private String credentialProject = "";
|
||||||
|
|
||||||
|
@Schema(title = "商店镜像代码", required = false)
|
||||||
|
private String imageCode = "";
|
||||||
|
|
||||||
|
@Schema(title = "商店镜像版本", required = false)
|
||||||
|
private String imageVersion = "";
|
||||||
|
|
||||||
|
@Schema(title = "商店镜像名称", required = false)
|
||||||
|
private String imageName = "";
|
||||||
|
|
||||||
|
@Schema(title = "商店镜像公共标识", required = false)
|
||||||
|
private Boolean imagePublicFlag = false;
|
||||||
|
|
||||||
|
@Schema(title = "商店镜像研发来源", required = false)
|
||||||
|
private String imageRDType = "";
|
||||||
|
|
||||||
|
@Schema(title = "商店镜像是否推荐", required = false)
|
||||||
|
private Boolean recommendFlag = true;
|
||||||
|
|
||||||
|
public StoreDispatchType(String dockerBuildVersion, DispatchRouteKeySuffix routeKeySuffix) {
|
||||||
|
super(Optional.ofNullable(dockerBuildVersion).orElse("StoreDispatchType empty image"), routeKeySuffix);
|
||||||
|
this.dockerBuildVersion = dockerBuildVersion;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.type.agent;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.type.agent
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:AgentType
|
||||||
|
* @Date:2025/03/27 10:47
|
||||||
|
* @Filename:AgentType
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum AgentType {
|
||||||
|
ID, // This is only for old pipeline, new pipelines will use name
|
||||||
|
NAME,
|
||||||
|
REUSE_JOB_ID; // 是否复用其他job的Agent节点
|
||||||
|
|
||||||
|
public boolean isReuse() {
|
||||||
|
return this == REUSE_JOB_ID;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.type.agent;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.type.DispatchType;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.type.agent
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:ThirdPartyAgentDispatch
|
||||||
|
* @Date:2025/03/27 10:47
|
||||||
|
* @Filename:ThirdPartyAgentDispatch
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public abstract class ThirdPartyAgentDispatch extends DispatchType {
|
||||||
|
private String value;
|
||||||
|
private AgentType agentType;
|
||||||
|
private String workspace;
|
||||||
|
private ThirdPartyAgentDockerInfo dockerInfo;
|
||||||
|
private ReusedInfo reusedInfo;
|
||||||
|
|
||||||
|
public ThirdPartyAgentDispatch(String value, AgentType agentType, String workspace, ThirdPartyAgentDockerInfo dockerInfo, ReusedInfo reusedInfo) {
|
||||||
|
super(value);
|
||||||
|
this.value = value;
|
||||||
|
this.agentType = agentType;
|
||||||
|
this.workspace = workspace;
|
||||||
|
this.dockerInfo = dockerInfo;
|
||||||
|
this.reusedInfo = reusedInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean idType() {
|
||||||
|
return (agentType == AgentType.ID) || (reusedInfo != null && reusedInfo.getAgentType() == AgentType.ID) ||
|
||||||
|
(agentType == AgentType.REUSE_JOB_ID && reusedInfo == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasReuseMutex() {
|
||||||
|
return this.agentType.isReuse() || this.reusedInfo != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnv() {
|
||||||
|
return this instanceof ThirdPartyAgentEnvDispatchType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSingle() {
|
||||||
|
return this instanceof ThirdPartyAgentIDDispatchType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract void replaceField(Map<String, String> variables);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract void cleanDataBeforeSave();
|
||||||
|
}
|
@ -0,0 +1,112 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.type.agent;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.utils.EnvUtils;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.type.agent
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:ThirdPartyAgentDockerInfo
|
||||||
|
* @Date:2025/03/27 10:47
|
||||||
|
* @Filename:ThirdPartyAgentDockerInfo
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public class ThirdPartyAgentDockerInfo {
|
||||||
|
private String image;
|
||||||
|
private Credential credential;
|
||||||
|
private DockerOptions options;
|
||||||
|
private String imagePullPolicy;
|
||||||
|
private ImageType imageType = ImageType.THIRD;
|
||||||
|
private ThirdPartyAgentDockerInfoStoreImage storeImage;
|
||||||
|
|
||||||
|
public void replaceField(Map<String, String> variables) {
|
||||||
|
image = EnvUtils.parseEnv(image, variables);
|
||||||
|
if (credential != null) {
|
||||||
|
if (!credential.getUser().isBlank()) {
|
||||||
|
credential.setUser(EnvUtils.parseEnv(credential.getUser(), variables));
|
||||||
|
}
|
||||||
|
if (!credential.getPassword().isBlank()) {
|
||||||
|
credential.setPassword(EnvUtils.parseEnv(credential.getPassword(), variables));
|
||||||
|
}
|
||||||
|
if (!credential.getCredentialId().isBlank()) {
|
||||||
|
credential.setCredentialId(EnvUtils.parseEnv(credential.getCredentialId(), variables));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (options != null) {
|
||||||
|
options.setVolumes(options.getVolumes().stream().map(v -> EnvUtils.parseEnv(v, variables)).toList());
|
||||||
|
options.setMounts(options.getMounts().stream().map(m -> EnvUtils.parseEnv(m, variables)).toList());
|
||||||
|
options.setGpus(EnvUtils.parseEnv(options.getGpus(), variables));
|
||||||
|
options.setPrivileged(Boolean.parseBoolean(EnvUtils.parseEnv(String.valueOf(options.getPrivileged()), variables)));
|
||||||
|
}
|
||||||
|
if (imagePullPolicy != null) {
|
||||||
|
imagePullPolicy = EnvUtils.parseEnv(imagePullPolicy, variables);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
class Credential {
|
||||||
|
private String user;
|
||||||
|
private String password;
|
||||||
|
private String credentialId;
|
||||||
|
private String acrossTemplateId;
|
||||||
|
private String jobId;
|
||||||
|
private String credentialProjectId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
class DockerOptions {
|
||||||
|
private List<String> volumes;
|
||||||
|
private List<String> mounts;
|
||||||
|
private String gpus;
|
||||||
|
private Boolean privileged;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
class ThirdPartyAgentDockerInfoStoreImage {
|
||||||
|
private String imageName;
|
||||||
|
private String imageCode;
|
||||||
|
private String imageVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
class ThirdPartyAgentDockerInfoDispatch {
|
||||||
|
private String agentId;
|
||||||
|
private String secretKey;
|
||||||
|
private String image;
|
||||||
|
private Credential credential;
|
||||||
|
private DockerOptions options;
|
||||||
|
private String imagePullPolicy;
|
||||||
|
|
||||||
|
public ThirdPartyAgentDockerInfoDispatch(String agentId, String secretKey, ThirdPartyAgentDockerInfo info) {
|
||||||
|
this.agentId = agentId;
|
||||||
|
this.secretKey = secretKey;
|
||||||
|
this.image = info.getImage();
|
||||||
|
this.credential = info.getCredential();
|
||||||
|
this.options = info.getOptions();
|
||||||
|
this.imagePullPolicy = info.getImagePullPolicy();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.type.agent;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.type.BuildType;
|
||||||
|
import cd.casic.ci.common.pipeline.utils.EnvUtils;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.type.agent
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:ThirdPartyAgentEnvDispatchType
|
||||||
|
* @Date:2025/03/27 10:48
|
||||||
|
* @Filename:ThirdPartyAgentEnvDispatchType
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class ThirdPartyAgentEnvDispatchType extends ThirdPartyAgentDispatch {
|
||||||
|
@JsonProperty("value")
|
||||||
|
private String envName;
|
||||||
|
private String workspace;
|
||||||
|
private String envProjectId;
|
||||||
|
private AgentType agentType = AgentType.NAME;
|
||||||
|
private ThirdPartyAgentDockerInfo dockerInfo;
|
||||||
|
private ReusedInfo reusedInfo;
|
||||||
|
|
||||||
|
public ThirdPartyAgentEnvDispatchType(String envName, String workspace, String envProjectId, ThirdPartyAgentDockerInfo dockerInfo, ReusedInfo reusedInfo) {
|
||||||
|
super(envName, agentType, workspace, dockerInfo, reusedInfo);
|
||||||
|
this.envName = envName;
|
||||||
|
this.workspace = workspace;
|
||||||
|
this.envProjectId = envProjectId;
|
||||||
|
this.dockerInfo = dockerInfo;
|
||||||
|
this.reusedInfo = reusedInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanDataBeforeSave() {
|
||||||
|
this.envName = this.envName.trim();
|
||||||
|
this.envProjectId = this.envProjectId != null ? this.envProjectId.trim() : null;
|
||||||
|
this.workspace = this.workspace != null ? this.workspace.trim() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replaceField(Map<String, String> variables) {
|
||||||
|
envName = EnvUtils.parseEnv(envName, variables);
|
||||||
|
envProjectId = EnvUtils.parseEnv(envProjectId, variables);
|
||||||
|
if (workspace != null && !workspace.isBlank()) {
|
||||||
|
workspace = EnvUtils.parseEnv(workspace, variables);
|
||||||
|
}
|
||||||
|
if (dockerInfo != null) {
|
||||||
|
dockerInfo.replaceField(variables);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BuildType buildType() {
|
||||||
|
return BuildType.THIRD_PARTY_AGENT_ENV;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.type.agent;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.type.BuildType;
|
||||||
|
import cd.casic.ci.common.pipeline.utils.EnvUtils;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.type.agent
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:ThirdPartyAgentIDDispatchType
|
||||||
|
* @Date:2025/03/27 10:48
|
||||||
|
* @Filename:ThirdPartyAgentIDDispatchType
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class ThirdPartyAgentIDDispatchType extends ThirdPartyAgentDispatch {
|
||||||
|
@JsonProperty("value")
|
||||||
|
private String displayName;
|
||||||
|
private String workspace;
|
||||||
|
private AgentType agentType = AgentType.NAME;
|
||||||
|
private ThirdPartyAgentDockerInfo dockerInfo;
|
||||||
|
private ReusedInfo reusedInfo;
|
||||||
|
|
||||||
|
public ThirdPartyAgentIDDispatchType(String displayName, String workspace, ThirdPartyAgentDockerInfo dockerInfo, ReusedInfo reusedInfo) {
|
||||||
|
super(displayName, agentType, workspace, dockerInfo, reusedInfo);
|
||||||
|
this.displayName = displayName;
|
||||||
|
this.workspace = workspace;
|
||||||
|
this.dockerInfo = dockerInfo;
|
||||||
|
this.reusedInfo = reusedInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanDataBeforeSave() {
|
||||||
|
this.displayName = this.displayName.trim();
|
||||||
|
this.workspace = this.workspace != null ? this.workspace.trim() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replaceField(Map<String, String> variables) {
|
||||||
|
displayName = EnvUtils.parseEnv(displayName, variables);
|
||||||
|
if (workspace != null && !workspace.isBlank()) {
|
||||||
|
workspace = EnvUtils.parseEnv(workspace, variables);
|
||||||
|
}
|
||||||
|
if (dockerInfo != null) {
|
||||||
|
dockerInfo.replaceField(variables);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BuildType buildType() {
|
||||||
|
return BuildType.THIRD_PARTY_AGENT_ID;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.type
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:package-info
|
||||||
|
* @Date:2025/03/27 10:44
|
||||||
|
* @Filename:package-info
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
package cd.casic.ci.common.pipeline.type;
|
@ -0,0 +1,79 @@
|
|||||||
|
package cd.casic.ci.common.pipeline.utils;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.common.pipeline.utils
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:EnvUtils
|
||||||
|
* @Date:2025/03/27 15:20
|
||||||
|
* @Filename:EnvUtils
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
public class EnvUtils {
|
||||||
|
private static final Pattern tPattern = Pattern.compile("(\\$[{](?<single>[^$^{}]+)})|(\\$[{]{2}(?<double>[^$^{}]+)[}]{2})");
|
||||||
|
|
||||||
|
public static String parseEnv(String command, Map<String, String> data) {
|
||||||
|
return parseEnv(command, data, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String parseEnv(String command, Map<String, String> data, boolean replaceWithEmpty, boolean isEscape) {
|
||||||
|
return parseEnv(command, data, replaceWithEmpty, isEscape, new HashMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String parseEnv(String command, Map<String, String> data, boolean replaceWithEmpty, boolean isEscape, Map<String, String> contextMap) {
|
||||||
|
if (command == null || command.isEmpty()) {
|
||||||
|
return command == null ? "" : command;
|
||||||
|
}
|
||||||
|
return parseTokenTwice(command, data, contextMap, replaceWithEmpty, isEscape, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String parseTokenTwice(String command, Map<String, String> data, Map<String, String> contextMap, boolean replaceWithEmpty, boolean isEscape, int depth) {
|
||||||
|
if (depth < 0) {
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
Matcher matcher = tPattern.matcher(command);
|
||||||
|
StringBuffer buff = new StringBuffer();
|
||||||
|
while (matcher.find()) {
|
||||||
|
String key = matcher.group("single");
|
||||||
|
if (key == null) {
|
||||||
|
key = matcher.group("double");
|
||||||
|
}
|
||||||
|
key = key.trim();
|
||||||
|
String value = data.get(key);
|
||||||
|
if (value == null && contextMap != null) {
|
||||||
|
value = contextMap.get(key);
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
|
value = !replaceWithEmpty ? matcher.group() : "";
|
||||||
|
} else {
|
||||||
|
if (depth > 0 && tPattern.matcher(value).find()) {
|
||||||
|
value = parseTokenTwice(value, data, contextMap, replaceWithEmpty, isEscape, depth - 1);
|
||||||
|
} else if (isEscape) {
|
||||||
|
value = escapeSpecialWord(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
matcher.appendReplacement(buff, Matcher.quoteReplacement(value));
|
||||||
|
}
|
||||||
|
matcher.appendTail(buff);
|
||||||
|
return buff.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String escapeSpecialWord(String keyword) {
|
||||||
|
String replaceWord = keyword;
|
||||||
|
if (!keyword.isEmpty()) {
|
||||||
|
String[] wordList = {"\\", "\""};
|
||||||
|
for (String word : wordList) {
|
||||||
|
if (replaceWord.contains(word)) {
|
||||||
|
replaceWord = replaceWord.replace(word, "\\" + word);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return replaceWord;
|
||||||
|
}
|
||||||
|
}
|
@ -8,10 +8,16 @@ import cd.casic.ci.common.pipeline.container.VMBuildContainer;
|
|||||||
import cd.casic.ci.common.pipeline.enums.BuildStatus;
|
import cd.casic.ci.common.pipeline.enums.BuildStatus;
|
||||||
import cd.casic.ci.common.pipeline.enums.JobRunCondition;
|
import cd.casic.ci.common.pipeline.enums.JobRunCondition;
|
||||||
import cd.casic.ci.common.pipeline.option.JobControlOption;
|
import cd.casic.ci.common.pipeline.option.JobControlOption;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.ElementAdditionalOptions;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.trigger.ManualTriggerElement;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.trigger.RemoteTriggerElement;
|
||||||
import cd.casic.framework.commons.util.reflect.ReflectUtil;
|
import cd.casic.framework.commons.util.reflect.ReflectUtil;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import static cd.casic.ci.common.pipeline.pojo.element.ElementAdditionalOptions.RunCondition.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author:mianbin
|
* @Author:mianbin
|
||||||
* @Package:cd.casic.ci.common.pipeline.utils
|
* @Package:cd.casic.ci.common.pipeline.utils
|
||||||
@ -99,9 +105,9 @@ public class ModelUtils {
|
|||||||
} else {
|
} else {
|
||||||
element.setCanRetry(null);
|
element.setCanRetry(null);
|
||||||
}
|
}
|
||||||
} else if (additionalOptions.getRunCondition() == RunCondition.PRE_TASK_FAILED_ONLY ||
|
} else if (additionalOptions.getRunCondition() == PRE_TASK_FAILED_ONLY ||
|
||||||
additionalOptions.getRunCondition() == RunCondition.PRE_TASK_FAILED_BUT_CANCEL ||
|
additionalOptions.getRunCondition() == PRE_TASK_FAILED_BUT_CANCEL ||
|
||||||
additionalOptions.getRunCondition() == RunCondition.PRE_TASK_FAILED_EVEN_CANCEL) {
|
additionalOptions.getRunCondition() == PRE_TASK_FAILED_EVEN_CANCEL) {
|
||||||
element.setCanRetry(null);
|
element.setCanRetry(null);
|
||||||
element.setCanSkip(null);
|
element.setCanSkip(null);
|
||||||
failElements.forEach(e -> {
|
failElements.forEach(e -> {
|
||||||
@ -166,8 +172,8 @@ public class ModelUtils {
|
|||||||
public static Set<String> getModelAtoms(Model model) {
|
public static Set<String> getModelAtoms(Model model) {
|
||||||
var atomCodes = new HashSet<String>();
|
var atomCodes = new HashSet<String>();
|
||||||
for (var stage : model.getStages()) {
|
for (var stage : model.getStages()) {
|
||||||
for (var container : stage.getContainers()) {
|
for (Container container : stage.getContainers()) {
|
||||||
for (var element : container.getElements()) {
|
for (Element element : container.getElements()) {
|
||||||
atomCodes.add(element.getAtomCode());
|
atomCodes.add(element.getAtomCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||||
|
*
|
||||||
|
* BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.
|
||||||
|
*
|
||||||
|
* A copy of the MIT License is included in this file.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Terms of the MIT License:
|
||||||
|
* ---------------------------------------------------
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||||
|
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
||||||
|
* the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||||
|
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cd.casic.ci.common.pipeline.utils;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class ObjectReplaceEnvVarUtil {
|
||||||
|
/**
|
||||||
|
* 把对象字段值中的占位符替换成环境变量
|
||||||
|
*
|
||||||
|
* @param obj 需要把占位符替换环境变量的对象(对象如果是集合对象,注意要选择支持增加、删除等操作的集合类型,不要选择类似SingletonMap这种)
|
||||||
|
* @param envMap 环境变量Map
|
||||||
|
* @return 变量替换后的对象
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object replaceEnvVar(Object obj, Map<String, String> envMap) {
|
||||||
|
if (obj instanceof Map) {
|
||||||
|
// 递归替换map对象中的变量
|
||||||
|
Set<Map.Entry<String, Object>> entrySet = ((Map) obj).entrySet();
|
||||||
|
for (Map.Entry entry : entrySet) {
|
||||||
|
Object value = entry.getValue();
|
||||||
|
if (!isNormalReplaceEnvVar(value)) {
|
||||||
|
entry.setValue(replaceEnvVar(value, envMap));
|
||||||
|
} else {
|
||||||
|
entry.setValue(handleNormalEnvVar(value, envMap));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (obj instanceof List) {
|
||||||
|
// 递归替换list对象中的变量
|
||||||
|
List dataList = (List) obj;
|
||||||
|
for (int i = 0; i < dataList.size(); i++) {
|
||||||
|
Object value = dataList.get(i);
|
||||||
|
if (!isNormalReplaceEnvVar(value)) {
|
||||||
|
dataList.set(i, replaceEnvVar(value, envMap));
|
||||||
|
} else {
|
||||||
|
dataList.set(i, handleNormalEnvVar(value, envMap));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (obj instanceof Set) {
|
||||||
|
// 递归替换set对象中的变量
|
||||||
|
Set objSet = (Set) obj;
|
||||||
|
Set replaceObjSet = new HashSet(objSet);
|
||||||
|
Iterator it = replaceObjSet.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Object value = it.next();
|
||||||
|
objSet.remove(value);
|
||||||
|
if (!isNormalReplaceEnvVar(value)) {
|
||||||
|
objSet.add(replaceEnvVar(value, envMap));
|
||||||
|
} else {
|
||||||
|
objSet.add(handleNormalEnvVar(value, envMap));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (isNormalReplaceEnvVar(obj)) {
|
||||||
|
// 替换基本类型对象或字符串对象中的变量
|
||||||
|
obj = handleNormalEnvVar(obj, envMap);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
// 把对象转换成map后进行递归替换变量
|
||||||
|
Map<String, Object> dataMap = JSONUtil.toBean(JSONUtil.toJsonStr(obj), Map.class);
|
||||||
|
replaceEnvVar(dataMap, envMap);
|
||||||
|
obj = JSONUtil.toBean(JSONUtil.toJsonStr(dataMap), obj.getClass());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
// 转换不了map的对象则进行直接替换
|
||||||
|
obj = EnvUtils.parseEnv(JSONUtil.toJsonStr(obj), envMap, false, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object handleNormalEnvVar(Object obj, Map<String, String> envMap) {
|
||||||
|
// 只有字符串参数才需要进行变量替换,其它基本类型参数无需进行变量替换
|
||||||
|
if (obj instanceof String) {
|
||||||
|
String objStr = ((String) obj).trim();
|
||||||
|
if (JSONUtil.isJsonObj(objStr)) {
|
||||||
|
try {
|
||||||
|
Object dataObj = JSONUtil.toBean((String) obj, Map.class);
|
||||||
|
// string能正常转换成map,则说明是json串,那么把dataObj进行递归替换变量后再转成json串
|
||||||
|
dataObj = replaceEnvVar(dataObj, envMap);
|
||||||
|
obj = JSONUtil.toJsonStr(dataObj);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
// 转换不了map的字符串对象则直接替换
|
||||||
|
obj = EnvUtils.parseEnv(JSONUtil.toJsonStr(obj), envMap, false, false);
|
||||||
|
}
|
||||||
|
} else if (JSONUtil.isJsonObj(objStr)) {
|
||||||
|
try {
|
||||||
|
JSONUtil.toList(JSONUtil.parseArray((String) obj), Object.class);
|
||||||
|
Object dataObj = JSONUtil.toList((String) obj, List.class);
|
||||||
|
// string能正常转成list,说明是json串,把dataObj进行递归替换变量后再转成json串
|
||||||
|
dataObj = replaceEnvVar(dataObj, envMap);
|
||||||
|
obj = JSONUtil.toJsonStr(dataObj);
|
||||||
|
} catch (Throwable e1) {
|
||||||
|
// 转换不了list的字符串对象则直接替换
|
||||||
|
obj = EnvUtils.parseEnv(JSONUtil.toJsonStr(obj), envMap, false, false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 转换不了map或者list的字符串对象则直接替换
|
||||||
|
obj = EnvUtils.parseEnv(JSONUtil.toJsonStr(obj), envMap, false, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断对象是否是普通替换对象
|
||||||
|
*
|
||||||
|
* @param obj 需要把占位符替换环境变量的对象(对象如果是集合对象,注意要选择支持增加、删除等操作的集合类型,不要选择类似SingletonMap这种)
|
||||||
|
* @return 是否是普通替换对象
|
||||||
|
*/
|
||||||
|
private static Boolean isNormalReplaceEnvVar(Object obj) {
|
||||||
|
return obj == null || ReflectUtil.INSTANCE.isNativeType(obj) || obj instanceof String;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package cd.casic.ci.common.pipeline.utils;
|
package cd.casic.ci.common.pipeline.utils;
|
||||||
|
|
||||||
import cd.casic.ci.common.pipeline.pojo.BuildParameters;
|
import cd.casic.ci.common.pipeline.pojo.BuildParameters;
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.Element;
|
||||||
import cd.casic.framework.commons.util.json.JsonUtils;
|
import cd.casic.framework.commons.util.json.JsonUtils;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package cd.casic.ci.common.pipeline.utils;
|
package cd.casic.ci.common.pipeline.utils;
|
||||||
|
|
||||||
|
import cd.casic.ci.common.pipeline.pojo.element.ElementProp;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -17,20 +19,20 @@ public class TriggerElementPropUtils {
|
|||||||
if (value == null || value.isBlank()) {
|
if (value == null || value.isBlank()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new ElementProp(name, value.split(","), ElementPropType.VUEX_INPUT);
|
return new ElementProp(name, value.split(","), ElementProp.ElementPropType.VUEX_INPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ElementProp staffInput(String name, List<String> value) {
|
public static ElementProp staffInput(String name, List<String> value) {
|
||||||
if (value == null || value.isEmpty()) {
|
if (value == null || value.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new ElementProp(name, value, ElementPropType.STAFF_INPUT);
|
return new ElementProp(name, value, ElementProp.ElementPropType.STAFF_INPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ElementProp selector(String name, List<String> value) {
|
public static ElementProp selector(String name, List<String> value) {
|
||||||
if (value == null || value.isEmpty()) {
|
if (value == null || value.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new ElementProp(name, value, ElementPropType.SELECTOR);
|
return new ElementProp(name, value, ElementProp.ElementPropType.SELECTOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,11 @@
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cd.casic.ci</groupId>
|
<groupId>cd.casic.ci</groupId>
|
||||||
<artifactId>ci-commons</artifactId>
|
<artifactId>commons-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cd.casic.ci</groupId>
|
||||||
|
<artifactId>commons-pipeline</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cd.casic.ci</groupId>
|
<groupId>cd.casic.ci</groupId>
|
||||||
|
@ -0,0 +1,143 @@
|
|||||||
|
package cd.casic.ci.process.api.process.utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.process.api.process.utils
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:Constants
|
||||||
|
* @Date:2025/03/27 11:09
|
||||||
|
* @Filename:Constants
|
||||||
|
*/
|
||||||
|
public class Constants {
|
||||||
|
public static final String PIPELINE_VERSION = "BK_CI_PIPELINE_VERSION";
|
||||||
|
public static final String PIPELINE_START_PARENT_PROJECT_ID = "BK_CI_PARENT_PROJECT_ID";
|
||||||
|
public static final String PIPELINE_START_PARENT_PIPELINE_ID = "BK_CI_PARENT_PIPELINE_ID";
|
||||||
|
public static final String PIPELINE_START_PARENT_PIPELINE_NAME = "BK_CI_PARENT_PIPELINE_NAME";
|
||||||
|
public static final String PIPELINE_START_PARENT_BUILD_ID = "BK_CI_PARENT_BUILD_ID";
|
||||||
|
public static final String PIPELINE_START_PARENT_BUILD_NUM = "BK_CI_PARENT_BUILD_NUM";
|
||||||
|
public static final String PIPELINE_START_PARENT_BUILD_TASK_ID = "BK_CI_PARENT_BUILD_TASK_ID";
|
||||||
|
public static final String PIPELINE_START_PARENT_EXECUTE_COUNT = "BK_CI_PARENT_EXECUTE_COUNT";
|
||||||
|
public static final String PIPELINE_START_USER_ID = "BK_CI_START_USER_ID";
|
||||||
|
public static final String PIPELINE_START_USER_NAME = "BK_CI_START_USER_NAME";
|
||||||
|
public static final String PIPELINE_START_WEBHOOK_USER_ID = "BK_CI_START_WEBHOOK_USER_ID";
|
||||||
|
public static final String PIPELINE_START_PIPELINE_USER_ID = "BK_CI_START_PIPELINE_USER_ID";
|
||||||
|
public static final String PIPELINE_START_SERVICE_USER_ID = "BK_CI_START_SERVICE_USER_ID";
|
||||||
|
public static final String PIPELINE_START_MANUAL_USER_ID = "BK_CI_START_MANUAL_USER_ID";
|
||||||
|
public static final String PIPELINE_START_TIME_TRIGGER_USER_ID = "BK_CI_START_TIME_TRIGGER_USER_ID";
|
||||||
|
public static final String PIPELINE_START_REMOTE_USER_ID = "BK_CI_START_REMOTE_USER_ID";
|
||||||
|
public static final String PIPELINE_START_REMOTE_CLIENT_IP = "BK_CI_START_REMOTE_CLIENT_IP";
|
||||||
|
public static final String PIPELINE_START_TYPE = "BK_CI_START_TYPE";
|
||||||
|
public static final String PIPELINE_START_CHANNEL = "BK_CI_START_CHANNEL";
|
||||||
|
public static final String PIPELINE_BUILD_NUM = "BK_CI_BUILD_NUM";
|
||||||
|
public static final String PIPELINE_BUILD_LAST_UPDATE = "BK_CI_BUILD_LAST_UPDATE";
|
||||||
|
public static final String PIPELINE_BUILD_SVN_REVISION = "BK_CI_BUILD_SVN_REVISION";
|
||||||
|
public static final String PIPELINE_BUILD_NUM_ALIAS = "BK_CI_BUILD_NUM_ALIAS";
|
||||||
|
public static final String PIPELINE_BUILD_URL = "BK_CI_BUILD_URL";
|
||||||
|
public static final String PIPELINE_TIMER_DISABLE = "BK_CI_TIMER_DISABLE";
|
||||||
|
public static final String PIPELINE_START_SUB_RUN_MODE = "BK_CI_SUB_PIPELINE_RUN_MODE";
|
||||||
|
|
||||||
|
public static final String GIT_MR_NUMBER = "BK_CI_GIT_MR_NUMBER";
|
||||||
|
public static final String GITHUB_PR_NUMBER = "BK_CI_GITHUB_PR_NUMBER";
|
||||||
|
|
||||||
|
public static final String PIPELINE_NAME = "BK_CI_PIPELINE_NAME";
|
||||||
|
public static final String PIPELINE_ID = "BK_CI_PIPELINE_ID";
|
||||||
|
public static final String WORKSPACE = "WORKSPACE";
|
||||||
|
|
||||||
|
public static final String PIPELINE_TIME_DURATION = "BK_CI_BUILD_TOTAL_TIME";
|
||||||
|
|
||||||
|
public static final String PIPELINE_BUILD_ID = "BK_CI_BUILD_ID";
|
||||||
|
public static final String PIPELINE_VMSEQ_ID = "BK_CI_BUILD_JOB_ID";
|
||||||
|
public static final String PIPELINE_ELEMENT_ID = "BK_CI_BUILD_TASK_ID";
|
||||||
|
public static final String PIPELINE_TURBO_TASK_ID = "BK_CI_TURBO_ID";
|
||||||
|
public static final String PROJECT_NAME = "BK_CI_PROJECT_NAME";
|
||||||
|
public static final String REPORT_DYNAMIC_ROOT_URL = "BK_CI_REPORT_DYNAMIC_ROOT_URL";
|
||||||
|
|
||||||
|
public static final String PROJECT_NAME_CHINESE = "BK_CI_PROJECT_NAME_CN";
|
||||||
|
|
||||||
|
public static final String PIPELINE_START_MOBILE = "BK_CI_IS_MOBILE";
|
||||||
|
|
||||||
|
public static final String PIPELINE_START_TASK_ID = "BK_CI_START_TASK_ID";
|
||||||
|
public static final String PIPELINE_RETRY_COUNT = "BK_CI_RETRY_COUNT";
|
||||||
|
public static final String PIPELINE_RETRY_BUILD_ID = "BK_CI_RETRY_BUILD_ID";
|
||||||
|
public static final String PIPELINE_RETRY_START_TASK_ID = "BK_CI_RETRY_TASK_ID";
|
||||||
|
public static final String PIPELINE_RETRY_ALL_FAILED_CONTAINER = "BK_CI_RETRY_ALL_FAILED_CONTAINER";
|
||||||
|
public static final String PIPELINE_SKIP_FAILED_TASK = "BK_CI_SKIP_FAILED_TASK";
|
||||||
|
|
||||||
|
public static final String BK_CI_BUILD_FAIL_TASKS = "BK_CI_BUILD_FAIL_TASKS";
|
||||||
|
public static final String BK_CI_BUILD_FAIL_TASKNAMES = "BK_CI_BUILD_FAIL_TASKNAMES";
|
||||||
|
|
||||||
|
public static final String PIPELINE_VIEW_MY_PIPELINES = "myPipeline";
|
||||||
|
public static final String PIPELINE_VIEW_MY_LIST_PIPELINES = "myListPipeline";
|
||||||
|
public static final String PIPELINE_VIEW_FAVORITE_PIPELINES = "collect";
|
||||||
|
public static final String PIPELINE_VIEW_ALL_PIPELINES = "allPipeline";
|
||||||
|
public static final String PIPELINE_VIEW_UNCLASSIFIED = "unclassified";
|
||||||
|
public static final String PIPELINE_VIEW_RECENT_USE = "recentUse";
|
||||||
|
|
||||||
|
public static final String PIPELINE_MATERIAL_URL = "BK_CI_PIEPLEINE_MATERIAL_URL";
|
||||||
|
public static final String PIPELINE_MATERIAL_BRANCHNAME = "BK_CI_PIPELINE_MATERIAL_BRANCHNAME";
|
||||||
|
public static final String PIPELINE_MATERIAL_ALIASNAME = "BK_CI_PIPELINE_MATERIAL_ALIASNAME";
|
||||||
|
public static final String PIPELINE_MATERIAL_NEW_COMMIT_ID = "BK_CI_PIPELINE_MATERIAL_NEW_COMMIT_ID";
|
||||||
|
public static final String PIPELINE_MATERIAL_NEW_COMMIT_COMMENT = "BK_CI_PIPELINE_MATERIAL_NEW_COMMIT_COMMENT";
|
||||||
|
public static final String PIPELINE_MATERIAL_NEW_COMMIT_TIMES = "BK_CI_PIPELINE_MATERIAL_NEW_COMMIT_TIMES";
|
||||||
|
|
||||||
|
public static final String MAJORVERSION = "BK_CI_MAJOR_VERSION";
|
||||||
|
public static final String MINORVERSION = "BK_CI_MINOR_VERSION";
|
||||||
|
public static final String FIXVERSION = "BK_CI_FIX_VERSION";
|
||||||
|
public static final String BUILD_NO = "BK_CI_BUILD_NO";
|
||||||
|
public static final String BUILD_STATUS = "BK_CI_BUILD_STATUS";
|
||||||
|
public static final String BK_DOCKER_TARGE_IMAGE_TAG = "BK_DOCKER_TARGE_IMAGE_TAG";
|
||||||
|
public static final String BK_DOCKER_TARGE_IMAGE_NAME = "BK_DOCKER_TARGE_IMAGE_NAME";
|
||||||
|
|
||||||
|
public static final String JOB_RETRY_TASK_ID = "job.retry_task_id";
|
||||||
|
|
||||||
|
public static final String PIPELINE_CREATE_USER = "BK_CI_PIPELINE_CREATE_USER";
|
||||||
|
public static final String PIPELINE_UPDATE_USER = "BK_CI_PIPELINE_UPDATE_USER";
|
||||||
|
public static final String PIPELINE_BUILD_REMARK = "BK_CI_BUILD_REMARK";
|
||||||
|
public static final String PIPELINE_ATOM_NAME = "BK_CI_ATOM_NAME";
|
||||||
|
public static final String PIPELINE_ATOM_CODE = "BK_CI_ATOM_CODE";
|
||||||
|
public static final String PIPELINE_ATOM_VERSION = "BK_CI_ATOM_VERSION";
|
||||||
|
public static final String PIPELINE_TASK_NAME = "BK_CI_TASK_NAME";
|
||||||
|
public static final String PIPELINE_STEP_ID = "BK_CI_STEP_ID";
|
||||||
|
public static final String PIPELINE_ATOM_TIMEOUT = "BK_CI_ATOM_TIMEOUT";
|
||||||
|
public static final String PIPELINE_DIALECT = "BK_CI_PIPELINE_DIALECT";
|
||||||
|
|
||||||
|
public static final String BK_CI_MATERIAL_ID = "BK_CI_MATERIAL_ID";
|
||||||
|
public static final String BK_CI_MATERIAL_NAME = "BK_CI_MATERIAL_NAME";
|
||||||
|
public static final String BK_CI_MATERIAL_URL = "BK_CI_MATERIAL_URL";
|
||||||
|
|
||||||
|
public static final String BK_CI_AUTHORIZER = "BK_CI_AUTHORIZER";
|
||||||
|
|
||||||
|
public static final int PIPELINE_SETTING_MAX_QUEUE_SIZE_DEFAULT = 10;
|
||||||
|
public static final int TASK_FAIL_RETRY_MAX_COUNT = 5;
|
||||||
|
public static final int TASK_FAIL_RETRY_MIN_COUNT = 1;
|
||||||
|
public static final int PIPELINE_SETTING_MAX_QUEUE_SIZE_MIN = 0;
|
||||||
|
public static final int PIPELINE_SETTING_MAX_QUEUE_SIZE_MAX = 200;
|
||||||
|
public static final int PIPELINE_SETTING_MAX_CON_QUEUE_SIZE_DEFAULT = 50;
|
||||||
|
public static final int PIPELINE_SETTING_MAX_CON_QUEUE_SIZE_MAX = 200;
|
||||||
|
public static final int PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_DEFAULT = 1;
|
||||||
|
public static final int PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_MIN = 1;
|
||||||
|
public static final int PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_MAX = 1440;
|
||||||
|
public static final int PIPELINE_TASK_MESSAGE_STRING_LENGTH_MAX = 4000;
|
||||||
|
public static final int PIPELINE_MESSAGE_STRING_LENGTH_MAX = 30000;
|
||||||
|
public static final int PIPELINE_CON_RUNNING_CONTAINER_SIZE_MAX = 30;
|
||||||
|
public static final int PIPELINE_MATRIX_MAX_CON_RUNNING_SIZE_DEFAULT = 5;
|
||||||
|
public static final int PIPELINE_MATRIX_CON_RUNNING_SIZE_MAX = 20;
|
||||||
|
public static final int PIPELINE_STAGE_CONTAINERS_COUNT_MAX = 256;
|
||||||
|
public static final int PIPELINE_CONDITION_EXPRESSION_LENGTH_MAX = 512;
|
||||||
|
public static final int PIPELINE_VARIABLES_STRING_LENGTH_MAX = 4000;
|
||||||
|
|
||||||
|
public static final String PIPELINE_TIME_START = "BK_CI_BUILD_START_TIME";
|
||||||
|
public static final String PIPELINE_TIME_END = "BK_CI_BUILD_END_TIME";
|
||||||
|
public static final String PIPELINE_BUILD_MSG = "BK_CI_BUILD_MSG";
|
||||||
|
|
||||||
|
public static final int PIPELINE_RES_NUM_MIN = 50;
|
||||||
|
|
||||||
|
public static final String KEY_PIPELINE_ID = "pipelineId";
|
||||||
|
public static final String KEY_PIPELINE_NAME = "pipelineName";
|
||||||
|
public static final String KEY_PROJECT_ID = "projectId";
|
||||||
|
public static final String KEY_TEMPLATE_ID = "templateId";
|
||||||
|
public static final String KEY_STAGE = "stage";
|
||||||
|
public static final String KEY_JOB = "job";
|
||||||
|
public static final String KEY_TASK = "task";
|
||||||
|
public static final String KEY_TASK_ATOM = "taskAtom";
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
package cd.casic.ci.process.api.process.utils;
|
||||||
|
|
||||||
|
import cd.casic.ci.log.scm.dal.pojo.CodeP4Repository;
|
||||||
|
import cd.casic.ci.log.scm.dal.pojo.CodeSvnRepository;
|
||||||
|
import cd.casic.ci.ticket.dal.enums.CredentialType;
|
||||||
|
import cd.casic.framework.commons.util.encrypt.DHUtil;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.process.api.process.utils
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:CredentialUtils
|
||||||
|
* @Date:2025/03/27 14:35
|
||||||
|
* @Filename:CredentialUtils
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class CredentialUtils {
|
||||||
|
|
||||||
|
public static Credential getCredential(Repository repository, List<String> credentials, CredentialType credentialType) {
|
||||||
|
if (repository instanceof CodeSvnRepository && ((CodeSvnRepository) repository).getSvnType() == CodeSvnRepository.SVN_TYPE_HTTP) {
|
||||||
|
return switch (credentialType) {
|
||||||
|
case USERNAME_PASSWORD -> {
|
||||||
|
if (credentials.size() <= 1) {
|
||||||
|
log.warn("Fail to get the username of the svn repo {}", repository);
|
||||||
|
yield new Credential(repository.getUserName(), credentials.get(0), null);
|
||||||
|
} else {
|
||||||
|
yield new Credential(credentials.get(0), credentials.get(1), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case TOKEN_USERNAME_PASSWORD -> {
|
||||||
|
yield new Credential(
|
||||||
|
credentials.get(0),
|
||||||
|
credentials.getOrDefault(1, ""),
|
||||||
|
credentials.getOrDefault(2, ""),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
default -> new Credential(repository.getUserName(), credentials.get(0), null);
|
||||||
|
};
|
||||||
|
} else if (repository instanceof CodeSvnRepository && credentialType == CredentialType.TOKEN_SSH_PRIVATEKEY) {
|
||||||
|
return new Credential(
|
||||||
|
credentials.get(0),
|
||||||
|
credentials.getOrDefault(1, ""),
|
||||||
|
repository.getUserName(),
|
||||||
|
credentials.getOrDefault(2, "")
|
||||||
|
);
|
||||||
|
} else if (repository instanceof CodeP4Repository && credentialType == CredentialType.USERNAME_PASSWORD) {
|
||||||
|
return new Credential(credentials.get(0), "", credentials.get(1));
|
||||||
|
} else {
|
||||||
|
String privateKey = credentials.get(0);
|
||||||
|
String passPhrase = credentials.size() > 1 && !credentials.get(1).isEmpty() ? credentials.get(1) : null;
|
||||||
|
return new Credential(repository.getUserName(), privateKey, passPhrase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String decode(String encode, String publicKey, byte[] privateKey) {
|
||||||
|
if (!StringUtils.hasText(encode)) return "";
|
||||||
|
byte[] decodedBytes = Base64.getDecoder().decode(encode);
|
||||||
|
byte[] publicKeyBytes = Base64.getDecoder().decode(publicKey);
|
||||||
|
return new String(DHUtil.decrypt(decodedBytes, publicKeyBytes, privateKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Credential {
|
||||||
|
private String username;
|
||||||
|
private String privateKey;
|
||||||
|
private String passPhrase;
|
||||||
|
private String svnToken;
|
||||||
|
private CredentialType credentialType;
|
||||||
|
|
||||||
|
public Credential(String username, String privateKey, String passPhrase) {
|
||||||
|
this.username = username;
|
||||||
|
this.privateKey = privateKey;
|
||||||
|
this.passPhrase = passPhrase;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Credential(String svnToken, String username, String privateKey, String passPhrase) {
|
||||||
|
this.svnToken = svnToken;
|
||||||
|
this.username = username;
|
||||||
|
this.privateKey = privateKey;
|
||||||
|
this.passPhrase = passPhrase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,183 @@
|
|||||||
|
package cd.casic.ci.process.api.process.utils;
|
||||||
|
|
||||||
|
import cd.casic.ci.process.api.process.constant.ProcessMessageCode;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author:mianbin
|
||||||
|
* @Package:cd.casic.ci.process.api.process.utils
|
||||||
|
* @Project:ops-pro
|
||||||
|
* @name:DependOnUtils
|
||||||
|
* @Date:2025/03/27 14:39
|
||||||
|
* @Filename:DependOnUtils
|
||||||
|
* @description:Todo
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class DependOnUtils {
|
||||||
|
|
||||||
|
private static final Pattern REGEX = Pattern.compile("[,;]");
|
||||||
|
|
||||||
|
public static void checkRepeatedJobId(Stage stage) {
|
||||||
|
Set<String> jobIdSet = new HashSet<>();
|
||||||
|
for (Container c : stage.getContainers()) {
|
||||||
|
String jobId = c.getJobId();
|
||||||
|
if (jobId == null || jobId.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (jobIdSet.contains(jobId)) {
|
||||||
|
String jobName = getContainerName(stage, c, jobId);
|
||||||
|
throw new ErrorCodeException(
|
||||||
|
Response.Status.CONFLICT.getStatusCode(),
|
||||||
|
ProcessMessageCode.ERROR_PIPELINE_JOBID_EXIST,
|
||||||
|
new String[]{jobName, jobId},
|
||||||
|
jobName + " 的jobId(" + jobId + ")已存在"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
jobIdSet.add(jobId);
|
||||||
|
}
|
||||||
|
removeNonexistentJob(stage, jobIdSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void removeNonexistentJob(Stage stage, Set<String> jobIdSet) {
|
||||||
|
for (Container c : stage.getContainers()) {
|
||||||
|
JobControlOption jobControlOption = null;
|
||||||
|
if (c instanceof VMBuildContainer) {
|
||||||
|
jobControlOption = ((VMBuildContainer) c).getJobControlOption();
|
||||||
|
} else if (c instanceof NormalContainer) {
|
||||||
|
jobControlOption = ((NormalContainer) c).getJobControlOption();
|
||||||
|
}
|
||||||
|
if (jobControlOption == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (jobControlOption.getDependOnType() != DependOnType.ID || jobControlOption.getDependOnId() == null || jobControlOption.getDependOnId().isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
List<String> existJobIds = jobControlOption.getDependOnId().stream()
|
||||||
|
.filter(jobIdSet::contains)
|
||||||
|
.toList();
|
||||||
|
jobControlOption.setDependOnId(existJobIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initDependOn(Stage stage, Map<String, String> params) {
|
||||||
|
Map<String, Container> allJobId2JobMap = new HashMap<>();
|
||||||
|
for (Container c : stage.getContainers()) {
|
||||||
|
String jobId = c.getJobId();
|
||||||
|
if (jobId == null || jobId.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
allJobId2JobMap.put(jobId, c);
|
||||||
|
}
|
||||||
|
if (allJobId2JobMap.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, List<String>> cycleCheckJobMap = new HashMap<>();
|
||||||
|
for (Container c : stage.getContainers()) {
|
||||||
|
JobControlOption jobControlOption = null;
|
||||||
|
if (c instanceof VMBuildContainer) {
|
||||||
|
jobControlOption = ((VMBuildContainer) c).getJobControlOption();
|
||||||
|
} else if (c instanceof NormalContainer) {
|
||||||
|
jobControlOption = ((NormalContainer) c).getJobControlOption();
|
||||||
|
}
|
||||||
|
if (jobControlOption == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
List<String> dependOnJobIds = getDependOnJobIds(new DependOnConfig(
|
||||||
|
jobControlOption.getDependOnType(),
|
||||||
|
jobControlOption.getDependOnId(),
|
||||||
|
jobControlOption.getDependOnName()
|
||||||
|
), params);
|
||||||
|
if (dependOnJobIds.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c.getJobId() != null) {
|
||||||
|
cycleCheckJobMap.put(c.getJobId(), dependOnJobIds);
|
||||||
|
}
|
||||||
|
Map<String, String> containerId2JobIds = new HashMap<>();
|
||||||
|
for (String dependOnJobId : dependOnJobIds) {
|
||||||
|
Container dependOnJob = allJobId2JobMap.get(dependOnJobId);
|
||||||
|
if (dependOnJob == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
containerId2JobIds.put(dependOnJob.getId(), dependOnJobId);
|
||||||
|
}
|
||||||
|
if (!containerId2JobIds.isEmpty()) {
|
||||||
|
jobControlOption.setDependOnContainerId2JobIds(containerId2JobIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Integer> visited = new HashMap<>();
|
||||||
|
for (String jobId : cycleCheckJobMap.keySet()) {
|
||||||
|
dsf(jobId, cycleCheckJobMap, visited, stage, allJobId2JobMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean enableDependOn(Container container) {
|
||||||
|
JobControlOption jobControlOption = null;
|
||||||
|
if (container instanceof VMBuildContainer) {
|
||||||
|
jobControlOption = ((VMBuildContainer) container).getJobControlOption();
|
||||||
|
} else if (container instanceof NormalContainer) {
|
||||||
|
jobControlOption = ((NormalContainer) container).getJobControlOption();
|
||||||
|
}
|
||||||
|
if (jobControlOption == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return switch (jobControlOption.getDependOnType()) {
|
||||||
|
case ID -> jobControlOption.getDependOnId() != null && !jobControlOption.getDependOnId().isEmpty();
|
||||||
|
case NAME -> jobControlOption.getDependOnName() != null && !jobControlOption.getDependOnName().isEmpty();
|
||||||
|
default -> false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String> getDependOnJobIds(DependOnConfig dependOnConfig, Map<String, String> params) {
|
||||||
|
return switch (dependOnConfig.getDependOnType()) {
|
||||||
|
case ID -> dependOnConfig.getDependOnId() != null ? dependOnConfig.getDependOnId() : Collections.emptyList();
|
||||||
|
case NAME -> {
|
||||||
|
if (dependOnConfig.getDependOnName() == null || dependOnConfig.getDependOnName().isEmpty()) {
|
||||||
|
yield Collections.emptyList();
|
||||||
|
} else {
|
||||||
|
String[] dependONames = dependOnConfig.getDependOnName().split(REGEX);
|
||||||
|
List<String> result = new ArrayList<>();
|
||||||
|
for (String name : dependONames) {
|
||||||
|
result.add(EnvUtils.parseEnv(name, params));
|
||||||
|
}
|
||||||
|
yield result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default -> Collections.emptyList();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void dsf(String jobId, Map<String, List<String>> dependOnMap, Map<String, Integer> visited, Stage stage, Map<String, Container> allJobId2JobMap) {
|
||||||
|
if (visited.getOrDefault(jobId, 0) == 1) {
|
||||||
|
String jobName = getContainerName(stage, allJobId2JobMap.get(jobId), jobId);
|
||||||
|
String dependJobName = getContainerName(stage, allJobId2JobMap.get(dependOnJobId), dependOnJobId);
|
||||||
|
throw new ErrorCodeException(
|
||||||
|
ProcessMessageCode.ERROR_PIPELINE_DEPENDON_CYCLE,
|
||||||
|
new String[]{jobName, dependJobName}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (visited.getOrDefault(jobId, 0) == 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
visited.put(jobId, 1);
|
||||||
|
List<String> dependOnJobIds = dependOnMap.getOrDefault(jobId, Collections.emptyList());
|
||||||
|
for (String dependOnJobId : dependOnJobIds) {
|
||||||
|
dsf(dependOnJobId, dependOnMap, visited, stage, allJobId2JobMap);
|
||||||
|
}
|
||||||
|
visited.put(jobId, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getContainerName(Stage stage, Container container, String jobId) {
|
||||||
|
if (container == null) {
|
||||||
|
return jobId;
|
||||||
|
}
|
||||||
|
String namePrefix = stage.getName() != null ? stage.getName().replaceFirst("stage-", "") : "";
|
||||||
|
return namePrefix + "-" + container.getId();
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user