v3 提交新的模型,但是模型不能运行,如果要运行,把ci-process卸载pom

This commit is contained in:
mian-bin@hotmail.com 2025-03-26 18:45:21 +08:00
parent 1f4ea9850c
commit a9820840f4
96 changed files with 4736 additions and 14 deletions

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,160 @@
package cd.casic.ci.common.api.constant;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.constant
* @Projectops-pro
* @nameCommonConstants
* @Date2025/03/26 18:02
* @FilenameCommonConstants
* @descriptionTodo
*/
public class CommonConstants {
public static final String BCI_CODE_PREFIX = "BCI_CODE_";
public static final String DEVOPS = "DevOps";
public static final int NUM_ONE = 1;
public static final int NUM_TWO = 2;
public static final int NUM_THREE = 3;
public static final int NUM_FOUR = 4;
public static final int NUM_FIVE = 5;
public static final int NUM_SIX = 6;
public static final int NUM_SEVEN = 7;
public static final int NUM_EIGHT = 8;
public static final int NUM_NINE = 9;
public static final String INIT_VERSION = "1.0.0"; // 初始化版本
public static final String BEGIN = "begin"; // 开始
public static final String EDIT = "edit"; // 提交信息
public static final String COMMIT = "commit"; // 提交
public static final String BUILD = "build"; // 构建
public static final String CHECK = "check"; // 验证
public static final String TEST = "test"; // 测试
public static final String CODECC = "codecc"; // 代码检查
public static final String APPROVE = "approve"; // 审核
public static final String END = "end"; // 结束
public static final String SUCCESS = "success"; // 成功
public static final String UNDO = "undo"; // 未执行
public static final String DOING = "doing"; // 执行中
public static final String FAIL = "fail"; // 失败
public static final String ONLINE = "online"; // 上线
public static final String TEST_ENV_PREPARE = "testEnvPrepare"; // 准备测试环境
public static final String ING = "ing"; //
public static final String LATEST = "latest"; // 最新
public static final String DEVELOP = "develop"; // 开发
public static final String DEPLOY = "deploy"; // 部署
public static final String SECURITY = "security"; // 安全
public static final String NORMAL = "normal"; // 正常
public static final String EXCEPTION = "exception"; // 异常
public static final String REQUIRED = "required"; // 必选
public static final String MIN_LENGTH = "minLength"; // 最小长度
public static final String MAX_LENGTH = "maxLength"; // 最大长度
public static final String DEFAULT = "default"; // 默认
public static final String JAVA = "java"; // java
public static final String PYTHON = "python"; // python
public static final String NODEJS = "nodejs"; // nodejs
public static final String GOLANG = "golang"; // golang
public static final String JS = "js"; // js
public static final String PATTERN_STYLE = "patternStyle"; // 正则表达式规则
public static final String MESSAGE = "message"; // 提示信息
public static final String STATIC = "static"; // 静态资源
public static final String NAME = "name"; // 名称
public static final String FAIL_NUM = "failNum"; // 失败数量
public static final String VERSION = "version"; // 版本号
public static final String TYPE = "type"; // 类型
public static final String OUTPUT_DESC = "description"; // 插件输出字段描述
public static final String COMPONENT = "component"; // 组件
public static final String PIPELINE_URL = "pipelineUrl"; // 流水线链接
public static final String ARTIFACT = "artifact"; // 构件
public static final String REPORT = "report"; // 报告
public static final String VALUE = "value"; //
public static final String MULTIPLE_SELECTOR = "multiple"; // 多选
public static final String SINGLE_SELECTOR = "single"; // 单选
public static final String OPTIONS = "options"; // 可选项
public static final String LABEL = "label"; // 标签
public static final String NO_LABEL = "noLabel"; // 无标题
public static final String URL = "url"; // url链接
public static final String PATH = "path"; // 路径
public static final String ARTIFACTORY_TYPE = "artifactoryType"; // 归档仓库类型
public static final String REPORT_TYPE = "reportType"; // 报告类型
public static final String DATA = "data"; // 数据
public static final String STRING = "string"; // 字符串
public static final String LATEST_MODIFIER = "latestModifier"; // 最近修改人
public static final String IMPORTER = "importer"; // 导入人
public static final String USAGE = "usage"; // 用途
public static final String ALIAS = "alias"; // 别名
public static final String LATEST_UPDATE_TIME = "latestUpdateTime"; // 最近修改时间
public static final String LATEST_EXECUTOR = "latestExecutor"; // 最近执行人
public static final String LATEST_EXECUTE_TIME = "latestExecuteTime"; // 最近执行时间
public static final String LATEST_EXECUTE_PIPELINE = "latestExecutePipeline"; // 最近执行流水线
public static final String DANG = "dang"; //
public static final String AND = "and"; //
public static final String OR = "or"; //
public static final String TIMETOSELECT = "timetoSelect"; // 时必选
public static final String MASTER = "master"; // 主干
public static final String SYSTEM = "system"; // 系统
public static final String IN_READY_TEST = "IN_READY_TEST"; // 正在测试中
public static final String BUILD_RUNNING = "buildRunning"; // 运行中
public static final String BUILD_QUEUE = "buildQueue"; // 构建排队中
public static final String BUILD_REVIEWING = "buildReviewing"; // 构建待审核
public static final String BUILD_STAGE_SUCCESS = "buildStageSuccess"; // 构建阶段性完成
public static final String BUILD_COMPLETED = "buildCompleted"; // 构建完成
public static final String BUILD_CANCELED = "buildCanceled"; // 构建已取消
public static final String BUILD_FAILED = "buildFailed"; // 构建失败
public static final String ID = "id"; // id
public static final String STATUS = "status"; // 状态
public static final String EXECUTE_COUNT = "executeCount";
public static final String LOCALE_LANGUAGE = "BK_CI_LOCALE_LANGUAGE"; // locale国际化语言信息
public static final String DEFAULT_LOCALE_LANGUAGE = "zh_CN"; // 默认语言信息
public static final String REQUEST_CHANNEL = "BK_CI_REQUEST_CHANNEL"; // 请求渠道
public static final String API_PERMISSION = "BK_CI_API_PERMISSION"; // 请求API权限
public static final String REQUEST_IP = "X-Forwarded-For"; // 请求IP
public static final String BK_CREATE = "bkCreate"; // 创建
public static final String BK_REVISE = "bkRevise"; // 修改
public static final String FAIL_MSG = "failMsg"; // 失败信息
public static final String KEY_START_TIME = "startTime";
public static final String KEY_END_TIME = "endTime";
public static final String KEY_CHANNEL = "channel";
public static final String HIDDEN_SYMBOL = "******";
public static final String KEY_DEFAULT = "default";
public static final String KEY_INPUT = "vuex-input";
public static final String KEY_TEXTAREA = "vuex-textarea";
public static final String KEY_CODE_EDITOR = "atom-ace-editor";
public static final String KEY_OS = "os";
public static final String KEY_SUMMARY = "summary";
public static final String KEY_DOCSLINK = "docsLink";
public static final String KEY_DESCRIPTION = "description";
public static final String KEY_WEIGHT = "weight";
public static final String KEY_ALL = "all";
public static final String API_ACCESS_TOKEN_PROPERTY = "access_token";
public static final String TEMPLATE_ACROSS_INFO_ID = "devops_template_across_info_id";
public static final String KEY_OS_NAME = "osName";
public static final String KEY_OS_ARCH = "osArch";
public static final String KEY_INVALID_OS_INFO = "invalidOsInfo";
public static final String KEY_VALID_OS_NAME_FLAG = "validOsNameFlag";
public static final String KEY_VALID_OS_ARCH_FLAG = "validOsArchFlag";
public static final String KEY_SCRIPT = "script";
public static final String KEY_COMMIT_ID = "commitId";
public static final String KEY_BRANCH = "branch";
public static final String KEY_REPOSITORY_HASH_ID = "repositoryHashId";
public static final String KEY_REPOSITORY_PATH = "repositoryPath";
public static final String KEY_VERSION = "version";
public static final String KEY_VERSION_NAME = "versionName";
public static final String KEY_UPDATED_TIME = "updatedTime";
public static final String KEY_INSTANCE_ERROR_INFO = "instanceErrorInfo";
public static final String KEY_DEFAULT_LOCALE_LANGUAGE = "defaultLocaleLanguage";
public static final String KEY_PROJECT_ID = "projectId";
public static final String KEY_PIPELINE_ID = "pipelineId";
public static final String KEY_PIPELINE_NUM = "pipelineNum";
public static final String KEY_ARCHIVE = "archive";
public static final String KEY_BRANCH_TEST_FLAG = "branchTestFlag";
public static final String KEY_TASK_ATOM = "taskAtom";
public static final String KEY_ELEMENT_ENABLE = "elementEnable";
public static final String KEY_SHA_CONTENT = "shaContent";
public static final String KEY_FILE_SHA_CONTENT = "fileShaContent";
public static final String BK_BUILD_ENV_START_FAILED = "bkBuildEnvStartFailed"; // 构建环境启动失败
public static final String BK_START_PULL_IMAGE = "bkStartPullImage"; // 开始拉取镜像镜像名称
public static final String BK_PULLING_IMAGE = "bkPullingImage"; // 正在拉取镜像,{0}进度{1}
public static final String BK_PUSH_IMAGE = "bkPushImage"; // 正在推送镜像,{0}进度{1}
public static final String BK_HUMAN_SERVICE = "bkHumanService"; // 人工服务
}

View File

@ -0,0 +1,225 @@
package cd.casic.ci.common.api.constant;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.constant
* @Projectops-pro
* @nameCommonMessageCode
* @Date2025/03/26 18:02
* @FilenameCommonMessageCode
* @descriptionTodo
*/
public class CommonMessageCode {
public static final String MSG_CODE_ROLE_PREFIX = "MSG_CODE_ROLE_PREFIX_"; // 角色国际化前缀
public static final String MSG_CODE_PERMISSION_PREFIX = "MSG_CODE_PERMISSION_PREFIX_"; // 操作权限国际化前缀
public static final String SUCCESS = "0"; // 成功
public static final int OAUTH_DENERD = 418; // 自定义状态码, 未进行oauth认证
public static final String SYSTEM_ERROR = "2100001"; // 系统内部繁忙请稍后再试
public static final String PARAMETER_IS_NULL = "2100002"; // 参数{0}不能为空
public static final String PARAMETER_IS_EXIST = "2100003"; // 参数值{0}已经存在系统请换一个再试
public static final String PARAMETER_IS_INVALID = "2100004"; // 参数值{0}为非法数据
public static final String OAUTH_TOKEN_IS_INVALID = "2100005"; // 无效的token请先oauth认证
public static final String PERMISSION_DENIED = "2100006"; // 无权限{0}
public static final String ERROR_SERVICE_NO_FOUND = "2100007"; // "找不到任何有效的{0}服务提供者"
public static final String ERROR_SERVICE_INVOKE_FAILURE = "2100008"; // "服务调用失败:{0},uniqueId={1}"
public static final String ERROR_INVALID_CONFIG = "2100009"; // "配置不可用:{0},uniqueId={1}"
public static final String ERROR_REST_EXCEPTION_COMMON_TIP = "2100010"; // 接口访问出现异常请联系助手或稍后再重试
public static final String ERROR_CLIENT_REST_ERROR = "2100011"; // 用户请求不合法参数或方法错误请咨询助手
public static final String ERROR_PROJECT_FEATURE_NOT_ACTIVED = "2100012"; // 项目[{0}]未开通该功能
public static final String ERROR_INVALID_PARAM_ = "2100013"; // 无效参数: {0}
public static final String ERROR_NEED_PARAM_ = "2100014"; // 缺少参数: {0}
public static final String PARAMETER_VALIDATE_ERROR = "2100015"; // {0}参数校验错误: {1}
public static final String ERROR_SERVICE_NO_AUTH = "2100016"; // 无访问服务的权限
public static final String ERROR_QUERY_NUM_TOO_BIG = "2100017"; // 查询的数量超过系统规定的值{0}请调整查询条件或咨询助手
public static final String ERROR_QUERY_TIME_RANGE_TOO_LARGE = "2100018"; // 查询的时间范围跨度最大最长时间范围跨度不能超过{0}
public static final String ERROR_HTTP_RESPONSE_BODY_TOO_LARGE = "2100019"; // http请求返回体太大
public static final String PERMISSION_DENIED_FOR_APP = "2100020"; // APP的无权限{0}
public static final String ERROR_SENSITIVE_API_NO_AUTH = "2100021"; // 无敏感API访问权限
public static final String PARAMETER_LENGTH_TOO_LONG = "2100022"; // 参数长度不能超过{0}个字符
public static final String PARAMETER_LENGTH_TOO_SHORT = "2100023"; // 参数长度不能小于{0}个字符
public static final String PARAMETER_ILLEGAL_ERROR = "2100024"; // {0}参数非法错误: {1}
public static final String PARAMETER_EXPIRED_ERROR = "2100025"; // {0}token过期错误: {1}
public static final String PARAMETER_SECRET_ERROR = "2100026"; // {0}密钥配置错误: {1}
public static final String PARAMETER_IS_EMPTY = "2100027"; // 参数不能为空
public static final String ERROR_QUERY_TIME_RANGE_ERROR = "2100028"; // 查询的时间范围跨度错误
public static final String SERVICE_NOT_EXIST = "2100029"; // 父服务不存在异常
public static final String ILLEGAL_GITCI_SERVICE_IMAGE_FORMAT = "2100030"; // GITCI Service镜像格式非法
public static final String THIRD_PARTY_SERVICE_DEVCLOUD_EXCEPTION = "2100031"; // 第三方服务-DEVCLOUD 异常请联系8006排查异常信息 -
public static final String CREATE_CONTAINER_INTERFACE_EXCEPTION = "2100032"; // 创建容器接口异常
public static final String CREATE_CONTAINER_RETURNS_FAILED = "2100033"; // 创建容器接口返回失败
public static final String CREATE_CONTAINER_TIMED_OUT = "2100034"; // 创建容器接口超时
public static final String OPERATION_CONTAINER_INTERFACE_EXCEPTION = "2100035"; // 操作容器接口异常
public static final String OPERATION_CONTAINER_RETURNED_FAILURE = "2100036"; // 操作容器接口返回失败
public static final String OPERATION_CONTAINER_TIMED_OUT = "2100037"; // 操作容器接口超时
public static final String GET_STATUS_INTERFACE_EXCEPTION = "2100038"; // 获取容器状态接口异常
public static final String GET_STATUS_TIMED_OUT = "2100039"; // 获取容器状态接口超时
public static final String CREATE_MIRROR_INTERFACE_EXCEPTION = "2100040"; // 创建镜像接口异常
public static final String CREATE_MIRROR_INTERFACE_RETURNED_FAILURE = "2100041"; // 创建镜像接口返回失败
public static final String CREATE_MIRROR_INTERFACE_EXCEPTION_NEW = "2100042"; // 创建镜像新版本接口异常
public static final String NEW_MIRROR_INTERFACE_RETURNED_FAILURE = "2100043"; // 创建镜像新版本接口返回失败
public static final String TASK_STATUS_INTERFACE_EXCEPTION = "2100044"; // 获取TASK状态接口异常
public static final String TASK_STATUS_TIMED_OUT = "2100045"; // 获取TASK状态接口超时
public static final String GET_WEBSOCKET_INTERFACE_EXCEPTION = "2100046"; // 获取websocket接口异常
public static final String PARAMETER_CANNOT_EMPTY_ALL = "2100047"; // 参数不能全部为空
public static final String USERS_EXCEEDS_THE_LIMIT = "2100048"; // 授权用户数越界:{0}
public static final String FAILED_TO_QUERY_GSE_AGENT_STATUS = "2100049"; // 查询 Gse Agent 状态失败
public static final String FAILED_TO_GET_AGENT_STATUS = "2100050"; // 获取agent状态失败
public static final String STAGES_AND_STEPS_CANNOT_EXIST_BY_SIDE = "2100053"; // stages和steps不能并列存在!
public static final String USER_NOT_PERMISSIONS_OPERATE_PIPELINE = "2100054"; // 用户({0})无权限在工程({1}){2}流水线{3}
public static final String USER_NOT_HAVE_PROJECT_PERMISSIONS = "2100055"; // 用户 {0}无项目{1}权限
public static final String UNABLE_GET_PIPELINE_JOB_STATUS = "2100056"; // 无法获取流水线JOB状态构建停止
public static final String JOB_BUILD_STOPS = "2100057"; // 流水线JOB已经不再运行构建停止
public static final String PIPELINE_NAME_OCCUPIED = "2100058"; // 流水线名称已被他人使用
public static final String INTERNAL_DEPENDENCY_SERVICE_EXCEPTION = "2100059"; // 内部依赖服务异常
public static final String PUBLIC_BUILD_RESOURCE_POOL_NOT_EXIST = "2100060"; // 公共构建资源池不存在请检查yml配置.
public static final String ERROR_LANGUAGE_IS_NOT_SUPPORT = "2100061"; // 该语言蓝盾目前不支持蓝盾目前支持的语言标识为{0}
public static final String INIT_SERVICE_LIST_ERROR = "2100062"; // 初始化服务列表异常问题
public static final String FILE_NOT_EXIST = "2100063"; // 文件{0}不存在
public static final String USER_ACCESS_CHECK_FAIL = "2100064"; // Gitlab access token 不正确
public static final String GITLAB_TOKEN_EMPTY = "2100065"; // GitLab Token为空
public static final String GITLAB_HOOK_URL_EMPTY = "2100066"; // GitLab hook url为空
public static final String GITLAB_TOKEN_FAIL = "2100067"; // GitLab Token不正确
public static final String GIT_TOKEN_FAIL = "2100068"; // Git Token不正确
public static final String SERCRT_EMPTY = "2100069"; // GIT 私钥为空
public static final String GIT_SERCRT_WRONG = "2100070"; // Git 私钥不对
public static final String PWD_EMPTY = "2100071"; // 用户密码为空
public static final String USER_NAME_EMPTY = "2100072"; // 用户名为空
public static final String GITLAB_INVALID = "2100073"; // 无效的GITLAB仓库
public static final String GIT_TOKEN_WRONG = "2100074"; // Git Token 不正确
public static final String GIT_LOGIN_FAIL = "2100075"; // Git 用户名或者密码不对
public static final String GIT_TOKEN_EMPTY = "2100076"; // Git Token为空
public static final String GIT_HOOK_URL_EMPTY = "2100077"; // Git hook url为空
public static final String TGIT_LOGIN_FAIL = "2100078"; // TGit 用户名或者密码不对
public static final String TGIT_TOKEN_FAIL = "2100079"; // TGit Token 不正确
public static final String TGIT_SECRET_WRONG = "2100080"; // TGit 私钥不对
public static final String SVN_SECRET_OR_PATH_ERROR = "2100081"; // SVN 私钥不正确 或者 SVN 路径没有权限
public static final String SVN_CREATE_HOOK_FAIL = "2100082"; // 添加SVN WEB hook 失败
public static final String LOCK_FAIL = "2100083"; // lock失败
public static final String UNLOCK_FAIL = "2100084"; // unlock失败
public static final String GIT_REPO_PEM_FAIL = "2100085"; // 代码仓库访问未授权
public static final String CALL_REPO_ERROR = "2100086"; // 代码仓库访问异常
public static final String P4_USERNAME_PASSWORD_FAIL = "2100087"; // p4用户名密码错误
public static final String PARAM_ERROR = "2100088"; // 参数错误
public static final String AUTH_FAIL = "2100089"; // {0}认证失败
public static final String ACCOUNT_NO_OPERATION_PERMISSIONS = "2100090"; // 账户没有{0}的权限
public static final String REPO_NOT_EXIST_OR_NO_OPERATION_PERMISSION = "2100091"; // {0}仓库不存在或者是账户没有该项目{1}的权限
public static final String GIT_INTERFACE_NOT_EXIST = "2100092"; // {0}平台没有{1}的接口
public static final String GIT_CANNOT_OPERATION = "2100093"; // {0}平台{1}操作不能进行
public static final String WEBHOOK_LOCK_UNLOCK_FAIL = "2100094"; // unlock webhooklock失败,请确认token是否已经配置
public static final String COMMIT_CHECK_ADD_FAIL = "2100095"; // Commit Check添加失败请确保该代码库的凭据关联的用户对代码库有Developer权限
public static final String ADD_MR_COMMENTS_FAIL = "2100096"; // 添加MR的评论失败请确保该代码库的凭据关联的用户对代码库有Developer权限
public static final String WEBHOOK_ADD_FAIL = "2100097"; // Webhook添加失败请确保该代码库的凭据关联的用户对代码库有{0}权限
public static final String WEBHOOK_UPDATE_FAIL = "2100098"; // Webhook更新失败请确保该代码库的凭据关联的用户对代码库有Developer权限
public static final String ENGINEERING_REPO_UNAUTHORIZED = "2100099"; // 工程仓库访问未授权
public static final String ENGINEERING_REPO_NOT_EXIST = "2100100"; // 工程仓库不存在
public static final String ENGINEERING_REPO_CALL_ERROR = "2100101"; // 工程仓库访问异常
public static final String NOT_MEMBER_AND_NOT_OPEN_SOURCE = "2100102"; // 非项目成员且项目为非开源项目
public static final String USER_NO_PIPELINE_PERMISSION = "2100108"; // 流水线: 用户无{0}权限
public static final String SERVICE_COULD_NOT_BE_ANALYZED = "2100109"; // 无法根据接口"{0}"分析所属的服务
public static final String RETURNED_RESULT_COULD_NOT_BE_PARSED = "2100110"; // 内部服务返回结果无法解析 status:{0} body:{1}
public static final String SERVICE_PROVIDER_NOT_FOUND = "2100111"; // 找不到任何有效的{0}{1}服务提供者
public static final String ILLEGAL_JOB_TYPE = "2100112"; // 非法的job类型!
public static final String ERROR_YAML_FORMAT_EXCEPTION = "2100113"; // {0} {1} 格式有误,应为 {2}, error message:{3}
public static final String ERROR_YAML_FORMAT_EXCEPTION_CHECK_STAGE_LABEL = "2100114"; // 请核对Stage标签是否正确
public static final String ERROR_YAML_FORMAT_EXCEPTION_LENGTH_LIMIT_EXCEEDED = "2100115"; // "{0} job.id 超过长度限制64 {1}}"
public static final String ERROR_YAML_FORMAT_EXCEPTION_NEED_PARAM = "2100116"; // {0} 中的step必须包含uses或run或checkout!
public static final String ERROR_YAML_FORMAT_EXCEPTION_SERVICE_IMAGE_FORMAT_ILLEGAL = "2100117"; // STREAM Service镜像格式非法
public static final String ERROR_YAML_FORMAT_EXCEPTION_STEP_ID_UNIQUENESS = "2100118"; // 请确保step.id唯一性!({0})
public static final String BUILD_RESOURCE_NOT_EXIST = "2100119"; // {0}构建资源不存在请检查yml配置.
public static final String ERROR_YAML_FORMAT_EXCEPTION_ENV_QUANTITY_LIMIT_EXCEEDED = "2100120"; // {0}配置Env数量超过100限制!
public static final String ERROR_YAML_FORMAT_EXCEPTION_ENV_VARIABLE_LENGTH_LIMIT_EXCEEDED = "2100121"; // {0}Env单变量{1}长度超过{2}字符!({3})
public static final String ERROR_PROJECT_API_ACCESS_NO_PERMISSION = "2100122"; // 项目[{0}]没有接口[{1}]的访问权限
public static final String ERROR_INTERFACE_RETRY_NUM_EXCEEDED = "2100123"; // 接口连续重试次数超过{0}请稍后再试
public static final String ERROR_PIPELINE_API_ACCESS_NO_PERMISSION = "2100124"; // 流水线[{0}]没有接口[{1}]的访问权限
public static final String TEMPLATE_PLUGIN_NOT_ALLOWED_USE = "2100125"; // 模板中插件{0}{1}版本的状态是{2}不允许使用
public static final String ADD_MR_FAIL = "2100126"; // 添加MR失败
public static final String ELEMENT_UPDATE_WRONG_PATH = "2100127"; // 更新插件的标注位置有误
public static final String ELEMENT_NOT_SUPPORT_TRANSFER = "2100128"; // 如下插件在 Code 方式下已不支持请修改后再切换: \n[{0}]
public static final String DISPATCH_NOT_SUPPORT_TRANSFER = "2100129"; // 如下构建环境在 Code 方式下不支持转换请修改后再切换: \n[{0}]
public static final String YAML_NOT_VALID = "2100130"; // yaml不合法 {0}
public static final String GIT_INVALID_PRIVATE_KEY = "2100131"; // 不支持的SSH私钥格式仅支持rsa格式私钥
public static final String THIRD_PARTY_SERVICE_OPERATION_FAILED = "2100132"; // 第三方服务[{0}]操作失败失败详情{1}
public static final String MR_ACCEPT_EVENT_NOT_SUPPORT_TRANSFER = "2100133"; // mr accept事件类型不支持code转换
public static final String SVN_TOKEN_FAIL = "2100135"; // SVN Token 不正确
public static final String SVN_TOKEN_EMPTY = "2100136"; // SVN Token 为空, 请检查代码库的凭证类型
public static final String ERROR_VARIABLE_NOT_FOUND = "2100137"; // SVN Token 为空, 请检查代码库的凭证类型
public static final String BK_CONTAINER_TIMED_OUT = "bkContainerTimedOut"; // 创建容器超时
public static final String BK_CREATION_FAILED_EXCEPTION_INFORMATION = "bkCreationFailedExceptionInformation"; // 创建失败异常信息
public static final String BK_FILE_NAME = "bkFileName"; // 文件名
public static final String BK_BELONG_TO_THE_PROJECT = "bkBelongToTheProject"; // 所属项目
public static final String BK_OPERATING = "bkOperating"; // 操作
public static final String BK_PUSH_FROM_BLUE_SHIELD_DEVOPS_PLATFORM = "bkPushFromBlueShieldDevopsPlatform"; // 来自蓝盾DevOps平台的推送
public static final String BK_TABLE_CONTENTS = "bkTableContents"; // 表格内容
public static final String BK_PLEASE_FEEL_TO_CONTACT_BLUE_SHIELD_ASSISTANT = "bkPleaseFeelToContactBlueShieldAssistant"; // 如有任何问题可随时联系蓝盾助手
public static final String BK_ETH1_NETWORK_CARD_IP_EMPTY = "bkEth1NetworkCardIpEmpty"; // eth1 网卡Ip为空因此获取eth0的网卡ip
public static final String BK_LOOPBACK_ADDRESS_OR_NIC_EMPTY = "bkLoopbackAddressOrNicEmpty"; // loopback地址或网卡名称为空
public static final String BK_FAILED_GET_NETWORK_CARD = "bkFailedGetNetworkCard"; // 获取网卡失败
public static final String BK_MANUAL_TRIGGER = "bkManualTrigger"; // 手动触发
public static final String BK_BUILD_TRIGGER = "bkBuildTrigger"; // 构建触发
public static final String BK_VIEW_DETAILS = "bkSeeDetails"; // 查看详情
public static final String BK_PROJECT_ID = "bkProjectId"; // # 项目ID:
public static final String BK_PIPELINE_NAME = "bkPipelineName"; // # 流水线名称:
public static final String BK_CREATE_SERVICE = "bkCreateService"; // 创建{0}服务
public static final String BK_SESSION_ID = "bkSessionId"; // 会话ID
public static final String BK_GROUP_ID = "bkGroupId"; // 群ID
public static final String BK_THIS_GROUP_ID = "bkThisGroupId"; // 本群ID={0}PS:群ID可用于蓝盾平台上任意企业微信群通知
public static final String BK_MISSING_RESOURCE_DEPENDENCY = "bkMissingResourceDependency"; // 依赖的资源不存在
public static final String BK_REQUEST_TIMED_OUT = "bkRequestTimedOut"; // 请求超时
public static final String BK_QUERY_PARAM_REQUEST_ERROR = "bkQueryParamRequestError"; // 查询参数请求错误
public static final String BK_JSON_BAD_PARAMETERS = "bkJsonBadParameters"; // JSON参数错误/Bad Parameters in json
public static final String BK_REQUEST_BODY_CONTENT_PARAMETER_INCORRECT = "bkRequestBodyContentParameterIncorrect"; // 请求体内容参数错误温馨提示请确认{0}是否符合要求
public static final String BK_REQUESTED_RESOURCE_DOES_NOT_EXIST = "bkRequestedResourceDoesNotExist"; // 请求的资源不存在
public static final String BK_NOT_OAUTH_CERTIFICATION = "bkNotOauthCertification"; // 你没有Oauth认证
public static final String BK_QUERY_PARAM_REQUEST_EMPTY = "bkQueryParamRequestEmpty"; // 请求的参数内容为空
public static final String BK_QUERY_PARAM_TYPE_ERROR = "bkQueryParamTypeError"; // 查询参数类型错误
public static final String BK_NOT_HAVE_PERMISSION_PERFORM_THIS_OPERATION = "bkNotHavePermissionPerformThisOperation"; // 你没有权限进行该操作
public static final String BK_FAILED_ACCESS_BACKGROUND_DATA = "bkFailedAccessBackgroundData"; // 访问后台数据失败已通知产品开发请稍后重试
public static final String BK_RESOURCES_THAT_NOT_AUTHORIZED_ACCESS = "bkResourcesThatNotAuthorizedAccess"; // 未授权访问的资源
public static final String BK_CODE_BASE_TRIGGERING = "bkCodeBaseTriggering"; // 代码库触发
public static final String BK_FAILED_START_BUILD_MACHINE = "bkFailedStartBuildMachine"; // 启动构建机失败
public static final String CREATE_BRANCH = "bkCreateBranch"; // 创建分支
public static final String DELETE_BRANCH = "bkDeleteBranch"; // 删除分支
public static final String GET_PROJECT_INFO = "bkGetProjectInfo"; // 获取项目详情
public static final String GET_COMMIT_REVIEW_INFO = "bkGetCommitReviewInfo"; // 获取Commit Review详情
public static final String GET_SESSION_INFO = "bkGetSessionInfo"; // 获取会话详情
public static final String OPERATION_BRANCH = "bkOperationBranch"; // 拉分支
public static final String OPERATION_TAG = "bkOperationTag"; // 拉标签
public static final String OPERATION_ADD_WEBHOOK = "bkOperationAddWebhook"; // 添加WEBHOOK
public static final String OPERATION_UPDATE_WEBHOOK = "bkOperationUpdateWebhook"; // 修改WEBHOOK
public static final String OPERATION_LIST_WEBHOOK = "bkOperationListWebhook"; // 查询WEBHOOK
public static final String OPERATION_ADD_COMMIT_CHECK = "bkOperationAddCommitCheck"; // 添加COMMIT CHECK
public static final String OPERATION_ADD_MR_COMMENT = "bkOperationAddMrComment"; // 添加MR COMMENT
public static final String OPERATION_LIST_MR = "bkOperationListMr"; // 添加MR
public static final String OPERATION_ADD_MR = "bkOperationAddMr"; // 添加MR
public static final String OPERATION_COMMIT = "bkOperationCommit"; // 拉提交记录
public static final String OPERATION_COMMIT_DIFF = "bkOperationCommitDiff"; // 查询commit变化
public static final String OPERATION_UNLOCK_HOOK_LOCK = "bkOperationUnlockHookLock"; // 解锁hook锁
public static final String OPERATION_MR_CHANGE = "bkOperationMrChange"; // 查询合并请求的代码变更
public static final String OPERATION_MR_INFO = "bkOperationMrInfo"; // 查询项目合并请求
public static final String OPERATION_GET_CHANGE_FILE_LIST = "bkOperationGetChangeFileList"; // 查询变更文件列表
public static final String OPERATION_GET_MR_COMMIT_LIST = "bkOperationGetMrCommitList"; // 获取合并请求中的提交
public static final String OPERATION_PROJECT_USER_INFO = "bkOperationProjectUserInfo"; // 获取项目中成员信息
public static final String OPERATION_TAPD_WORKITEMS = "bkOperationTapdWorkItems"; // 查看绑定的TAPD单
public static final String BK_USER_GROUP_CRATE_TIME = "bkUserGroupCrateTime"; // {0} 用户组:{1},{2} 创建于
public static final String BK_USER_RATING_ADMIN_CRATE_TIME = "bkUserRatingAdminCrateTime"; // {0} 分级管理员,{1} 创建于
public static final String BK_SECOND_LEVEL_ADMIN_CREATE = "bkSecondLevelAdminCreate"; // {0} 二级管理员, {1} 创建于
public static final String BK_SECOND_LEVEL_ADMIN_REVISE = "bkSecondLevelAdminRevise"; // {0} 二级管理员, {1} 修改于
public static final String BK_USER_REQUESTS_THE_PROJECT = "bkUserRequestsTheProject"; // 用户 {0} 申请{1}蓝盾项目 {2} ,请审批
public static final String BK_ENV_NOT_YET_SUPPORTED = "bkEnvNotYetSupported"; // 尚未支持 {0} {1}请联系 管理员 添加对应版本
public static final String BK_BUILD_ENV_TYPE = "BUILD_ENV_TYPE_"; // 构建环境-
public static final String BK_BUILD_ENV_TYPE_BUILDLESS = "BUILD_ENV_TYPE_BUILDLESS"; // 无编译环境
public static final String BK_BUILD_ENV_TYPE_BUILD_TRIGGERS = "BUILD_ENV_TYPE_BUILD_TRIGGER"; // 构建触发
public static final String TRANSFER_ERROR_CHECK_AGENT_ID_FAILED = "transferErrorCheckAgentIdFailed"; // 当前私有构建机数据有误或不存在
public static final String TRANSFER_ERROR_CHECK_ENV_ID_FAILED = "transferErrorCheckEnvIdFailed"; // 当前私有构建机集群数据有误或不存在
}

View File

@ -0,0 +1,119 @@
package cd.casic.ci.common.api.constant;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.constant
* @Projectops-pro
* @nameHttpStatus
* @Date2025/03/26 18:26
* @FilenameHttpStatus
* @descriptionTodo
*/
public enum HttpStatus {
CONTINUE(100, "Continue"),
SWITCHING_PROTOCOLS(101, "Switching Protocols"),
PROCESSING(102, "Processing"),
CHECKPOINT(103, "Checkpoint"),
OK(200, "OK"),
CREATED(201, "Created"),
ACCEPTED(202, "Accepted"),
NON_AUTHORITATIVE_INFORMATION(203, "Non-Authoritative Information"),
NO_CONTENT(204, "No Content"),
RESET_CONTENT(205, "Reset Content"),
PARTIAL_CONTENT(206, "Partial Content"),
MULTI_STATUS(207, "Multi-Status"),
ALREADY_REPORTED(208, "Already Reported"),
IM_USED(226, "IM Used"),
MULTIPLE_CHOICES(300, "Multiple Choices"),
MOVED_PERMANENTLY(301, "Moved Permanently"),
FOUND(302, "Found"),
MOVED_TEMPORARILY(302, "Moved Temporarily"),
SEE_OTHER(303, "See Other"),
NOT_MODIFIED(304, "Not Modified"),
USE_PROXY(305, "Use Proxy"),
TEMPORARY_REDIRECT(307, "Temporary Redirect"),
PERMANENT_REDIRECT(308, "Permanent Redirect"),
BAD_REQUEST(400, "Bad Request"),
UNAUTHORIZED(401, "Unauthorized"),
PAYMENT_REQUIRED(402, "Payment Required"),
FORBIDDEN(403, "Forbidden"),
NOT_FOUND(404, "Not Found"),
METHOD_NOT_ALLOWED(405, "Method Not Allowed"),
NOT_ACCEPTABLE(406, "Not Acceptable"),
PROXY_AUTHENTICATION_REQUIRED(407, "Proxy Authentication Required"),
REQUEST_TIMEOUT(408, "Request Timeout"),
CONFLICT(409, "Conflict"),
GONE(410, "Gone"),
LENGTH_REQUIRED(411, "Length Required"),
PRECONDITION_FAILED(412, "Precondition Failed"),
PAYLOAD_TOO_LARGE(413, "Payload Too Large"),
REQUEST_ENTITY_TOO_LARGE(413, "Request Entity Too Large"),
URI_TOO_LONG(414, "URI Too Long"),
REQUEST_URI_TOO_LONG(414, "Request-URI Too Long"),
UNSUPPORTED_MEDIA_TYPE(415, "Unsupported Media Type"),
REQUESTED_RANGE_NOT_SATISFIABLE(416, "Requested range not satisfiable"),
EXPECTATION_FAILED(417, "Expectation Failed"),
I_AM_A_TEAPOT(418, "I'm a teapot"),
INSUFFICIENT_SPACE_ON_RESOURCE(419, "Insufficient Space On Resource"),
METHOD_FAILURE(420, "Method Failure"),
DESTINATION_LOCKED(421, "Destination Locked"),
UNPROCESSABLE_ENTITY(422, "Unprocessable Entity"),
LOCKED(423, "Locked"),
FAILED_DEPENDENCY(424, "Failed Dependency"),
TOO_EARLY(425, "Too Early"),
UPGRADE_REQUIRED(426, "Upgrade Required"),
PRECONDITION_REQUIRED(428, "Precondition Required"),
TOO_MANY_REQUESTS(429, "Too Many Requests"),
REQUEST_HEADER_FIELDS_TOO_LARGE(431, "Request Header Fields Too Large"),
UNAVAILABLE_FOR_LEGAL_REASONS(451, "Unavailable For Legal Reasons"),
INTERNAL_SERVER_ERROR(500, "Internal Server Error"),
NOT_IMPLEMENTED(501, "Not Implemented"),
BAD_GATEWAY(502, "Bad Gateway"),
SERVICE_UNAVAILABLE(503, "Service Unavailable"),
GATEWAY_TIMEOUT(504, "Gateway Timeout"),
HTTP_VERSION_NOT_SUPPORTED(505, "HTTP Version not supported"),
VARIANT_ALSO_NEGOTIATES(506, "Variant Also Negotiates"),
INSUFFICIENT_STORAGE(507, "Insufficient Storage"),
LOOP_DETECTED(508, "Loop Detected"),
BANDWIDTH_LIMIT_EXCEEDED(509, "Bandwidth Limit Exceeded"),
NOT_EXTENDED(510, "Not Extended"),
NETWORK_AUTHENTICATION_REQUIRED(511, "Network Authentication Required");
private final int value;
private final String reasonPhrase;
HttpStatus(int value, String reasonPhrase) {
this.value = value;
this.reasonPhrase = reasonPhrase;
}
public int getValue() {
return value;
}
public String getReasonPhrase() {
return reasonPhrase;
}
public boolean isServerError() {
return value >= INTERNAL_SERVER_ERROR.getValue();
}
public static HttpStatus valueOf(int statusCode) throws IllegalArgumentException {
for (HttpStatus status : values()) {
if (status.getValue() == statusCode) {
return status;
}
}
throw new IllegalArgumentException("No matching constant for [" + statusCode + "]");
}
public static HttpStatus resolve(int statusCode) {
for (HttpStatus status : values()) {
if (status.getValue() == statusCode) {
return status;
}
}
return null;
}
}

View File

@ -0,0 +1,51 @@
package cd.casic.ci.common.api.constant;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.constant
* @Projectops-pro
* @namePipelineConstants
* @Date2025/03/26 15:59
* @FilenamePipelineConstants
* @descriptionTodo
*/
public class PipelineConstants {
public static final String PIPELINE_SUBPIPELINE_CALL_ELEMENT_ID = "pipeline.subpipeline.call.element.id";
public static final String PIPELINE_SUBPIPELINE_CALL_ELEMENT_NAME = "pipeline.subpipeline.call.element.name";
public static final String PIPELINE_GIT_REF = "GIT_CI_REF";
public static final String PIPELINE_GIT_HEAD_REF = "GIT_CI_HEAD_REF";
public static final String PIPELINE_GIT_BASE_REF = "GIT_CI_BASE_REF";
public static final String PIPELINE_GIT_REPO = "GIT_CI_REPO";
public static final String PIPELINE_GIT_REPO_ID = "GIT_CI_REPO_ID";
public static final String PIPELINE_GIT_REPO_NAME = "GIT_CI_REPO_NAME";
public static final String PIPELINE_GIT_REPO_GROUP = "GIT_CI_REPO_GROUP";
public static final String PIPELINE_GIT_REPO_CREATE_TIME = "GIT_CI_REPO_CREATE_TIME";
public static final String PIPELINE_GIT_REPO_CREATOR = "GIT_CI_REPO_CREATOR";
public static final String PIPELINE_GIT_EVENT = "GIT_CI_EVENT";
public static final String PIPELINE_GIT_EVENT_CONTENT = "GIT_CI_EVENT_CONTENT";
public static final String PIPELINE_GIT_SHA = "GIT_CI_SHA";
public static final String PIPELINE_GIT_SHA_SHORT = "GIT_CI_SHA_SHORT";
public static final String PIPELINE_GIT_BEFORE_SHA = "GIT_CI_BEFORE_SHA";
public static final String PIPELINE_GIT_BEFORE_SHA_SHORT = "GIT_CI_BEFORE_SHA_SHORT";
public static final String PIPELINE_GIT_COMMIT_MESSAGE = "GIT_CI_COMMIT_MESSAGE";
public static final String PIPELINE_GIT_EVENT_URL = "GIT_CI_EVENT_URL";
public static final String PIPELINE_GIT_ACTION = "GIT_CI_ACTION";
public static final String PIPELINE_GIT_YAML_PATH = "GIT_CI_YAML_PATH";
public static final String PIPELINE_GIT_REPO_URL = "GIT_CI_REPO_URL";
public static final String PIPELINE_GIT_BASE_REPO_URL = "GIT_CI_BASE_REPO_URL";
public static final String PIPELINE_GIT_HEAD_REPO_URL = "GIT_CI_HEAD_REPO_URL";
public static final String PIPELINE_GIT_COMMIT_AUTHOR = "GIT_CI_COMMIT_AUTHOR";
public static final String PIPELINE_GIT_UPDATE_USER = "GIT_CI_PIPELINE_UPDATE_USER";
public static final String PIPELINE_GIT_AUTHORIZER = "GIT_CI_AUTHORIZER";
public static final String PIPELINE_GIT_TAG_MESSAGE = "GIT_CI_TAG_MESSAGE";
public static final String PIPELINE_GIT_TAG_FROM = "GIT_CI_TAG_FROM";
public static final String PIPELINE_GIT_MR_ID = "GIT_CI_MR_ID";
public static final String PIPELINE_GIT_MR_IID = "GIT_CI_MR_IID";
public static final String PIPELINE_GIT_MR_URL = "GIT_CI_MR_URL";
public static final String PIPELINE_GIT_MR_TITLE = "GIT_CI_MR_TITLE";
public static final String PIPELINE_GIT_MR_DESC = "GIT_CI_MR_DESC";
public static final String PIPELINE_GIT_MR_PROPOSER = "GIT_CI_MR_PROPOSER";
public static final String PIPELINE_GIT_MR_ACTION = "GIT_CI_MR_ACTION";
public static final String PIPELINE_PAC_REPO_HASH_ID = "BK_CI_PAC_REPO_HASH_ID";
public static final String PIPELINE_GIT_TIME_TRIGGER_KIND = "schedule";
}

View File

@ -0,0 +1,30 @@
package cd.casic.ci.common.api.constant;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.constant
* @Projectops-pro
* @nameStringConstant
* @Date2025/03/26 18:26
* @FilenameStringConstant
* @descriptionTodo
*/
public class StringConstant {
public static String coerceAtMaxLength(String str, int maxLength) {
if (str.length() > maxLength) {
return str.substring(0, maxLength);
}
return str;
}
public static String appendIfNotEmpty(String str, String suffix, String separator) {
if (suffix != null && !suffix.isEmpty()) {
return str + separator + suffix;
}
return str;
}
public static String appendIfNotEmpty(String str, String suffix) {
return appendIfNotEmpty(str, suffix, ".");
}
}

View File

@ -0,0 +1,20 @@
package cd.casic.ci.common.api.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.enums
* @Projectops-pro
* @nameAgentAction
* @Date2025/03/26 10:13
* @FilenameAgentAction
* @descriptionTodo
*/
@Getter
@AllArgsConstructor
public enum AgentAction {
OFFLINE,
ONLINE;
}

View File

@ -0,0 +1,64 @@
package cd.casic.ci.common.api.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.enums
* @Projectops-pro
* @nameAgentStatus
* @Date2025/03/26 10:13
* @FilenameAgentStatus
* @descriptionTodo
*/
@Getter
@Slf4j
@AllArgsConstructor
public enum AgentStatus {
UN_IMPORT(0), // 未导入用户刚刚在界面上面生成链接
UN_IMPORT_OK(1), // 未导入但是agent状态正常这个时候还是不能用来当构建机
IMPORT_OK(2), // 用户已经在界面导入并且agent工作正常构建机只有在这个状态才能正常工作
IMPORT_EXCEPTION(3), // agent异常
DELETE(4); // 删除
private final int status;
@Override
public String toString() {
return String.valueOf(status);
}
public static AgentStatus fromStatus(int status) {
for (AgentStatus agentStatus : values()) {
if (agentStatus.getStatus() == status) {
return agentStatus;
}
}
log.error("Unknown agent status(" + status + ")");
return AgentStatus.UN_IMPORT;
}
public static boolean isDelete(AgentStatus status) {
return status == DELETE;
}
public static boolean isUnImport(AgentStatus status) {
return status == UN_IMPORT;
}
public static boolean isImportException(AgentStatus status) {
return status == IMPORT_EXCEPTION;
}
public static AgentStatus fromString(String status) {
for (AgentStatus agentStatus : values()) {
if (agentStatus.name().equals(status)) {
return agentStatus;
}
}
log.error("Unknown agent status(" + status + ")");
return AgentStatus.UN_IMPORT;
}
}

View File

@ -0,0 +1,26 @@
package cd.casic.ci.common.api.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.enums
* @Projectops-pro
* @nameBuildReviewType
* @Date2025/03/26 10:15
* @FilenameBuildReviewType
* @descriptionTodo
*/
@Getter
@AllArgsConstructor
public enum BuildReviewType {
TASK_REVIEW,
STAGE_REVIEW,
QUALITY_TASK_REVIEW_PASS,
QUALITY_TASK_REVIEW_ABORT,
QUALITY_CHECK_IN,
QUALITY_CHECK_OUT,
TRIGGER_REVIEW;
}

View File

@ -0,0 +1,21 @@
package cd.casic.ci.common.api.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.enums
* @Projectops-pro
* @nameBusTypeEnum
* @Date2025/03/26 10:16
* @FilenameBusTypeEnum
* @descriptionTodo
*/
@Getter
@AllArgsConstructor
public enum BusTypeEnum {
PIPELINE,
TEMPLATE;
}

View File

@ -0,0 +1,31 @@
package cd.casic.ci.common.api.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.enums
* @Projectops-pro
* @nameCheckoutRepositoryType
* @Date2025/03/26 10:16
* @FilenameCheckoutRepositoryType
* @descriptionTodo
*/
@Getter
@AllArgsConstructor
public enum CheckoutRepositoryType {
ID,
NAME,
URL,
SELF;
public static CheckoutRepositoryType parseType(String type) {
if (type == null || type.isBlank()) return ID;
return valueOf(type);
}
public static boolean skipTimerTriggerChange(String type) {
return "URL".equals(type) || "SELF".equals(type);
}
}

View File

@ -0,0 +1,22 @@
package cd.casic.ci.common.api.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.enums
* @Projectops-pro
* @nameCrudEnum
* @Date2025/03/26 10:16
* @FilenameCrudEnum
* @descriptionTodo
*/
@Getter
@AllArgsConstructor
public enum CrudEnum {
CREATE, // 增加
DELETE, // 删除
UPDATE, // 更新
READ; // 查询
}

View File

@ -0,0 +1,39 @@
package cd.casic.ci.common.api.enums;
import lombok.extern.slf4j.Slf4j;
import java.util.ServiceLoader;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.enums
* @Projectops-pro
* @nameEnumLoader
* @Date2025/03/26 10:16
* @FilenameEnumLoader
* @descriptionTodo
*/
@Slf4j
public class EnumLoader {
private static final AtomicBoolean MODIFY = new AtomicBoolean(false);
public static void enumModified() {
if (!MODIFY.compareAndSet(false, true)) {
return;
}
Class<EnumModifier> clazz = EnumModifier.class;
ServiceLoader<EnumModifier> fetcheries = ServiceLoader.load(clazz);
if (!fetcheries.iterator().hasNext()) {
fetcheries = ServiceLoader.load(clazz, ServiceLoader.class.getClassLoader());
}
fetcheries.forEach(modifier -> {
log.info("[ENUM MODIFIER]: " + modifier);
try {
modifier.modified();
} catch (Exception e) {
log.error("[ENUM MODIFIER]| load fail| " + e.getMessage(), e);
}
});
}
}

View File

@ -0,0 +1,14 @@
package cd.casic.ci.common.api.enums;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.enums
* @Projectops-pro
* @nameEnumModifier
* @Date2025/03/26 10:17
* @FilenameEnumModifier
* @descriptionTodo
*/
public interface EnumModifier {
void modified();
}

View File

@ -0,0 +1,32 @@
package cd.casic.ci.common.api.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.enums
* @Projectops-pro
* @nameFrontendTypeEnum
* @Date2025/03/26 10:26
* @FilenameFrontendTypeEnum
* @descriptionTodo
*/
@Getter
@AllArgsConstructor
public enum FrontendTypeEnum {
HISTORY("1.0"), // 历史老插件UI
NORMAL("1.1"), // 官方提供典型的插件UI配置方式
SPECIAL("1.2"); // 定制插件UI方式
private final String typeVersion;
public static FrontendTypeEnum getFrontendTypeObj(String typeVersion) {
for (FrontendTypeEnum frontendTypeEnum : values()) {
if (frontendTypeEnum.getTypeVersion().equals(typeVersion)) {
return frontendTypeEnum;
}
}
return null;
}
}

View File

@ -0,0 +1,22 @@
package cd.casic.ci.common.api.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.enums
* @Projectops-pro
* @nameOSType
* @Date2025/03/26 10:27
* @FilenameOSType
* @descriptionTodo
*/
@Getter
@AllArgsConstructor
public enum OSType {
WINDOWS,
LINUX,
MAC_OS,
OTHER;
}

View File

@ -0,0 +1,67 @@
package cd.casic.ci.common.api.enums;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import java.net.URLEncoder;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.enums
* @Projectops-pro
* @nameRepositoryConfig
* @Date2025/03/26 10:27
* @FilenameRepositoryConfig
* @descriptionTodo
*/
@Data
@Slf4j
@NoArgsConstructor
@AllArgsConstructor
public class RepositoryConfig {
private String repositoryHashId;
@Schema(title = "新版的git代码库名")
private String repositoryName;
@Schema(title = "新版的git插件的类型")
private RepositoryType repositoryType;
public RepositoryConfig(String repositoryHashId, String repositoryName, TriggerRepositoryType triggerRepositoryType, String selfRepoHashId) {
this.repositoryHashId = triggerRepositoryType == TriggerRepositoryType.SELF ? selfRepoHashId : repositoryHashId;
this.repositoryName = repositoryName;
this.repositoryType = TriggerRepositoryType.toRepositoryType(triggerRepositoryType) != null ? TriggerRepositoryType.toRepositoryType(triggerRepositoryType) : RepositoryType.ID;
}
@JsonIgnore
public String getRepositoryId() {
switch (repositoryType) {
case ID:
if (repositoryHashId == null || repositoryHashId.isBlank()) {
throw new ParamBlankException("代码库HashId为空");
}
return repositoryHashId;
case NAME:
if (repositoryName == null || repositoryName.isBlank()) {
throw new ParamBlankException("代码库名为空");
}
return repositoryName;
default:
throw new ParamBlankException("未知的代码库类型");
}
}
@JsonIgnore
public String getURLEncodeRepositoryId() {
try {
return URLEncoder.encode(getRepositoryId(), "UTF-8");
} catch (Exception e) {
throw new ParamBlankException("编码失败: " + e.getMessage());
}
}
@Override
public String toString() {
return "[repositoryHashId=" + repositoryHashId + ", repositoryName=" + repositoryName + ", repositoryType=" + repositoryType + "]";
}
}

View File

@ -0,0 +1,25 @@
package cd.casic.ci.common.api.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.enums
* @Projectops-pro
* @nameRepositoryType
* @Date2025/03/26 10:29
* @FilenameRepositoryType
* @descriptionTodo
*/
@Getter
@AllArgsConstructor
public enum RepositoryType {
ID,
NAME;
public static RepositoryType parseType(String type) {
if (type == null || type.isBlank()) return ID;
return RepositoryType.valueOf(type);
}
}

View File

@ -0,0 +1,24 @@
package cd.casic.ci.common.api.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.enums
* @Projectops-pro
* @nameRequestChannelTypeEnum
* @Date2025/03/26 10:30
* @FilenameRequestChannelTypeEnum
* @descriptionTodo
*/
@Getter
@AllArgsConstructor
public enum RequestChannelTypeEnum {
USER,
SERVICE,
BUILD,
OP,
OPEN,
API;
}

View File

@ -0,0 +1,37 @@
package cd.casic.ci.common.api.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.enums
* @Projectops-pro
* @nameScmCode
* @Date2025/03/26 10:30
* @FilenameScmCode
* @descriptionTodo
*/
@Getter
@AllArgsConstructor
public enum ScmCode {
GITEA("GITEA", "GITEA"), // 内部Gitea
GITHUB("GITHUB", "GITHUB"), // github
GITLAB("GITLAB", "GITLAB"); // github
private final String scmName;
private final String value;
public ScmType convertScmType() {
switch (this) {
case GITEA:
return ScmType.CODE_GIT;
case GITHUB:
return ScmType.GITHUB;
case GITLAB:
return ScmType.CODE_TGIT;
default:
throw new IllegalArgumentException("Unknown ScmCode: " + this);
}
}
}

View File

@ -0,0 +1,44 @@
package cd.casic.ci.common.api.enums;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public enum ScmType {
CODE_SVN("svn"),
CODE_GIT("git"),
CODE_GITLAB("gitlab"),
GITHUB("github"),
CODE_TGIT("tgit"),
CODE_P4("p4");
private final String alias;
public static Short parse(ScmType type) {
switch (type) {
case CODE_SVN:
return 1;
case CODE_GIT:
return 2;
case CODE_GITLAB:
return 3;
case GITHUB:
return 4;
case CODE_TGIT:
return 5;
case CODE_P4:
return 6;
default:
return 0;
}
}
public static ScmType parse(String alias) {
if (alias == null || alias.isBlank()) return null;
for (ScmType scmType : values()) {
if (scmType.alias.equals(alias)) {
return scmType;
}
}
return null;
}
}

View File

@ -0,0 +1,26 @@
package cd.casic.ci.common.api.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.enums
* @Projectops-pro
* @nameTaskStatusEnum
* @Date2025/03/26 10:50
* @FilenameTaskStatusEnum
* @descriptionTodo
*/
@Getter
@AllArgsConstructor
public enum TaskStatusEnum {
INIT,
HANDING,
FAIL,
SUCCESS,
PENDING_ROLLBACK,
ROLLBACKING,
ROLLBACK_SUCCESS,
ROLLBACK_FAIL;
}

View File

@ -0,0 +1,34 @@
package cd.casic.ci.common.api.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.api.enums
* @Projectops-pro
* @nameTriggerRepositoryType
* @Date2025/03/26 10:51
* @FilenameTriggerRepositoryType
* @descriptionTodo
*/
@Getter
@AllArgsConstructor
public enum TriggerRepositoryType {
ID,
NAME,
SELF,
NONE;
public static RepositoryType toRepositoryType(TriggerRepositoryType type) {
switch (type) {
case ID:
case SELF:
return RepositoryType.ID;
case NAME:
return RepositoryType.NAME;
default:
return null;
}
}
}

View File

@ -17,10 +17,16 @@
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>cd.casic.boot</groupId>
<artifactId>commons</artifactId>
</dependency>
<dependency>
<groupId>cd.casic.ci</groupId>
<artifactId>common-api</artifactId>
<version>2.0.0-jdk17</version>
</dependency>
</dependencies>
</project>

View File

@ -1,13 +0,0 @@
package cd.casic.ci.common.pipeline;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class CommonPipelineApplication {
public static void main(String[] args) {
SpringApplication.run(CommonPipelineApplication.class, args);
}
}

View File

@ -1,5 +1,7 @@
package cd.casic.ci.common.pipeline.container;
import cd.casic.ci.common.pipeline.IModelTemplate;
import cd.casic.ci.common.pipeline.pojo.time.BuildRecordTimeCost;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.swagger.v3.oas.annotations.media.Schema;
@ -19,7 +21,7 @@ import java.util.Map;
* @descriptionTodo
*/
@Data
@Schema(title = "流水线模型-多态基类")
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type")
@JsonSubTypes({

View File

@ -1,6 +1,7 @@
package cd.casic.ci.common.pipeline.pojo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
@ -14,6 +15,7 @@ import lombok.Data;
*/
@Data
@Schema(title = "构建模型-下拉框表单元素值")
@AllArgsConstructor
public class BuildFormValue {
@Schema(title = "元素值ID-标识符", required = true)
private String key;

View File

@ -0,0 +1,33 @@
package cd.casic.ci.common.pipeline.pojo.cascade;
import cd.casic.ci.common.pipeline.pojo.BuildFormValue;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.cascade
* @Projectops-pro
* @nameBuildCascadeProps
* @Date2025/03/26 10:04
* @FilenameBuildCascadeProps
* @descriptionTodo
*/
@Data
@Schema(title = "构建模型-表单元素属性")
@AllArgsConstructor
public class BuildCascadeProps {
// 级联ID
private String id;
// 级联下拉框值
private List<BuildFormValue> options;
// 后端搜索url
private String searchUrl;
// 搜索key
private String replaceKey;
// 级联子级
private BuildCascadeProps children;
}

View File

@ -0,0 +1,68 @@
package cd.casic.ci.common.pipeline.pojo.cascade;
import cd.casic.ci.common.pipeline.enums.BuildFormPropertyType;
import cd.casic.ci.common.pipeline.pojo.BuildFormProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.cascade
* @Projectops-pro
* @nameCascadeParam
* @Date2025/03/26 10:05
* @FilenameCascadeParam
* @descriptionTodo
*/
@Data
@Slf4j
@AllArgsConstructor
public abstract class CascadeParam {
private final BuildFormPropertyType type;
private final List<String> chain;
public BuildCascadeProps getProps(BuildFormProperty prop, String projectId) {
if (chain.size() < 2 || chain.size() != chainHandler().size()) {
// 最少两个链路节点且节点数和链式处理器数量相等
throw new IllegalArgumentException("chain size must be 2 and equal to chainHandler size");
}
Map<String, String> defaultValue = getDefaultValue(prop);
Map<String, BuildCascadeProps> map = new HashMap<>();
for (String key : chain) {
CascadeParamPropsHandler propsHandler = chainHandler().get(key);
if (propsHandler == null) {
throw new IllegalArgumentException("can not find handler for " + key + "|" + type);
}
map.put(key, propsHandler.handle(key, defaultValue.getOrDefault(key, ""), projectId));
}
// 链式关系处理
for (int i = chain.size() - 1; i > 0; i--) {
map.get(chain.get(i - 1)).setChildren(map.get(chain.get(i)));
}
return map.get(chain.get(0));
}
private Map<String, String> getDefaultValue(BuildFormProperty prop) {
Map<String, String> defaultValue = CascadePropertyUtils.parseDefaultValue(prop.getId(), prop.getDefaultValue(), prop.getType());
return chain.stream().allMatch(defaultValue::containsKey) ? defaultValue : Collections.emptyMap();
}
public abstract Map<String, CascadeParamPropsHandler> chainHandler();
public interface CascadeParamPropsHandler {
BuildCascadeProps handle(String key, String defaultValue, String projectId);
}
private static final Logger logger = LoggerFactory.getLogger(CascadeParam.class);
}

View File

@ -0,0 +1,85 @@
package cd.casic.ci.common.pipeline.pojo.cascade;
import cd.casic.ci.common.api.enums.ScmType;
import cd.casic.ci.common.pipeline.enums.BuildFormPropertyType;
import cd.casic.ci.common.pipeline.pojo.BuildFormValue;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.cascade
* @Projectops-pro
* @nameRepoRefCascadeParam
* @Date2025/03/26 10:06
* @FilenameRepoRefCascadeParam
* @descriptionTodo
*/
@Data
public class RepoRefCascadeParam extends CascadeParam {
public static final String SELECTOR_KEY_REPO_NAME = "repo-name";
public static final String SELECTOR_KEY_BRANCH = "branch";
private static final List<ScmType> SUPPORT_REPO_TYPE = Arrays.asList(
ScmType.CODE_GIT,
ScmType.GITHUB,
ScmType.CODE_SVN,
ScmType.CODE_TGIT,
ScmType.CODE_GITLAB
);
public RepoRefCascadeParam() {
super(BuildFormPropertyType.REPO_REF, Arrays.asList(SELECTOR_KEY_REPO_NAME, SELECTOR_KEY_BRANCH));
}
@Override
public Map<String, CascadeParamPropsHandler> chainHandler() {
return Map.of(
SELECTOR_KEY_REPO_NAME, repoNameHandler(),
SELECTOR_KEY_BRANCH, branchHandler()
);
}
private CascadeParamPropsHandler repoNameHandler() {
return (key, defaultValue, projectId) -> {
String repositoryTypes = SUPPORT_REPO_TYPE.stream().map(Enum::name).collect(Collectors.joining(","));
return new BuildCascadeProps(
key,
Collections.singletonList(new BuildFormValue(defaultValue, defaultValue)),
"process/api/user/buildParam/repository/" + projectId + "/aliasName?aliasName={words}&permission=LIST&repositoryType=" + repositoryTypes,
"{words}",
null
);
};
}
private CascadeParamPropsHandler branchHandler() {
return (key, defaultValue, projectId) -> new BuildCascadeProps(
key,
Collections.singletonList(new BuildFormValue(defaultValue, defaultValue)),
"/process/api/user/buildParam/" + projectId + "/repository/refs?search={branch}&repositoryType=NAME&repositoryId={parentValue}",
"{branch}",
null
);
}
public static Map<String, String> variableKeyMap(String key) {
return Map.of(
SELECTOR_KEY_REPO_NAME, key + "." + SELECTOR_KEY_REPO_NAME,
SELECTOR_KEY_BRANCH, key + "." + SELECTOR_KEY_BRANCH
);
}
public static Map<String, String> defaultValue() {
return Map.of(
SELECTOR_KEY_REPO_NAME, "",
SELECTOR_KEY_BRANCH, ""
);
}
}

View File

@ -0,0 +1,175 @@
package cd.casic.ci.common.pipeline.pojo.element;
import cd.casic.ci.common.pipeline.IModelTemplate;
import cd.casic.ci.common.pipeline.NameAndValue;
import cd.casic.ci.common.pipeline.enums.BuildStatus;
import cd.casic.ci.common.pipeline.enums.StartType;
import cd.casic.ci.common.pipeline.pojo.time.BuildRecordTimeCost;
import cd.casic.ci.common.pipeline.pojo.transfer.PreStep;
import cd.casic.ci.common.pipeline.utils.ElementUtils;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Map;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element
* @Projectops-pro
* @nameElement
* @Date2025/03/26 16:17
* @FilenameElement
* @descriptionTodo
*/
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "@type",
defaultImpl = EmptyElement.class
)
@JsonSubTypes({
@JsonSubTypes.Type(value = MatrixStatusElement.class, name = MatrixStatusElement.classType),
@JsonSubTypes.Type(value = CodeGitWebHookTriggerElement.class, name = CodeGitWebHookTriggerElement.classType),
@JsonSubTypes.Type(value = CodeGitlabWebHookTriggerElement.class, name = CodeGitlabWebHookTriggerElement.classType),
@JsonSubTypes.Type(value = CodeSVNWebHookTriggerElement.class, name = CodeSVNWebHookTriggerElement.classType),
@JsonSubTypes.Type(value = CodeGithubWebHookTriggerElement.class, name = CodeGithubWebHookTriggerElement.classType),
@JsonSubTypes.Type(value = CodeGitElement.class, name = CodeGitElement.classType),
@JsonSubTypes.Type(value = CodeGitlabElement.class, name = CodeGitlabElement.classType),
@JsonSubTypes.Type(value = GithubElement.class, name = GithubElement.classType),
@JsonSubTypes.Type(value = CodeSvnElement.class, name = CodeSvnElement.classType),
@JsonSubTypes.Type(value = LinuxScriptElement.class, name = LinuxScriptElement.classType),
@JsonSubTypes.Type(value = WindowsScriptElement.class, name = WindowsScriptElement.classType),
@JsonSubTypes.Type(value = ManualTriggerElement.class, name = ManualTriggerElement.classType),
@JsonSubTypes.Type(value = RemoteTriggerElement.class, name = RemoteTriggerElement.classType),
@JsonSubTypes.Type(value = TimerTriggerElement.class, name = TimerTriggerElement.classType),
@JsonSubTypes.Type(value = ManualReviewUserTaskElement.class, name = ManualReviewUserTaskElement.classType),
@JsonSubTypes.Type(value = SubPipelineCallElement.class, name = SubPipelineCallElement.classType),
@JsonSubTypes.Type(value = MarketBuildAtomElement.class, name = MarketBuildAtomElement.classType),
@JsonSubTypes.Type(value = MarketBuildLessAtomElement.class, name = MarketBuildLessAtomElement.classType),
@JsonSubTypes.Type(value = MarketCheckImageElement.class, name = MarketCheckImageElement.classType),
@JsonSubTypes.Type(value = QualityGateInElement.class, name = QualityGateInElement.classType),
@JsonSubTypes.Type(value = QualityGateOutElement.class, name = QualityGateOutElement.classType),
@JsonSubTypes.Type(value = CodeTGitWebHookTriggerElement.class, name = CodeTGitWebHookTriggerElement.classType),
@JsonSubTypes.Type(value = CodeP4WebHookTriggerElement.class, name = CodeP4WebHookTriggerElement.classType)
})
@NoArgsConstructor
@Data
@Schema(title = "Element 基类")
public abstract class Element implements IModelTemplate {
@Schema(title = "任务名称", required = false)
private String name;
@Schema(title = "id", required = false)
private String id;
@Schema(title = "状态(仅在运行构建时有用的中间参数,不要在编排保存阶段设置值)", required = false)
private String status;
@Schema(title = "执行次数(仅在运行构建时有用的中间参数,不要在编排保存阶段设置值)", required = false)
private int executeCount = 1;
@Schema(title = "是否重试(仅在运行构建时有用的中间参数,不要在编排保存阶段设置值)", required = false)
private Boolean canRetry;
@Schema(title = "是否跳过(仅在运行构建时有用的中间参数,不要在编排保存阶段设置值)", required = false)
private Boolean canSkip;
@Schema(title = "执行时间(仅在运行构建时有用的中间参数,不要在编排保存阶段设置值)", required = false)
private Long elapsed;//"即将被timeCost代替"
@Schema(title = "启动时间(仅在运行构建时有用的中间参数,不要在编排保存阶段设置值)", required = false)
private Long startEpoch;//"即将被timeCost代替"
@Schema(title = "插件原始版本(仅在运行构建时有用的中间参数,不要在编排保存阶段设置值)", required = false)
private String originVersion;
@Schema(title = "插件版本", required = true)
private String version = "1.*";
@Schema(title = "模板对比的时候是不是有变更(temporary field)", required = false)
private Boolean templateModify;
@Schema(title = "附加参数", required = false)
private ElementAdditionalOptions additionalOptions;
@Schema(title = "用户自定义ID用于上下文键值设置", required = false)
private String stepId;
@Schema(title = "各项耗时", required = true)
private BuildRecordTimeCost timeCost;
@Schema(title = "用户自定义环境变量(插件运行时写入环境)", required = false)
private List<NameAndValue> customEnv;
@Schema(title = "错误类型(仅在运行构建时有用的中间参数,不要在编排保存阶段设置值)", required = false)
private String errorType;
@Schema(title = "错误代码(仅在运行构建时有用的中间参数,不要在编排保存阶段设置值)", required = false)
private Integer errorCode;
@Schema(title = "错误信息(仅在运行构建时有用的中间参数,不要在编排保存阶段设置值)", required = false)
private String errorMsg;
@Schema(title = "插件名称,构建结束后的快照名称(仅在运行构建时有用的中间参数,不要在编排保存阶段设置值)", required = false)
private String atomName;
@Schema(title = "所属插件分类代码(仅在运行构建时有用的中间参数,不要在编排保存阶段设置值)", required = false)
private String classifyCode;
@Schema(title = "所属插件分类名称(仅在运行构建时有用的中间参数,不要在编排保存阶段设置值)", required = false)
private String classifyName;
@Schema(title = "任务运行进度", required = false)
private Double progressRate;
private String template;
private String ref;
private Map<String, String> variables;
private String asyncStatus;
public String getAtomCode() {
return getClassType();
}
public abstract String getClassType();
public String getTaskAtom() {
return "";
}
public Map<String, Object> genTaskParams() {
return JsonUtil.toMutableMap(this);
}
public void cleanUp() {
}
public PreStep transferYaml(JSONObject defaultValue) {
return null;
}
public boolean elementEnabled() {
return additionalOptions == null || additionalOptions.getEnable();
}
public void transformCompatibility() {
if (additionalOptions != null && (additionalOptions.getTimeoutVar() == null || additionalOptions.getTimeoutVar().isBlank())) {
additionalOptions.setTimeoutVar(String.valueOf(additionalOptions.getTimeout()));
}
}
public String findFirstTaskIdByStartType(StartType startType) {
return "";
}
public BuildStatus initStatus(boolean rerun) {
if (!elementEnabled()) {
return BuildStatus.SKIP;
} else if (rerun) {
return BuildStatus.QUEUE;
} else if (status != null && status.equals(BuildStatus.SKIP.name())) {
return BuildStatus.SKIP;
} else {
return BuildStatus.QUEUE;
}
}
public void disableBySkipVar(Map<String, Object> variables) {
ElementPostInfo elementPostInfo = additionalOptions != null ? additionalOptions.getElementPostInfo() : null;
boolean postFlag = elementPostInfo != null;
String elementId = postFlag ? elementPostInfo.getParentElementId() : id;
if (variables.get(ElementUtils.getSkipElementVariableName(elementId)) != null && "true".equals(variables.get(ElementUtils.getSkipElementVariableName(elementId)))) {
if (additionalOptions == null) {
additionalOptions = new ElementAdditionalOptions();
}
additionalOptions.setEnable(false);
}
}
public Map<String, Object> initTaskVar() {
return new java.util.HashMap<>();
}
}

View File

@ -0,0 +1,73 @@
package cd.casic.ci.common.pipeline.pojo.element;
import cd.casic.ci.common.pipeline.NameAndValue;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element
* @Projectops-pro
* @nameElementAdditionalOptions
* @Date2025/03/26 16:24
* @FilenameElementAdditionalOptions
* @descriptionTodo
*/
@Data
@Schema(title = "插件级别流程控制模型")
public class ElementAdditionalOptions {
@Schema(title = "是否启用", required = false)
private boolean enable = true;
@Schema(title = "是否失败时继续", required = false)
private boolean continueWhenFailed = false;
@Schema(title = "是否出现跳过按钮(手动继续)", required = false)
private Boolean manualSkip;
@Schema(title = "是否失败时重试", required = false)
private boolean retryWhenFailed = false;
@Schema(title = "重试计数", required = false)
private int retryCount = 0;
@Schema(title = "是否允许手动重试", required = false)
private boolean manualRetry = true;
@Schema(title = "超时分钟", required = false)
private Long timeout = 100L;
@Schema(title = "新的执行的超时时间,支持变量(分钟Minutes)出错则取timeout的值", required = false)
private String timeoutVar;
@JsonIgnore
private boolean change = false;
@Schema(title = "执行条件", required = false)
private RunCondition runCondition;
@Schema(title = "是否配置前置暂停", required = false)
private Boolean pauseBeforeExec = false;
@Schema(title = "订阅暂停通知用户", required = false)
private String subscriptionPauseUser = "";
@Schema(title = "", required = false)
private String otherTask;
@Schema(title = "自定义变量", required = false)
private List<NameAndValue> customVariables;
@Schema(title = "自定义条件", required = false)
private String customCondition;
@Schema(title = "插件post信息", required = false)
private ElementPostInfo elementPostInfo;
@Schema(title = "是否设置自定义环境变量", required = false)
@Deprecated
private Boolean enableCustomEnv = true;
@Schema(title = "用户自定义环境变量(插件运行时写入环境)", required = false)
@Deprecated
private List<NameAndValue> customEnv;
public enum RunCondition {
PRE_TASK_SUCCESS,
PRE_TASK_FAILED_BUT_CANCEL,
PRE_TASK_FAILED_EVEN_CANCEL,
PRE_TASK_FAILED_ONLY,
OTHER_TASK_RUNNING,
CUSTOM_VARIABLE_MATCH,
CUSTOM_VARIABLE_MATCH_NOT_RUN,
CUSTOM_CONDITION_MATCH,
PARENT_TASK_CANCELED_OR_TIMEOUT,
PARENT_TASK_FINISH
}
}

View File

@ -0,0 +1,28 @@
package cd.casic.ci.common.pipeline.pojo.element;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element
* @Projectops-pro
* @nameElementBaseInfo
* @Date2025/03/26 16:25
* @FilenameElementBaseInfo
* @descriptionTodo
*/
@Data
@Schema(title = "元素基本信息")
public class ElementBaseInfo {
@Schema(title = "元素ID", required = true)
private String elementId;
@Schema(title = "元素名称", required = true)
private String elementName;
@Schema(title = "插件代码", required = true)
private String atomCode;
@Schema(title = "插件版本号", required = true)
private String version;
@Schema(title = "元素在job中的位置")
private int elementJobIndex;
}

View File

@ -0,0 +1,28 @@
package cd.casic.ci.common.pipeline.pojo.element;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element
* @Projectops-pro
* @nameElementPostInfo
* @Date2025/03/26 16:25
* @FilenameElementPostInfo
* @descriptionTodo
*/
@Data
@Schema(title = "元素post信息")
public class ElementPostInfo {
@Schema(title = "入口参数")
private String postEntryParam;
@Schema(title = "执行条件")
private String postCondition;
@Schema(title = "父元素ID")
private String parentElementId;
@Schema(title = "父元素名称")
private String parentElementName;
@Schema(title = "父元素在job中的位置")
private int parentElementJobIndex;
}

View File

@ -0,0 +1,37 @@
package cd.casic.ci.common.pipeline.pojo.element;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element
* @Projectops-pro
* @nameElementProp
* @Date2025/03/26 16:26
* @FilenameElementProp
* @descriptionTodo
*/
@Data
@Schema(title = "插件属性")
public class ElementProp {
private String name;
private Object value;
private ElementPropType type;
public enum ElementPropType {
VUEX_INPUT("vuex-input"),
STAFF_INPUT("staff-input"),
SELECTOR("selector");
private final String value;
ElementPropType(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
}

View File

@ -0,0 +1,24 @@
package cd.casic.ci.common.pipeline.pojo.element;
import lombok.NoArgsConstructor;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element
* @Projectops-pro
* @nameEmptyElement
* @Date2025/03/26 16:26
* @FilenameEmptyElement
* @descriptionTodo
*/
@NoArgsConstructor
public class EmptyElement extends Element {
public EmptyElement(String name, String id) {
super();
}
@Override
public String getClassType() {
return "unknownType";
}
}

View File

@ -0,0 +1,50 @@
package cd.casic.ci.common.pipeline.pojo.element;
import cd.casic.ci.common.pipeline.pojo.element.atom.SubPipelineType;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Map;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element
* @Projectops-pro
* @nameSubPipelineCallElement
* @Date2025/03/26 16:28
* @FilenameSubPipelineCallElement
* @descriptionTodo
*/
@Data
@Schema(title = "子流水线调用", description = SubPipelineCallElement.classType)
public class SubPipelineCallElement extends Element {
public static final String classType = "subPipelineCall";
public static final String TASK_ATOM = "subPipelineCallAtom";
@Schema(title = "任务名称", required = true)
private String name = "自流水线调用";
@Schema(title = "id", required = false)
private String id;
@Schema(title = "状态", required = false)
private String status;
@Schema(title = "子流水线ID", required = true)
private String subPipelineId = "";
@Schema(title = "是否异步", required = true)
private boolean asynchronous;
@Schema(title = "新版的子流水线原子的类型")
private SubPipelineType subPipelineType = SubPipelineType.ID;
@Schema(title = "新版的子流水线名")
private String subPipelineName;
@Schema(title = "启动参数", required = false)
private Map<String, String> parameters;
@Override
public String getTaskAtom() {
return TASK_ATOM;
}
@Override
public String getClassType() {
return classType;
}
}

View File

@ -0,0 +1,68 @@
package cd.casic.ci.common.pipeline.pojo.element.agent;
import cd.casic.ci.common.api.enums.RepositoryType;
import cd.casic.ci.common.pipeline.enums.CodePullStrategy;
import cd.casic.ci.common.pipeline.pojo.element.Element;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element.agent
* @Projectops-pro
* @nameCodeGitElement
* @Date2025/03/26 16:33
* @FilenameCodeGitElement
* @descriptionTodo
*/
@Data
@NoArgsConstructor
@Schema(title = "拉取Git仓库代码", description = CodeGitElement.classType)
public class CodeGitElement extends Element {
public static final String classType = "CODE_GIT";
public static final String modeType = "mode.type";
public static final String modeValue = "mode.value";
@Schema(title = "任务名称", required = true)
private String name = "";
@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 = "revision 用于强制指定commitId", required = false)
private String revision;
@Schema(title = "checkout 策略", required = false)
private CodePullStrategy strategy = CodePullStrategy.INCREMENT_UPDATE;
@Schema(title = "代码存放路径", required = false)
private String path;
@Schema(title = "启动Submodule", required = false)
private Boolean enableSubmodule = true;
@Schema(title = "Git指定拉取方式", required = false)
private GitPullMode gitPullMode;
@Schema(title = "新版的git插件的类型")
private RepositoryType repositoryType;
@Schema(title = "新版的git代码库名")
private String repositoryName;
@Override
public Map<String, Object> genTaskParams() {
Map<String, Object> paramMap = JsonUtil.toMutableMap(this);
if (gitPullMode != null) {
paramMap.put(modeType, gitPullMode.getType().name());
paramMap.put(modeValue, gitPullMode.getValue());
}
return paramMap;
}
@Override
public String getClassType() {
return classType;
}
}

View File

@ -0,0 +1,67 @@
package cd.casic.ci.common.pipeline.pojo.element.agent;
import cd.casic.ci.common.pipeline.enums.CodePullStrategy;
import cd.casic.ci.common.pipeline.pojo.element.Element;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element.agent
* @Projectops-pro
* @nameCodeGitlabElement
* @Date2025/03/26 16:34
* @FilenameCodeGitlabElement
* @descriptionTodo
*/
@Data
@NoArgsConstructor
@Schema(title = "拉取Gitlab仓库代码", description = CodeGitlabElement.classType)
public class CodeGitlabElement extends Element {
public static final String classType = "CODE_GITLAB";
public static final String modeType = "mode.type";
public static final String modeValue = "mode.value";
@Schema(title = "任务名称", required = true)
private String name = "";
@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 = "revision 用于强制指定commitId", required = false)
private String revision;
@Schema(title = "checkout 策略", required = false)
private CodePullStrategy strategy = CodePullStrategy.INCREMENT_UPDATE;
@Schema(title = "代码存放路径", required = false)
private String path;
@Schema(title = "启动Submodule", required = false)
private Boolean enableSubmodule = true;
@Schema(title = "Git指定拉取方式", required = false)
private GitPullMode gitPullMode;
@Schema(title = "新版的gitlab原子的类型")
private RepositoryType repositoryType;
@Schema(title = "新版的gitlab代码库名")
private String repositoryName;
@Override
public Map<String, Object> genTaskParams() {
Map<String, Object> paramMap = JsonUtil.toMutableMap(this);
if (gitPullMode != null) {
paramMap.put(modeType, gitPullMode.getType().name());
paramMap.put(modeValue, gitPullMode.getValue());
}
return paramMap;
}
@Override
public String getClassType() {
return classType;
}
}

View File

@ -0,0 +1,72 @@
package cd.casic.ci.common.pipeline.pojo.element.agent;
import cd.casic.ci.common.pipeline.enums.CodePullStrategy;
import cd.casic.ci.common.pipeline.enums.SVNVersion;
import cd.casic.ci.common.pipeline.enums.SvnDepth;
import cd.casic.ci.common.pipeline.pojo.element.Element;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element.agent
* @Projectops-pro
* @nameCodeSvnElement
* @Date2025/03/26 16:36
* @FilenameCodeSvnElement
* @descriptionTodo
*/
@Data
@NoArgsConstructor
@Schema(title = "拉取SVN仓库代码", description = CodeSvnElement.classType)
public class CodeSvnElement extends Element {
public static final String classType = "CODE_SVN";
public static final String REPO_HASH_ID = "repositoryHashId";
public static final String REPO_NAME = "repositoryName";
public static final String REPO_TYPE = "repositoryType";
public static final String BRANCH_NAME = "branchName";
public static final String REVISION = "revision";
public static final String STRATEGY = "strategy";
public static final String PATH = "path";
public static final String enableSubmodule = "enableSubmodule";
public static final String enableVirtualMergeBranch = "enableVirtualMergeBranch";
public static final String specifyRevision = "specifyRevision";
public static final String svnDepth = "svnDepth";
public static final String svnPath = "svnPath";
public static final String svnVersion = "svnVersion";
@Schema(title = "任务名称", required = true)
private String name = "";
@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 = "revision 用于强制指定commitId", required = false)
private String revision;
@Schema(title = "checkout 策略", required = false)
private CodePullStrategy strategy = CodePullStrategy.INCREMENT_UPDATE;
@Schema(title = "代码存放路径", required = false)
private String path;
@Schema(title = "启动Submodule", required = false)
private Boolean enableSubmodule = true;
@Schema(title = "指定版本号", required = false)
private Boolean specifyRevision = false;
@Schema(title = "拉取仓库深度", required = false)
private SvnDepth svnDepth = SvnDepth.infinity;
@Schema(title = "SVN相对路径", required = false)
private String svnPath;
@Schema(title = "SVN的版本", required = false)
private SVNVersion svnVersion;
@Schema(title = "新版的svn原子的类型")
private RepositoryType repositoryType;
@Schema(title = "新版的svn代码库名")
private String repositoryName;
@Override
public String getClassType() {
return classType;
}
}

View File

@ -0,0 +1,68 @@
package cd.casic.ci.common.pipeline.pojo.element.agent;
import cd.casic.ci.common.api.enums.RepositoryType;
import cd.casic.ci.common.pipeline.enums.CodePullStrategy;
import cd.casic.ci.common.pipeline.pojo.element.Element;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element.agent
* @Projectops-pro
* @nameGithubElement
* @Date2025/03/26 16:37
* @FilenameGithubElement
* @descriptionTodo
*/
@Data
@NoArgsConstructor
@Schema(title = "拉取Github仓库代码", description = GithubElement.classType)
public class GithubElement extends Element {
public static final String classType = "GITHUB";
public static final String modeType = "mode.type";
public static final String modeValue = "mode.value";
@Schema(title = "任务名称", required = true)
private String name = "";
@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 = "checkout 策略", required = false)
private CodePullStrategy strategy = CodePullStrategy.INCREMENT_UPDATE;
@Schema(title = "代码存放路径", required = false)
private String path;
@Schema(title = "启动Submodule", required = false)
private Boolean enableSubmodule = true;
@Schema(title = "revision 用于强制指定commitId", required = false)
private String revision;
@Schema(title = "指定拉取方式", required = false)
private GitPullMode gitPullMode;
@Schema(title = "支持虚拟合并分支", required = false)
private Boolean enableVirtualMergeBranch = false;
@Schema(title = "新版的github原子的类型")
private RepositoryType repositoryType;
@Schema(title = "新版的github代码库名")
private String repositoryName;
@Override
public Map<String, Object> genTaskParams() {
Map<String, Object> paramMap = JsonUtil.toMutableMap(this);
if (gitPullMode != null) {
paramMap.put(modeType, gitPullMode.getType().name());
paramMap.put(modeValue, gitPullMode.getValue());
}
return paramMap;
}
@Override
public String getClassType() {
return classType;
}
}

View File

@ -0,0 +1,92 @@
package cd.casic.ci.common.pipeline.pojo.element.agent;
import cd.casic.ci.common.pipeline.NameAndValue;
import cd.casic.ci.common.pipeline.enums.BuildScriptType;
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.transfer.PreStep;
import com.alibaba.fastjson.JSONObject;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element.agent
* @Projectops-pro
* @nameLinuxScriptElement
* @Date2025/03/26 16:37
* @FilenameLinuxScriptElement
* @descriptionTodo
*/
@Data
@NoArgsConstructor
@Schema(title = "脚本任务linux和macOS环境", description = LinuxScriptElement.classType)
public class LinuxScriptElement extends Element {
public static final String classType = "linuxScript";
@Schema(title = "任务名称", required = true)
private String name = "执行Linux脚本";
@Schema(title = "id", required = false)
private String id;
@Schema(title = "状态", required = false)
private String status;
@Schema(title = "用户自定义ID", required = false)
private String stepId;
@Schema(title = "用户自定义环境变量(插件运行时写入环境)", required = false)
private List<NameAndValue> customEnv;
@Schema(title = "FAQ url链接", required = false)
private String errorFAQUrl;
@Schema(title = "脚本类型", required = true)
private BuildScriptType scriptType;
@Schema(title = "脚本内容", required = true)
private String script;
@Schema(title = "某次执行为非0时失败是否继续执行脚本", required = false)
private Boolean continueNoneZero;
@Schema(title = "启用脚本执行失败时归档的文件", required = false)
private Boolean enableArchiveFile = false;
@Schema(title = "脚本执行失败时归档的文件", required = false)
private String archiveFile;
@Schema(title = "附加参数", required = false)
private ElementAdditionalOptions additionalOptions;
@Override
public Map<String, Object> genTaskParams() {
Map<String, Object> mutableMap = super.genTaskParams();
try {
mutableMap.put("script", URLEncoder.encode(script, "UTF-8"));
} catch (Exception e) {
mutableMap.put("script", script);
}
return mutableMap;
}
@Override
public PreStep transferYaml(JSONObject defaultValue) {
Map<String, Object> res = new HashMap<>();
res.put("script", script);
if (continueNoneZero != null && continueNoneZero) {
res.put("continueNoneZero", true);
}
if (enableArchiveFile != null && enableArchiveFile && archiveFile != null) {
res.put("enableArchiveFile", true);
res.put("archiveFile", archiveFile);
}
return new PreStep(
name,
stepId,
getAtomCode() + "@" + getVersion(),
res
);
}
@Override
public String getClassType() {
return classType;
}
}

View File

@ -0,0 +1,106 @@
package cd.casic.ci.common.pipeline.pojo.element.agent;
import cd.casic.ci.common.pipeline.pojo.element.Element;
import cd.casic.ci.common.pipeline.pojo.transfer.PreStep;
import cd.casic.ci.common.pipeline.utils.TransferUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element.agent
* @Projectops-pro
* @nameManualReviewUserTaskElement
* @Date2025/03/26 16:44
* @FilenameManualReviewUserTaskElement
* @descriptionTodo
*/
@Data
@NoArgsConstructor
@Schema(title = "人工审核", description = ManualReviewUserTaskElement.classType)
public class ManualReviewUserTaskElement extends Element {
public static final String classType = "manualReviewUserTask";
@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 = true)
private List<String> reviewUsers;
@Schema(title = "描述", required = false)
private String desc;
@Schema(title = "审核意见", required = false)
private String suggest;
@Schema(title = "参数列表", required = false)
private List<ManualReviewParam> params;
@Schema(title = "输出变量名空间", required = false)
private String namespace;
@Schema(title = "发送的通知类型", required = false)
private List<String> notifyType;
@Schema(title = "发送通知的标题", required = false)
private String notifyTitle;
@Schema(title = "是否以markdown格式发送审核说明", required = false)
private Boolean markdownContent;
@Schema(title = "企业微信群id", required = false)
private List<String> notifyGroup;
@Schema(title = "审核提醒时间小时支持每隔x小时提醒一次", required = false)
private Integer reminderTime;
@Override
public String getTaskAtom() {
return "manualReviewTaskAtom";
}
@Override
public PreStep transferYaml(JSONObject defaultValue) {
Map<String, Object> input = new HashMap<>();
if (reviewUsers != null && !reviewUsers.isEmpty()) {
input.put("reviewUsers", reviewUsers);
}
if (desc != null && !desc.isEmpty()) {
input.put("desc", desc);
}
if (suggest != null && !suggest.isEmpty()) {
input.put("suggest", suggest);
}
if (params != null && !params.isEmpty()) {
input.put("params", params);
}
if (namespace != null && !namespace.isEmpty()) {
input.put("namespace", namespace);
}
if (notifyType != null && !notifyType.isEmpty()) {
input.put("notifyType", notifyType);
}
if (notifyTitle != null && !notifyTitle.isEmpty()) {
input.put("notifyTitle", notifyTitle);
}
if (markdownContent != null) {
input.put("markdownContent", markdownContent);
}
if (notifyGroup != null && !notifyGroup.isEmpty()) {
input.put("notifyGroup", notifyGroup);
}
if (reminderTime != null) {
input.put("reminderTime", reminderTime);
}
return new PreStep(
name,
stepId,
getAtomCode() + "@" + getVersion(),
TransferUtil.simplifyParams(defaultValue, input)
);
}
@Override
public String getClassType() {
return classType;
}
}

View File

@ -0,0 +1,82 @@
package cd.casic.ci.common.pipeline.pojo.element.agent;
import cd.casic.ci.common.pipeline.NameAndValue;
import cd.casic.ci.common.pipeline.enums.BuildScriptType;
import cd.casic.ci.common.pipeline.enums.CharsetType;
import cd.casic.ci.common.pipeline.pojo.element.Element;
import cd.casic.ci.common.pipeline.pojo.transfer.PreStep;
import com.alibaba.fastjson.JSONObject;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element.agent
* @Projectops-pro
* @nameWindowsScriptElement
* @Date2025/03/26 16:44
* @FilenameWindowsScriptElement
* @descriptionTodo
*/
@Data
@NoArgsConstructor
@Schema(title = "脚本任务windows环境", description = WindowsScriptElement.classType)
public class WindowsScriptElement extends Element {
public static final String classType = "windowsScript";
@Schema(title = "任务名称", required = true)
private String name = "执行Windows的bat脚本";
@Schema(title = "id", required = false)
private String id;
@Schema(title = "状态", required = false)
private String status;
@Schema(title = "用户自定义ID", required = false)
private String stepId;
@Schema(title = "用户自定义环境变量(插件运行时写入环境)", required = false)
private List<NameAndValue> customEnv;
@Schema(title = "FAQ url链接", required = false)
private String errorFAQUrl;
@Schema(title = "脚本内容", required = true)
private String script;
@Schema(title = "脚本类型", required = true)
private BuildScriptType scriptType;
@Schema(title = "字符集类型", required = false)
private CharsetType charsetType;
@Override
public Map<String, Object> genTaskParams() {
Map<String, Object> mutableMap = super.genTaskParams();
try {
mutableMap.put("script", URLEncoder.encode(script, "UTF-8"));
} catch (Exception e) {
mutableMap.put("script", script);
}
return mutableMap;
}
@Override
public PreStep transferYaml(JSONObject defaultValue) {
Map<String, Object> res = new HashMap<>();
res.put("script", script);
if (charsetType != null && !charsetType.equals(CharsetType.DEFAULT)) {
res.put("charsetType", charsetType.name());
}
return new PreStep(
name,
stepId,
getAtomCode() + "@" + getVersion(),
res
);
}
@Override
public String getClassType() {
return classType;
}
}

View File

@ -0,0 +1,21 @@
package cd.casic.ci.common.pipeline.pojo.element.atom;
import cd.casic.ci.common.pipeline.enums.ChannelCode;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element.atom
* @Projectops-pro
* @nameBeforeDeleteParam
* @Date2025/03/26 17:11
* @FilenameBeforeDeleteParam
* @descriptionTodo
*/
@Data
public class BeforeDeleteParam {
private String userId;
private String projectId;
private String pipelineId;
private ChannelCode channelCode = ChannelCode.BS;
}

View File

@ -0,0 +1,31 @@
package cd.casic.ci.common.pipeline.pojo.element.atom;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Map;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element.atom
* @Projectops-pro
* @nameElementBatchCheckParam
* @Date2025/03/26 17:11
* @FilenameElementBatchCheckParam
* @descriptionTodo
*/
@Data
public class ElementBatchCheckParam {
@Schema(description = "项目ID", required = true)
private String projectId;
@Schema(description = "流水线ID", required = true)
private String pipelineId;
@Schema(description = "用户ID", required = true)
private String userId;
@Schema(description = "上下文映射", required = true)
private Map<String, String> contextMap;
@Schema(description = "是否为模板", required = true)
private boolean isTemplate;
@Schema(description = "OAuth用户", required = false)
private String oauthUser;
}

View File

@ -0,0 +1,23 @@
package cd.casic.ci.common.pipeline.pojo.element.atom;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element.atom
* @Projectops-pro
* @nameElementCheckResult
* @Date2025/03/26 17:11
* @FilenameElementCheckResult
* @descriptionTodo
*/
@Data
public class ElementCheckResult {
@Schema(description = "校验结果", required = true)
private boolean result;
@Schema(description = "失败标题", required = false)
private String errorTitle;
@Schema(description = "失败详情", required = false)
private String errorMessage;
}

View File

@ -0,0 +1,22 @@
package cd.casic.ci.common.pipeline.pojo.element.atom;
import cd.casic.ci.common.pipeline.container.Container;
import cd.casic.ci.common.pipeline.container.Stage;
import cd.casic.ci.common.pipeline.pojo.element.Element;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element.atom
* @Projectops-pro
* @nameElementHolder
* @Date2025/03/26 17:12
* @FilenameElementHolder
* @descriptionTodo
*/
@Data
public class ElementHolder {
private Element element;
private Stage stage;
private Container container;
}

View File

@ -0,0 +1,70 @@
package cd.casic.ci.common.pipeline.pojo.element.atom;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element.atom
* @Projectops-pro
* @nameManualReviewParam
* @Date2025/03/26 17:12
* @FilenameManualReviewParam
* @descriptionTodo
*/
@Data
@NoArgsConstructor
public class ManualReviewParam {
@Schema(description = "参数名", required = true)
private String key = "";
@Schema(description = "参数内容", required = true)
private Object value = null;
@Schema(description = "参数类型", required = false)
private ManualReviewParamType valueType = ManualReviewParamType.STRING;
@Schema(description = "是否必填", required = true)
private boolean required = false;
@Schema(description = "参数描述", required = false)
private String desc = "";
@Schema(description = "下拉框列表", required = false)
private List<ManualReviewParamPair> options = null;
@Schema(description = "中文名称", required = false)
private String chineseName = null;
@Schema(description = "变量形式的options", required = false)
private String variableOption = null;
public void parseValueWithType(Map<String, String> variables) {
if (variables.containsKey(key) && variables.get(key) != null && !variables.get(key).isBlank()) {
switch (valueType) {
case BOOLEAN:
case CHECKBOX:
value = Boolean.parseBoolean(variables.get(key));
break;
default:
value = variables.get(key);
break;
}
} else {
// TODO: Implement ObjectReplaceEnvVarUtil.replaceEnvVar in Java
// value = ObjectReplaceEnvVarUtil.replaceEnvVar(value, variables);
}
if (variableOption != null && !variableOption.isBlank()) {
// TODO: Implement EnvUtils.parseEnv and JsonUtil.to in Java
// options = EnvUtils.parseEnv(variableOption, variables).let {
// List<ManualReviewParamPair> optionList = JsonUtil.to<List<Object>>(it).stream()
// .map(item -> new ManualReviewParamPair(item.toString(), item.toString()))
// .collect(Collectors.toList());
// optionList;
// };
}
}
}

View File

@ -0,0 +1,21 @@
package cd.casic.ci.common.pipeline.pojo.element.atom;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element.atom
* @Projectops-pro
* @nameManualReviewParamPair
* @Date2025/03/26 17:18
* @FilenameManualReviewParamPair
* @descriptionTodo
*/
@Data
public class ManualReviewParamPair {
@Schema(description = "参数名", required = true)
private String key;
@Schema(description = "参数内容", required = true)
private String value;
}

View File

@ -0,0 +1,30 @@
package cd.casic.ci.common.pipeline.pojo.element.atom;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element.atom
* @Projectops-pro
* @nameManualReviewParamType
* @Date2025/03/26 17:18
* @FilenameManualReviewParamType
* @descriptionTodo
*/
public enum ManualReviewParamType {
STRING("string"),
TEXTAREA("textarea"),
BOOLEAN("boolean"),
ENUM("enum"),
CHECKBOX("checkbox"),
MULTIPLE("multiple");
private final String value;
ManualReviewParamType(String value) {
this.value = value;
}
@Override
public String toString() {
return value;
}
}

View File

@ -0,0 +1,60 @@
package cd.casic.ci.common.pipeline.pojo.element.atom;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Set;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element.atom
* @Projectops-pro
* @namePipelineCheckFailedReason
* @Date2025/03/26 17:19
* @FilenamePipelineCheckFailedReason
* @descriptionTodo
*/
@Data
@NoArgsConstructor
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type")
@JsonSubTypes({
@JsonSubTypes.Type(value = PipelineCheckFailedMsg.class, name = PipelineCheckFailedMsg.CLASS_TYPE),
@JsonSubTypes.Type(value = PipelineCheckFailedErrors.class, name = PipelineCheckFailedErrors.CLASS_TYPE)
})
public abstract class PipelineCheckFailedReason {
@Schema(description = "失败信息描述", required = true)
protected String message;
}
class PipelineCheckFailedMsg extends PipelineCheckFailedReason {
public static final String CLASS_TYPE = "msg";
public PipelineCheckFailedMsg(String message) {
this.message = message;
}
}
class PipelineCheckFailedErrors extends PipelineCheckFailedReason {
public static final String CLASS_TYPE = "errors";
@Schema(description = "失败详情", required = true)
private List<ErrorInfo> errors;
public PipelineCheckFailedErrors(String message, List<ErrorInfo> errors) {
this.message = message;
this.errors = errors;
}
@Data
public static class ErrorInfo {
@Schema(description = "失败标题", required = true)
private String errorTitle;
@Schema(description = "失败详情", required = true)
private Set<String> errorDetails;
}
}

View File

@ -0,0 +1,15 @@
package cd.casic.ci.common.pipeline.pojo.element.atom;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.element.atom
* @Projectops-pro
* @nameSubPipelineType
* @Date2025/03/26 17:20
* @FilenameSubPipelineType
* @descriptionTodo
*/
public enum SubPipelineType {
ID,
NAME
}

View File

@ -0,0 +1,63 @@
package cd.casic.ci.common.pipeline.pojo.market;
import cd.casic.ci.common.pipeline.pojo.element.Element;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.market
* @Projectops-pro
* @nameAtomBuildArchiveElement
* @Date2025/03/26 17:31
* @FilenameAtomBuildArchiveElement
* @descriptionTodo
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(title = "插件发布归档", description = AtomBuildArchiveElement.CLASS_TYPE)
public class AtomBuildArchiveElement extends Element {
public static final String CLASS_TYPE = "atomBuildArchive";
@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 = true)
private String packageName = "${packageName}";
@Schema(title = "插件发布包所在相对路径", required = true)
private String filePath = "${filePath}";
@Schema(title = "插件发布包上传至仓库的目标路径", required = true)
private String destPath = "${atomCode}/${version}/${packageName}";
@Schema(title = "插件自定义UI前端文件所在相对路径", required = false)
private String frontendFilePath = "${BK_CI_CUSTOM_FRONTEND_DIST_PATH}";
@Schema(title = "插件自定义UI前端文件上传至仓库的目标路径", required = false)
private String frontendDestPath = "${atomCode}/${version}";
@Schema(title = "操作系统名称", required = false)
private String osName = "${matrixOsName}";
@Schema(title = "操作系统cpu架构", required = false)
private String osArch = "${matrixOsArch}";
@Schema(title = "是否有可用的操作系统名称配置", required = false)
private String validOsNameFlag;
@Schema(title = "是否有可用的操作系统cpu架构配置", required = false)
private String validOsArchFlag;
@Override
public String getClassType() {
return CLASS_TYPE;
}
}

View File

@ -0,0 +1,78 @@
package cd.casic.ci.common.pipeline.pojo.market;
import cd.casic.ci.common.pipeline.NameAndValue;
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.transfer.PreStep;
import cd.casic.ci.common.pipeline.utils.TransferUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.market
* @Projectops-pro
* @nameMarketBuildAtomElement
* @Date2025/03/26 17:32
* @FilenameMarketBuildAtomElement
* @descriptionTodo
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(title = "流水线模型-插件市场第三方构建环境类插件", description = MarketBuildAtomElement.CLASS_TYPE)
public class MarketBuildAtomElement extends Element {
public static final String CLASS_TYPE = "marketBuild";
@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 = true)
private String atomCode;
@Schema(title = "插件版本", required = false)
private String version = "1.*";
@Schema(title = "用户自定义ID", required = false)
private String stepId;
@Schema(title = "用户自定义环境变量(插件运行时写入环境)", required = false)
private List<NameAndValue> customEnv;
@Schema(title = "插件参数数据", required = true)
private Map<String, Object> data = new HashMap<>();
@Schema(title = "附加参数", required = false)
private ElementAdditionalOptions additionalOptions;
@Override
public String getAtomCode() {
return atomCode;
}
@Override
public PreStep transferYaml(JSONObject defaultValue) {
Map<String, Object> input = (Map<String, Object>) data.getOrDefault("input", new HashMap<>());
return new PreStep(
name,
stepId,
getAtomCode() + "@" + version,
TransferUtil.simplifyParams(defaultValue, input).isEmpty() ? null : TransferUtil.simplifyParams(defaultValue, input)
);
}
@Override
public String getClassType() {
return CLASS_TYPE;
}
}

View File

@ -0,0 +1,75 @@
package cd.casic.ci.common.pipeline.pojo.market;
import cd.casic.ci.common.pipeline.NameAndValue;
import cd.casic.ci.common.pipeline.pojo.element.Element;
import cd.casic.ci.common.pipeline.pojo.transfer.PreStep;
import cd.casic.ci.common.pipeline.utils.TransferUtil;
import com.alibaba.fastjson.JSONObject;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.market
* @Projectops-pro
* @nameMarketBuildLessAtomElement
* @Date2025/03/26 17:32
* @FilenameMarketBuildLessAtomElement
* @descriptionTodo
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(title = "流水线模型-插件市场第三方无构建环境类插件", description = MarketBuildLessAtomElement.CLASS_TYPE)
public class MarketBuildLessAtomElement extends Element {
public static final String CLASS_TYPE = "marketBuildLess";
@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 = true)
private String atomCode;
@Schema(title = "插件版本", required = false)
private String version = "1.*";
@Schema(title = "用户自定义ID", required = false)
private String stepId;
@Schema(title = "用户自定义环境变量(插件运行时写入环境)", required = false)
private List<NameAndValue> customEnv;
@Schema(title = "插件参数数据", required = true)
private Map<String, Object> data = new HashMap<>();
@Override
public String getAtomCode() {
return atomCode;
}
@Override
public PreStep transferYaml(JSONObject defaultValue) {
Map<String, Object> input = (Map<String, Object>) data.getOrDefault("input", new HashMap<>());
return new PreStep(
name,
stepId,
getAtomCode() + "@" + version,
TransferUtil.simplifyParams(defaultValue, input).isEmpty() ? null : TransferUtil.simplifyParams(defaultValue, input)
);
}
@Override
public String getClassType() {
return CLASS_TYPE;
}
}

View File

@ -0,0 +1,42 @@
package cd.casic.ci.common.pipeline.pojo.market;
import cd.casic.ci.common.pipeline.pojo.element.Element;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.market
* @Projectops-pro
* @nameMarketCheckImageElement
* @Date2025/03/26 17:34
* @FilenameMarketCheckImageElement
* @descriptionTodo
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(title = "验证镜像合法性", description = MarketCheckImageElement.CLASS_TYPE)
public class MarketCheckImageElement extends Element {
public static final String CLASS_TYPE = "marketCheckImage";
@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 String registryUser;
@Schema(title = "密码", required = false)
private String registryPwd;
@Override
public String getClassType() {
return CLASS_TYPE;
}
}

View File

@ -0,0 +1,83 @@
package cd.casic.ci.common.pipeline.pojo.matrix;
import cd.casic.ci.common.pipeline.NameAndValue;
import cd.casic.ci.common.pipeline.pojo.element.Element;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.ArrayList;
import java.util.List;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.matrix
* @Projectops-pro
* @nameMatrixStatusElement
* @Date2025/03/26 17:37
* @FilenameMatrixStatusElement
* @descriptionTodo
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(title = "流水线模型-矩阵纯运行状态插件", description = MatrixStatusElement.CLASS_TYPE)
public class MatrixStatusElement extends Element {
public static final String CLASS_TYPE = "matrixStatus";
@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 int executeCount = 1;
@Schema(title = "执行时间", required = false)
private Long elapsed;
@Schema(title = "启动时间", required = false)
private Long startEpoch;
@Schema(title = "上下文标识", required = false)
private String stepId;
@Schema(title = "用户自定义环境变量(插件运行时写入环境)", required = false)
private List<NameAndValue> customEnv;
@Schema(title = "原插件的类型标识")
private String originClassType;
@Schema(title = "原插件的市场标识")
private String originAtomCode;
@Schema(title = "原插件的内置标识")
private String originTaskAtom;
@Schema(title = "审核人", required = true)
private List<String> reviewUsers = new ArrayList<>();
@Schema(title = "拦截原子", required = false)
private String interceptTask;
@Schema(title = "拦截原子名称", required = false)
private String interceptTaskName;
@Override
public String getClassType() {
return CLASS_TYPE;
}
@Override
public String getTaskAtom() {
return originTaskAtom != null ? originTaskAtom : "";
}
@Override
public String getAtomCode() {
return originAtomCode != null ? originAtomCode : "";
}
}

View File

@ -0,0 +1,74 @@
package cd.casic.ci.common.pipeline.pojo.quality;
import cd.casic.ci.common.pipeline.pojo.element.Element;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.quality
* @Projectops-pro
* @nameQualityGateInElement
* @Date2025/03/26 17:39
* @FilenameQualityGateInElement
* @descriptionTodo
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(title = "质量红线(准入)", description = QualityGateInElement.CLASS_TYPE)
public class QualityGateInElement extends Element {
public static final String CLASS_TYPE = "qualityGateInTask";
@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 String interceptTask;
@Schema(title = "拦截原子名称", required = false)
private String interceptTaskName;
@Schema(title = "审核人", required = false)
private Set<String> reviewUsers = new HashSet<>();
@Override
public String getTaskAtom() {
return "qualityGateInTaskAtom";
}
@Override
public String getClassType() {
return CLASS_TYPE;
}
@Override
public Map<String, Object> initTaskVar() {
Map<String, Object> taskVar = new java.util.HashMap<>();
taskVar.put("name", name);
taskVar.put("version", getVersion());
taskVar.put(KEY_TASK_ATOM, getTaskAtom());
taskVar.put("classType", getClassType());
taskVar.put(KEY_ELEMENT_ENABLE, elementEnabled());
if (interceptTask != null) {
taskVar.put("interceptTask", interceptTask);
}
if (interceptTaskName != null) {
taskVar.put("interceptTaskName", interceptTaskName);
}
if (reviewUsers != null) {
taskVar.put("reviewUsers", reviewUsers);
}
return taskVar;
}
}

View File

@ -0,0 +1,76 @@
package cd.casic.ci.common.pipeline.pojo.quality;
import cd.casic.ci.common.pipeline.pojo.element.Element;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import static cd.casic.ci.common.api.constant.CommonConstants.*;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.quality
* @Projectops-pro
* @nameQualityGateOutElement
* @Date2025/03/26 17:41
* @FilenameQualityGateOutElement
* @descriptionTodo
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(title = "质量红线(准出)", description = QualityGateOutElement.CLASS_TYPE)
public class QualityGateOutElement extends Element {
public static final String CLASS_TYPE = "qualityGateOutTask";
@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 String interceptTask;
@Schema(title = "拦截原子名称", required = false)
private String interceptTaskName;
@Schema(title = "审核人", required = false)
private Set<String> reviewUsers = new HashSet<>();
@Override
public String getTaskAtom() {
return "qualityGateOutTaskAtom";
}
@Override
public String getClassType() {
return CLASS_TYPE;
}
@Override
public Map<String, Object> initTaskVar() {
Map<String, Object> taskVar = new java.util.HashMap<>();
taskVar.put("name", name);
taskVar.put("version", getVersion());
taskVar.put(KEY_TASK_ATOM, getTaskAtom());
taskVar.put("classType", getClassType());
taskVar.put(KEY_ELEMENT_ENABLE, elementEnabled());
if (interceptTask != null) {
taskVar.put("interceptTask", interceptTask);
}
if (interceptTaskName != null) {
taskVar.put("interceptTaskName", interceptTaskName);
}
if (reviewUsers != null) {
taskVar.put("reviewUsers", reviewUsers);
}
return taskVar;
}
}

View File

@ -0,0 +1,52 @@
package cd.casic.ci.common.pipeline.pojo.setting;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.setting
* @Projectops-pro
* @namePipelineRunLockType
* @Date2025/03/26 14:14
* @FilenamePipelineRunLockType
* @descriptionTodo
*/
@Getter
@Schema(title = "流水线运行锁定方式")
public enum PipelineRunLockType {
@Schema(title = "可同时运行多个构建任务(默认)")
MULTIPLE,
@Schema(title = "同一时间最多只能运行一个构建任务")
SINGLE,
@Schema(title = "最多只能运行一个构建任务,且失败时锁定")
SINGLE_LOCK,
@Schema(title = "锁定流水线,任何触发方式都无法运行")
LOCK,
@Schema(title = "并发组锁定项目级别同一组的构建为SINGLE模式")
GROUP_LOCK;
/**
* 注意数字与枚举的ordinal不一样ordinal是下标为0开始 而这以1为开始
*/
public static int toValue(PipelineRunLockType type) {
return switch (type) {
case MULTIPLE -> 1;
case SINGLE -> 2;
case SINGLE_LOCK -> 3;
case LOCK -> 4;
case GROUP_LOCK -> 5;
};
}
public static PipelineRunLockType valueOf(int value) {
return switch (value) {
case 1 -> MULTIPLE;
case 2 -> SINGLE;
case 3 -> SINGLE_LOCK;
case 4 -> LOCK;
case 5 -> GROUP_LOCK;
default -> MULTIPLE;
};
}
}
}

View File

@ -0,0 +1,151 @@
package cd.casic.ci.common.pipeline.pojo.setting;
import cd.casic.ci.common.api.enums.BkStyleEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
import static cd.casic.ci.common.pipeline.utils.Constants.*;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.setting
* @Projectops-pro
* @namePipelineSetting
* @Date2025/03/26 14:18
* @FilenamePipelineSetting
*/
@Data
@Accessors(chain = true)
@Schema(title = "流水线配置")
public class PipelineSetting {
@Schema(title = "项目id", required = false, readOnly = true)
private String projectId = "";
@Schema(title = "流水线id", required = false, readOnly = true)
private String pipelineId = "";
// 流水线基础配置
@Schema(title = "流水线名称", required = false)
private String pipelineName = "";
@Schema(title = "版本", required = false)
private int version = 1;
@Schema(title = "描述", required = false)
private String desc = "";
@Schema(title = "标签ID列表", required = false)
private List<String> labels = List.of();
@Schema(title = "标签名称列表(仅用于前端展示,不参与数据保存)", required = false)
private List<String> labelNames = List.of();
@Schema(title = "构建号生成规则", required = false)
private String buildNumRule; // 构建号生成规则
// 通知订阅相关配置
//"被successSubscriptionList取代"
@Schema(title = "订阅成功相关", required = false)
private Subscription successSubscription = new Subscription();
//"被failSubscriptionList取代"
@Schema(title = "订阅失败相关", required = false)
private Subscription failSubscription = new Subscription();
@Schema(title = "订阅成功通知组", required = false)
private List<Subscription> successSubscriptionList = null;
@Schema(title = "订阅失败通知组", required = false)
private List<Subscription> failSubscriptionList = null;
// 运行控制流水线禁用相关配置
@Schema(title = "Lock 类型", required = false)
private PipelineRunLockType runLockType = PipelineRunLockType.SINGLE_LOCK;
@Schema(title = "最大排队时长", required = false)
private int waitQueueTimeMinute = PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_DEFAULT;
@Schema(title = "最大排队数量", required = false)
private int maxQueueSize = PIPELINE_SETTING_MAX_QUEUE_SIZE_DEFAULT;
@Schema(title = "并发时,设定的group", required = false)
private String concurrencyGroup = PIPELINE_SETTING_CONCURRENCY_GROUP_DEFAULT;
@Schema(title = "并发时,是否相同group取消正在执行的流水线", required = false)
private boolean concurrencyCancelInProgress = false;
@Schema(title = "并发构建数量限制", required = false)
private Integer maxConRunningQueueSize = null; // MULTIPLE类型时并发构建数量限制
// 平台系统控制相关配置 不作为生成版本的配置
@Schema(title = "保存流水线编排的最大个数", required = false)
private final int maxPipelineResNum = PIPELINE_RES_NUM_MIN; // 保存流水线编排的最大个数
@Schema(title = "重试时清理引擎变量表", required = false)
private final Boolean cleanVariablesWhenRetry = false;
@Schema(title = "YAML流水线特殊配置", required = false)
private PipelineAsCodeSettings pipelineAsCodeSettings;
public static PipelineSetting defaultSetting(
String projectId,
String pipelineId,
String pipelineName,
Integer maxPipelineResNum,
Subscription failSubscription,
Boolean inheritedDialectSetting,
String pipelineDialectSetting
) {
return new PipelineSetting()
.setProjectId(projectId)
.setPipelineId(pipelineId)
.setPipelineName(pipelineName)
.setVersion(1)
.setDesc(pipelineName)
.setMaxPipelineResNum(maxPipelineResNum != null ? maxPipelineResNum : PIPELINE_RES_NUM_MIN)
.setWaitQueueTimeMinute(PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_DEFAULT)
.setMaxQueueSize(PIPELINE_SETTING_MAX_QUEUE_SIZE_DEFAULT)
.setRunLockType(PipelineRunLockType.MULTIPLE)
.setSuccessSubscription(null)
.setFailSubscription(null)
.setSuccessSubscriptionList(List.of())
.setFailSubscriptionList(failSubscription != null ? List.of(failSubscription) : null)
.setPipelineAsCodeSettings(PipelineAsCodeSettings.initDialect(
inheritedDialectSetting,
pipelineDialectSetting
));
}
// 校验流水线的通知设置是否为空即用户未配置或使用默认配置
public boolean notifySettingIsNull() {
boolean res = true;
if (successSubscriptionList != null && !successSubscriptionList.isEmpty() &&
successSubscriptionList.stream().anyMatch(subscription -> !subscription.getTypes().isEmpty())) {
res = false;
}
if (failSubscriptionList != null && !failSubscriptionList.isEmpty() &&
failSubscriptionList.stream().anyMatch(subscription -> !subscription.getTypes().isEmpty())) {
res = false;
}
if (successSubscription != null && !successSubscription.getTypes().isEmpty()) {
res = false;
}
if (failSubscription != null && !failSubscription.getTypes().isEmpty()) {
res = false;
}
return res;
}
// 校验流水线的并发组设置是否为空即用户未配置或使用默认配置
public boolean concurrencySettingIsNull() {
return runLockType != PipelineRunLockType.GROUP_LOCK;
}
public void fixSubscriptions() {
// 只有旧数据向新数据的更新取消旧数据的保存
if (successSubscriptionList == null && successSubscription != null) {
successSubscriptionList = List.of(successSubscription);
}
successSubscription = successSubscriptionList != null ? successSubscriptionList.get(0) : null;
if (failSubscriptionList == null && failSubscription != null) {
failSubscriptionList = List.of(failSubscription);
}
failSubscription = failSubscriptionList != null ? failSubscriptionList.get(0) : null;
}
public void copySubscriptionSettings(PipelineSetting other) {
this.successSubscription = other.getSuccessSubscription();
this.successSubscriptionList = other.getSuccessSubscriptionList();
this.failSubscription = other.getFailSubscription();
this.failSubscriptionList = other.getFailSubscriptionList();
}
public void copyConcurrencyGroup(PipelineSetting other) {
this.concurrencyGroup = other.getConcurrencyGroup();
this.concurrencyCancelInProgress = other.getConcurrencyCancelInProgress();
this.maxConRunningQueueSize = PIPELINE_SETTING_MAX_CON_QUEUE_SIZE_MAX;
}
}

View File

@ -0,0 +1,26 @@
package cd.casic.ci.common.pipeline.pojo.setting;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.setting
* @Projectops-pro
* @namePipelineSubscriptionType
* @Date2025/03/26 14:19
* @FilenamePipelineSubscriptionType
* @descriptionTodo
*/
@Getter
@Schema(title = "流水线-订阅-消息类型")
public enum PipelineSubscriptionType {
EMAIL,
RTX,
WECHAT,
SMS,
WEWORK,
VOICE,
// 企业微信群通知
WEWORK_GROUP
}

View File

@ -0,0 +1,53 @@
package cd.casic.ci.common.pipeline.pojo.setting;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.HashSet;
import java.util.Set;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.setting
* @Projectops-pro
* @nameSubscription
* @Date2025/03/26 14:20
* @FilenameSubscription
* @descriptionTodo
*/
@Data
@Accessors(chain = true)
@Schema(title = "设置-订阅消息")
public class Subscription {
@Schema(title = "通知方式(email, rtx)", required = true)
private Set<PipelineSubscriptionType> types = Set.of();
@Schema(title = "分组", required = false)
private Set<String> groups = Set.of();
@Schema(title = "通知人员", required = false)
private String users = "";
@Schema(title = "企业微信群通知开关", required = false)
private boolean wechatGroupFlag = false;
@Schema(title = "企业微信群通知群ID", required = false)
private String wechatGroup = "";
@Schema(title = "企业微信群通知转为Markdown格式开关", required = false)
private boolean wechatGroupMarkdownFlag = false;
@Schema(title = "通知的流水线详情连接开关", required = false)
private boolean detailFlag = false;
@Schema(title = "自定义通知内容", required = false)
private String content = "";
// 转换企业微信组通知
public Subscription fixWeworkGroupType() {
Set<PipelineSubscriptionType> fixTypes;
if (wechatGroupFlag && !types.contains(PipelineSubscriptionType.WEWORK_GROUP)) {
fixTypes = new HashSet<>(types);
fixTypes.add(PipelineSubscriptionType.WEWORK_GROUP);
} else {
fixTypes = types;
}
return new Subscription()
.setTypes(fixTypes)
.setWechatGroupFlag(false);
}
}

View File

@ -0,0 +1,18 @@
package cd.casic.ci.common.pipeline.pojo.setting;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.setting
* @Projectops-pro
* @nameSubscriptionGroup
* @Date2025/03/26 14:20
* @FilenameSubscriptionGroup
* @descriptionTodo
*/
@Data
public class SubscriptionGroup {
private String id;
private String name;
}

View File

@ -0,0 +1,28 @@
package cd.casic.ci.common.pipeline.pojo.time;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.time
* @Projectops-pro
* @nameBuildRecordTimeCost
* @Date2025/03/26 11:11
* @FilenameBuildRecordTimeCost
* @descriptionTodo
*/
@Data
@Schema(title = "各项执行耗时(单位毫秒)")
public class BuildRecordTimeCost {
@Schema(title = "系统耗时(由总耗时减去其他得出)", required = true)
private long systemCost = 0;
@Schema(title = "执行耗时", required = true)
private long executeCost = 0;
@Schema(title = "等待耗时(包括了排队和等待人工审核操作时间)", required = true)
private long waitCost = 0;
@Schema(title = "只处于排队的耗时流水线并发、Stage下Job并发和Job互斥", required = true)
private long queueCost = 0;
@Schema(title = "总耗时(结束时间-开始时间)", required = true)
private long totalCost = 0;
}

View File

@ -0,0 +1,35 @@
package cd.casic.ci.common.pipeline.pojo.time;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.time
* @Projectops-pro
* @nameBuildRecordTimeLine
* @Date2025/03/26 11:11
* @FilenameBuildRecordTimeLine
* @descriptionTodo
*/
@Data
@Schema(title = "各项执行耗时时刻")
public class BuildRecordTimeLine {
@Schema(title = "执行耗时时刻,计算结果需成对", required = false)
private List<Moment> executeCostMoments;
@Schema(title = "等待耗时时刻,计算结果需成对", required = false)
private List<Moment> waitCostMoments;
@Schema(title = "排队耗时流水线并发和Job互斥时刻计算结果需成对", required = false)
private List<Moment> queueCostMoments;
@Data
@Schema(title = "时间戳对")
public static class Moment {
@Schema(title = "开始时间")
private long startTime;
@Schema(title = "结束时间")
private long endTime;
}
}

View File

@ -0,0 +1,48 @@
package cd.casic.ci.common.pipeline.pojo.time;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.time
* @Projectops-pro
* @nameBuildTimestampType
* @Date2025/03/26 11:12
* @FilenameBuildTimestampType
* @descriptionTodo
*/
@Getter
@AllArgsConstructor
@Schema(title = "构建详情记录-时间戳类型(勿随意删除)")
public enum BuildTimestampType {
BUILD_REVIEW_WAITING("buildReviewWaiting"), // 流水线触发审核等待
BUILD_CONCURRENCY_QUEUE("buildConcurrencyQueue"), // 流水线并发排队
STAGE_CHECK_IN_WAITING("stageCheckInWaiting"), // stage准入等待
STAGE_CHECK_OUT_WAITING("stageCheckOutWaiting"), // stage准出等待
JOB_MUTEX_QUEUE("jobMutexQueue"), // job互斥并发排队
JOB_AGENT_REUSE_MUTEX_QUEUE("jobAgentReuseMutexQueue"), // jobAgent复用互斥排队
JOB_THIRD_PARTY_QUEUE("jobThirdPartyQueue"), // job第三方构建机资源排队
JOB_CONTAINER_STARTUP("jobContainerStartup"), // job构建机启动包含了第三方构建机资源等待
JOB_CONTAINER_SHUTDOWN("jobContainerShutdown"), // job构建机关闭
TASK_REVIEW_PAUSE_WAITING("taskReviewPauseWaiting"); // task等待包括插件暂停人工审核质量红线审核
private final String action;
// 使插件处于等待的类型
public boolean taskCheckWait() {
return this == TASK_REVIEW_PAUSE_WAITING;
}
// 使container处于排队的类型
public boolean containerCheckQueue() {
return this == JOB_MUTEX_QUEUE || this == JOB_THIRD_PARTY_QUEUE || this == JOB_AGENT_REUSE_MUTEX_QUEUE;
}
// 使stage处于等待的类型
public boolean stageCheckWait() {
return this == STAGE_CHECK_IN_WAITING || this == STAGE_CHECK_OUT_WAITING;
}
}

View File

@ -0,0 +1,31 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @nameElementInsertBody
* @Date2025/03/26 11:00
* @FilenameElementInsertBody
* @descriptionTodo
*/
@Data
@Schema(title = "yaml中插入插件入口")
public class ElementInsertBody {
@Schema(title = "当前yaml内容")
private String yaml = "";
@Schema(title = "需要插入的插件")
private Element data;
@Schema(title = "操作类型,INSERT为插入,UPDATE为更新")
private ElementInsertType type;
public enum ElementInsertType {
INSERT,
UPDATE
}
}

View File

@ -0,0 +1,23 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @nameElementInsertResponse
* @Date2025/03/26 11:00
* @FilenameElementInsertResponse
* @descriptionTodo
*/
@Data
@Schema(title = "yaml中插入插件返回")
public class ElementInsertResponse {
@Schema(title = "yaml内容")
private String yaml = "";
@Schema(title = "插入的插件定位坐标")
private TransferMark mark;
}

View File

@ -0,0 +1,32 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @nameIfType
* @Date2025/03/26 11:01
* @FilenameIfType
* @descriptionTodo
*/
@Getter
@AllArgsConstructor
@Schema(title = "IfType")
public enum IfType {
@Schema(title = "Success")
SUCCESS,
@Schema(title = "Failure")
FAILURE,
@Schema(title = "Cancelled")
CANCELLED,
@Schema(title = "Canceled")
CANCELED,
@Schema(title = "Always")
ALWAYS,
@Schema(title = "Always unless cancelled")
ALWAYS_UNLESS_CANCELLED
}

View File

@ -0,0 +1,17 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @nameMetaData
* @Date2025/03/26 11:07
* @FilenameMetaData
* @descriptionTodo
*/
@Data
public class MetaData {
private TemplateInfo templateInfo;
}

View File

@ -0,0 +1,21 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @namePositionBody
* @Date2025/03/26 11:01
* @FilenamePositionBody
* @descriptionTodo
*/
@Data
@Schema(title = "定位入口")
public class PositionBody {
@Schema(title = "当前yaml内容")
private String yaml = "";
}

View File

@ -0,0 +1,48 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @namePositionResponse
* @Date2025/03/26 11:01
* @FilenamePositionResponse
* @descriptionTodo
*/
@Data
@Schema(title = "yaml定位")
public class PositionResponse {
@Schema(title = "定位类型非error时应当必有")
private PositionType type;
@Schema(title = "当定位到JOB,STEP时有效表示当前stage的os类型")
private TransferVMBaseOS jobBaseOs;
@Schema(title = "当定位到STAGE,JOB,STEP时有效表示stage下标, -1 表示finally stage")
private Integer stageIndex;
@Schema(title = "当定位到JOB,STEP时有效表示container下标")
private Integer containerIndex;
@Schema(title = "当定位到JOB,STEP时有效表示job的id")
private String jobId;
@Schema(title = "当定位到STEP时有效表示step下标")
private Integer stepIndex;
@Schema(title = "当定位到STEP时有效拿到对应的element元素")
private Element element;
@Schema(title = "转换错误")
private String error;
public enum PositionType {
SETTING,
STAGE,
JOB,
STEP
}
}

View File

@ -0,0 +1,70 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @namePreStep
* @Date2025/03/26 11:01
* @FilenamePreStep
* @descriptionTodo
*/
@Data
@JsonFilter("yamlMetaDataJsonFilter")
@Schema(title = "PreStep")
@AllArgsConstructor
public class PreStep implements YamlMetaData {
private Boolean enable;
private Object checkout;
private String name;
private String id;
@Schema(title = "if")
@JsonProperty("if")
private Object ifField;
@Schema(title = "if-modify")
@JsonProperty("if-modify")
private List<String> ifModify;
private String uses;
private Map<String, Object> with;
@Schema(title = "timeout-minutes")
@JsonProperty("timeout-minutes")
private String timeoutMinutes;
@Schema(title = "continue-on-error")
@JsonProperty("continue-on-error")
private Object continueOnError;
@Schema(title = "retry-times")
@JsonProperty("retry-times")
private Integer retryTimes;
private Map<String, Object> env = new HashMap<>();
private String run;
private String shell;
@Schema(title = "can-manually-retry")
@JsonProperty("can-manually-retry")
private Boolean manualRetry;
@Override
public MetaData getYamlMetaData() {
return yamlMetaData;
}
private MetaData yamlMetaData;
}

View File

@ -0,0 +1,35 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.ArrayList;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @namePreviewResponse
* @Date2025/03/26 11:02
* @FilenamePreviewResponse
* @descriptionTodo
*/
@Data
@Schema(title = "流水线 yaml 带定位信息")
public class PreviewResponse {
@Schema(title = "yaml内容")
private String yaml;
@Schema(title = "流水线编排")
private List<TransferMark> pipeline = new ArrayList<>();
@Schema(title = "触发器配置")
private List<TransferMark> trigger = new ArrayList<>();
@Schema(title = "通知配置")
private List<TransferMark> notice = new ArrayList<>();
@Schema(title = "基础设置")
private List<TransferMark> setting = new ArrayList<>();
}

View File

@ -0,0 +1,53 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @nameResources
* @Date2025/03/26 11:02
* @FilenameResources
* @descriptionTodo
*/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(title = "Resources")
public class Resources {
private List<Repositories> repositories;
private List<ResourcesPools> pools;
@Data
public static class Repositories {
private String repository;
private String name;
private String ref;
private ResCredentials credentials;
}
@Data
public static class ResCredentials {
@Schema(title = "personal-access-token")
@JsonProperty("personal-access-token")
private String personalAccessToken;
}
@Data
public static class ResourcesPools {
private String from;
private String name;
@Override
public String toString() {
return from + "+" + name;
}
}
}

View File

@ -0,0 +1,52 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @nameRunAtomParam
* @Date2025/03/26 11:02
* @FilenameRunAtomParam
* @descriptionTodo
*/
@Data
public class RunAtomParam {
private String shell;
private String script;
private CharsetType charsetType;
public enum CharsetType {
DEFAULT,
UTF_8,
GBK;
public static CharsetType parse(String charset) {
for (CharsetType type : values()) {
if (type.name().equals(charset)) {
return type;
}
}
return DEFAULT;
}
}
public enum ShellType {
BASH("bash"),
CMD("cmd"),
POWERSHELL_CORE("pwsh"),
POWERSHELL_DESKTOP("powershell"),
PYTHON("python"),
SH("sh"),
WIN_BASH("win_bash"),
AUTO("auto");
private final String shellName;
ShellType(String shellName) {
this.shellName = shellName;
}
}
}

View File

@ -0,0 +1,18 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @nameTemplateInfo
* @Date2025/03/26 11:07
* @FilenameTemplateInfo
* @descriptionTodo
*/
@Data
public class TemplateInfo {
private boolean remote;
private String remoteTemplateProjectId;
}

View File

@ -0,0 +1,26 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @nameTransferActionType
* @Date2025/03/26 11:03
* @FilenameTransferActionType
* @descriptionTodo
*/
@Getter
@AllArgsConstructor
@Schema(title = "流水线互转操作类型")
public enum TransferActionType {
@Schema(title = "完整转换model -> yaml")
FULL_MODEL2YAML,
@Schema(title = "完整转换yaml -> model")
FULL_YAML2MODEL,
@Schema(title = "yaml 中插入的插件")
YAML_INSERT_TASK;
}

View File

@ -0,0 +1,25 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import cd.casic.ci.common.pipeline.pojo.PipelineModelAndSetting;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @nameTransferBody
* @Date2025/03/26 11:03
* @FilenameTransferBody
* @descriptionTodo
*/
@Data
@Schema(title = "互转入口")
public class TransferBody {
@Schema(title = "当前modelAndSetting,model转yaml时需带上")
private PipelineModelAndSetting modelAndSetting;
@Schema(title = "当前yaml内容model转yaml以及yaml转model都需要带上,如果首次互转没有就传空")
private String oldYaml = "";
@Schema(title = "yaml内容的来源yaml文件名用于流水线名称的缺省值")
private String yamlFileName;
}

View File

@ -0,0 +1,30 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @nameTransferMark
* @Date2025/03/26 11:04
* @FilenameTransferMark
* @descriptionTodo
*/
@Data
@Schema(title = "互转yaml定位")
public class TransferMark {
@Schema(title = "标记头")
private Mark startMark;
@Schema(title = "标记尾")
private Mark endMark;
@Data
public static class Mark {
@Schema(title = "行数 0开始")
private int line;
@Schema(title = "列数 0开始")
private int column;
}
}

View File

@ -0,0 +1,31 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import cd.casic.ci.common.pipeline.pojo.PipelineModelAndSetting;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @nameTransferResponse
* @Date2025/03/26 11:04
* @FilenameTransferResponse
* @descriptionTodo
*/
@Data
@Schema(title = "流水线互转-Response")
public class TransferResponse {
@Schema(title = "modelAndSetting")
private PipelineModelAndSetting modelAndSetting;
@Schema(title = "当前yaml内容")
private YamlWithVersion yamlWithVersion;
@Schema(title = "定位")
private TransferMark mark;
@Schema(title = "互转报错信息")
private String error;
@Schema(title = "是否支持YAML解析", required = true)
private boolean yamlSupported = true;
@Schema(title = "YAML解析异常信息")
private String yamlInvalidMsg;
}

View File

@ -0,0 +1,25 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @nameTransferVMBaseOS
* @Date2025/03/26 11:05
* @FilenameTransferVMBaseOS
* @descriptionTodo
*/
@Getter
@AllArgsConstructor
@Schema(title = "TransferVMBaseOS")
public enum TransferVMBaseOS {
MACOS,
LINUX,
WINDOWS,
BUILD_LESS
}

View File

@ -0,0 +1,16 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @nameYamlMetaData
* @Date2025/03/26 11:09
* @FilenameYamlMetaData
* @descriptionTodo
*/
public interface YamlMetaData {
MetaData getYamlMetaData();
}

View File

@ -0,0 +1,14 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @nameYamlMetaDataJsonFilter
* @Date2025/03/26 11:07
* @FilenameYamlMetaDataJsonFilter
* @descriptionTodo
*/
public class YamlMetaDataJsonFilter {
public static final String YAML_META_DATA_JSON_FILTER = "yamlMetaData";
}

View File

@ -0,0 +1,22 @@
package cd.casic.ci.common.pipeline.pojo.transfer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.pojo.transfer
* @Projectops-pro
* @nameYamlWithVersion
* @Date2025/03/26 11:05
* @FilenameYamlWithVersion
* @descriptionTodo
*/
@Data
@Schema(title = "通过解析后的YAML对象")
public class YamlWithVersion {
@Schema(title = "当前yaml内容")
private String yamlStr;
@Schema(title = "当前yaml的版本标识")
private String versionTag;
}

View File

@ -0,0 +1,184 @@
package cd.casic.ci.common.pipeline.utils;
import cd.casic.ci.common.pipeline.enums.BuildStatus;
import lombok.Getter;
import java.util.Set;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.utils
* @Projectops-pro
* @nameBuildStatusSwitcher
* @Date2025/03/26 14:59
* @FilenameBuildStatusSwitcher
* @descriptionTodo
*/
@Getter
public class BuildStatusSwitcher {
public static BuildStatus readyToSkipWhen(BuildStatus buildStatus) {
return buildStatus.isFailure() || buildStatus.isCancel() ? BuildStatus.UNEXEC : BuildStatus.SKIP;
}
private static final PipelineBuildStatusMaker pipelineStatusMaker = new PipelineBuildStatusMaker();
private static final StageBuildStatusMaker stageStatusMaker = new StageBuildStatusMaker();
private static final JobBuildStatusMaker jobStatusMaker = new JobBuildStatusMaker();
private static final TaskBuildStatusMaker taskStatusMaker = new TaskBuildStatusMaker();
public interface BuildStatusMaker {
Set<BuildStatus> statusSet();
default BuildStatus cancel(BuildStatus currentBuildStatus) {
BuildStatus canceled = BuildStatus.CANCELED;
if (currentBuildStatus == BuildStatus.UNKNOWN) {
return canceled;
}
if (currentBuildStatus.isReadyToRun()) {
return canceled;
}
if (currentBuildStatus.isRunning()) {
return canceled;
}
if (currentBuildStatus.isFinish()) {
return statusSet().contains(currentBuildStatus) ? currentBuildStatus : canceled;
}
return canceled;
}
default BuildStatus finish(BuildStatus currentBuildStatus) {
if (currentBuildStatus.isFinish() || currentBuildStatus == BuildStatus.STAGE_SUCCESS) {
if (statusSet().contains(currentBuildStatus)) {
return currentBuildStatus;
} else {
return currentBuildStatus.isFailure() ? BuildStatus.FAILED : BuildStatus.SUCCEED;
}
} else if (currentBuildStatus.isReadyToRun()) {
return BuildStatus.CANCELED;
} else {
return BuildStatus.SUCCEED;
}
}
default BuildStatus forceFinish(BuildStatus currentBuildStatus, boolean fastKill) {
if (currentBuildStatus.isFinish() || currentBuildStatus == BuildStatus.STAGE_SUCCESS) {
if (statusSet().contains(currentBuildStatus) && !fastKill) {
return currentBuildStatus;
} else {
return currentBuildStatus.isSuccess() ? BuildStatus.SUCCEED : BuildStatus.FAILED;
}
} else {
return BuildStatus.FAILED;
}
}
default BuildStatus switchByErrorCode(BuildStatus currentBuildStatus, Integer errorCode) {
return currentBuildStatus;
}
}
public static class TaskBuildStatusMaker implements BuildStatusMaker {
private static final Set<Integer> timeoutCodeSet = Set.of(2103006);
@Override
public Set<BuildStatus> statusSet() {
return Set.of(
BuildStatus.QUEUE,
BuildStatus.QUEUE_CACHE,
BuildStatus.RETRY,
BuildStatus.RUNNING,
BuildStatus.CALL_WAITING,
BuildStatus.REVIEWING,
BuildStatus.REVIEW_ABORT,
BuildStatus.REVIEW_PROCESSED,
BuildStatus.PAUSE,
BuildStatus.CANCELED,
BuildStatus.SUCCEED,
BuildStatus.FAILED,
BuildStatus.TERMINATE,
BuildStatus.SKIP,
BuildStatus.UNEXEC,
BuildStatus.QUEUE_TIMEOUT,
BuildStatus.QUALITY_CHECK_FAIL
);
}
@Override
public BuildStatus forceFinish(BuildStatus currentBuildStatus, boolean fastKill) {
if (currentBuildStatus.isFinish()) {
return statusSet().contains(currentBuildStatus) ? currentBuildStatus : (currentBuildStatus.isSuccess() ? BuildStatus.SUCCEED : BuildStatus.FAILED);
}
if (currentBuildStatus.isRunning() && !fastKill) {
return BuildStatus.TERMINATE;
}
return BuildStatus.FAILED;
}
@Override
public BuildStatus switchByErrorCode(BuildStatus currentBuildStatus, Integer errorCode) {
if (timeoutCodeSet.contains(errorCode)) {
return BuildStatus.QUEUE_TIMEOUT;
}
return currentBuildStatus;
}
}
public static class PipelineBuildStatusMaker implements BuildStatusMaker {
@Override
public Set<BuildStatus> statusSet() {
return Set.of(
BuildStatus.QUEUE,
BuildStatus.QUEUE_CACHE,
BuildStatus.RUNNING,
BuildStatus.CANCELED,
BuildStatus.SUCCEED,
BuildStatus.FAILED,
BuildStatus.TERMINATE,
BuildStatus.QUEUE_TIMEOUT,
BuildStatus.STAGE_SUCCESS
);
}
}
public static class StageBuildStatusMaker implements BuildStatusMaker {
@Override
public Set<BuildStatus> statusSet() {
return Set.of(
BuildStatus.QUEUE,
BuildStatus.QUEUE_CACHE,
BuildStatus.RUNNING,
BuildStatus.REVIEWING,
BuildStatus.PAUSE,
BuildStatus.CANCELED,
BuildStatus.SUCCEED,
BuildStatus.FAILED,
BuildStatus.TERMINATE,
BuildStatus.SKIP,
BuildStatus.UNEXEC,
BuildStatus.QUEUE_TIMEOUT,
BuildStatus.STAGE_SUCCESS
);
}
}
public static class JobBuildStatusMaker implements BuildStatusMaker {
@Override
public Set<BuildStatus> statusSet() {
return Set.of(
BuildStatus.QUEUE,
BuildStatus.QUEUE_CACHE,
BuildStatus.DEPENDENT_WAITING,
BuildStatus.LOOP_WAITING,
BuildStatus.PREPARE_ENV,
BuildStatus.RUNNING,
BuildStatus.CANCELED,
BuildStatus.SUCCEED,
BuildStatus.FAILED,
BuildStatus.TERMINATE,
BuildStatus.SKIP,
BuildStatus.UNEXEC,
BuildStatus.QUEUE_TIMEOUT,
BuildStatus.HEARTBEAT_TIMEOUT
);
}
}
}

View File

@ -0,0 +1,48 @@
package cd.casic.ci.common.pipeline.utils;
import cd.casic.ci.common.pipeline.enums.BuildFormPropertyType;
import cd.casic.ci.common.pipeline.pojo.cascade.RepoRefCascadeParam;
import cd.casic.framework.commons.util.json.JsonUtils;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.utils
* @Projectops-pro
* @nameCascadePropertyUtils
* @Date2025/03/26 15:02
* @FilenameCascadePropertyUtils
* @descriptionTodo
*/
@Slf4j
public class CascadePropertyUtils {
public static Map<String, String> getCascadeVariableKeyMap(String key, BuildFormPropertyType type) {
return type == BuildFormPropertyType.REPO_REF ? RepoRefCascadeParam.variableKeyMap(key) : Map.of();
}
public static Map<String, String> parseDefaultValue(String key, Object defaultValue, BuildFormPropertyType type) {
try {
if (defaultValue instanceof String) {
return JsonUtils.parseObject((String) defaultValue, new TypeReference<Map<String, String>>() {
});
} else {
return (Map<String, String>) defaultValue;
}
} catch (Exception ignored) {
log.warn("parse repo ref error, key: {}, defaultValue: {}", key, defaultValue);
return getDefaultValue(type);
}
}
private static Map<String, String> getDefaultValue(BuildFormPropertyType type) {
return type == BuildFormPropertyType.REPO_REF ? RepoRefCascadeParam.defaultValue() : Map.of();
}
public static boolean supportCascadeParam(BuildFormPropertyType type) {
return type == BuildFormPropertyType.REPO_REF;
}
}

View File

@ -0,0 +1,18 @@
package cd.casic.ci.common.pipeline.utils;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.utils
* @Projectops-pro
* @nameConstants
* @Date2025/03/26 15:39
* @FilenameConstants
* @descriptionTodo
*/
public class Constants {
public static final int PIPELINE_SETTING_MAX_QUEUE_SIZE_DEFAULT = 10;
public static final int PIPELINE_SETTING_MAX_CON_QUEUE_SIZE_MAX = 200;
public static final int PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_DEFAULT = 10;
public static final String PIPELINE_SETTING_CONCURRENCY_GROUP_DEFAULT = "${{ci.pipeline_id}}";
public static final int PIPELINE_RES_NUM_MIN = 50;
}

View File

@ -0,0 +1,28 @@
package cd.casic.ci.common.pipeline.utils;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.utils
* @Projectops-pro
* @nameElementUtils
* @Date2025/03/26 15:42
* @FilenameElementUtils
* @descriptionTodo
*/
public class ElementUtils {
public static final String skipPrefix = "devops_container_condition_skip_atoms_";
public static String getSkipElementVariableName(String elementId) {
return skipPrefix + elementId;
}
public static boolean getTaskAddFlag(Element element, boolean stageEnableFlag, boolean containerEnableFlag, boolean originMatrixContainerFlag) {
if (originMatrixContainerFlag) {
return false;
}
var elementPostInfo = element.getAdditionalOptions().getElementPostInfo();
var qualityAtomFlag = element instanceof QualityGateInElement || element instanceof QualityGateOutElement;
var enableFlag = stageEnableFlag && containerEnableFlag && element.elementEnabled();
return enableFlag || elementPostInfo != null || qualityAtomFlag;
}
}

View File

@ -0,0 +1,20 @@
package cd.casic.ci.common.pipeline.utils;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.utils
* @Projectops-pro
* @nameHeartBeatUtils
* @Date2025/03/26 15:47
* @FilenameHeartBeatUtils
* @descriptionTodo
*/
public class HeartBeatUtils {
public static String genHeartBeatKey(String buildId, String vmSeqId, Integer executeCount) {
if (executeCount != null) {
return "heartbeat:" + buildId + ":" + vmSeqId + ":" + executeCount;
} else {
return "heartbeat:" + buildId + ":" + vmSeqId;
}
}
}

View File

@ -0,0 +1,177 @@
package cd.casic.ci.common.pipeline.utils;
import cd.casic.ci.common.pipeline.Model;
import cd.casic.ci.common.pipeline.container.Container;
import cd.casic.ci.common.pipeline.container.NormalContainer;
import cd.casic.ci.common.pipeline.container.TriggerContainer;
import cd.casic.ci.common.pipeline.container.VMBuildContainer;
import cd.casic.ci.common.pipeline.enums.BuildStatus;
import cd.casic.ci.common.pipeline.enums.JobRunCondition;
import cd.casic.ci.common.pipeline.option.JobControlOption;
import cd.casic.framework.commons.util.reflect.ReflectUtil;
import java.util.*;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.utils
* @Projectops-pro
* @nameModelUtils
* @Date2025/03/26 15:53
* @FilenameModelUtils
* @descriptionTodo
*/
public class ModelUtils {
public static void initContainerOldData(Container c) {
if (c instanceof NormalContainer) {
if (c.getJobControlOption() == null) {
c.setJobControlOption(new JobControlOption(
true,
c.getMaxRunningMinutes(),
String.valueOf(c.getMaxRunningMinutes()),
c.isEnableSkip() ? (c.getConditions() != null && !c.getConditions().isEmpty() ? JobRunCondition.CUSTOM_VARIABLE_MATCH_NOT_RUN : JobRunCondition.STAGE_RUNNING) : JobRunCondition.STAGE_RUNNING,
c.getConditions()
));
}
} else if (c instanceof VMBuildContainer) {
if (c.getJobControlOption() == null) {
c.setJobControlOption(new JobControlOption(
true,
c.getMaxRunningMinutes(),
String.valueOf(c.getMaxRunningMinutes()),
JobRunCondition.STAGE_RUNNING
));
}
}
}
public static boolean canManualStartup(TriggerContainer triggerContainer) {
return triggerContainer.getElements().stream().anyMatch(element -> element instanceof ManualTriggerElement && ((ManualTriggerElement) element).elementEnabled());
}
public static boolean canRemoteStartup(TriggerContainer triggerContainer) {
return triggerContainer.getElements().stream().anyMatch(element -> element instanceof RemoteTriggerElement && ((RemoteTriggerElement) element).elementEnabled());
}
public static boolean stageNeedPause(TriggerContainer triggerContainer) {
return triggerContainer.getElements().stream().anyMatch(element -> element instanceof RemoteTriggerElement && ((RemoteTriggerElement) element).elementEnabled());
}
public static void refreshCanRetry(Model model) {
var lastStage = model.getStages().get(model.getStages().size() - 1);
if (lastStage.isFinally() && BuildStatus.parse(lastStage.getStatus()).isRunning()) {
return;
}
for (var s : model.getStages()) {
var stageStatus = BuildStatus.parse(s.getStatus());
s.setCanRetry(stageStatus.isFailure() || stageStatus.isCancel());
for (var c : s.getContainers()) {
initContainerOldData(c);
var jobStatus = BuildStatus.parse(c.getStatus());
c.setCanRetry(jobStatus.isFailure() || jobStatus.isCancel());
if (c.isCanRetry()) {
refreshContainer(c);
}
}
}
}
private static void refreshContainer(Container container) {
var failElements = new ArrayList<Element>();
container.getElements().forEach(element -> refreshElement(element, failElements));
}
private static void refreshElement(Element element, List<Element> failElements) {
var additionalOptions = element.getAdditionalOptions();
if (additionalOptions == null || !additionalOptions.isEnable()) {
return;
}
var taskStatus = BuildStatus.parse(element.getStatus());
if (!taskStatus.isFailure() && !taskStatus.isCancel()) {
element.setCanRetry(null);
element.setCanSkip(null);
return;
}
element.setCanRetry(additionalOptions.isManualRetry());
if (additionalOptions.isContinueWhenFailed()) {
if (additionalOptions.isManualSkip()) {
element.setCanSkip(true);
} else {
element.setCanRetry(null);
}
} else if (additionalOptions.getRunCondition() == RunCondition.PRE_TASK_FAILED_ONLY ||
additionalOptions.getRunCondition() == RunCondition.PRE_TASK_FAILED_BUT_CANCEL ||
additionalOptions.getRunCondition() == RunCondition.PRE_TASK_FAILED_EVEN_CANCEL) {
element.setCanRetry(null);
element.setCanSkip(null);
failElements.forEach(e -> {
e.setCanSkip(null);
e.setCanRetry(null);
});
}
if (element.isCanRetry()) {
failElements.add(element);
}
}
public static Model generatePipelineBuildModel(Map<String, Object> baseModelMap, Map<String, Object> modelFieldRecordMap) {
var modelStr = JsonUtil.toJson(generateBuildModelDetail(baseModelMap, modelFieldRecordMap), false);
return JsonUtil.to(modelStr, Model.class);
}
public static Map<String, Object> generateBuildModelDetail(Map<String, Object> baseModelMap, Map<String, Object> modelFieldRecordMap) {
modelFieldRecordMap.forEach((fieldRecordName, fieldRecordValue) -> {
if (!ReflectUtil.isCollectionType(fieldRecordValue)) {
baseModelMap.put(fieldRecordName, fieldRecordValue);
} else if (baseModelMap.get(fieldRecordName) == null) {
baseModelMap.put(fieldRecordName, fieldRecordValue);
} else {
if (fieldRecordValue instanceof Map<?, ?> && !((Map<?, ?>) fieldRecordValue).isEmpty()) {
var baseDataMap = (Map<String, Object>) baseModelMap.get(fieldRecordName);
var varDataMap = (Map<String, Object>) fieldRecordValue;
baseModelMap.put(fieldRecordName, generateBuildModelDetail(baseDataMap, varDataMap));
} else if (fieldRecordValue instanceof List<?> && !((List<?>) fieldRecordValue).isEmpty()) {
var baseDataList = (List<Object>) baseModelMap.get(fieldRecordName);
var varDataList = (List<Object>) fieldRecordValue;
handleListFieldMergeBus(baseDataList, varDataList);
}
}
});
return baseModelMap;
}
private static void handleListFieldMergeBus(List<Object> baseDataList, List<Object> recordDataList) {
for (int index = 0; index < recordDataList.size(); index++) {
var listItemObj = recordDataList.get(index);
if (!ReflectUtil.isCollectionType(listItemObj)) {
if (index > baseDataList.size() - 1) {
baseDataList.add(listItemObj);
} else {
baseDataList.set(index, listItemObj);
}
} else {
if (listItemObj instanceof Map<?, ?> && !((Map<?, ?>) listItemObj).isEmpty()) {
var baseListItemDataMap = index > baseDataList.size() - 1 ? new HashMap<String, Object>() : (Map<String, Object>) baseDataList.get(index);
var varListItemDataMap = (Map<String, Object>) listItemObj;
baseDataList.set(index, generateBuildModelDetail(baseListItemDataMap, varListItemDataMap));
} else if (listItemObj instanceof List<?> && !((List<?>) listItemObj).isEmpty()) {
var baseListItemDataList = index > baseDataList.size() - 1 ? new ArrayList<Object>() : (List<Object>) baseDataList.get(index);
var varListItemDataList = (List<Object>) listItemObj;
handleListFieldMergeBus(baseListItemDataList, varListItemDataList);
}
}
}
}
public static Set<String> getModelAtoms(Model model) {
var atomCodes = new HashSet<String>();
for (var stage : model.getStages()) {
for (var container : stage.getContainers()) {
for (var element : container.getElements()) {
atomCodes.add(element.getAtomCode());
}
}
}
return atomCodes;
}
}

View File

@ -0,0 +1,46 @@
package cd.casic.ci.common.pipeline.utils;
import cd.casic.ci.common.pipeline.pojo.BuildParameters;
import cd.casic.framework.commons.util.json.JsonUtils;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.utils
* @Projectops-pro
* @nameParameterUtils
* @Date2025/03/26 15:57
* @FilenameParameterUtils
* @descriptionTodo
*/
public class ParameterUtils {
public static String getListValueByKey(List<BuildParameters> list, String key) {
var valueMap = list.stream().filter(params -> params.getKey().equals(key)).map(BuildParameters::getValue).collect(Collectors.toList());
return !valueMap.isEmpty() ? valueMap.get(0).toString() : null;
}
public static String element2Str(Element element) {
var elementStr = JsonUtils.toJsonString(element);
return elementStr.length() > 65534 ? null : elementStr;
}
public static Map<String, Object> getElementInput(Element element) {
return getParamInputs(element.genTaskParams());
}
public static Map<String, Object> getParamInputs(Map<String, Object> taskParams) {
var json = taskParams.get("data");
if (json == null) {
return null;
}
var inputData = JsonUtil.toMap(json).get("input");
if (inputData == null) {
return null;
}
return JsonUtil.toMap(inputData);
}
}

View File

@ -0,0 +1,38 @@
package cd.casic.ci.common.pipeline.utils;
import com.alibaba.fastjson.JSONObject;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.utils
* @Projectops-pro
* @nameTransferUtil
* @Date2025/03/26 16:09
* @FilenameTransferUtil
* @descriptionTodo
*/
public class TransferUtil {
public static Map<String, Object> simplifyParams(JSONObject defaultValue, Map<String, Object> input) {
return input.entrySet().stream()
.filter(entry -> {
var inputValue = entry.getValue();
if (defaultValue.containsKey(entry.getKey())) {
return !new JSONObject(entry.getKey(), defaultValue.get(entry.getKey())).similar(new JSONObject(entry.getKey(), inputValue));
}
return true;
})
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
public static Map<String, Object> mixParams(JSONObject defaultValue, Map<String, Object> input) {
var out = input != null ? new HashMap<>(input) : new HashMap<>();
if (defaultValue != null) {
defaultValue.toMap().forEach((k, v) -> out.putIfAbsent(k, v));
}
return out;
}
}

View File

@ -0,0 +1,36 @@
package cd.casic.ci.common.pipeline.utils;
import java.util.List;
/**
* @Authormianbin
* @Packagecd.casic.ci.common.pipeline.utils
* @Projectops-pro
* @nameTriggerElementPropUtils
* @Date2025/03/26 16:09
* @FilenameTriggerElementPropUtils
* @descriptionTodo
*/
public class TriggerElementPropUtils {
public static ElementProp vuexInput(String name, String value) {
if (value == null || value.isBlank()) {
return null;
}
return new ElementProp(name, value.split(","), ElementPropType.VUEX_INPUT);
}
public static ElementProp staffInput(String name, List<String> value) {
if (value == null || value.isEmpty()) {
return null;
}
return new ElementProp(name, value, ElementPropType.STAFF_INPUT);
}
public static ElementProp selector(String name, List<String> value) {
if (value == null || value.isEmpty()) {
return null;
}
return new ElementProp(name, value, ElementPropType.SELECTOR);
}
}